瀏覽博客時看到這樣一個函數(shù),linux下的signal 函數(shù):void ( signal( int sig, void ( handler)( int )))( int );
雖說學(xué)過C語言但是看不懂啊失驶!沒學(xué)明白朝卒。研究了一下挡育,記錄下來吧驱还。
一、定義函數(shù)指針
return_type (*func_pointer)(parameter_list)
普通指針變量的定義
int * p;
char * pointer;
類型的限定都在變量前面胀莹;
函數(shù)指針類型的限定是前后都有,前面是返回類型婚温,后面是輸入?yún)?shù)描焰。
利用typedef 可以簡化上面的表達方式。
typedef return_type (*FunctionPointer) (parameter_list);
FunctionPointer func_pointer;
這樣是不是容易讀了缭召,和上面的功能一樣栈顷,定義了一個返回類型為return_type ,輸入?yún)?shù)為parameter_list的函數(shù)指針嵌巷。
二萄凤、定義返回函數(shù)指針的函數(shù)
return_type(*function(func_parameter_list))(parameter_list)
方框圈出來的表示返回類型為函數(shù)指針,剩下的部分就表示一個function函數(shù)搪哪,輸入?yún)?shù)為func_parameter_list靡努。
它就等價于 FunctionPointer function(func_parameter_list); 。
再看看:void ( *signal( int sig, void (* handler)( int )))( int );
signal是一個返回函數(shù)指針的函數(shù)晓折,signal的輸入為int 變量和一個函數(shù)指針惑朦。
三、函數(shù)指針的使用
#include <stdio.h>
int add(int a, int b);
void main()
{
int(*fun1)(int a, int b) = add;
int(*fun2)(int a, int b) = &add;
int(*fun3)(int a, int b) = *add;
printf("%d\n", fun1(1, 2));
printf("%d\n", fun2(1, 2));
printf("%d\n", fun3(1, 2));
char input[10];
gets(input);
}
int add(int a, int b)
{
return a + b;
}
函數(shù)名會被隱式的轉(zhuǎn)變?yōu)橹羔樌旄牛懊婕?和&操作符都不起作用漾月,printf的結(jié)果都是3。
四胃珍、神奇的代碼
int (*(*pf())())()
{ return nullptr; }
哇哦梁肿,這是個什么函數(shù)蜓陌!畫個框框分解它
小框表示返回的是一個函數(shù)指針,在圈個大框吩蔑,又是一個函數(shù)指針钮热。
它就表示,pf() 返回的是一個函數(shù)指針烛芬,這個函數(shù)指針對應(yīng)一個無輸入?yún)?shù)的函數(shù):返回值也是函數(shù)指針(對應(yīng)無輸入?yún)?shù)的函數(shù)隧期,返回值為int類型)。好復(fù)雜啊赘娄,有點暈仆潮!
利用typedef 簡化一下。
typedef int(*Fun1) ();
typedef Fun1(*Fun2) ();
Fun2 pf()
{
return nullptr;
}
這樣看就舒服多了遣臼。
五鸵闪、這又是什么鬼!
(*(void(*) ())0)();
畫個框看看:
小框里代表一個函數(shù)指針暑诸,常數(shù)前面加括號代表類型的強制轉(zhuǎn)換蚌讼。咦,它把0強制轉(zhuǎn)換成了一個函數(shù)指針个榕,并執(zhí)行篡石!這是什么操作啊西采!
六凰萨、一段驗證代碼
#include <stdio.h>
typedef int Function(int, int);
typedef int(*FunctionPointer1) (int, int);
typedef FunctionPointer1(*FunctionPointer2) ();
int fun1(int a, int b)
{
return a + b;
}
FunctionPointer1 fun2()
{
return fun1;
}
FunctionPointer2 fun3()
{
return fun2;
}
int(*(*fun4())())(int, int)
{
return fun2;
}
void main()
{
Function* fuction = fun1;
FunctionPointer1 fun = fun1;
int a = fun3()()(3, 4);
int b = fun4()()(5, 6);
printf("%d\n%d\n", a, b);
printf("fun1:%d\n*fun1:%d\n&fun1:%d", fun1, *fun1, &fun1);
printf("fun:%d\n*fun:%d\n&fun:%d", fun, *fun, &fun);
char chars[10];
gets(chars);
}
函數(shù)名前面加不加*,&操作符械馆,都是一個效果胖眷;函數(shù)指針前面加不加*操作符是一個效果,但是加上&操作符就代表著取指針的地址了霹崎。
可以通過typedef int Function(int, int); 為一種類型的函數(shù)定義別名珊搀,但是使用的時候只能定義指針形式的變量:
Function* fuction = fun1;
啊偶,到這就算結(jié)束了尾菇。