【不在混淆的C】指針函數、函數指針、回調函數
一、指針函數
函數的返回值是指針類型。
int* fun(int a,int b);
指針函數使用:
返回字元串
這裡要注意,”1234567890abc”是字元串常量,*p指向的字元串地址,返回的是這個地址,因為字元串常量不會因為函數消亡而釋放,所有主函數依然可以訪問到地址的內容。
#include <stdio.h> char* str(){ char *p="1234567890abc"; return p; } void main(){ printf("%s",str()); }
返回申請堆空間的內容
#include <stdio.h> int* str(){ //申請堆空間 int *p=malloc(20*sizeof(int)); //列印地址 printf("addr p:%d\r\n",p); //數據存儲 for(int i=0;i<20;i++){ p[i]=i; } return p; } void main(){ //調用 int *p=str(); //地址 printf("addr p:%d\r\n",p); //數據輸出 for(int i=0;i<20;i++) { printf("%d",p[i]); } //釋放堆空間 free(p); }
二、函數指針
如int類型指針(int* p)一樣,是一種指針類型
定義了一個函數,那麼編譯時系統就會為這個函數程式碼分配一段存儲空間,這段存儲空間的首地址稱為這個函數的地址。而函數名表示的就是這個地址。既然是地址我們就可以定義一個指針變數來存放,這個指針變數就叫作函數指針變數,簡稱函數指針。
定義形式:
返回值類型 (*函數指針變數名)(形參1類型,形參2類型,…)
如函數原型:
int fun1(int a,int b);
函數指針為:
int (*funp)(int,int)
如函數原型:
void fun2();
函數指針為:
void (*fun2p)();
使用時直接將函數名賦值給函數指針(指針變數名)即可,如:
#include <stdio.h> //找最大值 int max(int a,int b){ if(a>b) return a; return b; } //找最小值 int min(int a,int b){ if(a<b) return a; return b; } void main(){ //定義函數指針變數 pfun int (*pfun)(int,int); //賦值函數指針,找最大值 pfun=max;//或者為&max int c=pfun(10,20); printf("%d\r\n",c); //賦值函數指針,找最小值 pfun=min; //或者為&min c=pfun(10,20); printf("%d\r\n",c); }
輸出:
三、 回調函數
回調函數其實就是使用函數指針作為函數的形參
#include <stdio.h> //找最大值 int max(int a,int b){ if(a>b) return a; return b; } //找最小值 int min(int a,int b){ if(a<b) return a; return b; } //函數入口 int all(int a,int b,int (*pfun)(int,int)){ return pfun(a,b); } void main(){ int c=0; //找最大值調用 c=all(10,20,max); printf("%d\r\n",c); //找最小值調用 c=all(10,20,min); printf("%d\r\n",c); }
無返回值和無參數
#include <stdio.h> void pa(){ printf("aaaaaaaaaaaa\r\n"); } void pb(){ printf("bbbbbbbbbbbb\r\n"); } int pall(void (*pfun)()){ pfun(); } void main(){ pall(pa); pall(pb); }
執行結果