首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 陷阱大全(一):字符串、容器、指針、運算符與整型提升的隱性坑

     編輯:C++ 入門

字符串與標準庫 string


string s("hello");
cout << s.size() << endl;        // OK: 5
// cout << "hello".size() << endl; // ERROR: 字符串字面值是 const char*,無 size()
cout << s + "world" << endl;     // OK: string + const char* → string
// cout << "hello" + "world" << endl; // ERROR: 兩指針相加非法

規則:字面值類型為 const char[N],衰變為 const char*,**非** std::string。

長度獲取三重奏

表達式結果說明
strlen("123")3運行時計算,遇 \0 停止
sizeof("123")4編譯期常量,含結束符 \0
string("123").size()3string 成員,不含 \0

getline 陷阱

getline(is, str) 讀取一行並**丟棄換行符**,str 不含 \n。

迭代器 const 易混淆


vector::const_iterator it1;  // *it1 不可改,it1 可改(指向只讀)
const vector::iterator it2;  // *it2 可改,it2 不可改(常量迭代器)
const vector::const_iterator it3; // 兩者皆不可改

記憶口訣:**const 修飾右側最近的類型**。

vector 操作導致迭代器失效


vector v = {10};
auto it = v.begin();  // 指向 10
v.push_back(9);       // 可能觸發擴容、內存搬移
cout << *it;          // UB!it 已失效

原則:任何改變容量/大小的操作(push_back, insert, erase, resize, reserve 等)都可能使**所有**迭代器、指針、引用失效。

數組與指針


char c1[] = {'h','e','l','l','o'};  // sizeof=5
char c2[] = "hello";                // sizeof=6 (含 \0)
int a[3] = {1,2,3};
// int b[3] = a;      // ERROR: 數組不可賦值/作初始化
// int c[3][3] = {a,a,a}; // ERROR

空指針:int *p = 0; 或 nullptr 合法;int *p = intVar; 非法(即使 intVar=0)。

typedef 與 const 陷阱


typedef string* pstring;
const pstring cstr;   // 類型:string* const(常量指針),而非 const string*(指向常量的指針)
// 等價於 pstring const cstr;

閱讀技巧:**從右向左讀**,或將 const 放類型後理解。

聲明解析:由內向外讀


int *ip[4];      // ip 是數組[4],元素類型 int*(指針數組)
int (*ip)[4];    // ip 是指針,指向 int[4](數組指針)

運算符陷阱

除法/求模符號規則(C++11 規範:截向零)

aba/ba%b
++++
--+-
+--+
-+--

C++11 前負數除法/求模實現定義,現已統一截向零。

邏輯運算符短路

&&、|| **保證左先右後**,且僅在左側無法決定結果時求右側。

if (i < j < k) vs if (i < j && j < k)

前者:i 產生 0/1,再與 k 比較 → 只要 k>1 恆真。
後者:邏輯與,需同時滿足。

if (val) vs if (val == true)

前者:val != 0 即真。
後者:val == 1 才真(true 提升為 1)。
例:int val=2; if(val==true) → **不進入 if**!

多重賦值類型一致性


int ival; int *pval;
ival = pval = 0;  // ERROR: ival(int) vs pval(int*) 類型不兼容
string s1,s2;
s1 = s2 = "OK";   // OK: 同類型

delete 非 new 內存

若指針指向棧/全局/靜態內存,delete 行為未定義。編譯器通常不檢查,運行時崩潰/靜默損壞堆。

整型提升與有符號/無符號混合


int i = -5; unsigned int u = 1;
cout << (i > u) << endl;  // 輸出 1 (true)!
// 原因:i 提升為 unsigned,-5 變巨大正數 (4294967291)
short s = -5; unsigned short us = 1;
cout << (s > us) << endl; // 輸出 0 (false)
// 原因:short/unsigned short 均提升為 int,比較在有符號域

鐵律:避免有符號/無符號直接比較;需比較時顯式轉型或用 std::cmp_* (C++20)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved