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