第二章 語法陷阱
2.1 理解函式宣告
任何c變數的宣告都由兩部分組成:型別以及一組類似表示式的宣告符(declarator)。
float *g(), (*h)();
表示*g()與(*h)()是浮點表示式。因為()結合優先順序高於*,*g()也就是*(g()):g是乙個函式,該函式的返回值型別為指向浮點數的指標。同理,可以得出h是乙個函式指標,h所指向函式的返回值為浮點型別。
給定型別的型別轉換符,只需要把宣告中的變數名和宣告末尾的分號去掉,再將剩餘的部分用乙個括號整個「封裝」起來即可。例如,下面的宣告:
float (*h)();
表示h是乙個指向返回值為浮點型別的函式的指標,因此,
( float (*) () )
表示乙個「指向返回值為浮點型別的函式的指標」的型別轉換符。
void(*)() : 乙個指向返回值為void型別的函式的指標
(void(*)())0 : 將常數0轉型為「指向返回值為void的函式的指標」型別
2.2 運算子的優先順序問題
flag是乙個整數,且該整數值的二進位制表示中只有某一位是1,其餘各位均為0。
flags也是乙個整型變數,需要判斷它在常量flag為1的那位上是否同樣為1。
if ( flags & flag )
為了使可讀性更好,顯示判斷表示式的值是否為0,寫法如下:
if ( flags & flag != 0 )
雖然更好懂了,卻是乙個錯誤的語句。因為!=的優先順序高於&,上式等價於
if ( flags & ( flag != 0 ) )
hi 和 low是兩個整數,值介於0到15之間,如果r是乙個8位整數,且r的低4位與low各位商的數一致,而r的高4位與hi各位上的數一致。寫成如下:
r = hi << 4 + low ;
但是很不幸,這樣寫是錯誤的。加分運算的優先順序比移位運算的優先順序高,因此,本例實際上相當於:
r = hi << ( 4 + low );
更正方法1:加括號 r = ( hi <<4 ) + low;
更正方法2:將加號改為按位邏輯或 r = hi << 4 | low; //這種方法牽涉到移位與邏輯運算的優先順序,就更加不明顯了。
優先順序最高者其實並不是真正意義上的運算子,包括:陣列下表、函式呼叫操作符各結構成員選擇操作符。它們都是自左於右,因此a.b.c的含義是( a.b ).c,而不是a.( b.c )
單目運算子僅次於上面所述運算子。在所有的真正意義上的運算子中,它們的優先順序最高。因為函式呼叫的優先順序高於單目運算子的優先順序,所以,如果p是乙個函式指標,要呼叫p所指向的函式,必須這樣寫:( *p )()。 如果寫成 *p() 編譯器會理解成 *( p() )。型別轉換也是單目運算子,它的優先順序和其他單目運算子的優先順序一樣。單目運算子是自右至左,因此 *p++ 會被編譯器解釋成 *(p++),即取指向p所指向的物件,然後將p遞增1;而不是(*p)++,即取指標p所指向的物件,然後將該物件遞增1。
優先順序比單目運算子要低的,接下來是雙目運算子。在雙目運算子中,算術運算子的優先順序最高,移位運算子次之,關係運算子再次之,接著是邏輯運算子,條件運算子,最後是賦值運算子。
==和!= 的優先順序要低於其他關係運算子。因此如果要比較a與b的相對大小順序是否和c與d的相對大小順序一樣,可以這樣寫: a < b == c < d
^按位異或運算子
while ( c = getc ( in ) != eof )
putc ( c, out );
等價於 while ( c = ( getc ( in ) != eof ) )
2.3 注意作為語句結束標誌的分號
2.4 switch語句
2.5 函式呼叫
如果f 是乙個函式,f(); 是乙個函式呼叫語句,而 f; 卻是乙個什麼也不做的語句。更精確地說,這個語句計算函式f的位址,卻不呼叫該函式。
2.6 懸掛else引發的問題
else始終與同一對括號內最近的未匹配的if結合。
《C缺陷與陷阱》讀書筆記
一 為什麼很多程式設計規範上要求單字元符號兩邊用空格隔開呢?如 a 2 最好不要寫成 a 2 在 c陷阱與缺陷 中詞法陷阱部分講到 如y x p,原本想表達的意思是p指標指向除數,但實際編譯過程中,編譯器會將 理解為一段注釋的開始,編譯器將不斷地讀入字元,直到 出現為止 這一錯誤也在 c專家程式設計...
《C陷阱與缺陷》讀書筆記
如果乙個整型常數的第乙個字元是數字0,那麼該常量將被視作八進位制數。如0195相當於十進位制數141 c語言中,else始終與同一對括號內最近的未匹配的if結合。switch語句中的case語句若在結尾處無break,程式將會繼續執行下一條case語句 非陣列的指標 include char r,s...
C陷阱與缺陷讀書筆記(二)
第三章 3.1 指標與陣列 理解 int calendar 12 31 c語言中只有一維陣列,calendar是乙個一維陣列,該陣列含有12個陣列型別的元素,其中每個元素都 是乙個含有31個整型元素的陣列 int monthp 31 monthp 是乙個擁有31個整型元素的陣列,mouthp是乙個 ...