为什么第一个版本会导致程序崩溃,而第二个版本却没有?他们不是一回事吗?
char *shift = "mondo";
shift[3] = shift[2];
char shift[] = {'m', 'o', 'n', 'd', 'o', '\0'};
shift[3] = shift[2];
int main( void )
{
char *shift = "mondo";
shift[3] = shift[2];
char shift[] = {'m', 'o', 'n', 'd', 'o', '\0'};
shift[3] = shift[2];
return 0;
}
答案 0 :(得分:6)
没有!这是C中的重要问题之一。首先,您创建一个指向内存只读部分的指针,即您无法更改它,只能读取它。第二个,创建一个字符数组,即连续字符的内存的一部分,您可以同时具有读取和写入访问权限,这意味着您可以读取和更改数组的值。
答案 1 :(得分:3)
第一个指向字符串文字(通常在代码的只读部分,应该是const char *shift = "mondo";
但由于历史原因能够逃脱)|。
第二个创建一个数组,然后填充该数组。
因此它们不一样
答案 2 :(得分:2)
第一个是在.TEXT段中分配内存,而第二个是将它放入.BSS。 .TEXT段中的内存实际上是只读或const
:
char *string = "AAAA";
这会创建实际上是const char *
的内容,因为内存将作为字符串文字在.TEXT段中分配。由于这通常会被标记为只读,因此尝试写入它将产生访问冲突或分段错误。
你想这样做:
char string[] = "AAAA";
这将按预期工作,并为四个大写字母As的字符串分配内存,并使用变量string
作为指向该位置的指针。
答案 3 :(得分:1)
这将创建一个指向现有字符串的指针:
TreeMap
这会创建一个新的字符数组:
char *shift = "mondo";
在第二种情况下,您可以修改字符,因为它们是您刚刚创建的字符。
在第一种情况下,您只是指向一个永远不应该修改的现有字符串。存储字符串的位置的详细信息取决于特定的编译器。例如,它可以将字符串存储在不可修改的内存中。编译器也可以做一些技巧来节省空间。例如:
char shift[] = {'m', 'o', 'n', 'd', 'o', '\0'};
char *s1 = "hello there";
char *s2 = "there";
实际上可能指向位于s2
所指向的字符串的第七个位置的相同字母't'。
为避免混淆,更喜欢使用带有字符串文字的const指针:
s1
这样,如果您不小心尝试修改它,编译器会通知您。
答案 4 :(得分:1)
每当使用时定义字符串
char * str = "hello";
这由编译器隐式表达
const char * str= "hello";
这使得这个符号只读取程序存储器的位置。
但是在数组的情况下,相同的解释为
char const *array[];
这就是为什么编译器在用户尝试更改数组的基址时会尖叫的原因。
这是由编译器