轉自:這個地方
int*p[4]; // 指針數組。 是個有4個元素的數組,每個元素的是指向整型的指針。 ( 數組的每個元素都是指針 )
int(*p)[4]; // 數組指針。 它是一個指針,指向有4個整型元素的數組。 ( 一個指針指向有 4 個整型元素的數組 )
int*func(void); // 指針函數。 無參函數,返回整型指針。 ( 函數的返回值爲 int* )
int(*func)(void); // 函數指針,可以指向無參,且返回值爲整型指針的函數。 ( 函數的返回值爲 int )
右左法則:首先從最裏面的圓括號(未定義的標識符)看起,然後往右看,再往左看。每當遇到圓括號時,就應該掉轉閱讀方向。一旦解析完圓括號裏面所有的東西,就跳出圓括號。重複這個過程直到整個聲明。
從未定義的標識符開始閱讀,是因爲一個聲明裏面可能有多個標識符,但未定義的標識符只會有一個。
現在通過一些例子來討論右左法則的應用,先從最簡單的開始,逐步加深:
int(*func)(int*p);
首先找到那個未定義的標識符,就是func,它的外面有一對圓括號,而且左邊是一個 * 號,這說明 func 是一個指針,然後跳出這個圓括號,先看右邊,也是一個圓括號,這說明 (*func) 是一個函數,而 func 是一個指向這類函數的指針,就是一個函數指針,這類函數具有 int* 類型的形參,返回值類型是 int。
int(*func)(int*p,int(*f)(int*));
func 被一對括號包含,且左邊有一個 * 號,說明 func 是一個指針,跳出括號,右邊也有個括號,那麼 func 是一個指向函數的指針,這類函數具有 int* 和int(*)(int*) 這樣的形參,返回值爲 int 類型。再來看一看 func 的形參 int(*f)(int*),類似前面的解釋,f 也是一個函數指針,指向的函數具有 int* 類型的形參,返回值爲 int。
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 被一個圓括號包含,左邊又有一個 *,那麼 func 是一個指針,跳出括號,右邊是一個 [] 運算符號,說明 func 是一個指向數組的指針,現在往左看,左邊有一個 * 號,說明這個數組的元素是指針,再跳出括號,右邊又有一個括號,說明這個數組的元素是指向函數的指針。總結一下,就是:func 是一個指向數組的指針,這個數組的元素是函數指針,這些指針指向具有 int* 形參,返回值爲 int 類型的函數。
int(*(*func)(int*p))[5];
func 是一個函數指針,這類函數具有 int* 類型的形參,返回值是指向數組的指針,所指向的數組的元素是具有5個int 元素的數組。
要注意有些複雜指針聲明是非法的,例如:
int func(void)[5];
func 是一個返回值爲具有 5 個 int 元素的數組的函數。但 C 語言的函數返回值不能爲數組,這是因爲如果允許函數返回值爲數組,那麼接收這個數組的內容的東西,也必須是一個數組,但C/C++ 語言的數組名是一個右值,它不能作爲左值來接收另一個數組,因此函數返回值不能爲數組。
int func[5](void);
func 是一個具有 5 個元素的數組,這個數組的元素都是函數。這也是非法的,因爲數組的元素除了類型必須一樣外,每個元素所佔用的內存空間也必須相同,顯然函數是無法達到這個要求的,即使函數的類型一樣,但函數所佔用的空間通常是不相同的。
實際當中,需要聲明一個複雜指針時,如果把整個聲明寫成上面所示的形式,對程序可讀性是一大損害。應該用 typedef 來對聲明逐層分解,增強可讀性,例如對於聲明:
int(*(*func)(int*p))[5];
可以這樣分解:
typedef int(*PARA)[5];
typedef PARA(*func)(int*);
這樣就容易看得多了。
int(*(*func)[5][6])[7][8];
func 是一個指向數組的指針,這類數組的元素是一個具有 5×6 個 int 元素的二維數組,而這個二維數組的元素又是一個二維數組。
如下,typedef 的分解方法:
typedef int(*PARA)[7][8];
typedef PARA(*func)[5][6];
int(*(*(*func)(int*))[5])(int*);
func 是一個函數指針,這類函數的返回值是一個指向數組的指針,所指向數組的元素也是函數指針,指向的函數具有int* 形參,返回值爲int。
typedefint(*PARA1)(int*);
typedef PARA1(*PARA2)[5];
typedef PARA2(*func)(int*);
int(*(*func[7][8][9])(int*))[5];
func 是一個數組,這個數組的元素是函數指針,這類函數具有 int* 的形參,返回值是指向數組的指針,所指向的數組的元素是具有 5 個int 元素的數組。
typedefint(*PARA1)[5];
typedef PARA1(*PARA2)(int*);
typedef PARA2 func[7][8][9];