C語言——函數指針類型轉換
昨天為了避免跨層調用API搞了個回調函數,用了函數指針,因為參數類型的問題總是編譯報錯,今天就看了兩篇博文學習學習,順便做做筆記。
其實正常來講只要把函數指針的參數個數、類型和返回值這些函數指針的標簽或者說是屬性寫對了的話就不會有社么問題,但我也不知道怎么著就會報錯【擦汗】
正好趁著這個機會好好了解一下函數的用時的棧空間和函數指針的使用。
1、函數指針
函數名本就是一個常量指針常量,指向代碼區的函數本體,帶有一些屬性(標簽),就類似于“ int * ”帶有的屬性是“ int ”。
函數指針是和某個函數帶有相同屬性的指針,函數指針被賦值后同樣指向代碼區的函數本體。
更改函數指針的屬性(參數、返回值)并不影響這個指針指向函數本體。
2、參數傳遞
猜測在同一線程中所有函數傳參使用的棧空間的起始地址都是同一個。
同一線程:
1 #include <stdio.h> 3 4 void fi3(int a, int b, int c) 5 { 6 printf("fi3:\t"); 7 printf("%d, %d, %d\n", &a, &b, &c); 8 } 9 10 void mpp(int a, int b,int c) 11 { 12 printf("mpp:\t"); 13 printf("%d, %d, %d\n", &a, &b, &c); 14 } 15 16 17 int main() 18 { 19 void (*I3)(void) = (void (*)(void))fi3; 20 I3(); 21 mpp(7,8,9); 22 return 0; 23 } 24 25 編譯運行: 26 PS F:\tinyxml_2_6_2\tinyxml> gcc .\main.cpp -o pmain 27 PS F:\tinyxml_2_6_2\tinyxml> .\pmain.exe 28 29 輸出結果: 30 fi3: 6422272, 6422276, 6422280 31 mpp: 6422272, 6422276, 6422280
不同線程:
#include <stdio.h> #include <pthread.h> void mpp(int a, int b,int c) { printf("mpp:\t"); printf("%d, %d, %d\n", &a, &b, &c); } void *pthreadFun(void *arg) { mpp(7,8,9); } int main() { float val1 = 1.23; float val2 = 2.34; void *statRet = nullptr; pthread_t tid[2] = {0}; pthread_create(&tid[0], nullptr, pthreadFun, (void *)&val1); pthread_create(&tid[1], nullptr, pthreadFun, (void *)&val2); pthread_join(tid[0], &statRet); pthread_join(tid[1], &statRet); return 0; } 編譯運行: PS F:\tinyxml_2_6_2\tinyxml> gcc .\main.cpp -o pmain -lpthread PS F:\tinyxml_2_6_2\tinyxml> .\pmain.exe 輸出: mpp: 15597240, 15597244, 15597248 mpp: 17694392, 17694396, 17694400
此處貼圖表示線程內函數參數棧空間(我用的是Windows的gcc的編譯環境,地址):

3、函數調用
調用函數時會先將函數形參復制到參數棧空間中,再執行代碼區中的函數體。
函數參數是存在最小傳遞單位的,這里是4字節,可能與進程4G地址空間或是32位CPU帶寬是4byte有關系,這里先留個坑。
每次調用函數參數棧空間中的數據不會被全部置位,而是用到那個單元格的空間就把那個單元格(最小單位)的空間用新的參數覆蓋。
#include <stdio.h> void fc3(char a, char b, char c) { printf("fc3:\t"); printf("%d, %d, %d\n", a, b, c); } void fi3(int a, int b, int c) { printf("fi3:\t"); printf("%d, %d, %d\n", a, b, c); } int main() { fc3(1, 2, 3); void(*F3)(int) = (void (*)(int))fi3; F3(66); return 0; } 編譯運行: PS F:\tinyxml_2_6_2\tinyxml> gcc .\main.cpp -o pmain PS F:\tinyxml_2_6_2\tinyxml> .\pmain.exe 輸出結果: fc3: 1, 2, 3 fi3: 66, 2, 3
關于三篇大佬的博客:

浙公網安備 33010602011771號