您好,登錄后才能下訂單哦!
小編給大家分享一下函數(shù)指針和回調(diào)函數(shù)的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
一. 函數(shù)指針
關(guān)于函數(shù)指針的概念,可以想到一個(gè)整型指針指向的是一個(gè)整型,它的值是所指向?qū)ο蟮牡刂?;一個(gè)字符串指針指向的是一個(gè)字符串,它的值是所指向字符串的首地址;因此,一個(gè)函數(shù)指針當(dāng)然是一個(gè)指針變量了,它所指向的是一個(gè)函數(shù),它的值就是所指向函數(shù)的入口地址。
函數(shù)指針的定義如下:
typedef int data_type; data_type (*pfun)(data_type, data_type);
上面的語(yǔ)句中定義了一個(gè)函數(shù)指針pfun,它表示指向一個(gè)返回值為data_type,參數(shù)為兩個(gè)data_type類(lèi)型的函數(shù),上面第一個(gè)括號(hào)也就是(*pfun)的括號(hào)不能省略,否則就會(huì)變成:
data_type *pfun(data_type, data_type);
這樣的話就為聲明一個(gè)函數(shù)名為pfun的函數(shù)了,它的返回值為data_type*,參數(shù)為兩個(gè)data_type類(lèi)型的參數(shù);
下面舉個(gè)栗子說(shuō)明函數(shù)指針的使用:
#include <iostream> using namespace std; typedef int data_type; data_type add(data_type& a, data_type& b) { return (a + b); } int main() { data_type a = 2; data_type b = 3; data_type (*pfun)(data_type&, data_type&); pfun = &add; cout<<pfun(a, b)<<endl; return 0; }
上面的程序中實(shí)現(xiàn)了一個(gè)函數(shù)add,并且定義了一個(gè)函數(shù)指針pfun指向這個(gè)函數(shù),對(duì)函數(shù)指針的賦值和使用其他指針賦值語(yǔ)句一樣,可以取函數(shù)的地址直接賦過(guò)去,但是因?yàn)楹瘮?shù)名作為函數(shù)的入口地址,因此也可以不加取地址操作符“&”而直接將函數(shù)名賦給函數(shù)指針;要注意的是,函數(shù)指針的定義中,參數(shù)類(lèi)型、個(gè)數(shù)和返回值必須和要指向的函數(shù)原型中的參數(shù)類(lèi)型、個(gè)數(shù)和返回值一一對(duì)應(yīng);
運(yùn)行程序會(huì)得到結(jié)果5;
指針在C/C++中是一個(gè)很靈活的變量,它可以指向與自己類(lèi)型相同的不同存儲(chǔ)空間,比如在數(shù)組中通??梢杂弥羔榿?lái)操縱,但這里值得注意的是,在一個(gè)數(shù)組或者字符串中使用指針進(jìn)行加減操作會(huì)進(jìn)行相應(yīng)的移位指向下一個(gè)空間,有整型指針數(shù)組也就自然會(huì)有函數(shù)指針數(shù)組,它的數(shù)組成員都是一個(gè)個(gè)指向某個(gè)函數(shù)的函數(shù)指針,而在這樣的數(shù)組中用指針進(jìn)行加減操作就指向的是不同的函數(shù)指針也就是不同的函數(shù)了,單純的對(duì)一個(gè)函數(shù)指針進(jìn)行加減操作是不能夠的,它并不會(huì)指向在當(dāng)前函數(shù)上面或下面定義的某個(gè)函數(shù)。
像給一個(gè)整型指針賦值一樣,可以給一個(gè)函數(shù)指針賦予不同的函數(shù),這樣就可以靈活的用一個(gè)指針來(lái)調(diào)用不同的函數(shù)而不用將每個(gè)函數(shù)都顯式的寫(xiě)出來(lái)。
二. 回調(diào)函數(shù)
上面談?wù)摰暮瘮?shù)指針其實(shí)就是在為談回調(diào)函數(shù)做鋪墊,什么是回調(diào)函數(shù)?其實(shí)回調(diào)函數(shù)就是函數(shù)指針的一種使用,用戶自己定義一個(gè)函數(shù),將這個(gè)指向這個(gè)函數(shù)的函數(shù)指針作為參數(shù)傳遞給一個(gè)系統(tǒng)函數(shù)或者中間函數(shù),當(dāng)這個(gè)系統(tǒng)函數(shù)或中間函數(shù)執(zhí)行的時(shí)候調(diào)用這個(gè)函數(shù)指針去執(zhí)行用戶定義的函數(shù),那么用戶定義的這個(gè)函數(shù)就叫做回調(diào)函數(shù)。
為什么會(huì)有回調(diào)函數(shù)呢?難道就不能在一個(gè)函數(shù)里面直接調(diào)用用戶所寫(xiě)的函數(shù)而不是傳參過(guò)去嗎?這種直接使用被調(diào)用函數(shù)的用法是在我們知道調(diào)用函數(shù)的內(nèi)部實(shí)現(xiàn)機(jī)制的情況下直接寫(xiě)入的,那么,如果調(diào)用函數(shù)是系統(tǒng)內(nèi)部函數(shù)或者是別人所給的一個(gè)函數(shù)借口呢?再如果有一種設(shè)計(jì)需求,要求執(zhí)行一個(gè)函數(shù)但并不知道調(diào)用該函數(shù)的函數(shù)是如何操縱的呢?這樣就沒(méi)辦法直接在調(diào)用函數(shù)內(nèi)部寫(xiě)入被調(diào)用函數(shù)了,而是需要傳入一個(gè)函數(shù)地址,至于該函數(shù)是如何調(diào)用如何來(lái)實(shí)現(xiàn)的,我們并不需要關(guān)心。
從上面的分析來(lái)看,回調(diào)函數(shù)的使用并不是你傳給我,我調(diào)用你,而是還需要有一個(gè)起始的函數(shù)來(lái)調(diào)用系統(tǒng)函數(shù)或者中間函數(shù)將回調(diào)函數(shù)的地址作為參數(shù)給傳過(guò)去,可畫(huà)圖說(shuō)明:
圖中的虛線,如果中間函數(shù)是系統(tǒng)函數(shù),首先會(huì)由起始函數(shù)調(diào)用系統(tǒng)函數(shù)而由用戶態(tài)進(jìn)入內(nèi)核態(tài)去由執(zhí)行操作系統(tǒng)的函數(shù),然后系統(tǒng)函數(shù)內(nèi)部會(huì)執(zhí)行調(diào)用用戶實(shí)現(xiàn)的一個(gè)callback函數(shù)而從內(nèi)核態(tài)再返回到用戶態(tài)去執(zhí)行調(diào)用callback函數(shù),我個(gè)人認(rèn)為也可以這么理解回調(diào)函數(shù)的回調(diào)二字,因此虛線是用戶態(tài)和內(nèi)核態(tài)的一個(gè)劃分;但如果中間函數(shù)并不是系統(tǒng)函數(shù),那么就一直會(huì)在用戶態(tài)而不會(huì)接觸到系統(tǒng)內(nèi)部。
栗子時(shí)間:
#include <iostream> using namespace std; void print() { //代碼 cout<<"hello..."<<endl; //代碼 } void say_hello(void (*pfun)(void)) { //代碼 pfun(); //代碼 } int main() { //代碼 say_hello(print); //代碼 return 0; }
上面就是一個(gè)再簡(jiǎn)單不過(guò)的小栗子,注釋掉的代碼就可以是用戶自己其他的實(shí)現(xiàn),而如果栗子中的say_hello函數(shù)是系統(tǒng)函數(shù)或者是別人傳過(guò)來(lái)的一個(gè)函數(shù)接口的話,其內(nèi)部實(shí)現(xiàn)我們是無(wú)法干涉和了解的,因此,只需要將我們希望執(zhí)行的回調(diào)函數(shù)地址給傳過(guò)去,從而完成我們需要回調(diào)函數(shù)來(lái)完成的任務(wù)就可以了。
以上是“函數(shù)指針和回調(diào)函數(shù)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。