關於c語言中的復雜原型聲明 分類: 嵌入式開發學習 2011-07-18 23:04 534人閱讀 評論(1) 收藏


c語言中的復雜原型聲明是很多人都頭痛的事,下面我說一下自己的理解。主要是從理解的角度說明聲明的內容。

 

 1.首先是從左往右找到未聲明的標識符,
2.再找將未聲明標識符括起來的最里層的小括號的一大塊,再根據運算符的等級(提醒越是里面的小括號優先級比外面的小括號就有優先,如(*(*func)(int *))將*func括起來的比將*(*func)(int *)括起來的優先)和結合性來分析,當分析時遇到指針時的下一步就應該確定指針指向什么類型 /遇到數組時下一步就確定數組的元素內容是什么個數是多少 /遇到函數時的下一步就確定函數的類型(函數的類型即函數參數是什么返回又是什么)
3.每分析完一層小括號就往外跳到又是將未聲明標識符括起來的一大塊,再根據第2步,如此循環直至將整塊聲明都分析完

下面開始來例子(聲明例子來源於網上的,大家可以在網上找一些關於例子中聲明的分析)

實例1如下:
int (*func)(int);
(網上的分析)
先看標識符,(*func)是一個整體標識符
再看右邊,有(),故這個標識符是表示一個函數,其有一個int型的參數
最后看左邊,有個int,表示這個函數是返回整形
再回溯,(*func)是一個函數,那么func自然是一個指向函數的指針
綜上,func是一個函數指針,該函數有一個整形參數,並返回整形值
上例出自C吧的貼子http://tieba.baidu.com/f?kz=925000075
int (*func)(int);
(根據整理的方法分析)
首先從左往右找到未聲明的標識符(這里是func).再找將標識符括起來的所有小括號中最里層的那個小括號,最里層的小括號括起來的一大塊是(*func),修飾標識符func的是*,所以func是一個指針,現在就開始確定指針指向什么類型,這里因括號里的內容分析完了就跳出來找第二個將它包起來的小括號(由里往外數最里層的小括號為一),往外數這里沒有第二個將標識符括起來的小括號,而只剩int (      ) (int);。再根據優先級來看 int (      ) (int) 中(int)比 int 要高。 所以指針func是一個指向函數的指針(此時要確定函數類型即參數和返回值各是什么) (int)里面是函數的參數即為int, 在int (      ) (int)左邊的int 是函數的返回值

func是一個指針(指向什么),該指針指向一個函數(函數是什么類型即參數和返回值各是什么)。該函數指針指向的函數類型是帶一個int型參數,返回一個int。
或直接說
func是一個指向一個類型(這類型是指指針指向函數的類型)為帶int整形參數返回一個int的函數指針

 

 

 

實例2如下:
int (*func[5])(int *p);
(網上的分析)
func右邊是一個[]運算符,說明func是一個具有5個元素的數組,func的左邊有一個*,說明func的元素是指針,要注意這里的*不是修飾func的,而是修飾func[5]的,原因是[]運算符優先級比*高,func先跟[]結合,因此*修飾的是func[5]。跳出這個括號,看右邊,也是一對圓括號,說明func數組的元素是函數類型的指針,它所指向的函數具有int*類型的形參,返回值類型為int
int (*func[5])(int *p);
(根據整理的方法分析)
首先找未聲明的標識符再找將該標識符括起來的最里層的小括號,即是
(*func[5])根據優先級知func是一個數組(數組元素的內容是什么),此時括號里還有*沒分析。所以*修飾func[ ],即數組元素的內容是指針(指針指向什么),跳出括號再根據優先級得 ( ) 比 int 高,即指針指向函數(函數的參數和返回值是什么),函數的類型帶一個(int *p)參數返回值一個 int。
綜合可得:
func是一個元素個數為5數組(數組元素的內容是什么),數組元素的內容是一個指針(指向什么),該指針指向一個函數(參數和返回值各是什么),函數指針指向的函數類型是帶一個(int *p)參數,返回一個int.
或說:
func是一個元素個數為5的指針數組,該指針數組的內容指向一個類型是帶一個(int *p)參數返回一個int的函數指針
再下面的說法不知行不行?
func是一個元素內容為指向類型是帶一個(int *p)參數返回一個int的函數指針數組,該函數指針數組大小為5

 

 

 

8樓

實例3如下:
int *func(int *)[5];
(根據整理方法的分析)
首先找到未聲明標識符,這里是func,再找小括號(這里沒將它括起來的小括號),根據等級知 ( ) 比 * 高,func是一個函數,函數帶一個(int *)參數,返回什么? 有根據等級知 [ ] 比 * 高,即函數返回一個元素個數為5的數組,數組的元素內容是什么,*修飾數組的內容是指針,int表該指針指向一個int。
綜合來說:
func是一個函數,函數帶一個(int *)形參,返回一個數組元素個數為5的數組,數組元素的內容是指針,該指針指向的類型是int。
或說:
func是一個帶(int *)參數返回一個元素個數為5的指針數組的函數,
指針數組的內容是(int*)。
但函數返回一個元素個數為5的數組正確嗎? NO
則該聲明int *func(int *)[5]不符合規則
若用小括號將*func(int *)括起來呢?
即int ( *func(int *) )[5],請自己動手試試分析該聲明以及判斷正確與否
請根據方法自行分析以下聲明以及判斷正確與否
int *func[5](int*);

 

 

 

