问题在于您试图修改一个字符串常量。这样做会导致程序的行为未定义。
说您不能修改字符串常量是一种过度简化。说字符串常量是const
是不正确的;它们不是。
警告:以下是离题内容。
字符串字面值"this is a test"
是类型为char[15]
(14个字符加1个终止符'\0'
)的表达式。在大多数情况下,包括此处,这样的表达式会被隐式转换为指向数组第一个元素的指针,类型为char*
。
尝试修改由字符串字面值引用的数组的行为是未定义的--不是因为它是const
(它不是),而是因为C标准明确规定了它是未定义的。
某些编译器可能允许您这样做。您的代码实际上可能会修改与字面量对应的静态数组(这可能会在以后导致混乱)。
但是,大多数现代编译器将存储该数组在只读内存中--不是物理ROM,而是在由虚拟内存系统保护免受修改的内存区域中。 尝试修改这样的内存的结果通常是分段错误和程序崩溃。
那么为什么字符串字面值不是const
?既然您确实不应该尝试修改它们,那肯定有道理--C ++确实让字符串字面值成为const
。原因是历史原因。在1989年ANSI C标准引入之前,const
关键字并不存在(尽管某些编译器可能在此之前就已经实现了它)。因此,一个ANSI之前的程序可能如下所示:
#include <stdio.h>
print_string(s)
char *s;
{
printf("%s\n", s);
}
main()
{
print_string("Hello, world");
}
无法强制规定print_string
不允许修改指向s
的字符串。将ANSI C中的字符串文字声明为const
将破坏现有代码,这是ANSI C委员会非常努力避免的。此后没有好的机会来进行这种语言变更。(C++的设计者,主要是Bjarne Stroustrup,并不像对于与C的向后兼容性一样关注。)