c**
inta; // 乙個整形
int* a; // 乙個指標, 批向乙個整形 (整形指標)
int* a(); // 乙個函式, 反回乙個整形指標
int* a[10]; // 乙個陣列, 裡面存放著整形指標
int(*a)(); // 乙個指標, 指向乙個函式, 該函式返回整形
int(*a); // 乙個指標, 指向乙個陣列, 陣列裡放著整形
int a; // 乙個整形上面的問題不大哦, 下面先給出讀的方法int * a; // 乙個指標, 批向乙個整形 (整形指標)
int * a(); // 乙個函式, 反回乙個整形指標
int * a[10]; // 乙個陣列, 裡面存放著整形指標
int (*a)(); // 乙個指標, 指向乙個函式, 該函式返回整形
int (*a); // 乙個指標, 指向乙個陣列, 陣列裡放著整形
從左向右看, 找到第乙個識別符號,上例中就是 a
1.先往右看, 如果是 [..] 那麼 讀作"a 是乙個陣列", 接下來的東西,就是陣列元素的型別,和大小了,如果是 "(...)" 那麼就是乙個函式, 剩下的就是描述函式的引數和返回值了。遇到右括號就往左。
2.再往左看, 如果字首是 * 那麼讀作 "a 是乙個指標", 接下來分析指向什麼。
3.讀過的就用xx替換掉,並把xx當做識別符號,重複上面的步驟,直到確定變數型別。
c**
int* a(); // 從左向右看, 找到a, 再向右看, 是(), 那麼"a是乙個函式",
// 引數? 無, 返回值? int *, 哦, 是乙個整形指標
int* a[10]; // 從左向右看, 找到 a, 再向右看, 是 , 那麼 "a 是乙個陣列"
// 大小? 10, 型別? int *, 還是整形指標
int(*a)(); // 找到a, 被括號括住, 只能向左看, 是 *, 那麼 "a 是乙個指標"
// 指向什麼? 去掉分析過的部分, int ***(), 哦, 是乙個函式
int(*a)[10]; // 同樣, "a 是乙個指標",
// 指向什麼? 去掉分析過的部分是? int ***[10], 指向乙個陣列
int * a(); // 從左向右看, 找到a, 再向右看, 是(), 那麼"a是乙個函式",來幾個複雜一點的.// 引數? 無, 返回值? int *, 哦, 是乙個整形指標
int * a[10]; // 從左向右看, 找到 a, 再向右看, 是 , 那麼 "a 是乙個陣列"
// 大小? 10, 型別? int *, 還是整形指標
int (*a)(); // 找到a, 被括號括住, 只能向左看, 是 *, 那麼 "a 是乙個指標"
// 指向什麼? 去掉分析過的部分, int ***(), 哦, 是乙個函式
int (*a)[10]; // 同樣, "a 是乙個指標",
// 指向什麼? 去掉分析過的部分是? int ***[10], 指向乙個陣列
c**
int* * (*a)();
int * * (*a)();從左向右看, 找到第乙個識別符號, a , 被括號括住了, 往左看, 是 *, 讀作"a 是乙個指標"
指向什麼? int ** ***(); 哦, 是乙個函式
引數是? 空
返回值: int **, 哦~~
合起來就是: a 是乙個指標, 該指標指向乙個函式, 這個函式返回乙個指標(返回的這個指標指向乙個整形指標)
再來乙個:
c**
char*(*c[10])(int**p); // 這個例子來自於expert c programming
char *(*c[10])(int **p); // 這個例子來自於expert c programming一眼看過去想暈
沒事.
從左到右找到了第乙個識別符號, c, 再往右看, 是, 讀作 "c 是乙個陣列"
陣列的元素是什麼
先去掉分析過的部分是 char *(****)(int **p)
哦, ***處開始, 往右看不下去, 往左看, 是*, 那麼 "陣列的元素是乙個指標", 指向什麼呢?
再去掉分析過的部分, char ****(int **p); 到這一步基本上一眼就能看出了, 就不多廢話了
原來是指向乙個函式: 這個函式的引數是 int **p, 返回值是 char *
合起來就是: c是乙個陣列, 這個陣列大小是 10, 這個陣列裡面存放著 指標, 是乙個函式指標, 這個函式
指標的引數是 int **p, 返回值是 char *
呵呵。 很容易吧!
等等, 加入const 好像更暈
"const在指標左邊修飾型別, 在指會右邊,修飾指標"
c**
const
int* a; // 指標指向的整形是 const的
int*consta; // 指標a 是 const的
const int * a; // 指標指向的整形是 const的宣告中還可以加typedef哦int * const a; // 指標a 是 const的
一般是
typedef ************x;
***x 的讀取方法和上面的一模一樣, 但僅僅引入乙個新的名字,而不是為變數分配空間
要讀的話, 可以讀作「a 表示乙個...」, 而不是 "a 是乙個...."
用 typedef 可以讓我們輕鬆好多, 可以讓我們一眼看出申明,或定義的東西
上面看過的這個複雜的東西:char *(*c[10])(int **p);
可以變成這樣
typedef char * (*fun_ptr)(int **p); //fun_ptr 表示乙個函式指標, 用上述規則看
那麼上面的東東就是:
fun_ptr c[10]; // 一眼就能看出來了,裡面是 fun_ptr
最後乙個例子:
void (*signal(int sig, void(*func)(int)))(int); // 這個例子來自於expert c programming
從左往右看, 找到 signal, 再往右看, 是(...) "signal 是乙個函式"
引數是什麼? 看括號裡面的 ( int sig, void(*func)(int) ) 有兩個引數, 第乙個是 int, 第二個是 void (*func)(int), 是乙個函式指標。
返回值是什麼? 先去掉分析過的部分, 變成 void (****x)(int) , 返回值是乙個函式指標, 看,上面的第二個引數一樣。
合起來就是: signal是乙個函式, 引數有兩個, 乙個是int ,還有乙個是 函式指標, 返回值是乙個函式指標 。
當然,typedef 後會比較直觀
c**
typedef
void(*func_ptr)(int); //給函式指標乙個名字
func_ptr signal(int, func_ptr); // 現在一看就明白了
總結:首先要確定第乙個識別符號的型別是什麼,基本上有三種情況,是指標就接著分析指向什麼型別,是陣列就接著分析大小和元素型別,是函式就接著分析引數和返回值型別。把分析過的換乘xx,按照同樣的步驟繼續分析下去。
指標巢狀讀法
作者寫的很不錯!有種豁然開朗的感覺,不再死記硬背了。c語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是乙個既著名又常用的方法。不過,右左法則其實並不是c標準裡面的內容,它是從c標準的宣告規定中歸納出來的方法。c標準的宣告規則,是用來解決如何建立宣告的,而右左法則是...
函式指標的讀法
指標的概念在c裡面非常重要,而對於函式指標的理解更有利於掌握程式執行的過程。對於以下宣告 char f int float 要從 f 開始讀,f表明f為乙個指標,而 f int float 表明f是乙個函式指標,這個函式有2個引數,分別位int 和float。最後我們知道它是乙個返回值為char 和...
C語言複雜定義的讀法(右左法則)
右左法則的運用 右左法則 先找到變數,先向右邊看再向左邊看,看到括號代表函式,方括號代表陣列,代表指標。int arr 5 arr是乙個函式指標陣列,該陣列裡的元素指向乙個形參為空,返回值為函式指標,該指標指向乙個形參為空,返回值為int fioat b b是函式,該函式形參為空,返回值為陣列指標,...