《C陷阱與缺陷》讀書筆記2

2021-05-26 20:21:13 字數 1958 閱讀 3102

第二章   語法陷阱

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是乙個 ...