C 99 個常見錯誤 一

2021-05-22 15:44:59 字數 2470 閱讀 7360

a.基礎問題

1.過分注釋(對注釋的更新與**不一致), 字面常量(幻數,看不出意義, 可用 enum 或 const 解決).

2.全域性變數.  

<--幼稚的訊息傳遞機制

(1) 可用函式呼叫得到 (2) 可用乙個類單例得到

3.未能區分函式過載和形參預設值.

4.引用:

引用只是其初始化物的別名.引用是沒有位址的,甚至不占有任何儲存空間. 由於無位址,宣告指向引用的指標,引用的引用都是不合法的。

注:沒有空引用,也無型別為void的引用。任何可作為左值的都可被引用 .

指向陣列的引用 : int ( & array )[10] ;     <=保留了尺寸

int f(double) ;     f(18.6) <=> (*f)(18.6)

5.對常量的誤區:

const <- 常量,  10 <- 字面量

const volatile <= 只限制對const 的直接修改,間接修改是可行的,不會引發未定義的行為(??)

6.無視語言的精妙之處:

(1) bool r = a < b ;       <=  never use if in this case !!! 不要用 if

(2) 位遮蔽演算法:      b & m & ((b & m) - 1)      ;;結果為0則沒選或只選乙個

(3) 如果條件運算子表示式兩個選擇結果都為左值,那麼這個表示式就是左值 : a

(4) 內建索引運算子 :

p[-2]  <=>  *(p + (-2))  <=> * ( -2 + p)  <=>  (-2)[p]

(5) switch  <= 只管入口,如果要直下,最好加上注釋.

另:case 可不在同一級,case 可在任何地方.

7.空指標: #define null ((char * )0)  / ((void*)0)  / 0

故,最好用 0 : c * cp = 0;

8.無視習慣用法:

x ( const x &) ;      x & operator = ( const x &)

語法問題:

1. int * ip = new int(12) ;     //僅初始化了乙個整數,並非乙個陣列

int a[12] ; int a(12); 

vector iv(12);         <--下標訪問,不用顯式**

注:最好的記憶體申請形式就是根本不做這個記憶體申請,直接用標準庫中元件.

2. 不定的求值順序:

(a=12) + a

a=( p() + q() ) + r();

<---可以有六種順序

thing * pthing = new ( thing ( initval() ) ;

<---可以肯定 operator new 會比 thing 型別建構函式先呼叫(先分配空間,後初始化.)

return  f(), g(), h();

a = f() + g() ? p() : q(); <=> a = ( f() + g() ) ? p() : q();

左結合性:該運算子先會繫結左邊那個引數;

-> 有很高的優先順序, 但是低於 ()

++ 高於 -> *

3. for 語句 

if ( char * thename = lookup( name ))

for ( int i = 0 ; ; )

4. 取大優先: list < vector < string >> lovos;    //  >>之間要有空格!!,不然會被當作...

5.宣告飾詞:  先連線,再量化,最後型別

int const * const * pp1;    extern const int;

6. 是函式還是物件: string x(); <-函式宣告,多義    string x(void)

string * sp1 = new string () ; <=> sp1 = m new string; (後面較好)

7.自反初始化:

int var = 12;

8. 運算子名字查詢的反常行為:

中序語法呼叫:

函式呼叫語法: 名字查詢遵從標準形式

9 operator -> : 過載版本是一元的,並且它必須返回乙個可用 -> 訪問其成員的物件.

預處理問題:

1. #define 的作用域並未被限制在名字空間中;

盡量不要用 #define 呼叫的偽函式. ---> static const ,函式物件,operator()

2. 如果除錯**在最終生成的可執行檔案中根本不存在,那麼編譯器會剔除無用**...

if( false )

避免用 #if 作為源**的控制.

3. assert 是乙個巨集 <--- 即也是乙個偽函式.   #define assert(e) ((void) 0)

----->所以,當使用 assert 時,不要在 e 中使用函式呼叫.

C99標準之前沒有bool型別(C99提供)

我們知道在c 裡有專門的bool型別,用來表示真或假。但是在c語言裡沒有這樣的型別。表示式的值0為假,非0為真。所以條件判斷語句 if while 非常靈活,甚至乙個指標型別都可以是條件表示式。為了使程式更清晰,我們常常會給出如下的巨集定義 typedef int bool define true ...

復合文字(C99)

1.假如需要向帶有乙個int參量的函式傳遞乙個值,您可以傳遞乙個int變數,也可以傳遞乙個int常量,比如5。在c99標準之前,陣列引數的情況是不相同的 可以傳遞陣列,但沒有所謂的陣列常量可供傳遞。c99新增了復合文字 compound literal 文字是非符號常量,例如5是int型別的文字,8...

keil arm 中配置c99方法 及 C99特性

配置方法 option c c misc controls c99 附c99特性 在ansi的標準確立後,c語言的規範在一段時間內沒有大的變動,然而c 在自己的標準化建立過程中繼續發展壯大。標準修正案一 在1994年為c語言建立了乙個新標準,但是只修正了一些c89標準中的細節和增加更多更廣的國際字符...