接續(xù)上篇C語言基礎(chǔ)及指針③函數(shù)與二級(jí)指針
在上一篇中 柒竞, 我們學(xué)習(xí)了函數(shù)與二級(jí)指針 锌钮, 函數(shù)和java中的方法類似 , 只是缺少了訪問控制符 , 二級(jí)指針也就是指針的指針 陡鹃, 指針里面存儲(chǔ)的是指針的地址 , 可以通過*
操作符不斷往上追溯 保礼, 然后通過內(nèi)存地址操作內(nèi)存空間 镐依。
函數(shù)指針
當(dāng)我們定義一個(gè)函數(shù)的時(shí)候 , 這個(gè)函數(shù)也會(huì)像變量一樣 吁断, 會(huì)有一個(gè)內(nèi)存地址 趁蕊, 我們也可以將函數(shù)定義成為一個(gè)函數(shù)指針 , 但函數(shù)不同于變量 仔役, 變量存儲(chǔ)的是固定的值 掷伙, 而函數(shù)指針存儲(chǔ)的是函數(shù)的內(nèi)存地址 。下面我就用一個(gè)示例來說明:
// windows 彈出框頭文件
#include <Windows.h>
/*函數(shù)*/
void message() {
MessageBox(NULL, "我是彈出框", "消息", NULL);
}
void main() {
// 函數(shù)指針定義 , 返回值(函數(shù)指針名稱)(函數(shù)參數(shù)) = 函數(shù)名稱
void(*func_p)() = &message;
// 調(diào)用函數(shù)指針
func_p();
printf("函數(shù)指針地址:%#x\n", func_p);
getchar();
}
輸出:
函數(shù)指針地址:0xe6d31073
我們可以通過函數(shù)指針地址 又兵, 反匯編我們的程序員 任柜, 查看他的跳轉(zhuǎn)
由上圖我們可以看出 , 我們的函數(shù)指針 沛厨, 通過jmp指令跳轉(zhuǎn)到另一個(gè)地址上 宙地, 下面我來看看message的地址里面是什么:
我們看到通過函數(shù)指針里面存儲(chǔ)的是一個(gè)函數(shù)的地址 ,然后通過一個(gè)jmp指令調(diào)到我們的函數(shù)定義執(zhí)行 逆皮。
有了我們的函數(shù)指針 宅粥, 我們可以做很多事情 , 下面我們來看一個(gè)簡(jiǎn)單的示例:
int add(int num1, int num2) {
return num1 + num2;
}
int minus(int num1, int num2) {
return num1 - num2;
}
// 將函數(shù)指針直接定義到函數(shù)形參中 电谣, 類似java中的多態(tài)
// 我們可以函數(shù)指針作為函數(shù)參數(shù)傳入
void showMsg(int(*c)(int num1, int num2), int a, int b) {
int r = c(a, b);
printf("計(jì)算完成=%d\n", r);
}
void main() {
showMsg(add, 10, 10);
showMsg(minus, 30, 2);
}
getchar();
輸出:
計(jì)算完成=20
計(jì)算完成=28
通過傳入函數(shù)地址 粹胯, 就可以調(diào)用函數(shù)進(jìn)行運(yùn)算 蓖柔, 我們只要按照傳入的參數(shù)和返回值 , 寫我們自己的函數(shù) 风纠, 通過這個(gè)方法 况鸣, 我們就可以統(tǒng)一的實(shí)現(xiàn)我們函數(shù)的功能 。下面我們來寫一個(gè)回調(diào)函數(shù):
/*模擬網(wǎng)絡(luò)請(qǐng)求回調(diào)*/
void requestNet(char* url , void(*callBack)(char *)) {
printf("請(qǐng)求地址:%s , 正在請(qǐng)求網(wǎng)絡(luò)....\n",url);
// 模擬網(wǎng)絡(luò)請(qǐng)求耗時(shí)
Sleep(2000);
char* str = "我是請(qǐng)求的網(wǎng)絡(luò)數(shù)據(jù) 竹观, 落花有意隨流水 镐捧, 流水無情戀落花\n";
callBack(str);
}
/*回調(diào)函數(shù)*/
void netCallBack(char *str) {
printf("網(wǎng)絡(luò)請(qǐng)求回調(diào)\n");
printf("請(qǐng)求到的數(shù)據(jù):%s" ,str);
}
void main() {
char* url = "www.zhuyongit.com";
requestNet(url, netCallBack);
}
輸出:
請(qǐng)求地址:www.zhuyongit.com , 正在請(qǐng)求網(wǎng)絡(luò)....
網(wǎng)絡(luò)請(qǐng)求回調(diào)
請(qǐng)求到的數(shù)據(jù):我是請(qǐng)求的網(wǎng)絡(luò)數(shù)據(jù) , 落花有意隨流水 臭增, 流水無情戀落花
我們模擬了網(wǎng)絡(luò)請(qǐng)求的常見封裝 懂酱, 使用一個(gè)回調(diào)函數(shù)來接收我們請(qǐng)求回來的數(shù)據(jù) 。函數(shù)指針很強(qiáng)大 誊抛, 我們可以直接傳入函數(shù)名稱 列牺, 再另一個(gè)函數(shù)里面執(zhí)行我們傳入的函數(shù) , 如果是在java里面 拗窃,我還需要傳入一個(gè)對(duì)象 瞎领, 再通過對(duì)象來調(diào)用方法 , 在C語言里面 随夸, 直接通過函數(shù)指針就可以搞定 九默。
Android程序員學(xué)C系列:
C語言基礎(chǔ)及指針①
C語言基礎(chǔ)及指針②之指針內(nèi)存分析
C語言基礎(chǔ)及指針③函數(shù)與二級(jí)指針
C語言基礎(chǔ)及指針④函數(shù)指針
C語言基礎(chǔ)及指針⑤動(dòng)態(tài)內(nèi)存分配
C語言基礎(chǔ)及指針⑥字符操作
C語言基礎(chǔ)及指針⑦結(jié)構(gòu)體與指針
C語言基礎(chǔ)及指針⑧文件IO
C語言基礎(chǔ)及指針⑨聯(lián)合體與枚舉
C語言基礎(chǔ)及指針⑩預(yù)編譯及jni.h分析