C語言之指針-複雜指針類型解析

1.什麼是複雜指針
int a;
int *a;
int * (*(*a));    

int *(*(*pfun)(int *))[5];
(1)指向指針的指針
通常我們稱int *a,指針a就是一個常見的指向int類型的指針變量。int **a就是一個二級指針,它是一個指向指針的指針,int *是一個整體,被指向對象。
而三級指針int ***a同樣如此, 所指的對象是一個int **類型,所以可稱其爲一個一個指向指針的指針,他所指向的指針指向一個指向整型數的指針。
(2)指針,數組和函數的結合
當指針和數組與函數結合時,一個表達式可能會變得相當複雜。
我們以前領教過形如int *(*pfun)(int *)的函數指針的函數,也見識過int *(*pa)[5]的數組指針的數組。
(3)對於int *(*(*pfun)(int *))[5]
即便如此,我們看到int *(*(*pfun)(int *))[5]這種表達式也會感覺到很奇怪,他到底是數組還是指針或者時函數?
這個時候我們應該一步步的分解它,首先看到他的變量名pfun,它結合了一個*變成*pfun,所以無疑它是一個指針,(*pfun)的之外左邊是*,右邊是(int *)。
當遇到這種情況我們考慮運算符的結合和優先級,所以(*pfun)先結合(int *)形成(*pfun)(int *),這時pfun是一個指向函數的指針。
然後結合左邊的*變成*(pfun)(int *),函數指針pfun返回了一個指針值。(*(*pfun)(int *))之外又面臨和*還有[]結合的問題。
針對此類問題,如果沒有運算符在()內,都是從右往左結合的,(*(pfun)(int *))先結合[5]形成(*(*pfun)(int *))[5]。
我們說函數*(*pfun)(int *)返回了一個指針值,所以(*(*pfun)(int *))結合了一個[5]也就是指向數組的指針,不過這個指針作爲函數指針的返回值。
最後結合外層的*變成*(*(*pfun)(int *))[5]變成一個指針函數,所以這個表達式總體來看是一個int類型的複合指針函數。
我們給int *(*(*pfun)(int *))[5]命一個名爲:一個指針所指向的函數的返回值類型的指針指向5個整型指針的數組。

2.更多複合指針的解析
(1)接下來看看類似的複合指針

int *(*fun[5])(int *);從內到外分別是指針數組,函數指針和指針函數。命名爲五個指針類型的數組,每個指針指向一個返回值爲整型指針的函數。
int (*(*fun)(int *))[5];從內到外分別是函數指針,指針函數和數組指針。
(2)對於int (*printSum(int a, int b, int (*pfun)(int,int)))(int,int)
我們再瞭解了這些指針的結合之後,對於上篇文章中出現的這個函數原型也可以解析一下。
從它函數名printSum開始,先結合(int a, int b, int (*pfun)(int,int))作爲參數(兩個int和一個int型函數指針),它是一個函數。
*printSum(int a, int b, int (*pfun)(int,int))到這個部分,它是一個指針函數,也就是返回值是指針。
int (*printSum(int a, int b, int (*pfun)(int,int)))(int,int)而該指針又和外部的int (int,int)結合形成int (*)(int,int)變成函數指針。
而此函數指針就是他的返回值。它是一個返回函數指針的函數。
這樣就解釋了printSum函數爲什麼不是int (*)(int,int) printSum(int a,int b, int (*pfun)(int,int))。
(3)複合指針的使用案例
一個經典的c語言複合指針案例(*(void(*)())0)();它是一個值強制轉換爲函數指針再進行函數調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章