《C陷阱和缺陷》讀書總結隨筆

2021-10-09 22:44:59 字數 1977 閱讀 3028

第二章 句法缺陷

第三章 鏈結

第四章 語義缺陷

第五章 庫函式

第六章 預處理器

第七章 可移植性缺陷

第八章 這裡是空閒空間

=是賦值運算子,==是比較運算子

如:

if

(x=y)

foo(

);

仔細看,便會發現if中的判斷為=,而非==,這段的意思是,講x設定為y的值並檢查是否非零。

有些編譯器會給出警告,所以要寫出上面**的原意

如下:

if

((x=y)!=0

)foo()

;

假設變數 a 的值為 1,變數 b 的值為 0

位運算子作用於位,並逐位執行操作。&、 | 和 ^ 的真值表如下所示:

n-- >0的含義是n-- >0而不是n- ->0,根據貪心法編譯器讀入》之前n-- 已經是乙個整體了

a+++++b的含義是((a++)++)+b,但語法是錯誤的,a++的結果不能作為左值再進行運算,因此編譯器不會接受a++作為後面的++運算子的運算元。

if

(flags & flag !=

0)

這一段**被編譯器解釋為

if

(flags &

(flag !=0)

)

因為!=比&繫結得更緊密

需要記住的兩個重要的東西是:

所有的邏輯運算子具有比所有關係運算子都低的優先順序。

一位運算子比關係運算子繫結得更緊密,但又不如數**算符。

switch語句中case後面的break根據需要可以進行省卻

case subtract:

opnd2 =

-opnd2;

/* no break; */

case add:

可以這樣進行**編寫

哈哈哈,看到這樣寫我笑出聲,這樣寫卻很合理

和其他程式語言不同,c 要求乙個函式呼叫必須有乙個引數列表,但可以沒有引數。因此,如果

f 是乙個函式,

f();

就是對該函式進行呼叫的語句,而

f;什麼也不做。它會作為函式位址被求值,但不會呼叫它。

如果兩個檔案,乙個包含如下宣告

int n;

另乙個包含如下宣告

long n;

這不是乙個有效的c程式

a < b && c < d
&&有短路原則,即ac 中有兩個簡單的規則控制著函式引數的轉換:

(1)比 int 短的整型被轉換為 int;

(2)比 double短的浮點型別被轉換為 double。

#include

main()

這段程式看起來好像要講標準輸入複製到標準輸出。實際上,它並不完全會做這些。

原因是 c 被宣告為字元而不是整數。這意味著它將不能接收可能出現的所有字元包括 eof。

因此這裡有三種可能性。

某些合法的輸入字元在被「截斷後」使得c的取值與eof相同

c根本不可能取到eof這個值,將會陷入死迴圈

還可能執行正常,但是完全是巧合。編譯器在比較表示式中並不是比較c和eof,而是比較getchar函式的返回值與eof

不能忽視巨集定義中的空格

巨集並不是函式,最好將巨集定義中的每個引數都用括號括起來

巨集並不是語句,巨集定義後不能加分號

巨集並不是型別定義

《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陷阱和缺陷 連線

一,概念 聯結器的作用在於把有編譯器或彙編器生成的若干個目標模組,整合成乙個被稱為載入模組或可執行檔案的實體,該實體能夠被作業系統直接執行。其中,某些模組式直接作為輸入提供給聯結器的 而另外一些目標木塊則是根據連線過程的需要,從包括有型別printf函式的庫檔案中取得的。二,連線過程問題的根源 c程...