日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

函数指针与回调函数详解

發(fā)布時間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数指针与回调函数详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

函數(shù)指針回調(diào)函數(shù)詳解

1.什么是函數(shù)指針?

函數(shù)(的)指針就是指針。這個指針存放一個函數(shù)的地址,而函數(shù)的名稱就該函數(shù)的入口,即地址。這類似于數(shù)組名就是數(shù)組的首地址。我們可以通過反匯編直觀的查看到函數(shù)名和函數(shù)地址的關(guān)系。

080483c4 <rfun>:80483c4: 55 push %ebp80483c5: 89 e5 mov %esp,%ebp80483c7: 83 ec 28 sub $0x28,%esp······80483f3: e8 cc ff ff ff call 80483c4 <rfun>······

第一行080483c4就是函數(shù)在內(nèi)存中的地址,后面的 rfun 就是函數(shù)名,還可以看出第二行和第一行的地址相同,所以可以知道函數(shù)名就是該函數(shù)的入口地址。?
第6行的call 80483c4 rfun就是再次調(diào)用這個函數(shù),回到這個函數(shù)的入口出執(zhí)行,可以看出該函數(shù)是一個遞歸函數(shù)。

2.函數(shù)指針的使用

2.1調(diào)用函數(shù)

我們就用函數(shù)指針調(diào)用剛才的rfun函數(shù)。

int rfun(unsigned x);//函數(shù)的聲明

通過函數(shù)的聲明,可以得到rfun函數(shù)的返回值類型,參數(shù)類型和參數(shù)個數(shù)。這些都是定義指針函數(shù)的必要條件!既然函數(shù)名就是函數(shù)地址,我們就可以用一個指針指向它,函數(shù)指針如下:

int (*pfun)(unsigned);//函數(shù)指針的定義 pfun = rfun;//函數(shù)指針的初始化

pfun就是指針變量,可以直接用函數(shù)名rfun賦值給pfun這個指針。函數(shù)指針在調(diào)用時和函數(shù)調(diào)用一致,只是用指針代替了函數(shù)名。

pfun(x);//函數(shù)指針的調(diào)用

函數(shù)指針不能自增和自減操作,否則程序會崩潰。

2.2作為函數(shù)的參數(shù)

函數(shù)指針作為A函數(shù)的參數(shù),A函數(shù)稱為回調(diào)函數(shù)。A函數(shù)的定義為:

int rfun_call(int (*pfun)(unsigned), unsigned x) {return pfun(x); }

這個函數(shù)的第一個參數(shù)是一個返回值為int類型,參數(shù)為一個且是unsigned類型函數(shù)的指針,第二個參數(shù)是 unsigned類型。

3.什么是回調(diào)函數(shù)?

回調(diào)函數(shù)(Callback Functions)就是一個通過函數(shù)指針調(diào)用的函數(shù)。

如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)。剛才的rfun_call就是一個回調(diào)函數(shù)。這個函數(shù)是自己寫的,下面就用系統(tǒng)感受一下的回調(diào)函數(shù)。

先說明兩個Linux系統(tǒng)函數(shù),一個是alarm函數(shù),一個是signal函數(shù)

①alarm函數(shù),也稱為鬧鐘函數(shù),它可以在進程中設置一個定時器,當定時器指定的時間到時,它向進程發(fā)送SIGALRM信號。

#include <unistd.h>//alarm的頭文件 unsigned int alarm(unsigned int seconds);//alarm的函數(shù)原型

②signal函數(shù),執(zhí)行了signal()調(diào)用后,進程只要接收到類型為sig的信號,不管其正在執(zhí)行程序的哪一部分,就立即執(zhí)行func()函數(shù)。當func()函數(shù)執(zhí)行結(jié)束后,控制權(quán)返回進程被中斷的那一點繼續(xù)執(zhí)行。

#include <signal.h>//signal函數(shù)的頭文件typedef void (*sighandler_t)(int);//sighandler_t是一個指向返回值為void,參數(shù)為int的函數(shù)指針 sighandler_t signal(int signum, sighandler_t handler);//signal函數(shù)的原型

描述一個場景:?
你要睡覺,只睡2秒,所以你定了一個2秒的鬧鐘,到第3秒時,鬧鐘給你發(fā)信號,說時間到了

#include <stdio.h> #include <unistd.h> #include <signal.h>void fun(int signum) {printf("時間到了,起床!\n"); }int main() {int i;alarm(3);//定2秒鬧鐘,第3秒會響鈴,也就是發(fā)信號signal(SIGALRM, fun);//接收鬧鈴的信號,去執(zhí)行fun()for(i = 0; i < 3; i++){sleep(1);//描述時間的流逝printf("%d秒過去了\n", i+1);}printf("睡覺結(jié)束");return 0; }

執(zhí)行結(jié)果如下:

[root@menwen-linux test]# ./callback 1秒過去了 2秒過去了 時間到了,起床! 3秒過去了 睡覺結(jié)束

在時間到第三秒的時候,signal函數(shù)執(zhí)行了fun函數(shù),執(zhí)行完fun函數(shù),就會繼續(xù)執(zhí)行“睡覺結(jié)束”。?
如果不設置鬧鈴(注釋alarm(3)),程序就會一直按順序執(zhí)行,直到程序結(jié)束,永遠不會執(zhí)行回調(diào)函數(shù)。?
signal函數(shù)就是一個回調(diào)函數(shù),接收一個函數(shù)指針,和一個信號量SIGALRM,在Linux內(nèi)核代碼中,SIGALRM等信號其實是一堆宏定義,都對應一個數(shù)值

#define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 #define SIGILL 4 ...... #define SIGPIPE 13 #define SIGALRM 14 #define SIGTERM 15 #define SIGSTKFLT 16 #define SIGCHLD 17 等等.....

或者命令行輸入kill -l 也會對應出現(xiàn)這個信號量。

[menwen@menwen-linux 6th_day]$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM ...... 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX

回調(diào)函數(shù)不是由該函數(shù)的實現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時由另外的一方調(diào)用的,用于對該事件或條件進行響應。我們實現(xiàn)了fun函數(shù),而我們不調(diào)用該函數(shù),而是去睡覺(或者干其他事),等到時間到,回調(diào)函數(shù)就會去響應,這是一種系統(tǒng)異步處理的機制。

總結(jié)

以上是生活随笔為你收集整理的函数指针与回调函数详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。