C 指標之右左法則

2021-07-11 20:11:06 字數 2520 閱讀 1091

**:

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

the right-left rule: start reading the declaration from theinnermost parentheses, go right, and then go left. when youencounter parentheses, the direction should be reversed. onceeverything in the parentheses has been parsed, jump out of it.continue till the whole declaration has been parsed.

這段英文的翻譯如下:

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

總之對宣告進行分析,最根本的方法還是按優先順序和結合性來模擬替換,從那些最基本的宣告進行模擬,簡化,從而進行理解。下面分析幾個例子,來具體闡述如何使用這種方法。

#1:int* (*a[5])(int, char*);

首先看到識別符號名a,""優先順序大於"*",a與"[5]"先結合。所以a是乙個陣列,這個陣列有5個元素,每乙個元素都是乙個指標,指標指向"int*(int, char*)",很明顯,指向的是乙個函式,這個函式引數是"int,char*",返回值是"int*"。ok,結束了乙個。:)

#2:void (*b[10]) (void (*)());

b是乙個陣列,這個陣列有10個元素,每乙個元素都是乙個指標,指標指向乙個函式,函式引數是"void(*)()"【注:這也是乙個函式指標, 引數為空,返回為void】,返回值是"void"。完畢!

#3:int(*)() (*c)[9];

c是乙個指標,指標指向乙個陣列,這個陣列有9個元素,每乙個元素都是"int(*)()"(也即乙個函式指標,指向乙個函式,這個函式的引數為空,返回值是int型)。

#4:int (*(*d)[5])(int *);

(*d)------指標;

(*d)[5]------這個指標指向乙個陣列;

*(*d)[5]------這個陣列中每個元素都是指標型別;

int (int *)------ 什麼型別的指標?這個型別的。

#5:int (*(*e)(int *))[5];

*e-----向右遇到括號,向左遇到*,說明e是個指標,啥指標呢?

(*e)(int *)------跳出括號向右遇到(int *),說明這個指標是個函式指標,形參為int*,返回值為何?且聽下回分解:);

*(*e)(int *)------返回值為何?向右遇到括號,再向左,喔,遇到*了,那就是返回了乙個指標了。啥指標呢?同樣地,下回分解;

(*(*e)(int *))[5]-------向右遇到,說明那是個指向陣列的指標,是啥陣列呢?不急,慢慢來;

int (*(*e)(int *))[5]-------向左遇到int,喔,明白了,就是個簡單的整型陣列。over

當然實際當中,當需要宣告乙個複雜指標時,如果把整個宣告寫成上面所示的形式,對程式可讀性將是乙個巨大損害。誰要是寫出這樣bt的指標宣告,那就真是丟rp了,估計會被罵死!。

還是用typedef來對宣告逐層分解替換下吧,增強可讀性。

例如對於上面的宣告:int (*(*func)(int *))[5]; 可以這樣分解:

typedef int (*parr)[5];

typedef parr (*func)(int *);

這樣就容易讀得多了啊!

再看看這個啥意思? typedef int (* (* (*func)(int *) )[5] )(int *); ----暈了吧。

其實typedef int (* (* (*func)(int *) )[5] )(int *);

等價與下面的:)

typedef int (*pf)(int *);

typedef pf (*parray)[5];

typedef parray (*func)(int *);

(*(void (*)())0)();------->這個呢?

按左右法則:

(void (*)()) -----是乙個返回值為void,引數為空的函式指標原型。

(void (*)())0-----把0強轉成乙個返回值為void,引數為空的函式指標,指標指向的位址為0.

*(void (*)())0-----前面加上*表示整個是乙個返回值為void的函式的名字

(*(void (*)())0)()------這當然就是乙個函式呼叫了。

再typedef化簡下:

typedef void (*pf)();

(*(pf)0)();

cattycat

理解C語言函式宣告 複雜指標解析之右左法則

the right left rule start reading the declaration from the innermost parentheses,go right,and then go left.when you encounter parentheses,the directio...

C指標右左法則

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

C指標右左法則

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