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

因为 char s[] = "0123",是语法糖。"0123"是常量字符串,不能修改。但是使用字符数组编译器会把"0123"在栈上复制一份,并把首地址赋值给数组名。

lmbtfy.cn/s/0tHcH1k-sa

www.gnu.org/software/c-intro-and-ref/manual/html_node/String-Constants.html

前面在编译的时候就会生成字符串常量在静态常量区(好像是这个区,有点忘了),后者是栈上的一个字符数组

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.似乎还没有说字符串常量一定在只读内存中,不清楚什么场景下会出现。

#2 你不想回答可以不回答,没必要在这里展示你作为 IT 工作者还使用百度这个搞笑的事实。

两个都可以修改,一个是指针,一个是数组。

godbolt.org/z/T9d38EWTq这个网站挺好,我也是在 v 站看到的

#5 单片机会有这样处理方式,字符串直接存在闪存中,cpu 可以通过地址总线读取,但是不能直接进行写入操作

#8 这个网站好哎 不过汇编都还给老师了哈哈哈

我写 c 的时候,一直是认为一样的,不同写法而已。不过那已经是三十年前的事儿了。

第一种指针 s 指向一个字符串常量"0123",第二种方法定义了一个字符数组 s ,初始化为字符串"0123"

你需要的是一本《 c primer plus 》,更进一步如果你要搞清楚作用域和内存分配的问题,可以看看《征服 c 指针》,少问人,多读书

一个栈上放指针,一个直接放数据

十多年以前仔细研究过这个 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 文件只有一个段,这个段可读可写可执行。总之这个问题和系统的段页式内存管理,以及编译器连接器都有关系

新手确实要过这一关,一楼解释的就很好。

我之前也被还有 char *s 和 char []s 搞晕

指针怎么就不能修改了?

插个题外话,不喜勿喷都 2024 年,C 语言这套古怪遗留语言表达该扔垃圾箱了

可这个问题,确实百度都能直接找到答案

C++会提示"const char " 类型的值不能用于初始化 "char " 类型的实体。C 不会。不过 C 会把这个字符串存只读段里,所以写的话会报段错误。我说怎么怪怪的,越看越不对劲。只能说这套该扔就扔吧。

//main.cpp int a = 0; 全局初始化区 char p1; 全局未初始化区 main() { int a = 4; 栈,4 也是存在栈上 char s[] = "abc"; 栈 "abc"也是存在栈上 char p2; 栈 char p3 = "123456"; 123456\0 在常量区(是在 Data 段上),p3 在栈上。 static int c =0 ; 全局(静态)初始化为 0,就是放在 BSS 段 p1 = (char )malloc(10); p2 = (char *)malloc(20); malloc 分配得来得 10 和 20 字节的区域就在堆区。因为属于动态申请分配内存空间 strcpy(p1, "123456"); 123456\0 放在常量区,编译器可能会将它与 p3 所指向的"123456"优化成一个地方。 }