標籤:
第一章:詞法陷阱
編譯器中負責將程式分解為一個一個符號的部分,一般稱為“詞法分析器”。例如,對於語句:
if ( x == big ) big = x ;
它的第一個符號是C語言關鍵字if,緊接著下一個符號是左括弧,在下一個符號是標識符x,在下一個是大於符號,在下一個是標識符big,以此類推。在C語言中,符號之間的空白(包括空格、定位字元、分行符號)將被忽略,因此上面的語句還可以寫成:
if
(
x
==
big
)
big
=
x
;
這裡還需要強調一下“C語言忽略符號間空白”。第一:“符號”的意思並不是“字母”,例如上面的語句中的“==”和“big”,它們都包含了多個字母,但是它們從整體上是一個符號,不可分割。第二:忽略符號與符號之間的空白,意即經過編譯器的詞法分析之後,符號與符號之間的空白不會被作為一個符號。但是,請注意的是,第二點並不意味著可以亂用空格,例如,在上面的語句中,“==”不可以寫做“= =”,如果寫成後者,便成了兩個賦值號,程式的意思也就變了。
1.1 = 不同於 ==
前者是賦值,後者是判斷相等,對於C語言初學者,很容易就犯誤用的錯誤。
1.2 &和|不同於&&和||
前兩者是位元運算,後兩者是關係運算。
1.3 詞法分析中的“貪進法”
C語言中的某些符號,例如/、*、和=,只有一個字元,稱為單字元符號。而C語言中的其他符號,例如/*和==,以及標識符,包括了多個字元,稱為多字元符號。那麼當C語言的編譯器的詞法分析模組讀入了一個字元‘/’後又跟了一個字元‘*’,那麼編譯器就必須做出判斷:是將其作為兩個分別的符號對待,還是合起來作為一個符號對待。C語言解決這個問題的方案很簡單,那就是“貪進法”:每一個符號應該包含儘可能多的字元。
需要注意的是,除了字串和字元常量,符號的中間不能嵌有空白(空格符、定位字元和分行符號)。例如,“==”是單個符號,而“= =”則是兩個符號。例如下面的運算式:
a---b
那麼按照“貪進法”,它的含義是:
(a--) - b
而:
a- --b
的含義是:
a - (--b)
再例如下面的語句,本意似乎是用x除以p所指向的值,把所得的商再賦值給y:
y = x/*p /* p指向除數*/
而實際上,因為“貪進法”,上面語句中的x後面的/*會被C語言詞法分析器理解為一段注釋的開始。
正確的表達當如下:
y = x/ *p /* p指向除數*/
或者更清楚一點:
y = x/(*p) /* p指向除數*/
1.4整型常量
021不同於21,前者是八進位,後者是十進位。
練習1-1 寫一個測試程式,無論是對於允許嵌套注釋的編譯器還是對不允許嵌套注釋的編譯器,該程式都能夠正常通過編譯,但是兩種情況下程式的執行結果卻不相同。
答案: /*/*/0*/**/1
在允許嵌套注釋的情況下,上式值為1;
在不允許嵌套注釋的情況下,上式值為0*1;
C缺陷與陷阱----讀書筆記---第一章