3

可能重复:
C 中的 char s[] 和 char *s 有什么区别?

更多的是一般性问题,而不是试图解决某些问题,我一直在阅读 C 编程语言书,他们注意区分

char amessage[] = "blah";
char *pmessage = "blah";

不同之处在于一个是 char 数组,另一个是指向字符串常量的指针。他们说修改 char 数组是可以接受的,但你不应该修改字符串常量,因为它会触发未定义的行为。我的问题是:存储在内存中的字符串常量与 char 数组的存储方式不同吗?为什么我可以修改它

char *p = "this is a string constant";
*(p+2) = 'a';
printf("%s", p);

如您所料,最终打印“这是一个字符串常量”。我可以理解它是如何有意义的,因为字符串常量不应最终在运行时被更改,因为它可能会使其他人/您自己在处理您的代码时感到困惑,而不是期望它的价值会改变,但在纯粹的功能方面它有什么问题,可能触发的未定义行为是什么?当 char 数组不会触发时,它会如何机械地适得其反?我只是想知道我是否遗漏了有关字符串常量在内存中的工作方式以及编译器如何看待它们的信息。

4

3 回答 3

4

至少在我的电脑上,以下程序崩溃:

#include <stdio.h>
int main() { 
  char *p = "this is a string constant";
  *(p+2) = 'a';
  printf("%s", p);
}

如果它似乎对你有用(它可能在某些嵌入式编译器上),你只是走运了。未定义的行为意味着程序可以做任何事情。见http://blog.regehr.org/archives/213

另请参阅char s[] 和 char *s 有什么区别?.

于 2011-05-12T03:21:37.437 回答
1

在 char 数组的情况下,字符串文字的内容"blah"也被复制到堆栈中。所以你可以在不调用 UB 的情况下修改它,因为它毕竟只是一个副本。

如果char *您实际上尝试修改原始字符串文字并按照标准 UB。

于 2011-05-12T03:13:38.047 回答
0

使用字符串常量,不能保证数据将存储在哪里——编译器可以自由地做它想做的任何技巧,因为你应该被禁止写入它。因此,例如,指针实际指向加载的可执行代码本身中定义字符串常量的位置并不是闻所未闻的。

于 2011-05-12T03:20:12.310 回答