C 語(yǔ)言復(fù)雜類型聲明讀寫(xiě)

C 語(yǔ)言的聲明應(yīng)該從右向左讀,依次地役首,各符號(hào)指涉其左邊的符號(hào)丹皱。例如:

// example 1
const int *i; 

其中包含 constint宋税、*摊崭、i 這四個(gè)符號(hào),依次從右向左:

  • i 指涉 *杰赛,說(shuō)明 i 是一個(gè)指針呢簸。
  • * 指涉 int,說(shuō)明該指針指向一個(gè) int 類型乏屯。
  • int 指涉 const根时,說(shuō)明該 int 是一個(gè)常量。

這樣辰晕,此聲明的涵義就非常清楚了蛤迎。同樣的,

// example 2
int const *i; 

可讀作:i 是一個(gè)指針含友,該指針指向一個(gè)常量替裆,該常量是一個(gè) int 類型校辩。顯然,此聲明與前者等價(jià)辆童。而

// example 3
int * const i; 

可讀作:i 是一個(gè)常量宜咒,該常量是一個(gè)指針,該指針指向一個(gè) int 類型把鉴。顯然故黑,此聲明的涵義與前者不同,而所謂的指針常量和常量指針庭砍,這樣一讀也很容易區(qū)分了场晶。

對(duì)于聲明中包含函數(shù)參數(shù)列表的圓括號(hào)以及數(shù)組的方括號(hào)的情況,在從右向左讀之前怠缸,應(yīng)從右向左遞歸地將這些括號(hào)移動(dòng)到變量名的左邊诗轻。例如:

// example 4
int ar[4][2];

從右向左,首先發(fā)現(xiàn)數(shù)組的方括號(hào) [2]凯旭,將其移動(dòng)到變量名的左邊概耻,變?yōu)椋?/p>

int [2]ar[4];

再將 [4] 移動(dòng)到變量名的左邊使套,變?yōu)椋?/p>

int [2][4]ar;

可讀作:ar 是一個(gè)長(zhǎng)度為 4 的數(shù)組罐呼,該數(shù)組中的每一項(xiàng)是一個(gè)長(zhǎng)度為 2 的數(shù)組,該數(shù)組中的每一項(xiàng)是一個(gè) int 類型侦高。

// example 5
int f(char);

將函數(shù)參數(shù)列表的圓括號(hào) (char) 移動(dòng)到變量名的左邊嫉柴,變?yōu)椋?/p>

int (char)f;

可讀作:f 是一個(gè)函數(shù),該函數(shù)輸入一個(gè) char 類型奉呛,輸出一個(gè) int 類型计螺。

移動(dòng)時(shí)應(yīng)將所有圓括號(hào)視為一個(gè)整體,對(duì)于變量名在一個(gè)圓括號(hào)中瞧壮,而被移動(dòng)的符號(hào)在該圓括號(hào)外部的情況登馒,應(yīng)移動(dòng)到該圓括號(hào)的左邊。例如:

// example 6
int (*(*funcs)[])(char);

首先發(fā)現(xiàn)函數(shù)參數(shù)列表的圓括號(hào) (char)咆槽,且位于包含變量名的圓括號(hào) (*(*funcs)[]) 外部陈轿,將其移動(dòng)到該圓括號(hào)左邊,變?yōu)椋?/p>

int (char)(*(*funcs)[]);

再將 [] 移動(dòng)到包含變量名的圓括號(hào) (*funcs) 左邊秦忿,變?yōu)椋?/p>

int (char)(*[](*funcs));

這里我們可以去掉那些無(wú)關(guān)緊要的表達(dá)優(yōu)先級(jí)的圓括號(hào)(顯然麦射,不包括函數(shù)參數(shù)列表的圓括號(hào))來(lái)簡(jiǎn)化我們的工作。我們知道灯谣,對(duì)于從左向右結(jié)合結(jié)合律不成立的操作潜秋,靠左邊的括號(hào)可以去掉,比如 (a - b) - c 可以簡(jiǎn)化為 a - b - c胎许,而其余括號(hào)不可峻呛,如 a - (b - c)罗售。而我們這里讀類型聲明顯然是從右向左結(jié)合結(jié)合律不成立,所以靠右邊的括號(hào)可以去掉杀饵,而其余括號(hào)不可莽囤。這樣,上面的聲明化簡(jiǎn)為:

int (char)*[]*funcs;

讀作:funcs 是一個(gè)指針切距,該指針指向一個(gè)數(shù)組朽缎,該數(shù)組中的每一項(xiàng)是一個(gè)指針,該指針指向一個(gè)函數(shù)谜悟,該函數(shù)輸入一個(gè) char 類型话肖,輸出一個(gè) int 類型。

如果聲明中包含多個(gè)變量名葡幸,無(wú)論顯式或隱式的最筒,移動(dòng)的標(biāo)的應(yīng)為其所指涉的變量名。例如:

