深入解析C++中函數(shù)指針及其數(shù)組、typedef關(guān)鍵字用法舉例
一、函數(shù)指針變量的創(chuàng)建
1、什么是函數(shù)指針變量?
類(lèi)比整型指針和數(shù)組指針的概念,我們可以得出:函數(shù)指針變量是用來(lái)存放函數(shù)地址的變量,通過(guò)這個(gè)地址我們可以調(diào)用相應(yīng)的函數(shù)。
2、函數(shù)是否有地址?
通過(guò)以下測(cè)試代碼可以驗(yàn)證:
#include <stdio.h>
void test() {
printf("hehe\n");
}
int main() {
printf("test: %p\n", test);
printf("&test: %p\n", &test);
return 0;
}輸出結(jié)果:

結(jié)果表明函數(shù)確實(shí)有地址,且函數(shù)名就是函數(shù)的地址,也可以通過(guò)&函數(shù)名的方式獲取函數(shù)地址。(重點(diǎn)!?。。?/span>
3、創(chuàng)建函數(shù)指針變量
函數(shù)指針變量的聲明語(yǔ)法與數(shù)組指針類(lèi)似:
void test() {
printf("hehe\n");
}
// 兩種等效的函數(shù)指針聲明方式
void (*pf1)() = &test;
void (*pf2)() = test;
int Add(int x, int y) {
return x + y;
}
// 函數(shù)指針聲明,參數(shù)名可省略
int (*pf3)(int, int) = Add;
int (*pf4)(int x, int y) = &Add;4、函數(shù)指針類(lèi)型解析
以int (*pf3)(int x, int y)為例:int (*) (int x, int y) 為pf3函數(shù)指針變量的類(lèi)型

二、函數(shù)指針變量的使用
通過(guò)函數(shù)指針調(diào)用函數(shù)的示例:
#include <stdio.h>
int Add(int x, int y) {
return x + y;
}
int main() {
int(*pf)(int, int) = Add;
// 兩種等效的調(diào)用方式
printf("%d\n", (*pf)(2, 3)); // 顯式解引用
printf("%d\n", pf(3, 5)); // 隱式調(diào)用
return 0;
}輸出結(jié)果:

三、兩段有趣的代碼
以下兩段有趣的代碼出自《C陷阱和缺陷》:
1、解釋(*(void (*)())0)();
這段代碼的功能是:調(diào)用位于內(nèi)存地址0處的函數(shù)。
讓我們逐步解析:
void (*)():這是一個(gè)函數(shù)指針類(lèi)型,表示"指向一個(gè)沒(méi)有參數(shù)且返回void的函數(shù)的指針"。(void (*)())0:將整數(shù)值0強(qiáng)制轉(zhuǎn)換為上述函數(shù)指針類(lèi)型。這表示"把地址0當(dāng)作一個(gè)函數(shù)的地址"。*(void (*)())0:解引用這個(gè)函數(shù)指針,得到位于地址0處的函數(shù)。(*(void (*)())0)():最后調(diào)用這個(gè)函數(shù)(通過(guò)函數(shù)指針調(diào)用)。
實(shí)際意義:這段代碼嘗試調(diào)用內(nèi)存地址0處的函數(shù)。在嵌入式系統(tǒng)中,這可能是調(diào)用復(fù)位向量或啟動(dòng)代碼的方式。但在大多數(shù)現(xiàn)代操作系統(tǒng)中,這會(huì)引發(fā)段錯(cuò)誤(segmentation fault),因?yàn)榈刂?通常是被保護(hù)的區(qū)域。
2、解釋void (*signal(int, void(*)(int)))(int);
這是一個(gè)函數(shù)聲明,聲明了名為signal的函數(shù)。讓我們分解它:
- 最內(nèi)層:
void(*)(int):這是一個(gè)函數(shù)指針類(lèi)型,表示"指向一個(gè)接受int參數(shù)且返回void的函數(shù)的指針"。 signal(int, void(*)(int)):signal是一個(gè)函數(shù),它接受兩個(gè)參數(shù):一個(gè)int、一個(gè)上述類(lèi)型的函數(shù)指針- 整個(gè)聲明:
void (*signal(int, void(*)(int)))(int):表示signal函數(shù)返回一個(gè)函數(shù)指針,這個(gè)指針指向"接受int參數(shù)且返回void的函數(shù)"。
更易讀的寫(xiě)法(使用typedef,下面會(huì)講解):
typedef void (*sighandler_t)(int); // 定義函數(shù)指針類(lèi)型 sighandler_t signal(int signum, sighandler_t handler);
實(shí)際意義:這是Unix/Linux系統(tǒng)中用于設(shè)置信號(hào)處理器的標(biāo)準(zhǔn)函數(shù)聲明。它:
- 接受一個(gè)信號(hào)編號(hào)(int)和一個(gè)處理該信號(hào)的函數(shù)指針
- 返回之前為該信號(hào)設(shè)置的處理函數(shù)指針
四、typedef關(guān)鍵字
typedef用于類(lèi)型重命名,可以簡(jiǎn)化復(fù)雜類(lèi)型的聲明。
1、基本用法
typedef unsigned int uint; // 將unsigned int重命名為uint typedef int* ptr_t; // 將int*重命名為ptr_t
2、對(duì)于數(shù)組指針和函數(shù)指針的重命名
新的類(lèi)型名必須在*的右邊:
typedef int(*parr_t)[5]; // 將數(shù)組指針類(lèi)型int(*)[5]重命名為parr_t typedef void(*pfun_t)(int); // 將函數(shù)指針類(lèi)型void(*)(int)重命名為pfun_t
3、使用typedef簡(jiǎn)化代碼void (*signal(int, void(*)(int)))(int);
typedef void(*pfun_t)(int); pfun_t signal(int, pfun_t);
五、函數(shù)指針數(shù)組
數(shù)組是存放相同類(lèi)型數(shù)據(jù)的存儲(chǔ)空間。我們已經(jīng)學(xué)過(guò)指針數(shù)組:
int *arr[10]; // 數(shù)組的每個(gè)元素是int*
如果要存儲(chǔ)函數(shù)地址,就需要使用函數(shù)指針數(shù)組。函數(shù)指針數(shù)組的定義方式:
int (*parr1[3])(); // 正確:包含3個(gè)函數(shù)指針的數(shù)組,每個(gè)指針指向返回int的無(wú)參函數(shù)
下面是錯(cuò)誤用法:
int *parr2[3](); // 錯(cuò)誤:錯(cuò)誤語(yǔ)法 int (*)() parr3[3]; // 錯(cuò)誤:錯(cuò)誤語(yǔ)法
解析parr1:
parr1先與[]結(jié)合,說(shuō)明它是一個(gè)數(shù)組- 數(shù)組的內(nèi)容是
int (*)()類(lèi)型的函數(shù)指針
函數(shù)指針數(shù)組常用于實(shí)現(xiàn)狀態(tài)機(jī)或回調(diào)函數(shù)機(jī)制,是C語(yǔ)言中一種強(qiáng)大的編程技術(shù)。
到此這篇關(guān)于深入解析C++中函數(shù)指針及其數(shù)組、typedef關(guān)鍵字用法舉例的文章就介紹到這了,更多相關(guān)C++函數(shù)指針 typedef關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于CLion配置visual?studio(msvc)和JOM多核編譯的問(wèn)題
這篇文章主要介紹了CLion配置visual?studio(msvc)和JOM多核編譯,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
C++ OpenCV模擬實(shí)現(xiàn)微信跳一跳
這篇文章主要介紹了使用C++和OpenCV模擬實(shí)現(xiàn)微信跳一跳功能,本文圖文并茂通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12
使用Qt開(kāi)發(fā)一個(gè)簡(jiǎn)易圖片查看器的完整指南
本文介紹了使用Qt開(kāi)發(fā)一個(gè)簡(jiǎn)易圖片查看器的完整過(guò)程,項(xiàng)目通過(guò)3個(gè)核心控件(QLabel、QLineEdit、QPushButton)實(shí)現(xiàn)圖片選擇、路徑顯示和圖片預(yù)覽功能,感興趣的小伙伴可以了解下2026-05-05
C語(yǔ)言詳細(xì)分析講解關(guān)鍵字const與volatile的用法
在C語(yǔ)言中,我們經(jīng)常會(huì)見(jiàn)到const和volatile這兩個(gè)關(guān)鍵字,那么我們今天就來(lái)介紹下這兩個(gè)關(guān)鍵字,提起?const?關(guān)鍵字,我們可能首先想到的是經(jīng)過(guò)它修飾的變量便是常量了。其實(shí)我們這種想法是錯(cuò)誤的,其實(shí)?const?修飾的變量是只讀的,其本質(zhì)還是變量2022-04-04
C++ boost::asio編程-域名解析詳細(xì)介紹
這篇文章主要介紹了C++ boost::asio編程-域名解析詳細(xì)介紹的相關(guān)資料,這里附有實(shí)例代碼,幫助大家學(xué)習(xí)理解這部分知識(shí),需要的朋友可以參考下2016-11-11

