【不在混淆的C】指標函式、函式指標、回撥函式

東小東發表於2021-02-24

一、指標函式

函式的返回值是指標型別。

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);
}

執行結果

相關文章