char数组用字符串字面量初始化最安全,编译器自动补'\0'并零填充剩余空间;花括号初始化需显式指定各元素,不自动补'\0';运行时赋值须用strcpy或std::copy;推荐优先使用std::string以避免缓冲区问题。

char数组声明时用字符串字面量初始化,编译器自动补\0
这是最安全、最常用的初值方式。比如char buf[10] = "hello";,编译器会把"hello"(含末尾\0)拷贝进数组,剩余位置填\0。注意:数组长度必须 ≥ 字符串长度+1,否则编译报错error: initializer-string for char array is too long。
常见错误是写成char buf[5] = "hello";——看似5个字母,实则需要6字节存'h','e','l','l','o','\0'。这时要么扩数组,要么用{'h','e','l','l','o'}显式初始化(但不带\0,后续不能当C风格字符串用)。
用花括号列表初始化,每个元素必须显式指定
适合需要精确控制每个字节的场景,比如构造非字符串用途的缓冲区。例如:char data[4] = {0x01, 0xFF, 'A', 0};。这种写法不会自动补\0,也不会检查是否构成合法字符串。
容易踩的坑:
立即学习“C++免费学习笔记(深入)”;
- 如果数组长度大于初始化列表项数,未指定位置会被零初始化(这点和字符串字面量一致)
- 如果用
{'a','b','c'}初始化char buf[10],后7个元素是\0,但buf仍不是以\0结尾的字符串——因为第4个元素才是\0,而strlen(buf)会返回3,没问题;但若写成char buf[3] = {'a','b','c'};,则完全没\0,printf("%s", buf)会越界读内存
运行时赋值别直接用=,得用strcpy或std::copy
C++里数组名不是左值,声明后不能整体赋值,比如buf = "world";会编译失败:error: assignment to array type 'char [10]'。
正确做法:
- 用
strcpy(buf, "world");——但必须确保buf足够大,且目标空间可写;不检查长度,有溢出风险 - 更安全用
strncpy(buf, "world", sizeof(buf)-1); buf[sizeof(buf)-1] = '\0'; - C++11起推荐
std::copy("world", "world"+6, buf);,前提是知道源长度;或者用std::string替代原生数组
用std::string替代char[]能避开大部分陷阱
除非对接C API或做嵌入式底层开发,否则直接用std::string更省心。它自动管理内存、保证以\0结尾、支持拷贝赋值、无缓冲区溢出风险。例如std::string s = "hello"; s = "world";完全合法。
唯一要注意的是:需要传C风格字符串时,记得用s.c_str(),且该指针仅在s生命周期内有效——这点常被忽略,尤其在返回局部std::string的c_str()时,会导致悬空指针。


















