【不在混淆的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);
}

執行結果

Tags: