首先聲明如果你對int (*a)[10], char* const (*next());已經了解,就不要看了,一個聲明是沒什么意思的,這篇文章只是想闡述下C語言是怎么解析它的聲明。
聲明里面可以包括的元素有:類型說明符(int, void, char,struct...),存儲類型extern, static, register, 類型限定符(const, volatile), 變量名(標識符), 符號(*,圓括號和中括號);
總體原則是,找到標識符(即是我們平時叫的變量名),從右向左解析;
具體步驟如下:
1. 找到聲明中最左邊的標識符,去掉標識符 => 變量是叫“標識符”
2. 查看標識符右邊的下一個符號,如果是方括號,取出可能的大小,去掉方括號 =>是一個數組。
3. 查看標識符右邊的下一個符號,
如果是左圓括號,取出可能的參數,一直到右括號 => 是一個函數
4. 查看標識符左邊的符號,如果是左括號,找到對應的右括號,并把括號中的聲明組合在一起。回到第2步重新開始執行。
5. 查看標識符左邊的符號,如果是const, volatile,*, 繼續向左讀直到不是這三個類型為止。重復第4步。 =>解釋為const, volatile,指向什么的指針
6. 剩下的符號一并讀入 =>static unsigned int
你可能想問這幾步就可以解決了? 是的,這就是所謂的神奇解碼環。
下面我來隨便驗證下這個算法:
先來個簡單的
int (*a)[10] 和 int* a[10];
聲明式 步驟 執行結果
int (*a)[10] 第1步 找到最左邊的標識符a,表示a是一個…
int (*)[10] 第2,3步 不匹配
int (*)[10] 第4步 匹配(,直接讀到),包括*,表示a是一個指向…指針.Step2
int [10] 第2步 匹配[10],表示a是一個指向..size=10的數組的指針
int 第3,4,5 不匹配
結束 第6步 表示a是一個指向int數組的指針
int* a[10] 第1步 a是一個
int* [10] 第2步 a是一個…size=10的數組
int* 第3步 不匹配
int 第4步 匹配,a是一個存放著指針,size=10的數組
int 第5步 匹配,a是一個存放著int指針,size=10的數組
大家看的出兩個聲明的結果是一個是指針,一個是數組。
int a1[10];
int a2[20];
int (*b)[10];
int* c[10];
a[0] = 10;
b = &a2; //報錯,cannot convert from 'int (*)[20]' to 'int (*)[10]'
b = &a1; //b是指向size=10的數組的指針
c[0] = &a1[0]; //c是一個數組,里面存放的是指針,指針指向int;
(未完待續)