字符串字面量 (String Literal)
字符串字面量是把文本直接写进源代码的方式,例如 "hello"。在 C 里,它不仅是“字符序列”,还是一个具有明确类型和存储期的对象表示。
1. 基本语义
普通字符串字面量的类型是“char 数组”,长度等于字符数加终止空字符 '\0'。它具有静态存储期,程序整个执行期间都存在。你可以读取它的内容,但对其进行修改会触发未定义行为。
const char *s = "abc";运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
上面写法用 const char * 接收更清楚地表达了“只读意图”。
2. 字面量拼接
相邻字符串字面量会在翻译阶段自动拼接,因此下面两段写法等价:
const char *a = "hello, " "world";
const char *b = "hello, world";2
运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
拼接发生在编译期,不会在运行期产生额外连接开销。
3. 内嵌空字符
字面量中可以出现 '\0'。这会影响把它当作 C 风格字符串时可见的“逻辑结尾”。
const char raw[] = "ab\0cd";运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
raw 的数组长度仍包含全部字符和最终终止符,但用 %s 输出时会在第一个 '\0' 处停止。
4. 编码前缀
C 还支持带前缀的字符串字面量(如 u8""、u""、U""、L""),用于表达不同字符编码或宽字符语义。具体类型和编码规则与实现支持度有关,跨平台代码应保持编码策略一致,并在接口边界显式转换。
5. 与字符数组初始化的区别
下面两种写法看起来相似,但语义不同:
char a[] = "abc"; /* 数组对象,可修改内容 */
const char *p = "abc"; /* 指向字符串字面量,不应修改 */
a[0] = 'A'; /* 有效 */
/* p[0] = 'A'; */ /* 未定义行为 */2
3
4
5
运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
当你需要可写文本缓冲时,应使用数组对象或可写存储,而不是直接修改字面量内容。
6. 作为函数实参时的退化
字符串字面量在表达式语境里通常会退化为指向首元素的指针,因此传参给 const char * 形参很自然;但这不改变它本身“静态存储期字面量对象”的属性。理解这层关系后,就不容易把“可传指针”误读成“可修改内容”。
7. 跨模块共享时的约束
若同一文本需要在多个源文件共享,优先通过 const char * 只读接口暴露,或在单一实现文件中定义 const char[] 再通过声明引用。这样既能保持只读语义,也能避免各模块复制字面量导致维护分散。
8. 习题
写出一个“相邻字符串字面量拼接”的示例,并说明拼接发生在什么时候(编译期还是运行期)。