字符串常量与C中的char数组

可能重复:
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); 

如您所料,结束打印“thas是一个字符串常量”。 我可以理解它是如何有意义的,因为字符串常量不应该最终在运行时被更改,因为它可能会混淆其他人/你自己处理你的代码并不期望它的价值改变,但纯粹function性的术语是什么错误的什么是可能触发的未定义行为,以及当char数组不能时它会如何机械地适得其反? 我只是想知道我是否遗漏了一些关于字符串常量如何在内存中工作以及编译器如何看到它们的内容。

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

 #include  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之间的区别是什么? 。

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

char *情况下,您实际上尝试修改原始字符串文字,并根据标准UB。

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