字符字面量用单引号表示 char 类型值,字符串字面量用双引号表示 const char[N] 数组;'a' 是字符,"a" 是含 '\0' 的二元素数组,二者类型不同、内存布局不同、不可隐式转换。

字符字面量用单引号,字符串字面量用双引号
这是最常混淆的起点:C++ 里 'a' 是一个 char 类型的值,而 "a" 是一个以空字符结尾的 const char[2] 数组(即字符串字面量)。编译器不会自动帮你转换——把 "a" 赋给 char 变量,会报错 error: cannot convert 'const char*' to 'char'。
常见错误现象:
- 写成
char c = "x";—— 编译失败,因为右边是地址,不是字符 - 用
strcmp("a", 'a')—— 类型不匹配,strcmp要两个const char* - 误以为
sizeof("a") == sizeof(char)—— 实际是2(含\0)
字符变量只能存一个字符,不能存字符串
char 类型变量占 1 字节,只够存一个 ASCII 或 UTF-8 单字节字符。它和 C 风格字符串(char[] 或 char*)是两回事。
使用场景与限制:
立即学习“C++免费学习笔记(深入)”;
- 需要单个符号处理时(比如解析输入、状态标记),用
char c = 'Q'; - 想存多个字符?必须用数组或指针:
char s[] = "hello";或const char* s = "hello"; - 别写
char s = "hello";—— 这是类型错误,不是警告,是硬性编译失败 - 注意
char s[5] = "hello";会溢出("hello" 实际长 6 字节),编译器可能静默截断或报错
多字节字符和 Unicode 让事情变复杂
C++ 标准里,'€' 或 '中' 这类字符不是“一个 char”,而是依赖源文件编码和编译器设置的实现定义行为。在 UTF-8 源码中,'中' 实际占 3 字节,但 char 只能拿第一个字节,其余丢失。
关键事实:
-
char是字节类型,不是“字符类型”;它不理解 Unicode 码点 - 宽字符字面量
L'中'类型是wchar_t,但大小和编码平台相关(Windows 是 UTF-16,Linux 常为 UTF-32) - 现代项目建议用
std::u8string+u8"中文"处理 UTF-8 字符串,但单引号仍不能用于多字节字面量:u8'中'是非法的 - 别指望
strlen("中") == 1—— 它返回 3(UTF-8 编码下)
字符串字面量存储在只读内存,不可修改
"hello" 这类字面量通常放在数据段的只读页,试图改写会导致运行时崩溃(SIGSEGV)或未定义行为。
典型翻车操作:
-
char* s = "hello"; s[0] = 'H';—— 看似合法语法,运行时报错 - 正确做法是复制到可写内存:
char s[] = "hello"; s[0] = 'H';(数组初始化会拷贝) - 或者用
std::string:std::string s = "hello"; s[0] = 'H'; - 注意
const char* s = "hello";加const是良好习惯,但不改变存储位置,只约束指针本身
真正容易被忽略的是:字符和字符串的类型差异不是语法糖,而是底层内存布局、类型系统和 ABI 的刚性约束。哪怕只差一对引号,编译器就可能拒绝链接、运行时崩溃,或者在不同平台表现不一。



















