組成
三類修飾符號( ),[ ],以及 * 在一個聲明中表示標識符中包含一個函式,數組,或指針類型。複雜聲明符可能包含上面三種符號的任何一種或多種的組合。
三種基本符號的含義如下:
( )
函式返回值類型為... (暗示聲明一個函式)
[ ]
數組的元素類型為... (暗示聲明一個數組)
*
指針指向的類型為... (暗示聲明一個指針)
在聲明符中,這些符號(括弧,中括弧,星號)在表達式中和操作符有相同的優先權和結合性,當然,你可以用額外的括弧來改變他們的解讀順序。例如:
int *abc[10]; // 解析為一個包含10個元素的數組,它的類型是指向int的指針
int (*abc)[10]; // 解析為一個指針,指向的內容是10個元素的數組,數組類型是int.
在聲明符中如果包含了函式類型,()表示函式包含了對參數的聲明,下面的例子聲明了一個指向函式的指針:
int (*fPtr)(double x); // fPtr是一個指向函式的指針,該函式有一個double類型的參數,同時他的返回值是int //類型
解析方法
解析複雜聲明符時,先從標識符開始解析,並重複下面兩個步驟直到所有符號解析完:
1. 如果標示符右邊跟的是左小括弧(()或左中括弧([),那么解析括弧裡面的內容.
2. 否則,如果標示符左邊是星號(*),那就解析星號。
例子1
extern char *(* fTab[ ])(void);
下面的表格說明了解析過程:
| | |
| | |
| | |
3.解析完中括弧,把括弧裡面的解析完,即標識符左邊的* | | |
| | |
| | |
| | |
我們把這個解析串起來:“ ftab是一個數組,數組的類型是一個指向函式的指針,函式沒有形參,並且函式返回值是一個指向char的指針。”
上述例子中fTab 有一個不完整的數組類型,因為它沒有給出數組的大小,在使用該數組之前,必須在其他地方先定義數組的長度。另外,* fTab[ ] 外面的括弧是必要的,沒有的話 fTab就變成了聲明一個數組,數組的元素變成是函式了,這是非法的。
例子2
這個例子說明了怎么聲明一個函式標識符。
float (* func( ))[3][10];
標識符func是...
一個函式,它的返回值類型是...
一個指針,指向...
一個數組,數組有三個元素,元素類型是...
一個數組,數組有10個元素,元素類型是...
float.
換句話說,這個函式 func返回一個指向二維數組(3行10列)的指針。再一次,* func( )周圍的括弧是必要的,沒有括弧會被解析成:返回一個數組,這是非法的。