C語(yǔ)言進(jìn)階:指針的進(jìn)階(4)
函數(shù)指針
函數(shù)指針的定義
整型指針存放整型的地址;數(shù)組指針存放數(shù)組的地址;那么類(lèi)比可得,函數(shù)指針存放函數(shù)的地址。
顯然,函數(shù)指針指向函數(shù),存放函數(shù)的地址。搞懂函數(shù)指針,先了解函數(shù)的地址。
&函數(shù)名或函數(shù)名代表函數(shù)地址,與&數(shù)組名和數(shù)組名略有不同,&函數(shù)名和函數(shù)名完全一致。
函數(shù)的地址必然要放到函數(shù)指針里,函數(shù)指針的類(lèi)型該如何寫(xiě)呢?(以Add函數(shù)為例)
//整型指針 int* pa = &a; //字符指針 char* pc = &ch; //數(shù)組指針 int(*pa)[10] = &arr; //函數(shù)指針 - 存放函數(shù)地址 int(*pf)(int, int) = &Add;
函數(shù)指針的類(lèi)型
int Add(int x, int y); //1. int(*pf)(int, int) = &Add; //2. int *pf(int, int) = &Add;
倘若,去掉括號(hào)
int* pf(int, int),
pf就變成函數(shù)名,返回類(lèi)型是int*。所以指針必須帶括號(hào)。
前文已交代,指針,去掉指針名和*就是指針?biāo)赶虻淖兞款?lèi)型。
- 整型指針,去掉*和指針名,即為整型變量類(lèi)型int。字符指針,為字符類(lèi)型char。數(shù)組指針,去掉后為數(shù)組類(lèi)型int[10]。
- 函數(shù)指針,去掉*和指針名,即為函數(shù)的類(lèi)型int(int,int)。
總結(jié)
- 去掉指針名pf,即為指針類(lèi)型
int(*)(int, int)
- 去掉指針名pf和*,即為指針?biāo)赶虻暮瘮?shù)類(lèi)型為
int(int, int)
函數(shù)指針的使用
計(jì)算機(jī)硬件程序經(jīng)常通過(guò)調(diào)用地址的方式來(lái)調(diào)用函數(shù),因此需要使用函數(shù)指針調(diào)用函數(shù)。
int Add(int x, int y) { return x + y; } int main() { //1. int(*pf)(int, int) = &Add;//函數(shù)指針指向Add函數(shù) //2. int(*pf)(int, int) = Add; //1. int ret = (*pf)(2, 3); //2. int ret = pf(2, 3); printf("%d\n", ret); return 0; }
前面已經(jīng)交代,&函數(shù)名和函數(shù)名都是函數(shù)的地址,完全等價(jià)。所以?xún)煞N初始化函數(shù)指針的方式都可以。
既然函數(shù)名Add
可以直接賦值給函數(shù)指針pf,說(shuō)明二者等價(jià)。函數(shù)指針名pf不解引用也可以使用,*在此處形同虛設(shè),甚至于不寫(xiě)或?qū)懚鄠€(gè)都并無(wú)大礙,僅為理解。
既然函數(shù)名也是函數(shù)地址,所以對(duì)其解引用也是可以的。我們甚至可以這樣寫(xiě),但僅限娛樂(lè),沒(méi)有必要。
Add(2, 3);//1 (*Add)(2, 3);//2 (*&Add)(2, 3);//3
Example
解釋下列代碼
//1. (*(void(*)())0)(); //2. void (*signal(int, void(*)(int)))(int);
1.void(*)()
是函數(shù)指針類(lèi)型,放在( )0中,也就是把0強(qiáng)制轉(zhuǎn)換成地址,該地址處存放一個(gè)函數(shù)其類(lèi)型為void(*)(void)
。
2.這樣(void(*)())0
就變成了指針,指向該地址的函數(shù),且對(duì)其解引用訪(fǎng)問(wèn)此函數(shù)。
3.(*(void(*)())0)
也相當(dāng)于(*pf)
,通過(guò)函數(shù)指針解引用代替函數(shù)名,函數(shù)名后面帶上();
,相當(dāng)于(*pf)();
也就是一次不傳參的函數(shù)調(diào)用。
1.signal先和()結(jié)合,說(shuō)明signal為函數(shù)名,其后(int, void(*)(int)),為其參數(shù)列表。
2.去掉函數(shù)名稱(chēng)和參數(shù)列表,剩下的void(*)(int)就是返回類(lèi)型,所以是一次函數(shù)聲明。
void (* signal(int, void(*)(int)) ) (int); typedef void(* pf_t)(int);//typedef簡(jiǎn)化代碼 pf_t signal(int, pf_t);
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)圖片轉(zhuǎn)pdf
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)圖片轉(zhuǎn)pdf功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以了解一下2022-06-06C++實(shí)現(xiàn)學(xué)生考勤信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生考勤信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12C語(yǔ)言詳解熱門(mén)考點(diǎn)結(jié)構(gòu)體內(nèi)存對(duì)齊
C?數(shù)組允許定義可存儲(chǔ)相同類(lèi)型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是?C?編程中另一種用戶(hù)自定義的可用的數(shù)據(jù)類(lèi)型,它允許你存儲(chǔ)不同類(lèi)型的數(shù)據(jù)項(xiàng),本篇讓我們來(lái)了解C?的結(jié)構(gòu)體內(nèi)存對(duì)齊2022-04-04基于C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的音樂(lè)系統(tǒng)
C++中的Beep 函數(shù)是一個(gè)發(fā)出嗡鳴聲的函數(shù),本文將利用這個(gè)函數(shù)實(shí)現(xiàn)制作一個(gè)簡(jiǎn)單的聲音系統(tǒng)。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-12-12Visual Studio2022+QT6創(chuàng)建桌面應(yīng)用實(shí)現(xiàn)
本文主要介紹了Visual Studio2022+QT6創(chuàng)建桌面應(yīng)用實(shí)現(xiàn),文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02C/C++實(shí)現(xiàn)線(xiàn)性順序表的示例代碼
使用順序存儲(chǔ)結(jié)構(gòu)的線(xiàn)性存儲(chǔ)結(jié)構(gòu)的表為線(xiàn)性順序表。本文將分別利用C語(yǔ)言和C++實(shí)現(xiàn)線(xiàn)性順序表,文中示例代碼講解詳細(xì),需要的可以參考一下2022-05-05C語(yǔ)言不用鏈表完成學(xué)生管理系統(tǒng)(完整代碼)
這篇文章主要介紹了C語(yǔ)言不用鏈表完成學(xué)生管理系統(tǒng)(完整代碼),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)詳解小白篇
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ),非常適合初學(xué)數(shù)據(jù)結(jié)構(gòu)的小白,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-09-09