天天看點

C/C++中的指針函數與函數指針,以及函數指針在回調函數和函數指針數組中的應用

首先,我們先要明确一點,函數指針是一個指針,隻不過這個指針指向的對象有些特殊,是一個函數。指針函數是一個函數,隻不過函數的傳回值是一個指針。

一、指針函數,指針函數的一般定義格式是:

類型* 函數名(形參清單)

{

      語句塊;

      return 傳回值;

}

舉個例子如下:

#include <stdio.h>

#include <string.h>

char* fun(char p[],int n)

{   

   char *buf;

   buf = p; 

   return buf;

}

int main()

{

   char str[]="pointer";

   printf("%s",fun(str,strlen(str)));

   return 0;

}
           

編譯及運作結果如下

C/C++中的指針函數與函數指針,以及函數指針在回調函數和函數指針數組中的應用

二、函數指針

       1.函數指針的定義格式:

          傳回類型 (*函數指針名)(形參類型清單);//注:可以沒有形參類型清單,但要有 () 表示形參類型及個數在指派時決定

          例如:int (*fun)(int);  這就定義了一個指向傳回值為int型,形參為int型的函數的函數指針 fun。

        2.函數指針的指派:

              有這麼一個和fun指針比對的函數fun1,那麼它的指派為:fun = fun1;

       int fun1(int n)

      {

          printf("%d\n",n);

          return 0;

       }

      3.函數指針的一個應用是回調函數,下面我們定義倆個不同的.cpp檔案,實作一個回調函數

       第一個檔案fs.cpp  

/*NULL的頭檔案*/

#include <stddef.h>

extern int fun1(int n);

int(*g_funp)(int)=NULL;

int fun(int(*funp)(int n))

{

  fun1(100);

  g_funp = funp;

  return 0;

}
           

第二個檔案test.cpp

#include <stdio.h>

#include <string.h>

/*回調函數*/

extern int fun(int (*funp)(int n));

int fun1(int n)

{

   printf("%d\n",n);

   return 0;

}

int main()

{

   fun(fun1);

   return 0;

}
           

編譯及運作結果如下:

C/C++中的指針函數與函數指針,以及函數指針在回調函數和函數指針數組中的應用
C/C++中的指針函數與函數指針,以及函數指針在回調函數和函數指針數組中的應用

程式分析:

 main函數調用fun函數,并傳遞一個函數指針fun1,在fun函數中又去回調fun1函數,其中在fs.cpp檔案中又定義了一個函數指針g_funp,并在fun中将傳過來的參數指派給它,目的是以後能在fs.cpp中其他函數中調用這個fun1(當然這個是在fun1定義成static時的一種處理,fun1如果沒有定義成static時直接使用extern聲明調用即可),一般函數指針在linux中的寫法常是被封裝成結構體的一個成員,然後在傳參的時候把整個結構體傳過去,接着再去處理函數指針這個成員。

4.函數指針的另一個應用,函數指針數組

      對于有多個函數調用時,正常我們會通過輸入的編号結合switch case去調用對應的函數,那麼當函數個數十分龐大時就         使用switch case的效率就十分低了,為此我們引入函數指針數組

舉個例子如下:

#include <stdio.h>

int add(int a,int b)
{
    return a+b;
}

int dec(int a,int b)
{
    return a-b;
}

int seq(int a)
{
    return a*a;
}

int main()
{
   /*因為函數的參數個數既有一個的也有倆個的是以定義成()這種形式*/
    int (*funparry[3])()={add,dec,seq};
    int i=0,data1=0,data2=0,ret; 
    while(1)
    {
      printf("0. add\n");
      printf("1. dec\n");
      printf("2. seq\n");
      printf("select number\n");
      scanf("%d",&i);
      if(i==2)
      {
          printf("input data1\n");
          scanf("%d",&data1);
          ret = funparry[i](data1);
      }
      else
      {
          printf("input data1 and data2\n");
          scanf("%d %d",&data1,&data2);
          ret = funparry[i](data1,data2);
      }
      printf("result is %d\n",ret);
    }

   return 0;
}
           

執行結果如下:

C/C++中的指針函數與函數指針,以及函數指針在回調函數和函數指針數組中的應用