C语言中字符串字面量与字符数组是什么?二者有何区别?
嘿,刚学C的时候搞混字符串字面量和字符数组真的太正常了!我当年啃《Head First C》的时候也在这个点上卡过一会儿,给你掰扯清楚核心区别:
字符串字面量 vs 字符数组:核心差异
1. 存储位置与可变性
- 字符数组:比如写
char arr[] = "hello";,编译器会把字符串的内容(包括末尾的终止符'\0')拷贝到栈内存里(如果是局部变量的话)。你完全可以修改数组里的任意字符,比如arr[0] = 'H';,程序跑起来一点问题都没有。 - 字符串字面量:像
char *str = "hello";里的"hello",是编译期就确定的常量,存放在程序的只读数据段里。要是你敢尝试修改它,比如str[0] = 'H';,直接触发未定义行为——大概率程序崩溃,运气好点也会出现莫名其妙的结果。
2. 内存分配逻辑
- 字符数组:声明时编译器会自动计算需要的内存大小(比如
"hello"是5个字符加'\0',共6字节),这块内存是完全属于你的,你可以自由读写。 - 字符串字面量:它本身是编译阶段就存在的只读数据,
char *str只是一个指针,指向这个常量的首地址而已——并没有额外分配内存来存储字符串内容,你只是“借”了个指针指向现成的只读数据。
3. 初始化的灵活性
- 字符数组:除了用字符串字面量初始化,还能逐个字符赋值,比如
char arr[] = {'h','e','l','l','o','\0'};。不过要注意,要是忘了加'\0',它就只是普通字符数组,不能用printf("%s")这类字符串函数处理。 - 字符串字面量:本质是
const char[]类型的常量,C语言出于历史兼容,允许用char *指向它,但这是个不严谨的写法——在C++里就必须用const char *来声明,强制你记住它是只读的。
4. 指针与数组的本质区别
- 字符数组的名字
arr是指向首元素的常量指针,你不能给arr赋值(比如arr = "world";是非法的),但可以修改它指向的数组内容。 - 用字符串字面量赋值的指针
str是普通指针,你可以让它指向其他字符串字面量或者字符数组(比如str = "world";是合法的),但依然碰不得它指向的字面量内容。
举个直观的代码例子
#include <stdio.h> int main() { // 字符数组:可自由修改 char arr[] = "hello"; arr[0] = 'H'; printf("修改后的字符数组:%s\n", arr); // 输出 Hello // 字符串字面量:只读,禁止修改 char *str = "hello"; // str[0] = 'H'; // 取消注释会直接触发未定义行为! printf("字符串字面量:%s\n", str); // 输出 hello return 0; }
内容的提问来源于stack exchange,提问作者user5405648
相关产品推荐
相关产品推荐