// example 7
int (*funcs[2])(double (*)(char));

其中蔚叨, (char) 所指涉的變量為 (*) 中的隱式變量床蜘,而 [2] 指涉 funcs,變?yōu)椋?/p>

int (double (char)*)*[2]funcs;

最后來(lái)欣賞一個(gè)變態(tài)的例子:

// example 8
int (*(*(*funcs)[2])(double (*callback)(char)))(long)

顯然蔑水,應(yīng)變?yōu)椋?/p>

int (long)(*(double (char)(*callback))(*[2](*funcs)));

然后化簡(jiǎn)為:

int (long)*(double (char)*callback)*[2]*funcs;

別慌邢锯,相信你能讀的:funcs 是一個(gè)指針,該指針指向一個(gè)數(shù)組搀别,該數(shù)組中的每一項(xiàng)是一個(gè)指針丹擎,該指針指向一個(gè)函數(shù),該函數(shù)輸入一個(gè)名為 callback 的指針(該指針指向一個(gè)函數(shù)歇父,該函數(shù)輸入一個(gè) char 類型蒂培,輸出一個(gè) double 類型),輸出一個(gè)指針榜苫,該指針指向一個(gè)函數(shù)护戳,該函數(shù)輸入一個(gè) long 類型,輸出一個(gè) int 類型垂睬。是不是很簡(jiǎn)單媳荒?

寫(xiě)

掌握了讀,寫(xiě)就很簡(jiǎn)單了羔飞。首先從右向左寫(xiě)肺樟,再?gòu)淖笙蛴遥瑢⒑瘮?shù)參數(shù)列表的圓括號(hào)以及數(shù)組的方括號(hào)逻淌,遞歸地移動(dòng)到其所指涉的變量名的右邊么伯。如果跨越了多個(gè)符號(hào)(包括隱式的變量名)則需要給跨越的這一段加括號(hào)。例如卡儒,先寫(xiě)出上文中的:

int (double (char)*)*[2]funcs;

從左向右遞歸田柔,先處理 (char)俐巴,其所指涉的是隱式的指針變量,因此跨越了兩個(gè)符號(hào): * 和隱式的變量硬爆,需要給這兩個(gè)符號(hào)加括號(hào)欣舵,變?yōu)椋?/p>

int (double (*)(char))*[2]funcs;

再處理外層的 (double (*)(char)),變?yōu)椋?/p>

int (*[2]funcs)(double (*)(char));

最后處理 [2]缀磕,變?yōu)椋?/p>

int (*funcs[2])(double (*)(char));

結(jié)論

作為當(dāng)代主流的類 C 語(yǔ)言的先驅(qū)缘圈,C 語(yǔ)言的設(shè)計(jì)沒(méi)有同類語(yǔ)言可以參照,難免存在一些不合理之處袜蚕,過(guò)于復(fù)雜不友好的類型聲明規(guī)則便是其一糟把。好在 C 語(yǔ)言還有 typedef 機(jī)制,類型聲明應(yīng)善用 typedef 來(lái)降低復(fù)雜度牲剃。如果非要寫(xiě)出過(guò)于復(fù)雜的類型聲明遣疯,你可能會(huì)被項(xiàng)目其他人員群毆致死!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凿傅,一起剝皮案震驚了整個(gè)濱河市缠犀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌聪舒,老刑警劉巖辨液,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異过椎,居然都是意外死亡室梅,警方通過(guò)查閱死者的電腦和手機(jī)戏仓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)疚宇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人赏殃,你說(shuō)我怎么就攤上這事敷待。” “怎么了仁热?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵榜揖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抗蠢,道長(zhǎng)举哟,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任迅矛,我火速辦了婚禮妨猩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秽褒。我一直安慰自己壶硅,他們只是感情好威兜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著庐椒,像睡著了一般椒舵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上约谈,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天笔宿,我揣著相機(jī)與錄音,去河邊找鬼棱诱。 笑死措伐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的军俊。 我是一名探鬼主播侥加,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼粪躬!你這毒婦竟也來(lái)了担败?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镰官,失蹤者是張志新(化名)和其女友劉穎提前,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體泳唠,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狈网,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笨腥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拓哺。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脖母,靈堂內(nèi)的尸體忽然破棺而出士鸥,到底是詐尸還是另有隱情,我是刑警寧澤谆级,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布烤礁,位于F島的核電站,受9級(jí)特大地震影響肥照,放射性物質(zhì)發(fā)生泄漏脚仔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一舆绎、第九天 我趴在偏房一處隱蔽的房頂上張望鲤脏。 院中可真熱鬧,春花似錦亿蒸、人聲如沸凑兰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姑食。三九已至波岛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間音半,已是汗流浹背则拷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留曹鸠,地道東北人煌茬。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像彻桃,于是被迫代替她去往敵國(guó)和親坛善。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容