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() | 3 | string 成員,不含 \0 |
getline 陷阱getline(is, str) 讀取一行並**丟棄換行符**,str 不含 \n。
vector::const_iterator it1; // *it1 不可改,it1 可改(指向只讀)
const vector::iterator it2; // *it2 可改,it2 不可改(常量迭代器)
const vector::const_iterator it3; // 兩者皆不可改
記憶口訣:**const 修飾右側最近的類型**。
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](數組指針)
| a | b | a/b | a%b |
|---|---|---|---|
| + | + | + | + |
| - | - | + | - |
| + | - | - | + |
| - | + | - | - |
C++11 前負數除法/求模實現定義,現已統一截向零。
&&、|| **保證左先右後**,且僅在左側無法決定結果時求右側。
if (i < j < k) vs if (i < j && j < k)前者:ik 比較 → 只要 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 行為未定義。編譯器通常不檢查,運行時崩潰/靜默損壞堆。
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)。