亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

C語言中的函數指針學習筆記

2020-01-26 14:38:15
字體:
來源:轉載
供稿:網友

一、定義函數指針

return_type (*func_pointer)(parameter_list)

普通指針變量的定義

int * p;char * pointer;

類型的限定都在變量前面;
函數指針類型的限定是前后都有,前面是返回類型,后面是輸入參數。

2016420154232853.png (449×127)

利用typedef 可以簡化上面的表達方式。

typedef return_type (*FunctionPointer) (parameter_list);FunctionPointer func_pointer;

這樣是不是容易讀了,和上面的功能一樣,定義了一個返回類型為return_type ,輸入參數為parameter_list的函數指針。

二、定義返回函數指針的函數
return_type(*function(func_parameter_list))(parameter_list)

2016420154256143.png (558×129)

方框圈出來的表示返回類型為函數指針,剩下的部分就表示一個function函數,輸入參數為func_parameter_list。
它就等價于 FunctionPointer function(func_parameter_list); 。
再看看:

void ( *signal( int sig, void (* handler)( int )))( int );

2016420154323228.png (400×63)

signal是一個返回函數指針的函數,signal的輸入為int 變量和一個函數指針。

三、函數指針的使用

#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; }

函數名會被隱式的轉變為指針,前面加*和&操作符都不起作用,printf的結果都是3。

四、神奇的代碼

int (*(*pf())())(){ return nullptr; }

哇哦,這是個什么函數!畫個框框分解它

2016420154405912.png (400×63)

小框表示返回的是一個函數指針,在圈個大框,又是一個函數指針。
它就表示,pf() 返回的是一個函數指針,這個函數指針對應一個無輸入參數的函數:返回值也是函數指針(對應無輸入參數的函數,返回值為int類型)。好復雜啊,有點暈!
利用typedef 簡化一下。

typedef int(*Fun1) (); typedef Fun1(*Fun2) (); Fun2 pf() {    return nullptr; }

這樣看就舒服多了。

五、這又是什么鬼!

(*(void(*) ())0)();

畫個框看看:

2016420154437319.png (299×61)

小框里代表一個函數指針,常數前面加括號代表類型的強制轉換。咦,它把0強制轉換成了一個函數指針,并執行!這是什么操作啊!
六、一段驗證代碼

#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); }

函數名前面加不加*,&操作符,都是一個效果;函數指針前面加不加*操作符是一個效果,但是加上&操作符就代表著取指針的地址了。
可以通過typedef int Function(int, int); 為一種類型的函數定義別名,但是使用的時候只能定義指針形式的變量:

Function* fuction = fun1;

七、一個問題
在stackoverflow上偶爾看到如下的問題,代碼如下

#includevoid hello() { printf("hello"); }int hello_1(){    printf("hello 1");    return 0;} int main(void) {  (*****hello)();  (****hello_1)();}

   執行結果是無論hello前面有多少個指針符號,都是執行hello()函數,打印“hello”。
  為什么出現這樣的結果呢:
    用指針指向一個函數是OK的,但是仍然還要被轉化為一個function pointer。其實使用*來指向一個函數 == CALL這個函數。因此無論指向多少次,仍然也是調用這個函數。
為什么一個函數會被轉化成一個指針呢?答案就是將函數默認的轉換成函數指針,可以減少&的使用,編譯器默認的將函數轉化為函數指針,也省得你每次調用函數時加*調用函數。
  哈哈,也就是我們之前說的,函數即指針。似乎有點不是很清晰,再看下面的例子

void foo() {    printf("Foo to you too!.../n");}; int a = 2;int* test(){    return &a;}int main(){  int i;  void (*p1_foo)() = foo;  void (*p2_foo)() = *foo;  void (*p3_foo)() = &foo;  void (*p4_foo)() = *&foo;  void (*p5_foo)() = &*foo;  void (*p6_foo)() = **foo;  void (*p7_foo)() = **********************foo;   (*p1_foo)();  (*p2_foo)();  (*p3_foo)();  (*p4_foo)();  (*p5_foo)();  (*p6_foo)();  (*p7_foo)();  i = *(***test)();printf("i=%d/n",i);}

上面的列子不出例外,都能正常打印我們想要的數據。
但是對于&,則要進行仔細的分析一下:
&對于一個函數的操作,是返回一個指針,指向函數的指針,如果在對此指針執行&也就是&&foo,則會返回error,因為&foo是一個指針數值,也就是一個rvalue類型,再對他進行&操作,顯然是返回error的。

