C高階篇(非BUG的語言特性)

2021-07-03 08:28:41 字數 1934 閱讀 8552

許多新手程式設計師經常會犯的一種錯誤,就是將 i = 3; 與 i == 3 相互混淆,前者表示乙個賦值語句,而後者常常作為判斷的條件。還有的程式設計師想將指標指向null時,寫成了p == null; 這樣的話變成了什麼?不過不用擔心,這種錯誤編譯器能夠辨別。

nul與null:在c語言中,nul表示乙個字串的結束,用字元表示為'\0',我們通常用'\0'這種字元常量作為判斷條件而不是nul。null表示為空,用null表示什麼也不指向(即空指標)。

switch、case、default:在用switch的時候,每個case後要加上乙個break語句,除非你想讓後面的case一一執行,那樣看起來比沒使用switch還要麻煩。break語句總是靠近最近的迴圈語句或者switch語句,請注意你的**風格,不要低估它的影響,它曾經導致at&t歷史上第一次重大的網路癱瘓。**如下:

能看出只進行了case thing1: 然後直接跳出了整個switch嗎?

在ansi c下引入了一種新風格,如下:

但是如果我們將s中的第四個字串後面的逗號去掉,那麼這個char指標就只有三個元素了,而後面的迴圈輸出的是四個元素。這樣會發生什麼錯誤?越界了,因為我們之前定義的字串常量只有三個,這裡卻引用了四個,第四個哪來的?問記憶體管理器去。

c語言運算子優先順序存在的問題也有許多,例如說.運算子高於*,然而*p.f表示什麼?有人可能會誤解為(*p).f,但實際上是*(p.f)。

高於*,例如int *ap,有人可能誤解為ap是個指向int陣列的指標,但實際上ap是個元素為int指標的陣列,也就是指標陣列。

函式()高於*,例如int *fp(),有人可能誤解fp是個函式指標,函式返回int,但是實際上卻是返回int *的fp。

總之,最好在我們辦公的位置上貼上一張優先順序表,方便檢視,在寫程式的時候也要時常注意。若我們對優先順序判斷失誤,整個**的意思就有可能收到影響,我想象你不希望這樣。除了優先順序外,還要考慮語句的結合性,有些是左結合有些是右結合,當幾個操作符具有相同的優先順序時決定先執行哪乙個。例如:

int a,b = 2,c = 3;

a = b = c;

第二個語句賦值符優先順序都一樣,所以考慮其結合性,賦值符具有右結合性,就是說表示式中最右邊的操作最先執行,然後從右向做執行。最終a的值為3。

早期gets()中的bug導致了internet蠕蟲,就在2023年11月,蠕蟲程式入侵了數千台接入internet的計算機,而最終原因卻是因為gets()函式沒有對讀入的字元數設定乙個限制。我們知道字元陣列的空間是堆疊自動分配的,當使用者輸入超過了這個陣列的規定字元,gets()函式將會繼續把多出來的字元壓到堆疊中。如果黑闊想通過這些多餘的字元來改邪堆疊中某個專案的內容,那···不解釋,這個在高階技術貌似叫緩衝區溢位攻擊。可以用fgets來代替gets,例如:

*c = fgets(s,sizeof(s),stdin);    //fgets(源,n-1字元數,欲讀取的流)

這樣函式就不會超出緩衝區的範圍,也不會由於其他人執行程式而覆蓋堆疊中的重要區域。

這樣的話會出現編譯錯誤,但是我們加上必要的空格:z = y++ + ++x;

還有另一種關於空格的錯誤,就是z = *x/*y; 表面上我們看到的是將兩個指標變數的值相除,但在仔細思考,我們發現/*是注釋符呀,這樣就出錯了。但是多加個空格z = *x / *y;

是的,我們在用c進行開發的時候,可能會遇到由於c的語言特性產生的錯誤,這方面的案例太多太多了,有的因為將「,」寫成「.」而損失了上千萬。我想你一定不希望自己有這樣的遭遇,那麼就需要你留個心眼,考慮程式是否存在邏輯錯誤或者實體(語句)錯誤。

C語言特性BUG

1.關鍵字const並不能把變數變成常量,在乙個符號前加上const限定符只是表明這個符號不能被賦值。也就是說它的值對於這個符號來說是唯讀的,但它並不能防止通過程式的內部的方法來修飾這個值。const最有用之處就是用它來限定函式的形參。這樣該函式將不會修改指標所指的資料。const和 的組合通常只用...

Python語言的高階特性

python函式式程式設計只是借鑑函式式程式設計的一些特點,可以理解成一半函式一半python 需要講述 存在問題 用法 計算乙個數字的100倍數 stm lambda x 100 x print stm 89 結果 8900 多個引數 stm2 lambda x,y,z,x y 10 z 100 ...

C 函式的高階特性

函式過載 編譯器會為每乙個函式產生乙個內部名稱。重新命名機制與函式的形參有關,與函式返回值無關。所以函式過載函式名相同,形參列表不同才能過載。注意 c 程式需要呼叫已經被編譯的c函式,c 提供了乙個c連線交換指示符extern c 來解決這個問題 ifdef cplusplus extern c e...