2011-05-12 51 views
2

可能重复:
What is the difference between char s[] and char *s in C?字符串常量VS字符数组用C

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

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

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

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

结束了印刷“全髋关节置换是一个字符串常量”正如您所料。我可以理解它作为字符串是否合理常量不应该最终在运行时被更改,因为它可能会混淆其他人/自己在处理您的代码,而不期望它有改变的价值,但是在纯粹的功能方面有什么问题有了它,什么是未定义的行为,可能会触发,以及如何在机械上可能会适得其反,当一个字符数组不会?我只是想知道我是否错过了字符串常量如何在内存中工作,以及编译器如何看待它们。

回答

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?

+0

我正在使用vc2010。感谢您发现另一个问题在我搜索时没有看到:D – ameer 2011-05-12 05:02:28

+0

大多数嵌入式编译器都会将字符串文字存储在真正的ROM中,因此他们不太可能允许修改。基于RAM的系统(如DOS)的旧编译器更可能允许这样做。 – Lundin 2011-05-12 06:43:03

1

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

char *的情况下,您实际上尝试修改原始字符串文本并按照UB标准进行修改。

0

对于字符串常量,不能保证数据将存储在何处 - 编译器可以自由地执行任何想要的操作,因为您应该禁止写入它。因此,例如,指针实际指向已定义字符串常量的加载可执行代码本身的位置,这并不是闻所未闻。