常見複雜指標宣告的解析 很詳細)

2022-07-22 17:42:16 字數 2952 閱讀 4917

//兩個原則

//右左法則:首先從最裡面的圓括號看起,然後往右看,再往左看。每當遇到圓括號時,就應該掉轉閱讀方向。一旦解析完圓括號裡面所有的東西,就跳出圓括號。重複這個過程直到整個宣告解析完畢。

//堅持使用typedef來進行型別重定義,不確定優先順序的地方可以多加括號。

1. int *p[n];

//這個就是int型指標陣列,即n個int型指標所組成的陣列

2. int (*p)[n];

//首先p是乙個指標,基型別是具有n個int元素的陣列,即陣列指標

3. int (*p[m])[n];或者int (*(p[m]))[n];

//這是乙個陣列指標陣列,怎麼看呢?先看括號內的,*p[m],很顯然這是乙個陣列(優先順序高於*),什麼陣列呢?具有m個指標變數的陣列。括號內的型別是指標,著我們知道了,跳出括號,int (指標)[n],

//是不是很眼熟?看2的形式,所以裡面的指標不是一般的指標,而是具有n個整型資料的陣列指標。

//如果現在我們要定義乙個陣列指標陣列來訪問二維陣列a[5][4],該怎麼定義呢?

//我們就和解析的過程反著來定義就可以了,看到這個名字,「陣列指標陣列」,從左往右看,先看到陣列指標,那我們就先來定義陣列指標,注意,將來是要訪問a[5][4]的(a是乙個具有5個元素的陣列,這5個元

//素每個都是具有4個int資料的一維陣列),將來我們的陣列指標就是要指向這個一維陣列的

//陣列指標定義:int (*p)[4];  再來定義指標陣列,在這裡前面的資料型別本來就已經是指標(陣列指標)了,所以在 *pa[m]裡就沒必要加*了,可以直接定義成int (*p[m])[n];

//如果我利用typedef就簡單明瞭多了:

//可以參考的形式有:

//a.    

typedef  int (*a)[n];

typedef  a  (b[m]);

b   b;//等價於int (*(b[m]))[n];比較侷限

//b.

typedef  int (*a)[n];

typedef  a  (b);

b   b[m];//等價於int (*(b[m]))[n];

//c.

typedef  int      (a)[n];

typedef  a    *(b[m]);

b   b;//等價於int (*(b[m]))[n];比較侷限

//d.

typedef  int      (a)[n];

typedef  a      *(b);

b   b[m];//等價於int (*(b[m]))[n];

//e.

typedef  int (*(a))[n];

a   b[m];

//f.

typedef  int      a[n];

a   *b[m];

//上面的宣告中,()在有的地方是可以不加的

4. int (*func)(int *p);

//這是乙個基本的函式指標定義方法,無法分解。(這裡說明的是:函式名內容也是位址)

5. int (*func)(int *p, int (*f)(int*)); 

//用typedef分解:

typedef int (*func)(int *);

int (*func)(int *p,func f);

//典型的例子

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

//展開如下:

void     (* signal(int signum, void (* handler)(int)))(int );

6. int (*func[5])(int *p);

// 這是乙個函式指標陣列,總的來說func是個陣列,什麼樣的陣列呢?原來裡面的陣列元素都是乙個個函式指標。可以這樣分解

typedef int (* func)(int *p);

func   func[5];

//func這個陣列的元素的型別是引數維int *,返回值為int 的函式指標

7. int (*(*func)[5])(int *p);

//這是乙個函式指標陣列指標,注意讀法,前面六個字函式指標陣列是修飾最後的指標,所以總提來說func是乙個指標,什麼樣的指標呢?

//指向具有5個元素的陣列,那這個陣列的元素是什麼型別呢?哦,原來是函式指標型別,什麼型別的函式指標呢?引數int *,返回值 int。

//用typedef分解

typedef int (* (a))(int *p);

typedef a   (b)[5];

typedef b    *m

m    func;

//或者

b   *func;

8. int (*(*func)(int *p))[5]; 

//乍一看,我也看不出來它什麼型別,不過可以分解嘛

typedef  int (*(a))[5];//a是函式指標型別

a  (* func)(int *p);

//這下該看出來是什麼型別來吧,func是個函式指標,它引數很簡單 int *,複雜就複雜在返回值,返回值的型別是a,a的型別就是乙個陣列指標,

//而且這個陣列指標指向的是具有5個int資料的陣列。

總結:1.如果我們是去讀別人的已經宣告好的複雜型別,那麼我們可以這樣,用typedef來將其分解,分解的原則是:

從最外層的開始用typedef來定義,然後用定義好的型別再去一層一層得定義內部,知道遇見了被定義的標示符為止

2.如果我們知道需要宣告乙個什麼東西了,比如前面的 「函式指標陣列指標」,我們這樣來宣告:從左往右看,找到第乙個修飾詞「函式指標」,我們就定義乙個函式指標

接下來遇到來「陣列」,我們再用定義好的函式指標型別來定義乙個陣列。最後,我們在這個陣列的型別上再定義乙個指標就 可以了。

指標 複雜的宣告

int fp1 int 10 1.從變數名開始 fp1 2.往右看,是 因此往左看,是 乙個指標 3.跳出括號,碰到了 int 乙個帶乙個int引數的函式 4.向左看,發現乙個 函式 返回乙個指標 5.跳出括號,向右看,碰到 10 乙個10元素的陣列 6.向左看,發現乙個 指標 7.向左看,發現in...

指標 複雜的宣告

int fp1 int 10 閱讀步驟 1.從變數名開始 fp1 2.往右看,是 因此往左看,是 乙個指標 3.跳出括號,碰到了 int 乙個帶乙個int引數的函式 4.向左看,發現乙個 函式 返回乙個指標 5.跳出括號,向右看,碰到 10 乙個10元素的陣列 6.向左看,發現乙個 指標 7.向左看...

指標(挑戰複雜的宣告)

ansi c 的標準庫中,有乙個atexit 的函式。如果使用這個函式,當程式正常結束的時候,可以調回乙個指定的乙個函式。原型定義如下 int atexit void func void 怎麼看呢?1.著眼於識別符號。intatexit void func void 2.解釋用於函式的 int at...