指向函数的指针
先说说int (*p) (); 吧,简单的理解,这就可以理解为调用函数,其中(*p)这个整体可以看作是函数名称,p代表函数的入口地址。很简单的理解吗,c语言中()就代表了函数,所以把 *p用括号括在一起变作 (*p)就代表了一个函数。下面举个例子:
#include <stdio.h>
int main()
{
int num;
int choice;
int res;
int *p = NULL;
int change(int a,int (*p)(int a));
int two(int a);
int eight(int a);
//int sixteen(int a);
printf("Enter an integer:");
scanf("%d",&num);
printf("Bin output press 1\
Octal output press 2\
Hex output press 3\
Please enter your choice:\n");
scanf("%d",&choice);
if(choice == 1)
{
printf("Bin:");
change(num, two);
}
if(choice == 2)
{
printf("Octal:");
change(num, eight);
}
if(choice == 3)
{
printf("Hex:");
printf("%X",num);
//change(num, sixteen);
}
printf("\n");
return 0;
}
int change(int a,int (*p)(int a))
{
int res;
res = (*p)(a);
printf("%d\n",res);
}
int two(int a)
{
int i,res=0,k=1;
while( a )
{
i = a % 2;
res = k*i + res;
k = k*10;
a = a /2;
}
return res;
}
int eight(int a)
{
int i,res=0,k=1;
while( a )
{
i = a % 8;
res = k*i + res;
k = k*10;
a = a / 8;
}
return res;
}
个人感觉这个例子很能练习调用函数和指向函数的指针吧。
这个程序功能就是输入一个数字 ,然后对其输出格式进行选择(1代表二进制输出,2代表八进制,3是十六进制输出)。
其中change函数便是一个选择函数,按下1或者2或者3进行对应函数选择工作,主函数中先将num值传递给change,而后change再将其传给two等转换函数,在change函数中,p便是选择指向函数的指针,main函数先将two等函数入口地址传递给change中形参,change函数在对其进行调用。
在这儿由于我是初学者,能力有限,主要还是自己懒,没有把十进制转化为十六进制的算法写出来,请大家见谅。
上述程序中main到change再到two的历程,我也是个初学者,不是很懂,若此文有幸能为大家看见,欢迎留言一起探讨,后期我也将请教我的老师。
上面一个程序如果大家觉得难懂,下面贴一个简单点的程序,加深大家对于指向函数的指针 的理解吧。
#include <stdio.h>
int main()
{
int a = 1;
int b = 1;
int res;
int add(int x,int y);
int (*p)(int m, int n);
p = add;
res = (*p)(a, b);
printf("res = %d\n", res);
return 0;
}
int add(int x,int y)
{
return (x + y);
}
返回指针值的函数
接下来再来说说这个int *p(), 为了便于理解,可以把这个p换成一个函数的名字 ,比如fun,那么
int *fun()代表的是调用这个函数后,这个函数的返回值是一个指针。
接下来我们也来举一个例子
#include <stdio.h>
int main()
{
int week, day;
int *GetDay(int *p_week, int *p_day);
int *p_week = NULL;
int *p_day = NULL;
int *p;
printf("Enter week day:\t");
scanf("%d %d", &week, &day);
p_week = &week;
p_day = &day;
p = GetDay(p_week, p_day);
printf("\nIt is the %dest day of this month",*p);
printf("\n");
return 0;
}
int *GetDay(int *p_week, int *p_day)
{
int week;
int day;
int temp, res;
int *pt = NULL;
week = *p_week;
day = *p_day;
switch(week)
{
case 1:
temp = 0;
break;
case 2:
temp = 7;
break;
case 3:
temp = 14;
break;
case 4:
temp = 21;
break;
case 5:
temp = 28;
break;
}
res = day + temp;
pt = &res;
return (pt);
}
这是一个简单的程序,大致意思是,你输入这个月的第几周的第几天,该程序将其自动转化为这个月的第多少天。其中这个 int *GetDay(int *p_week, int *p_day); 就是一个返回值为指针的函数。他将结果res的地址返回给主函数。
在这儿又想起来了一些琐碎的知识点,在函数调用中,只有通过地址,才能做数据的双向传递,现在回过头来看,我的这个程序当时虽然运行成功了,但是还是存在bug,这个res 变量不应该在GetDay 函数中声明,这样会导致在这个函数调用结束后系统自动收回其内存单元造成错误。
解决办法很简单,其一是在main 与 头文件中定义res为全局变量;另一个方法就是在main函数来定义,在GetDay函数中用 extern 进行声明。
回到正题,文中基类型都是int,其实也可以是别的,比如float,char什么的,如果是float,那么返回的指针指向的就是一个float型数据,其它同理。