詞法分析中的“貪心法”
- 每個(gè)符號(hào)應(yīng)該包含盡可能多的字符。
a---b等同于(a--)-b。
a+++++b被編譯器視為((a++)++)+b,語(yǔ)法上是不正確的。
字符與字符串
單引號(hào)引起的字符代表一個(gè)整數(shù)。
雙引號(hào)引起的字符串代表一個(gè)指向無(wú)名數(shù)組起始字符的指針。
理解函數(shù)聲明
(* (void (*) () ) 0) ();
這是一個(gè)經(jīng)典的例子。分析如下:
void (*) ()指向返回值為void類(lèi)型的函數(shù)指針( void (*) () ) 0將0進(jìn)行類(lèi)型轉(zhuǎn)換(* ( void (*) () ) 0) ();調(diào)用地址為0的子例程
運(yùn)算符優(yōu)先級(jí)
- 優(yōu)先級(jí)由高到低排列
- 數(shù)組下標(biāo)** [ ]、函數(shù)調(diào)用操作符( )、各結(jié)構(gòu)成員選擇操作符 ->**和 **. **。自左與右結(jié)合。
- 單目運(yùn)算操作符,包括類(lèi)型轉(zhuǎn)換。 自右至左結(jié)合。
- 雙目運(yùn)算操作符,其中優(yōu)先級(jí)順序 算術(shù)運(yùn)算符>位移運(yùn)算符>關(guān)系運(yùn)算符>邏輯運(yùn)算符。 自左向右結(jié)合
- 三目運(yùn)算符(條件運(yùn)算符)。 自右至左結(jié)合。
- 賦值運(yùn)算符。 自右至左結(jié)合。
- 逗號(hào)運(yùn)算符。 自左與右結(jié)合。
運(yùn)算符優(yōu)先級(jí)所引發(fā)的錯(cuò)誤很難發(fā)現(xiàn)。
while ( c == '\t '|| c = ' '|| c == '\n' )
事實(shí)上,該語(yǔ)句的正確劃分如下。
while ( (c == '\t '|| c ) = ( ' '|| c == '\n' ))
該語(yǔ)句不僅是將==誤寫(xiě)為=,還導(dǎo)致了表達(dá)式左端為不可修改的左值。
switch函數(shù)的優(yōu)勢(shì)與劣勢(shì)
- 程序在switch中順序執(zhí)行,不受case標(biāo)號(hào)影響。
switch (color) {
case 1:printf("red");
case 2:printf("yellow");
case 3:printf("blue");
}
若color=2執(zhí)行結(jié)果為 yellowblue
使用不對(duì)稱(chēng)邊界
- 用第一個(gè)入節(jié)點(diǎn)和第一個(gè)出界點(diǎn)來(lái)表示一個(gè)數(shù)值的范圍
一個(gè)字符串中由下標(biāo)為16到下標(biāo)為37的字符元素所組成的字串,它的長(zhǎng)度是多少呢?
若將其表示為整數(shù)x滿(mǎn)足x** >= 16(入界點(diǎn))且x < **38(出界點(diǎn)),則很容易計(jì)算其結(jié)果。
該技巧可以用在for循環(huán)中,用來(lái)循環(huán)結(jié)束的標(biāo)志。
使用頭文件
- 每個(gè)外部對(duì)象只在一個(gè)頭文件中聲明,需要用到該外部對(duì)象的所有模塊都包含這個(gè)頭文件(包括其定義該外部對(duì)象的模塊)
返回整數(shù)的getchar函數(shù)
- 單引號(hào)引起的字符代表一個(gè)整數(shù)。
- 若使用char接收,可能無(wú)法容下EOF。
宏可能產(chǎn)生的問(wèn)題
- 宏定義中的空格
#define f (x) ((x)-1)
該宏定義為f代表(x) ((x)-1)
- 宏不是函數(shù)
#define abs(x) x>0?x:-x
abs(a-b)
展開(kāi)后為
a-b>0?a-b:-a-b //并不是我們期望的-(a-b)
因此,宏定義中應(yīng)該把每個(gè)參數(shù)都用括號(hào)括起來(lái),整個(gè)表達(dá)式也應(yīng)該用括號(hào)括起來(lái)。
- 存在副作用
#define max(a,b) ( (a) > (b) ? (a) : (b) )
biggest = max ( biggest , x[i++])
展開(kāi)后
biggest = ( (biggest)>(x[i++]) ? (biggest) : (x[i++])
i一次可能遞增2。
- 宏不是類(lèi)型定義
#define T1 struct foo *
T1 a,b
展開(kāi)為
struct foo * a , b
兩者類(lèi)型不同。