複雜指標讀法

2021-05-23 09:30:20 字數 4139 閱讀 5689

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的

int * const a; // 指標a 是 const的

宣告中還可以加typedef哦

一般是

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是函式,該函式形參為空,返回值為陣列指標,...