&&foo  //EROOR&*&*&*&*&*&*foo //OK&******&foo  //OK

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲女人天堂视频| 欧美激情在线狂野欧美精品| 色狠狠av一区二区三区香蕉蜜桃| 国产男女猛烈无遮挡91| 久久在线观看视频| 亚洲第一天堂无码专区| 中文字幕精品一区久久久久| 亚洲国产第一页| 亚洲天堂精品在线| 国产精品一区二区三区成人| 91亚洲精品久久久久久久久久久久| xvideos成人免费中文版| 日韩三级影视基地| 国产精品视频最多的网站| 亚洲а∨天堂久久精品9966| 亚洲国产精品悠悠久久琪琪| 亚洲风情亚aⅴ在线发布| 黄色成人在线播放| 日韩成人网免费视频| 亚洲欧美日韩精品| www.xxxx欧美| 精品国内自产拍在线观看| 激情亚洲一区二区三区四区| 九九久久精品一区| 午夜精品久久久久久99热| 日韩av成人在线| 久青草国产97香蕉在线视频| 亚洲欧美国产日韩中文字幕| 国产日韩av在线播放| 亚洲欧美精品伊人久久| 日韩暖暖在线视频| 欧美疯狂性受xxxxx另类| 久久精品福利视频| 成人午夜两性视频| 欧美日韩一区二区三区| 欧美裸身视频免费观看| 色视频www在线播放国产成人| 亚洲欧美制服中文字幕| 国产精品爱久久久久久久| 亚洲一区中文字幕在线观看| 国产欧美久久久久久| 日韩小视频网址| 久久久国产一区| 国产精自产拍久久久久久| 欧美日韩不卡合集视频| 91精品啪在线观看麻豆免费| 国产精品草莓在线免费观看| 国产91色在线播放| 欧洲中文字幕国产精品| 亚洲欧美另类在线观看| 成人午夜在线视频一区| 日韩av最新在线观看| 亚洲激情视频在线播放| 九色成人免费视频| 久久久久久美女| 97精品视频在线| 国产在线视频91| 色哟哟网站入口亚洲精品| 色综合天天狠天天透天天伊人| 一区二区欧美久久| 亚洲国产美女精品久久久久∴| 日本一区二区三区在线播放| 亚州av一区二区| 91免费福利视频| 成人有码在线播放| 中文字幕成人精品久久不卡| 国产成人拍精品视频午夜网站| 欧美激情手机在线视频| 亚洲精品成人久久| 在线观看日韩www视频免费| 成人精品福利视频| 日韩高清电影好看的电视剧电影| 精品一区二区三区四区| 一级做a爰片久久毛片美女图片| 国产精品久久久久99| 91地址最新发布| 国产精品久久久久久久久借妻| 精品视频—区二区三区免费| 久久久精品在线| 国产日韩欧美视频在线| 亚洲免费av电影| 国产ts一区二区| 日本在线精品视频| 欧洲日韩成人av| 国产欧美日韩精品专区| 亚洲综合精品伊人久久| 久久久999国产| 成人情趣片在线观看免费| 国产脚交av在线一区二区| 九九热视频这里只有精品| 久久精品成人欧美大片| 在线电影欧美日韩一区二区私密| 欧美激情一区二区久久久| 国产精品69av| 国产精品日韩在线一区| 国产欧美欧洲在线观看| 亚洲美女av在线| 91精品一区二区| 国产亚洲精品久久久优势| 国产一区红桃视频| 国语自产精品视频在免费| 国产伦精品免费视频| 欧美孕妇毛茸茸xxxx| 国产69精品久久久| 日韩精品中文字| 911国产网站尤物在线观看| 亚洲精品国产电影| 另类美女黄大片| 成人欧美在线观看| 中文国产成人精品久久一| 亚洲精品wwww| 欧美在线视频观看免费网站| 国产专区欧美专区| 在线看欧美日韩| 欧美中文字幕精品| 中文字幕日韩欧美在线视频| 日韩中文综合网| 一色桃子一区二区| 国产精品爽黄69| 中文字幕无线精品亚洲乱码一区| 亚洲一区999| 亚州国产精品久久久| 亚洲欧美国产制服动漫| 国产成人综合精品在线| 亚洲成色www8888| 伊人精品在线观看| 欧美一区二区三区图| 456亚洲影院| 黑人与娇小精品av专区| 国产精品一区二区三区久久久| 欧美性xxxx18| 欧美激情高清视频| 亚洲奶大毛多的老太婆| 亚洲人成网站999久久久综合| 91视频8mav| 亚洲毛片在线看| 久久久极品av| 国产精品96久久久久久又黄又硬| 亚洲丝袜av一区| 亚洲国产精品国自产拍av秋霞| 国产精品美女久久久免费| 国产有码在线一区二区视频| 国产精品第七十二页| 欧美视频一区二区三区…| 国产视频精品xxxx| 国产精品久久久久不卡| 尤物九九久久国产精品的特点| 欧美一区二粉嫩精品国产一线天| 中文字幕av日韩| 国产精品亚洲片夜色在线| 国产成人av网址| 欧美三级免费观看| 精品露脸国产偷人在视频| 久久精品国产免费观看| 亚洲一区亚洲二区亚洲三区| 日韩成人久久久| 欧美日韩国产丝袜另类| 91精品综合久久久久久五月天| 欧美国产日韩一区二区在线观看| 日韩综合中文字幕| 国产亚洲视频在线观看| 欧美理论电影在线观看| 亚洲成色777777在线观看影院| 国产精品久久久久久一区二区|