我有一个概念上的疑问。
char ch[20]="some string";
我想知道 ch 是如何存储的,即是分配了 20 个字节还是只是分配给它的字符串的长度?我们可以在这里访问类似 ch[18] 的内容吗?
我想知道
ch
是如何存储的,即20
是分配字节还是分配给它的字符串的长度?
ch
它按名称创建一个长度为字符的数组,20
并用“一些字符串”对其进行初始化。
是的,数组大小为 20 个字节。
我们可以在这里访问类似 ch[18] 的内容吗?
我们可以。甚至修改内容。
好读:
char a[] = “string”; 和有什么区别?和 char *p = “字符串”;
要在评论中回答 Q:
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
ch:| s | o | m | e | | s | t | r | i | n | g | \0 | | | b | \0 |
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
0 1 2 3 4 5 6 7 8 9 10 11 12 ...... 18 19
当你这样做时,
ch[18]='b';
修改已经发生,只是你看不到它。
printf
通过检测确定字符串的结尾\0
。当\0
你初始化它时,它被放置在字符串的末尾。C/C++ 中的规则在声明一个数组时,只要给定初始化器,任何未初始化的元素都会自动设置为 0。正如你在上面的图表描述中看到的,修改后的字符是放在printf
认为是字符串结尾的内容之后,因此您无法在printf
.
如果您通过 for 循环通过迭代每个字符输出字符串,您可以看到您的修改。
是否分配了 20 个字节
是的,因为您告诉它分配了 20 个字节。只是数组的前 12 个字节将使用您的字符串及其尾随 NUL进行初始化,其他字节用零填充。但是,您仍然可以访问(读取和写入)数组的所有 20 个字节,即 fromch[0]
到ch[19]
。
如果你写过
char ch[] = "some string";
thench
将被创建为 12 元素数组:
{ 's', 'o', m', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', 0 }
只有这样,尝试读取或写入超出数组 i 的边界才会是错误的。e. ch[12]
并且更高的索引会调用未定义的行为。
如果你写
char *ch = "some string";
这真的很糟糕,如果你需要一个字符串文字作为 char 指针,你真的应该写
const char *ch = "some string";
在这种情况下,ch
指针指向一个 12 字节长的字符串,其中的字符是常量,因此它们是只读的 - 尝试修改它们(除了读取边界之外)再次是未定义的行为.
ch
由于您声明它使用 20 个字节,因此分配了20 个字节。是的,您可以访问 ch[18]。
问题与
char ch[20] = "some string";
ch[18] = 'b';
printf("%s",ch);
是存储了包含其NULL
终止符的文字“某些字符串”,因此当您打印它时,该字符串只会打印到第一个空终止符。
是的,您可以访问 ch[18],您过度分配了数组,并且常量字符串之后的字节仍然存在,其中充满了未初始化的数据。查看内存位置。
`how ch is being stored` and `whether 20 bytes are allocated`
实际分配了20个字节,分配的内存地址是不变的。这里的“ch”是指向所分配内存的第一个字节(或字符)的指针。而“ch+1”指向分配的内存的第二个字节。
Can we access something like ch[18] here?
如果字符串的长度小于你请求的内存大小(本例为20),你仍然得到请求的大小,其他字节的值不确定(可能为0或不为0,但在vc6中,通常是初始化为 0)。ch[18] 可以访问,但值可能未知。因此,如果您想访问它们,您可能必须自己努力将它们初始化为 0。