複雜宣告解析

2021-09-02 10:31:19 字數 3002 閱讀 6677

c語言的指標很久沒看了,複習一下,做一下總結。c語言的複雜宣告,例如:void (*f(int,int (*)(int)))();怎麼樣,是不是很複雜?看著摸不到頭腦,不知從何說起。看了挺多資料,主要是應用「右左法則」,現總結如下:

1.基本的c語言宣告:

①int a;//宣告乙個整形數a

②int *a;//宣告乙個指標,該指標指向乙個整形數

③int **a;//宣告了乙個指標,該指標指向乙個指標,這個指標指向乙個整形數

④int a[10];//宣告乙個陣列,該陣列有十個元素,每個元素是乙個整形數

⑤int *a[10];//運算子的優先順序高於*,因此a先與[10]結合,a是乙個具有十個元素的陣列,每個元素是乙個指向int型的指標

⑥int (*a)[10];//()的優先順序高於,因此a是乙個指標,這個指標指向乙個陣列,這個陣列具有10個元素,每個元素是乙個int型

⑦int *f();//f是乙個函式,該函式無引數,返回值是乙個指向整形數的指標

⑧int *f(int);//f是乙個函式,該函式有乙個int型的引數,返回值是乙個指向整形數的指標

⑨int (*f)();//f是乙個指標(不是函式),該指標指向乙個函式,該函式無引數,返回值是乙個int型整數。

以上是基礎的c語言的宣告,上過c語言的都應該很熟悉。但是這個呢,void *(*c)(char,int(*)());僅僅知道上述好像還不足以解析。

2.右左法則:

the right-left rule: start reading the declaration from the innermost parentheses, go right, and then goleft. when you encounter parentheses, the direction should be reversed. once everything in the parentheses hasbeen parsed, jump out of it. continue till the whole declaration has been parsed.

即:從最裡面的圓括號(未定義的標示符標示符)開始,先往右看,在往左看,遇到「)」即調轉方向,向左遇到「(」則跳出圓括號,重複這個過程,知道宣告解析完畢。看起來有點抽象,上例子:int *(*c)(char,int(*)());

按照我們的法則走一遍:

①從c開始,向右看,是「)」,調轉方向,遇到「*」,說明c是乙個指標,接著遇到「(」,跳出這層括號,向右;

②是乙個括號,說明是乙個函式,即①中的指標指向這個函式,這個函式有兩個引數,乙個是char型,進入另外乙個;

③解析這個引數,從*開始,是乙個指標,向右遇到「)」,調轉,遇到「(」,跳出圓括號,向右,是乙個(),說明是乙個無引數的函式,這個指標指向這個函式,向左,遇到「int」 說明 這個函式的返回值是int型。到此②中的函式的兩個引數解析完畢;

④(*c)後面的解析完畢,向左,是乙個*,說明②中這個函式的返回值是乙個指標,接著向左,遇到「int」,說明返回的這個 指標指向int型整數。

總結上述:c是乙個指標,指標指向乙個函式1,函式1有兩個引數,乙個引數是char型別,另乙個引數是乙個函式指標,這個函式無引數,返回值為int,函式1的返回值是乙個指標,指向int型別。

接著來看:float(*(*b())[10])();

①從b開始,向右,遇到「()」,說明b是乙個函式,無引數,接著向右遇到「)」,轉向;

②遇到*,是乙個指標,說明這個函式返回值是乙個指標,接著向左,遇到「(」,跳出這個括號;

③向右,遇到「[10]」 ,說明這是乙個陣列,具有十個元素,說明②中的指標指向乙個陣列,接著向右;

④遇到「)」,轉向,遇到「*」,是乙個指標,說明③中陣列每乙個元素是乙個指標,接著向左;

⑤遇到「(」,跳出該括號,向右遇到「()」,是乙個函式,說明④中的指標指向乙個函式,無引數,右邊完畢,向左;

⑥遇到float說明函式的返回值是float型別,完畢。

總結上述:

b是乙個函式,函式的返回值是乙個指標,指標指向乙個陣列,陣列的每乙個元素是乙個指標,指標指向乙個函式,該函式無引數,返回值是float型別。

再來乙個:int *(*(*array[5])()) ()

從array開始,向右,[5],array是乙個具有五個元素的陣列,向左,*,每個元素是乙個指標,跳出該括號,向右,是(),說明是乙個函式,指標指向這個函式,且函式無引數,向右遇到「)」,轉向,遇到*,是乙個指標,說明該函式的返回值乙個指標,向左,遇到「(」,跳出括號,向右,(),是乙個函式,無引數,即指標指向該函式,右邊完畢,向左,遇到*,說明該函式返回指標,接著左,int,指向int型。

總結:array是乙個陣列,陣列中有五個元素,每個元素是是乙個指標,指向乙個函式,這個函式無引數,返回值是乙個指標,指向乙個函式,這個函式無引數,返回值是乙個int型的指標。

總結上述三個例子:指標有指向,函式有返回和引數,陣列有元素型別,把握這幾點。

再來乙個:int (*(*pf)(int,int(*)(int,int)))(int,int);

宣告乙個函式指標pf,所指向的函式有2個引數分別為int型和乙個函式指標,並且這個函式的返回值也是乙個函式指標,作為引數和返回值的這兩個函式指標所指向的函式都 有兩個int型引數,並且返回值也為int型。

再來乙個:int (*(*func)(int *p))[5];

①func開始,向右,「)」,向左,*,即func是乙個指標,指向。。跳出括號;

②(int *p),說明是乙個函式,即上述指標指向乙個函式,引數是乙個int型指標,p是形參名,無意義,返回值為。。。;

③轉向,*,②中的函式返回值是乙個指標,指向。。。。跳出括號,;

④向右,[5],是乙個陣列,③中函式的返回值是乙個陣列,有五個元素,每個元素的型別。。。。

⑤左,int,每個元素的型別是int。完畢

func是乙個函式指標,這類函式具有int*型別的形參,返回值是指向陣列的指標,所指向的陣列的元素是具有5個int元素的陣列。

今天講得是怎麼樣解析乙個已經宣告好複雜宣告接下來的文章將逆過來,怎麼根據功能寫出正確的複雜的宣告。雖然c語言允許複雜的宣告,但是在實際應用中並不提倡。

複雜宣告展開

分解 1 fp 和 號括在一起,說明 fp 是乙個指標,指向 t1 型別 typedef int t1 void 10 用其他型別定義型別t1 t1 fp fp是指向t1型別的指標2 t1 應該是乙個函式型別,引數是 void 返回值是 t2 型別 typedef int t2 10 用其他型別定義...

語言複雜宣告的解析 csdn轉

摘錄的別人的 c語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是乙個既著名又常用的方法。不過,右左法則其實並不是c標準裡面的內容,它是從c標準的宣告規定中歸納出來的方法。c標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如何辯識乙個宣告的,兩者可以說...

解析c語言的複雜宣告實踐

看了那篇文章,總結一下,解析複雜宣告其實就是從最裡面的未定義識別符號開始,左邊和右邊同時找一對符號來配對,不斷向外擴充套件,最後完成解析。int func 5 6 7 8 func是個指標,這個指標指向什麼呢。那我們就可外圍,左邊和右邊找一對符號 5 6 這表示乙個二維陣列,陣列元素是指標。所以fu...