C語言基礎及指標④函式指標
接續上篇C語言基礎及指標③函式與二級指標
在上一篇中 , 我們學習了函式與二級指標 , 函式和java中的方法類似 , 只是缺少了訪問控制符 , 二級指標也就是指標的指標 , 指標裡面儲存的是指標的地址 , 可以通過*
操作符不斷往上追溯 , 然後通過記憶體地址操作記憶體空間 。
函式指標
當我們定義一個函式的時候 , 這個函式也會像變數一樣 , 會有一個記憶體地址 , 我們也可以將函式定義成為一個函式指標 , 但函式不同於變數 , 變數儲存的是固定的值 , 而函式指標儲存的是函式的記憶體地址 。下面我就用一個示例來說明:
// windows 彈出框標頭檔案 #include <Windows.h> /*函式*/ void message() { MessageBox(NULL, "我是彈出框", "訊息", NULL); } void main() { // 函式指標定義 , 返回值(函式指標名稱)(函式引數) = 函式名稱 void(*func_p)() = &message; // 呼叫函式指標 func_p(); printf("函式指標地址:%#x\n", func_p); getchar(); }
輸出:
函式指標地址:0xe6d31073
我們可以通過函式指標地址 , 反彙編我們的程式設計師 , 檢視他的跳轉
函式指標彙編1.png
由上圖我們可以看出 , 我們的函式指標 , 通過jmp指令跳轉到另一個地址上 , 下面我來看看message的地址裡面是什麼:
函式指標彙編2.png
我們看到通過函式指標裡面儲存的是一個函式的地址 ,然後通過一個jmp指令調到我們的函式定義執行 。
有了我們的函式指標 , 我們可以做很多事情 , 下面我們來看一個簡單的示例:
int add(int num1, int num2) { return num1 + num2; } int minus(int num1, int num2) { return num1 - num2; } // 將函式指標直接定義到函式形參中 , 類似java中的多型 // 我們可以函式指標作為函式引數傳入 void showMsg(int(*c)(int num1, int num2), int a, int b) { int r = c(a, b); printf("計算完成=%d\n", r); } void main() { showMsg(add, 10, 10); showMsg(minus, 30, 2); } getchar();
輸出:
計算完成=20
計算完成=28
通過傳入函式地址 , 就可以呼叫函式進行運算 , 我們只要按照傳入的引數和返回值 , 寫我們自己的函式 , 通過這個方法 , 我們就可以統一的實現我們函式的功能 。下面我們來寫一個回撥函式:
/*模擬網路請求回撥*/ void requestNet(char* url , void(*callBack)(char *)) { printf("請求地址:%s , 正在請求網路....\n",url); // 模擬網路請求耗時 Sleep(2000); char* str = "我是請求的網路資料 , 落花有意隨流水 , 流水無情戀落花\n"; callBack(str); } /*回撥函式*/ void netCallBack(char *str) { printf("網路請求回撥\n"); printf("請求到的資料:%s" ,str); } void main() { char* url = "www.zhuyongit.com"; requestNet(url, netCallBack); }
輸出:
請求地址:www.zhuyongit.com , 正在請求網路....
網路請求回撥
請求到的資料:我是請求的網路資料 , 落花有意隨流水 , 流水無情戀落花
我們模擬了網路請求的常見封裝 , 使用一個回撥函式來接收我們請求回來的資料 。函式指標很強大 , 我們可以直接傳入函式名稱 , 再另一個函式裡面執行我們傳入的函式 , 如果是在java裡面 ,我還需要傳入一個物件 , 再通過物件來呼叫方法 , 在C語言裡面 , 直接通過函式指標就可以搞定 。
作者:逝我
連結:https://www.jianshu.com/p/181b50e02c89
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。