C 语言字符串用数组和指针初始化为什么会有这样的区别?
直接用数组初始化:
#include <stdio.h>
int main(void) {
char str[] = "abc";
int i = 0;
while (str[i] != '\0') {
printf("%c\n", str[i]);
i++;
}
str[1] = 'd';
return 0;
}
没有问题,正常输出,没有报错。
但是如果用指针初始化:
#include <stdio.h>
int main(void) {
char *str = "abc";
int i = 0;
while (str[i] != '\0') {
printf("%c\n", str[i]);
i++;
}
str[1] = 'd';
return 0;
}
它执行到 str[1] = 'd'
的时候,就会报 segmentation fault,我在网上搜了一下,
都是说通过指针初始化的字符串是个常量,不能改变。感觉这个很坑啊,只是 char str[] = "abc"
和 char *str = "abc";
这样小的区别而已,为什么通过指针初始化的那个就要是常量呢?是 C 语言规定就是这样,还是是可以理解的?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器就是这么做的,记住就行了,不必太纠结。
对linux来说,程序加载后内存是分段的。
对于
char *c="abc"
;程序启动时直接加载到了.data段。当你再定义一个char *d="abc"
时,这两个指针公用一块内存。因此你不能随便改这里的内容,它是共享的,只读的。你就理解成编译器共享常量字符串为了省内存吧。
但是对于
char a[]="abc"
;这种定义是在程序执行时,动态在stack段申请的,因此a,b两个指针的地址不一样。就只有你一个人用,而且函数返回后就销毁了。栈上的内存都是可以随便更改的。验证:
结果:
指针初始化时定义了一个指针指向常量地址,而数组初始化时是该数组申请了地址空间用于存储常量字符串的内容。因此,前者不可变,而后者是可变的。
数组的字符串内存属于
栈
, 所以是可读可写
;指针的字符串内存属于
代码块
, 只可读
, 这个地址程序运行后一直存在且不变.