首先,贴上一段代码和它的运行结果。
#include
#include
typedef char (*fnp)() ;//声明函数指针的时候是不需要带参数的,但是要规定返回值
int fn1(char a , int b)
{
return a;
}
char fn2(char a , int b ,int c)
{
return a;
}
//这样是一个返回为返回值为int的函数
int (* intptr_function())()
{
return fn1;//返回值是fn1
}
int main(int argc, char *argv[])
{
void *p = fn1;
void *p0 = fn1(8 , 90);//这是错误的,p0保存的是函数的返回值
fnp p1 = fn1; //p1、p2是函数指针的正规用法
fnp p2 = fn2 ;
printf("Values of function p? are :\n%d\t%d\t%d\t%d\n\n" ,
((fnp)p)(4,5), //将p强制转换成函数指针类型
p0, p1(4,6) ,
p2(9,6,3)) ;
printf("Sizes of these values are :\n%d\t%d\t%d\t%d\n\n" ,
sizeof(((fnp)p)(4,5) ),
sizeof(p0), //结果为4,因为p0是void*类型,
sizeof(p1(4,6)) ,
sizeof(p2(9,6,3))) ;
printf("Values of function p? are :\n%d\t%d\t%d\t%d\n\n" ,
((int(*)())p)(4,5), //此处与上不同,
//p被强制转换成int(*)()类型的指针,
//指向返回值为int的函数
p0, p1(4,6) ,
p2(9,6,3)) ;
printf("Sizes of these values are :\n%d\t%d\t%d\t%d\n\n" ,
sizeof(((int(*)())p)(4,5) ), //结果为4,因为强制转换后反函数返回值为int型
sizeof(p0),
sizeof(p1(4,6)) ,
sizeof(p2(9,6,3))) ;
/***************使用返回值为函数的函数指针*****************/
int (* (*fnptr)())();//这是一个指向返回为返回值为int的函数
fnptr = intptr_function ;
printf("The result of that function is %d.\n" , fnptr()(9,6));
return 0;
}
函数指针的声明形如:
char (*fnp)(char, char)
其实可以不必声明参数,即:
char (*fnp)()
在这里,使用 typedef char (*fnp)() ; 来定义fnp为返回值为char类型的指针。
函数名是指向函数本身的指针,但是,把函数赋值给void * 类型的指针,并不是像下面这样。
void *p0 = fn1(8 , 90);
这样子做,只是意味着,在p0初始化的时候,把fn1(8,90)的运算结果赋值给它。
我们通过打印sizeof(p0)可以看出,它到底只是一个指针类型的变量,而不是我们函数的返回值char类型。
正确的方法是把函数名赋值给void*型指针变量,然后,把它强制转换为函数指针类型再传入参数执行。
void *p = fn1;//函数名赋值给p
((fnp)p)(4,5);//把p强制转换为函数指针后执行
强制转换的方法除了像上文,先typedef为某个类型,还可以如下,不过比较晦涩:
((int(*)())p)(4,5);//它的类型是(int(*)()
最后还有一个老生常谈的问题,定义一个返回值为函数的函数指针,即函数A执行的结果是一个指针,而这个指针指向函数B。
最直观的方法当然是先把函数B的函数指针typedef,然后再去定义函数A的函数指针。形如:
typedef char (*fnp)() ;
fnp (*ptr) ();//ptr就是返回值为函数的函数指针
或者直接这样声明:
int (* (*fnptr)())();
那么这个返回值为函数指针的函数怎么写?
同样,最直观可以写成:
fnp intptr_function()
{
/******/
}
也可以写成:
int (* intptr_function())()
{
return fn1;//返回值是fn1
}