1. 程式人生 > >C語言缺陷與陷阱語義分析

C語言缺陷與陷阱語義分析

語義分析

(程式設計師本意是希望表示某種事物,而實際表示的卻是另外一種事物)

1.     指標和陣列

陣列值必須注意的兩點:(1)C語言只有一維陣列,且陣列大小必須在編譯期作為一個常數確定下來;(2)對一個數組只能進行:確定該陣列的大小,以及獲得指向該陣列下標為0的元素的指標。

若一個指標指向的是陣列中的一個元素,那麼給該指標加1就能夠得到該陣列中下一個元素的指標,該該指標減1就能夠得到該陣列中上一個元素的指標。

只有在兩個指標指向同一個陣列中的元素時,對兩個指標相加、減才有意義。

2.     非陣列的指標

對於字串常量,不但包括字串中所有字元,還包含一個空字元(’\0’)的記憶體區域地址。

在進行常量字串的複製等操作時,要注意:(1)利用malloc申請分配的記憶體是否成功;(2)分配的記憶體使用之後應及時釋放;(3)分配記憶體的大小應為strlen(str)+1。

3.     作為引數的陣列宣告

使用陣列名作為引數,那麼陣列名會立刻被轉換為指向該陣列第一個元素的指標。

如果指標引數為一個數組,則表示指向某一陣列的起始元素的指標。

4.     避免“舉隅法”(以含義更寬泛的詞語來代替含義相對較窄的詞語,或者相反。如以整體代表部分,或者以部分代表整體)

複製指標並不同時複製指標所指向的資料

5.     空指標並非空字串

當常數0被轉換為指標使用時,這個指標絕對不能被解除引用。即,當將0賦值給一個指標變數時,絕對不能企圖使用該指標所指向的記憶體中儲存的內容。

6.     邊界計算與不對稱邊界

在C中,一個數組有N個元素,則其下標從0~N-1.為了避免陣列越界、“欄杆錯誤”等情況的發現,最好的處理方法是:用第一個入界點和第一個出界點來表示一個數值範圍。

在處理迴圈時,運用--n>=0的效率比較高

7.     求值順序

在C中,只有&&、||、?:和,存在規定的求值順序。

&&和||先對左側運算元求值,只在需要時才對右側運算元求值;

在a?b:c,先對a求值,根據a 的值再求b或c的值;

,(逗號運算子),先對左側運算元求值,然後該值被“丟棄”,再對右側運算元求值。(注意:分隔函式引數的逗號並非逗號運算子)

8.     運算子&&、||和!

按位運算子&、|、~對運算元處理的方式是:將其視作一個二進位制的位序列,分別對其每個位進行操作。(注意:負數的表示為其補碼);

邏輯運算子&&、||、!對運算元處理的方式是:將其視作要麼是“真”,要麼是“假”。

9.     整數溢位

無符號算術運算中,沒有所謂的溢位;

若算術運算子的一個運算元是有符號整數,另一個是無符號整數,那麼有符號整數會被自動轉換為無符號整數;

若算術運算子的兩個運算元都是有符號整數,溢位有可能發生,但溢位的結果是未定義的。

10.  為函式main提供返回值

在C中main函式返回型別預設為整型,通過main函式的返回值來告知作業系統該函式的執行是成功還是失敗。一般情況下,返回0代表程式執行成功,返回非0代表程式執行失敗。