- C陷阱與缺陷
- (美)安德魯·凱尼格
- 1019字
- 2021-01-15 16:46:07
1.3 詞法分析中的“貪心法”
C語(yǔ)言的某些符號(hào),例如/ 、* 、和=,只有一個(gè)字符,稱為單字符符號(hào)。而C語(yǔ)言中的其他符號(hào),例如/*和 = = ,以及標(biāo)識(shí)符,包括了多個(gè)字符,稱為多字符符號(hào)。當(dāng)C編譯器讀入一個(gè)字符'/'后又跟了一個(gè)字符'*',那么編譯器就必須做出判斷:是將其作為兩個(gè)分別的符號(hào)對(duì)待,還是合起來(lái)作為一個(gè)符號(hào)對(duì)待。C語(yǔ)言對(duì)這個(gè)問(wèn)題的解決方案可以歸納為一個(gè)很簡(jiǎn)單的規(guī)則:每一個(gè)符號(hào)應(yīng)該包含盡可能多的字符。也就是說(shuō),編譯器將程序分解成符號(hào)的方法是,從左到右一個(gè)字符一個(gè)字符地讀入,如果該字符可能組成一個(gè)符號(hào),那么再讀入下一個(gè)字符,判斷已經(jīng)讀入的兩個(gè)字符組成的字符串是否可能是一個(gè)符號(hào)的組成部分;如果可能,繼續(xù)讀入下一個(gè)字符,重復(fù)上述判斷,直到讀入的字符組成的字符串已不再可能組成一個(gè)有意義的符號(hào)。這個(gè)處理策略有時(shí)被稱為“貪心法”,或者更口語(yǔ)化一點(diǎn),稱為“大嘴法”。Kernighan與Ritchie對(duì)這個(gè)方法的表述如下,“如果(編譯器的)輸入流截至某個(gè)字符之前都已經(jīng)被分解為一個(gè)個(gè)符號(hào),那么下一個(gè)符號(hào)將包括從該字符之后可能組成一個(gè)符號(hào)的最長(zhǎng)字符串”。
需要注意的是,除了字符串與字符常量,符號(hào)的中間不能嵌有空白(空格符、制表符和換行符)。例如,==是單個(gè)符號(hào),而 = = 則是兩個(gè)符號(hào),下面的表達(dá)式
a---b
與表達(dá)式
a -- - b
的含義相同,而與
a - -- b
的含義不同。同樣,如果/是為判斷下一個(gè)符號(hào)而讀入的第一個(gè)字符,而/之后緊接著*,那么無(wú)論上下文如何,這兩個(gè)字符都將被當(dāng)作一個(gè)符號(hào)/*,表示一段注釋的開始。
根據(jù)代碼中注釋的意思,下面語(yǔ)句的本意似乎是用x除以p所指向的值,把所得的商再賦給y:
y = x/*p /* p指向除數(shù)*/;
而實(shí)際上,/*被編譯器理解為一段注釋的開始,編譯器將不斷地讀入字符,直到*/出現(xiàn)為止。也就是說(shuō),該語(yǔ)句直接將x的值賦給y,根本不會(huì)顧及后面出現(xiàn)的p。將上面的語(yǔ)句重寫如下:
y = x / *p /* p指向除數(shù) */;
或者更加清楚一點(diǎn),寫作:
y = x/(*p) /* p指向除數(shù) */;
這樣得到的實(shí)際效果才是語(yǔ)句注釋所表示的原意。
諸如此類的準(zhǔn)二義性(near-ambiguity)問(wèn)題,在有的上下文環(huán)境中還有可能招致麻煩。例如,老版本的C語(yǔ)言中允許使用=+來(lái)代表現(xiàn)在+=的含義。這種老版本的C編譯器會(huì)將
a=-1;
理解為下面的語(yǔ)句
a =- 1;
亦即
a = a - 1;
因此,如果程序員的原意是
a = -1;
那么所得結(jié)果將使其大吃一驚。
另外,盡管/*看上去像一段注釋的開始,但在下例中這種老版本的編譯器會(huì)將
a=/*b;
當(dāng)作
a =/ *b ;
這種老版本的編譯器還會(huì)將復(fù)合賦值視為兩個(gè)符號(hào),因而可以毫無(wú)疑問(wèn)地處理
a >> = 1;
而一個(gè)嚴(yán)格的ANSI C編譯器則會(huì)報(bào)錯(cuò)。
- Learning NServiceBus(Second Edition)
- 基于免疫進(jìn)化的算法及應(yīng)用研究
- MySQL數(shù)據(jù)庫(kù)管理與開發(fā)實(shí)踐教程 (清華電腦學(xué)堂)
- Unity 5.x By Example
- C語(yǔ)言程序設(shè)計(jì)
- 智能搜索和推薦系統(tǒng):原理、算法與應(yīng)用
- Quantum Computing and Blockchain in Business
- MySQL程序員面試筆試寶典
- CodeIgniter Web Application Blueprints
- Hands-On Robotics Programming with C++
- Python數(shù)據(jù)預(yù)處理技術(shù)與實(shí)踐
- SQL Server 2014 Development Essentials
- C#教程
- SQL Server 2008數(shù)據(jù)庫(kù)應(yīng)用技術(shù)(第2版)
- 移動(dòng)智能系統(tǒng)測(cè)試原理與實(shí)踐