天天看點

C語言中的“六大陷阱”,你可能已經知道了兩個

前戲

要了解一個C 程式,僅僅了解組成該程式的符号是不夠的,我們還需要了解這些符号是如何組成聲明、表達式、語句和程式的。今天我們就來讨論一下不一樣的文法結構。

1. 正确了解函數聲明

你是否見過這樣的代碼“((void()())0)();”,你能知道這是上面意思嗎?

看不懂不用擔心,下面我們來分析一下:任何C變量的聲明都由兩部分組成:類型以及一組類似表達式的聲明符(declarator)。聲明符從表面上看魚表發揮有些類似,對他就隻應該傳回一個聲明給定的結果。(void ()()0)是将常數0 轉型為“指向傳回值為void 的函數的指針”類型。而((void(*)())0)();就可以看成是一個函數調用,末尾的分号使得表達式成為一個語句。當然我們也可以使用typedef來世表達式更加清晰:

typedef void (*funcptr)();
(*(funcptr)0)();           

2. 運算符的優先級問題

在 C語言中,運算符優先級有15個之多,如果不知道運算符的優先級我們在處理問題,分析代碼時,就非常被動,那麼我們可以對運算符進行簡單的分組,了解各組運算符之間的相對優先級,那麼記起來就相對簡單了,可以簡單的記做:!> 算術運算符 > 關系運算符>&&>|| > 指派運算符。

  1. 語句結束符的分号問題

    C語言以分号“;”,作為語句結束的标志,那麼如果在表達式後多寫了分号,會出現什麼結果呢?這個分号也許會被視作一個不會産生任何實際效果的空語句,或者編譯器會因為這個多餘的分号産生一條警告資訊,可以根據警告資訊去掉這個分号。但一個例外就是在if 或者while語句之後多寫一個分号,此時原來在if或者while之後的語句即使一條單獨的語句,魚條件判斷沒有了任何關系。請看一下代碼:

If(x > y)return;
If(x > y);return;
           

這兩句完全是不一樣的

4. Switch 語句問題

C語言中的switch,在case分支後都需要添加一個break;語句,不然會已知順着語句執行下去,達不到我們需要的效果。

5. 函數調用

與其他程式設計語言不同,C語言要求:在函數調用時及時函數不帶參數,也應該包含參數清單,是以,如果f 是一個函數,f();一個函數調用,而f;卻是一個什麼也不做的語句。

6. else 懸挂問題

我們經常聽到說else要和if 配對使用,然而在我們寫代碼時,還是會經常出錯,例如如下代碼:

C語言中的“六大陷阱”,你可能已經知道了兩個

這段代碼的本意是分為兩種情況,x 等于0 不等于0,然而上面的代碼表達的意思卻截然不同。即 想不等于0,程式不做處理,x 等于0時,判斷y的值,做出不同的處理。

-

如有侵權,請聯系删除

繼續閱讀