終于決定開c言語這一塊的文章啦,昨天看了一下c的聲明,發(fā)現(xiàn)網(wǎng)上雖然有很多人在說這件事情,但是都不太透徹,我自己認為我這個理解方式比較簡單,而且實用,可以對付任何復雜的聲明,比如:char *(*(*f(char *(*para)(char *)))[2])();是不是一看這個聲明有點懵?不急,來看看我下面的解析你就覺得這個聲明也很簡單!
復雜聲明中的類型說明符有:()、[]、*三種。其中()用于說明函數(shù)類型以及改變說明的先后順序;[]用于說明數(shù)組類型;*則用于說明指針類型。數(shù)據(jù)類型名可以是int、char、float、double、void等基本類型名,也可以是用戶自定義的構造類型。在解釋復雜聲明時,要按照()、[]優(yōu)先級最高,*次之,而數(shù)據(jù)類型名的優(yōu)先級最低的順序來解釋。當()和[]同時在復雜聲明中出現(xiàn)時,就需要考慮類型說明符的結合性。C語言規(guī)定,類型說明符()和[]的結合性是左結合,即按從左至右的順序進行解釋。
本文為了邏輯清楚,在后面的例子中都會按照優(yōu)先級的順序,將各個類型說明符按從左到右通過箭頭連接的方式來說明。
對于不同的類型說明符,有不同的處理方式。
如果類型說明符為指針,則下一步按照優(yōu)先級,來判斷指針指向的內(nèi)容的類型。
如果類型為函數(shù),首先判斷(???)的參數(shù)???的類型,下一步按照優(yōu)先級判斷返回值的類型。
如果類型為數(shù)組,下一步按照優(yōu)先級來判斷數(shù)組中內(nèi)容的類型。
根據(jù)上面三條規(guī)則,遞歸整個聲明表達式,就可以完全的解釋聲明的內(nèi)容了。
下面來一些例子說明一下:
int (*func)(int);
提取出各個片段之后為:
func -->*-->(int)-->int
通過()改變了結合順序,所以func先和*結合,判斷func為指針。下一步判斷這個指針指向的內(nèi)容,(*func)(int)右面是一個函數(shù)類型說明符,所以func指向的是一個函數(shù),func為函數(shù)指針(func變量的所有信息都已經(jīng)聲明完畢)。接著去判斷func指向的函數(shù),(int)說明這個函數(shù)接收一個int類型的參數(shù)。最后看這個返回值,是int類型。所以總結如下:
func是一個函數(shù)指針,指向一個接收一個int類型參數(shù)并且返回值為int類型的函數(shù)。
int (*func[5])(int *p);
提取出各個片段之后為:
func-->[5]-->*-->(int *p)-->int
由于[]的優(yōu)先級要高于*,所以func先和[5]結合,所以func是一個五個元素的數(shù)組。下一步判斷數(shù)組中的內(nèi)容。接下來是一個*說明這個數(shù)組中的內(nèi)容為指針。下一步判斷這個指針的類型,(int *p)表示這個指針為一個函數(shù)指針,指向的函數(shù)參數(shù)為一個int指針,下一步判斷返回值,int,說明這個函數(shù)返回值的類型是int。
總結:func是一個數(shù)組,數(shù)組中的每一個元素都是一個函數(shù)指針,指向的函數(shù)接收一個int指針參數(shù)并返回一個int值。
int *func(int *)[5];
提取出各個片段:
func-->(int *)-->[5]-->*-->int
func與(int *)結合,說明func為一個函數(shù),改函數(shù)的參數(shù)為int *,下面判斷返回值:返回一個數(shù)組[5],然后判斷數(shù)組里面的元素類型,為指針(*),指針指向一個int。所以總結:
func是一個接收一個int *的函數(shù),返回值為包含5個元素的數(shù)組,數(shù)組元素為指針類型,并且指向int類型。
PS:這個例子的邏輯說明沒有問題,但是實際上是一個不合法的變量聲明,因為這個函數(shù)返回了一個數(shù)組,實際上,在c中是不允許函數(shù)返回值為一個數(shù)組的。
相信到了這個地方,你對c語言的復雜聲明有了一定的了解,接下來我們就來說開頭那個最復雜的變量聲明??!
char *(*(*f(char *(*para)(char *)))[2])();
解釋的順序還是按照上面的順序來:
f-->(char *(*para)(char *))-->*-->[2]-->*-->()-->*-->char
1 2 3 4 5 6 7
看上去挺恐怖的吧,看我一一道來
f與1最先結合,說明f是一個函數(shù),這個函數(shù)接收一個char *(*para)(char *)這種類型的參數(shù)。
先判斷這個參數(shù)的類型:para-->*-->(char *)-->char
para是一個指針,指向一個接收一個char *并返回一個char的函數(shù)。
所以f是一個函數(shù),這個函數(shù)接收的參數(shù)為指向一個接收一個char *參數(shù)并返回一個char的函數(shù)。
接下來分析f函數(shù)的返回值:2為*,所以返回值為一個指針,接下來分析指向的內(nèi)容,3為[2],所以指針指向一個包含2個元素的數(shù)組,下面分析數(shù)組的元素類型,4為*,所以數(shù)組中的類型為指針,分析指針指向的內(nèi)容,5為(),所以這個指針指向一個參數(shù)為空的函數(shù),這個函數(shù)的返回值類型為6*(指針),并且指向一個7char類型。
所以綜上分析:f是一個函數(shù),這個函數(shù)接收一個函數(shù)指針作為參數(shù),這個函數(shù)指針指向一個接收char *參數(shù),并返回一個char的函數(shù),f的返回值為一個指向一個包含兩個元素的數(shù)組的指針,數(shù)組中包含的元類型為一個函數(shù)指針,該函數(shù)指針指向一個參數(shù)為空,返回一個char *的函數(shù)。
是不是很簡單呢?嘿嘿
聯(lián)系客服