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

时间:2011-05-12 03:10:30

标签: c arrays string char memory-model

  

可能重复:
  What is the difference between char s[] and char *s in C?

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

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

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

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

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

3 个答案:

答案 0 :(得分:3)

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

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

如果它似乎对你有用(某些嵌入式编译器可能会这样),那么你就是幸运的。未定义的行为意味着允许程序执行任何操作。请参阅http://blog.regehr.org/archives/213

另见What is the difference between char s[] and char *s?

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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