1

如果您能帮助我理解下一个代码中究竟发生了什么,我将不胜感激?(写“a”而不是“a”等......)。我的意思是什么将存储在内存中,为什么程序不会崩溃。

char str[10] ; 
str[0] = "a";
str[1] = "b";
str[2] = "\0";

谢谢。

4

3 回答 3

2

C 允许它,但它并没有按照您的期望做。对于第一个(str[0]"a"),编译器所做的是将编译器创建的字符数组转换"a"为指针,然后将其转换为指针char

所以存储的是字符串字面量数组地址str[0]的最后一个字节。"a"

于 2013-07-31T09:48:07.907 回答
2

'a' 是具有 ASCII 值 97 的单个字符(类型char)。“a”是 C 风格的字符串,一个char包含两个元素“a”和“\0”的数组。

如果您编译上面的代码,您将收到三个针对三个分配的警告。在 GCC 上,这些警告是这样说的:

main.c:6:12: warning: assignment makes integer from pointer without a cast [enabled by default]

让我们在您的代码中进行第一个分配:

str[0] = "a";

右侧操作数“a”是 a char *。左边的操作数是 a char,它是一个整数类型。正如警告提示的那样,它获取指针的值,将其转换为整数,然后将其截断为 的大小char并将截断的值存储在str[0]. 因此,赋值后str[0]不会像您期望的那样包含值“a”(ASCII 97),而是如上所述获得的一些值。

到目前为止一切顺利,程序没有崩溃的原因,只需注意str不会包含任何有意义的字符串。

现在,如果您尝试使用该字符串做一些有用的事情,例如打印它:

printf("%s", str);

您找到了可能导致程序崩溃(或导致许多其他问题,例如内存损坏)的原因。问题是最后一个赋值 ,str[2] = "\0"没有像您预期的那样正确终止字符串。因此,您最终会得到一个未正确以 NULL 结尾的 C 样式字符串。这是一条通向灾难的可靠而短暂的道路。

要测试此行为,请尝试显示在str这些分配之后存储的实际值:

printf("%d - %d - %d", str[0], str[1], str[2]);

您很可能会发现与预期不同的值(97、98、0)。

于 2013-07-31T09:46:53.553 回答
0

Simplistic terms... Take this for an example, -Image an array as a Rack with lots of shelves. -String are basically like an array of chars. -Chars are like knick-knacks. 'a' is a char and "a" is a string. Reworded: 'a' is a knick-knack and "a" is a rack with a knick-knack 'a' in it. Str[10] is a rack with 10 shelves. Now doing this, Str[0] = "a"; is like shoving a rack with a knick-knack 'a' in it, on to the first shelf of another rack...

So it's like shoving a whole rack into another rack, and then expect it to have it fit...

Even if this answer has no logic at all, its just to show that, str[0] = "a"; makes absolutely no sense either. You might as well just do str[0] = 97; to just completely forget about quotes.. :P

于 2013-07-31T10:34:42.947 回答