这个行为在不同的c和c++的编译器上有会不同的行为,应该说char *a = "hello world";这种写法不能算错误的写法,所以c编译器不报错也不警告。早期的K&C认 为这是完全合法的,但从K&C第二版标准开始就明确指出“修改string literal的结果是未定义的,字符串并不总是可修改的,可能会放在只读内存区域“。从C89开始,这个问题有了更明确的规定。char *a = "hello world";定义a是一种字符指针类并使用指定的字符数组(类型为array of char)“hello world"初始化,如果试图修改数组的内容行为将是未定义的。关键的解释就在"未定义“这个解释上,实际上未定义不是错误,它在这里表示代码不可移值。 所以在c89和c99规范的”公共扩展“部分有如下规则:String literals是可修改的,此时指向另外一个内容完全相同的对象。在c++中则有区别,c++2003标准规定string literal是由const字符数组构成的(array of n const char),所以C++明确了string literal是不可修改的。C++没有规定所有内容相同的string literal会指向同一个对象(相同的内容指向唯一的对象),这是由编译器实现决定的,同时指出了试图修改string literal的行为是未定义的。为了兼容C,所以不加const 的char*依然是可用的,但通常编译器会给出警告。最后C++标准明确规定不赞成这样做(deprecated)。 修饰为deprecated表示将 来不再支持这个特性。
所以,最好使用const char* p="hello world";且无法通过p[]修改字符串。
C++用string类来定义字符串:
string s = "abcde";,如果这样定义,那么s[0]是'a',s[1]就是'b',string类就是这样的特性(这里,s是字符串的首地址)。
C语言这样定义字符串是最好的,char c[] = "abcde";(注意:这样没有指定数组大小的定义系统会在最后自动加上'\0'字符,字符串长度为5+1 = 6),c[0]就是首个字符a(这里c是字符串的首地址)。