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