c語言結構體中的函數指針與函數

1. 函數指針

  一般的函數指針可以這麼定義:

  int(*func)(int,int);

  表示一個指向含有兩個int參數並且返回值是int形式的任何一個函數指針. 假如存在這樣的一個函數:

  int add2(int x,int y)

  {

  return x+y;

  }

  那麼在實際使用指針func時可以這樣實現:

  func=&add2; //指針賦值,或者func=add2; add2與&add2意義相同

  printf("func(3,4)=%d\n",func(3,4));

  事實上,爲了代碼的移植考慮,一般使用typedef定義函數指針類型.

  typedef int(*FUN)(int,int);

  FUN func=&add2;

  func();

  2.結構體中包含函數指針

  其實在結構體中,也可以像一般變量一樣,包含函數指針變量.下面是一種簡單的實現.

  #include "stdio.h"

  struct DEMO

  {

  int x,y;

  int (*func)(int,int); //函數指針

  };

  int add2(int x,int y)

  {

  return x+y;

  }

  void main()

  {

  struct DEMO demo;

  demo.func=&add2; //結構體函數指針賦值

  printf("func(3,4)=%d\n",demo.func(3,4));

  }

  上面的文件保存爲mytest.c,在VC6.0和gcc4中編譯通過.

  3.結構體中的函數

  既然C++在介紹類的時候說過,類是取代結構體的.可見結構體的功能並非我們平時用到的這麼簡單,沒有太多人知道結構體中也可以有自己的函數成員.

  舉個例子:

  #include "stdio.h"

  struct DEMO

  {

  int m;

  DEMO(int k) //構造函數

  {

  this->m=k;

  printf("after init,m=%d\n",m);

  }

  void func()//一般函數

  {

  printf("function of struct.\n");

  }

  };

  void main()

  {

  struct DEMO demo(33);

  demo.func();

  }

  保存爲mytest1.c , VC6.0和gcc編譯都會出錯. 這可能說明標準C是不支持結構體包括函數成員形式的(因爲後綴.c使得VC或gcc選擇c編譯器). 但是如果將文件後綴改爲.cpp(也就是選擇c++編譯),就不再有錯誤了,得到結果:

  after init,m=33

  function of struct.

  也就是說,在C++中允許結構體包含函數成員,而標準C不支持. 進一步發現,c++中甚至允許結構體中含有構造函數、重載、public/private等等.這樣看來,結構體真的與類越來越靠近相似了!

  C++擴充了結構體的功能。但C++中爲了介紹面向對象的類,卻淡化了同樣
精彩的結構體。當我們寫一些小程序而覺得沒有必要去構造類的時候,選擇結構體確實會方便很多.


  ========================================

  函數指針的說明:

  已知函數指針定義聲明 float (*h)();

  怎麼理解語句? (*(void (*)())0)();

  這是一個C語句,表示(*p)(); 其中p指向0, 0被強制轉換成(void (*)())格式。

  或者用typedef將上面式子分成兩步:

  typedef void (*pFUNC)(); //pFUNC表示一種函數指針類型,這樣的函數式void fun()形式.

  (*(pFunc)0)();

  對於這一點,在unix編程signal方面用到過,如下:

  signal函數原型: void (*signal(int signo,void (*func)(int)))(int);

  其第二個參數func是一個void型函數指針(該函數參數爲int),並且返回一個void型函數指針(該函數參數爲int),簡化這個定義, 可以typedef void Sigfunc(int); 然後signal函數原形寫爲 Sigfunc* signal(int,Sigfunc*);

  三個常量用於替代這樣的指針。定義如下:

  #define SIG_ERR (void (*)())-1

  #define SIG_DFL (void (*)())0

  #define SIG_IGN (void (*)())1

  函數應用

  if(signal(SIGUSR1,sig_func)==SIG_ERR)

  err_sys("can't catch SIGUSR1");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章