實例4如下:
int (*(*func)[5])(int *p);
(網上的分析)
func被一個圓括號包含,左邊又有一個*,那么func是一個指針,跳出括號,右邊是一個[]運算符號,說明func是一個指向數組的指針,現在往左看,左邊有一個*號,說明這個數組的元素是指針,再跳出括號,右邊又有一個括號,說明這個數組的元素是指向函數的指針。總結一下,就是:func是一個指向數組的指針,這個數組的元素是函數指針,這些指針指向具有int*形參,返回值為int類型的函數。
int (*(*func)[5])(int *p);
(根據整理的方法分析)
首先找未聲明的標識符再找將該標識符括起來的最里層的小括號,即(*func)可知func是一個指針(指向什么),跳出括號即到(*(      )[5]),根據優先級知 [ ] 比 * 高;所以指針func指向一個元素個數為5的數組(數組元素的內容是什么),(括號里還有*即)*是修飾數組的元素內容是指針(指針指向什么),再跳出括號即為int (*(      )[ ])(int *p),優先級中( ) 比 * 高,所以指針指向函數(函數的參數和返回是什么),指針指向函數的類型是帶一個(int *p)參數返回一個int。
則綜合分析:
func是一個指針,該指針指向元素個數為5的數組,數組元素的內容是指針,該指針指向類型是一個帶(int *p)參數返回一個int的函數指針。
或說:
func是一個指向元素個數為5的數組指針,該數組元素的內容是一個指向類型為帶一個(int *p)參數返回一個int的函數指針

 

 

 

 

實例7如下:
int (*(*(*func)(int *))[5])(int *);
(網上的分析)
func是一個函數指針,這類函數的返回值是一個指向數組的指針,所指向數組的元素也是函數指針,指向的函數具有int*形參,返回值為int。
(根據整理的方法分析)
(分析提醒:將未聲明的標識符func括起來的小括號有三個(在這例里將*func括起來的小括號(紅色)是第一個/最里層,將*(*func)(int *)括起來的小括號(藍色)是第二個,將*(*(*func)(int *))[5]括起來的小括號(綠色)是第三個/最外層,最里的( )優先級會先屏蔽相對於它來說屬外的( ) ,即在分析時應該是紅色的小括號/(最里的小括號)會屏蔽藍色的小括號/(由里往外數是第二個小括號),分析到藍色的小括號時,藍色的小括號會綠色的小括號/(由里往外數是第三個小括號) ,以此類推 …………
綜合來說就是越是里面的小括號優先級比外面的小括號就有優先級))
int (*(*(*func)(int *))[5])(int *);
首先找到將未聲明的標識符擴起來的最里層小括號,這里是(*func),所以func是一個指針,括號里的全部都分析完了就跳出括號,即到(*(      )(int *)),因( )比*高所以指針func指向函數,指針指向的類型是一個函數,該函數的參數是(int *),*修飾帶一個(int*)形參函數的返回值是指針,第二個括號里的全部也都分析完了就跳出括號即( * ( (     )(     )) [5] ) 因 [ ] 比 * 高,所以函數返回的指針指向元素個數為5的數組,此時括號里的*修飾的是數組元素的內容為指針,第三個括號里的全部也都分析完了就跳出括號
即int (   (   (      ) ( ) ) [ ] )   (int *)又根據優先級知數組元素內容是一個指向函數的指針,該函數類型帶一個(int *)參數,返回一個int數。
則   int (*(*(*func)(int *))[5])(int *);
func是一個指針,指針指向的類型是帶一個(int *)參數返回一個指針,該指針指向元素個數為5的指針數組,該指針數組的元素內容是一個指向類型為帶一個(int *)參數返回一個int的函數指針。
或:
func是一個指向類型為帶一個(int *)參數返回一個指向個數為5的指針數組的函數指針,該指針數組的元素內容指向一個類型為帶(int *)返回int的函數指針

 

 

以下兩例子請自己分析,總結的答案在下面給出(建議讀者學完后到網上找一些更為復雜的例子來鞏固對復雜聲明的分析和理解)
void (*signal(int signum,void(* handler)(int)))(int);
(上面的聲明是signal.h下signal的聲明)

int (*(*func[7][8][9])(int*))[5];

……
……
……
……
……
……
……
……
void
(   *signal ( int signum,void(* handler)(int) )   )
(int);
signal是一個帶( int signum,   void(* handler)(int) )參數返回一個指向類型為帶一個(int)參數無返回的函數指針,signal帶的第一個參數是int,第二個參數是指向類型帶一個int參數無返回的函數指針。

int (*(*func[7][8][9])(int*))[5];
func是一個7*8*9(三維)指針數組,7*8*9(三維)指針數組的元素內容是一個指向類型為一個帶(int*)參數返回一個指向元素個數為5且指向類型為int的數組指針的函數指針
int (*(*func[7][8][9])(int*))[5];
func是一個指向類型是帶一個(int*)返回一個指向元素個數為5且類型是int的數組指針的函數指針數組,該函數指針數組大小為7*8*9.

 

版權聲明:本文為博主原創文章,未經博主允許不得轉載。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: