導言 程序設計語言中充滿陷阱,一不小心就會掉入其中萬劫不復,之所以有陷阱,是因為語言的設計細節不符合程序員的直覺 所以你會發現,語言越高級越注重順從程序員的直覺。 c++也有許多陷阱,所謂山不過來,我就過去,因此將c++中易錯點、難點集合於此,會不定期更新。 參考:c++中的陷阱(一) 控制語句 在swtich語句中存在一個普遍的誤解,以為程序只會執行匹配的case標號相關聯的語句,實際上,程序從該點開始執行,並跨越case邊界繼續執行其他語句,直到swtich結束或遇到break 對於switch結構,只能在它的最後一個case標號或default標號後面定義變量,這是為了避免出現代碼跳過變量的定義和初始化的情況。如果需要為某個特殊的case定義變量,則可以引入塊語句,在該塊語句中定義變量,從而保證這個變量在使用前被定義和初始化。 char c = 'b'; switch(c){ case 'b': { int i = 0; //right i定義在語句塊中 cout<<"b"<<endl; } case 'c': cout<<"c"<<endl; default: ; } char c = 'b'; switch(c){ case 'b': int i = 0; //error cout<<"b"<<endl; case 'c': cout<<"c"<<endl; default: ; } do-while語句中,任何在循環條件中引用的變量都必須在do語句之前就已經存在 string input; do{ cout<<input<<endl; cin >> input; }while(input != "bye"); //right do{ string input; cout<<input<<endl; cin >> input; }while(input != "bye"); //error 變量input只存在於花括號的塊作用域中 while(bool status = true){ //right cout<<"hello"<<endl; } do{ cout<<"hello"<<endl; }while(bool status = true); //error 變量status必須在do語句之前就已經存在 函數 返回值為void的函數,return後一般不能接表達式,但有一個例外,即返回另一個返回類型同樣是void的函數的調用結果 void func1(){} void func2(){return func1();} //right int main(){ func2(); return 0; } 函數的返回值是引用類型時,謹記不能返回局部對象的引用。因為在函數執行完畢時,將釋放分配給局部對象的存儲空間,此時,對局部對象的引用就會指向不確定的內存 函數的返回值是指針時,謹記不能返回局部對象的指針,理由同上 返回引用的函數返回一個左值,因此可以給返回的引用賦值 int &func(int &i){return i;} int main(){ int ival = 0; cout<<ival<<endl; // 0 func(ival) = 1; //func返回引用,因此返回的是一個左值 cout<<ival<<endl; // 1 return 0; } const對象、指向const對象的指針或引用只能用於調用其const成員函數,如果嘗試用他們調用非const成員函數,則是錯誤的 區分重載與非重載 非重載 int func(const int i); int func(int i); int func(int *const i); int func(int *i); typedef int integer; int func(int i); int func(integer i); void fun(int i=0); void fun(string s=""); 重載 int func(const int &i); int func(int &i); int func(const int *i); int func(int *i); 重載函數的實參類型轉換 int func(int i){ cout<<"int func"<<endl;} int func(unsigned char){ cout<<"unsigned char func"<<endl;} int main(){ char c = 'a'; func(c); //打印 int func } /* char類型到int型是類型提升,char類型到unsigned char類型是類型轉換,在實參匹配時類型提升優於類型轉換 實參類型的轉換等級:1.精確匹配 2.通過類型提升 3.通過標准轉換 4.通過類類型轉換 */ int func(int i, int ii){ cout<<"int func"<<endl;} int func(double d, double dd){ cout<<"double func"<<endl;} int main(){ int i=0; double d=0.0; func(i,d); //error 二義性 } /* 在調用重載函數時,編譯器會試圖尋找最佳匹配,若無法確定唯一的最佳匹配,則報錯 */ enum ABC {a, b, c}; int func(ABC val){} int main(){ ABC v = a; func(v); //right func(1); //error 不能直接將整數值作為枚舉類型的實參