char *s = "0123"和 char s[] = "0123"的区别

40 天前
 rookiemaster

为什么前者不可以修改,后者可以修改,是因为存储区域的问题吗?

2422 次点击
所在节点    C
22 条回复
huang119412
40 天前
因为 char s[] = "0123",是语法糖。"0123"是常量字符串,不能修改。但是使用字符数组编译器会把"0123"在栈上复制一份,并把首地址赋值给数组名。
tuwulin365
40 天前
tzxxxx
40 天前
throcean
40 天前
前面在编译的时候就会生成字符串常量在静态常量区(好像是这个区,有点忘了),后者是栈上的一个字符数组
tzxxxx
40 天前
https://www.gnu.org/software/c-intro-and-ref/manual/html_node/String-Constants.html
这个链接中说:The string constant is probably stored in a read-only area of memory.
似乎还没有说字符串常量一定在只读内存中,不清楚什么场景下会出现。
qq135449773
40 天前
@tuwulin365 #2

你不想回答可以不回答,没必要在这里展示你作为 IT 工作者还使用百度这个搞笑的事实。
leonshaw
40 天前
两个都可以修改,一个是指针,一个是数组。
liuidetmks
40 天前
https://godbolt.org/z/T9d38EWTq

这个网站挺好,我也是在 v 站看到的
DiamondY
40 天前
@tzxxxx #5 单片机会有这样处理方式,字符串直接存在闪存中,cpu 可以通过地址总线读取,但是不能直接进行写入操作
oIMOo
40 天前
@liuidetmks #8 这个网站好哎 不过汇编都还给老师了哈哈哈
hefish
40 天前
我写 c 的时候,一直是认为一样的,不同写法而已。
不过那已经是三十年前的事儿了。
outgoing4443
40 天前
第一种指针 s 指向一个字符串常量"0123",第二种方法定义了一个字符数组 s ,初始化为字符串"0123"
Nosub
40 天前
你需要的是一本《 c primer plus 》,更进一步如果你要搞清楚作用域和内存分配的问题,可以看看《征服 c 指针》,少问人,多读书
MrKrabs
40 天前
一个栈上放指针,一个直接放数据
lff0305
40 天前
十多年以前仔细研究过这个 char *s = "0123"。当时用的还是 VC6.
结果比较有意思(针对 VC6 ,之后的应该改进了)。

对于 Debug 版,“0123” 会被放到只读数据段里面(好像是叫.rdata). char* s 是个指向这个只读数据段中一小段数据的一个指针。任何对这个数据段的写操作都会引发段错误。

相应的这避免了两次调用相同的函数,结果不一致的问题。
比如下面的代码,假设可写,那么会有

test() {
char*s = "123";
printf("%s", s);
s[1] = 'a';
}

test();
test(); <--- 这里打印出来 1a3 ,和程序的语义不一致。

有意思的是上面的代码在 Release 版是没有出错的,打印出来两行 123 和 1a3 。
当时看了下的结果是,
对于 Debug 版,生成的 exe 有三个段,代码段(可执行),只读数据段(只读),普通数据段(可读可写)。
而对于 Release 版,连接器把所有三个段捏到一起去了,整个 exe 文件只有一个段,这个段可读可写可执行。

总之这个问题和系统的段页式内存管理,以及编译器连接器都有关系
FaiChou
39 天前
新手确实要过这一关,一楼解释的就很好。
jaycelhz
39 天前
我之前也被还有 char **s 和 char *[]s 搞晕
xuanbg
39 天前
指针怎么就不能修改了?
zooo
39 天前
插个题外话,不喜勿喷

都 2024 年,C 语言这套古怪遗留语言表达该扔垃圾箱了
Inn0Vat10n
39 天前
@qq135449773 可这个问题,确实百度都能直接找到答案

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1028174

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX