核心結論
'mn' 非法:單引號內只能包含單個字符 (或轉義序列視為單字符)。
"\\" 合法:雙引號內為字符串字面量,此處包含單個反斜線字符 (轉義後)。
語法規則詳解
1. 字符常量 (Character Constant) — 單引號 `''`
- 形式:`'c'`,其中 `c` 為單個字符:可打印字符、轉義序列 (`\n` `\t` `\\` `\'` `\"` `\?` `\0` `\xHH` `\uXXXX` `\UXXXXXXXX`)。
- 型別:C 語言中為
int (C++ 中為 char),值為該字符在執行字符集中的編碼值 (通常 ASCII/UTF-8 碼點)。
- 合法例子:`'a'` `'Z'` `'0'` `' '` `'\n'` `'\t'` `'\\'` `'\''` `'\0'` `'\x41'` (`'A'`)。
- 非法例子:`''` (空)、`'ab'` (多字符)、`'你好'` (多字節字符,C11 前無標準支援)、`'\xy'` (十六進制轉義超出 2 位)。
- 多字符常量:`'mn'` 在 C 標準中屬於實現定義行為 (通常編碼為 `'m' << 8 | 'n'`),但不可移植、強烈不建議使用,編譯器通常給出警告。
2. 字符串字面量 (String Literal) — 雙引號 `""`
- 形式:`"..."`,包含零個或多個字符的序列。
- 型別:`char[]` (數組類型),長度為字符數 + 1 (隱含結束符 `\0`)。
- 存儲:通常放在唯讀數據段,嘗試修改導致未定義行為 (段錯誤)。
- 合法例子:`""` (空串)、`"Hello"`、`"Line1\nLine2"`、`"C:\\Path\\File.txt"`、`"He said \"Hi\""`、`"\x48\x65\x6C\x6C\x6F"` (`"Hello"`)。
- 轉義序列:同字符常量,但在雙引號內 `\"` 必須轉義,`\'` 可選轉義。
3. 單引號 vs 雙引號:本質區別
| 特性 | 字符常量 `'c'` | 字符串字面量 `"c"` |
| 包含字符數 | 恰好 1 個 (含轉義序列視為 1 個) | 0 或多個 |
| 型別 | int (C) / char (C++) | char[N] (數組類型) |
| 值 | 字符編碼值 (如 65) | 首元素地址 (指針 char*) |
| 大小 `sizeof` | sizeof(int) (通常 4) | 字符數 + 1 (含 `\0`),如 `sizeof("a") == 2` |
| 可修改性 | 右值,不可修改 | 左值 (數組),但內容通常在唯讀段,修改 UB |
| 用途 | 單字符比較、switch case、賦值給 char | 字符串操作、printf 格式、初始化 char 數組/指針 |
常見陷阱與避坑
| 代碼 | 問題 | 修正 |
| `if (ch == "a")` | 比較 `char` 與 `char*` (地址),永假 | `if (ch == 'a')` |
| `char *p = 'abc';` | 將 `int` 賦值給指針,危險 | `char *p = "abc";` 或 `char arr[] = "abc";` |
| `char c = "a";` | 指針賦值給 `char`,截斷/警告 | `char c = 'a';` |
| `switch (str) { case "abc": ... }` | `switch` 僅接受整數表達式,`case` 僅接受整數常量表達式 | 用 `strcmp` / `strncmp` / `std::string` (C++) |
| `'\\n'` | 雙字符常量 (反斜線 + n),非法/實現定義 | `'\n'` (單個換行符) |
| `"\n"` vs `'\n'` | 前者為包含換行符的字符串 (長度 2),後者為換行符字符值 (10) | 按需選擇 |
進階:寬字符與 Unicode (C11/C++11)
/* 寬字符常量 (型別 wchar_t) */
L'a' // 寬字符 'a'
L'\n' // 寬字符換行
L"Hello" // 寬字符串 (型別 wchar_t[])
/* UTF-8 字符串字面量 (C11/u8 前綴,型別 char[]) */
u8"中文" // UTF-8 編碼字節序列
/* UTF-16/UTF-32 字符串字面量 (C11) */
u"中文" // UTF-16 (型別 char16_t[])
U"中文" // UTF-32 (型別 char32_t[])
/* 原始字符串字面量 (C11/R"(...)"),無轉義 */
R"(C:\Path\File.txt)" // 等價於 "C:\\Path\\File.txt"
R"delim(Hello "World")delim" // 自定義分隔符
總結
- 單引號 = 單字符值 (型別 int/char):`'a'` `'\n'` `'\\'`。
- 雙引號 = 字符串 (型別 char[],含隱含 \0):`"a"` `"\n"` `"\\"` `""`。
- 'mn' 非法 (多字符常量,實現定義,禁用)。
- '\\' 合法 (字符常量,值為反斜線碼 92);"\\" 合法 (字符串,長度 2,含反斜線和 `\0`)。
- 嚴格區分字符值與字符串地址,杜絕 `ch == "a"`、`char *p = 'a'` 等低級錯誤。
掌握字符/字符串字面量語法,是 C/C++ 基礎功夫的核心組成部分,請反覆練習至肌肉記憶。