我有一个概念上的怀疑。
char ch[20]="some string";
我想知道如何存储ch,即是否分配了20个字节,还是只分配了字符串的长度?我们可以在这里访问ch [18]吗?
答案 0 :(得分:3)
我想知道如何存储
ch
,即是否分配了20
个字节,还是只分配了分配给它的字符串的长度?
它创建一个名为ch
的数组,其长度为20
个字符,并使用“some string”将其初始化。
是的,该数组的大小为20个字节。
我们可以在这里访问ch [18]吗?
是的,我们可以。甚至修改内容。
好读:
What is the difference between char a[] = “string”; and char *p = “string”;
在评论中回答问题:
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
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循环输出每个字符的字符串,你可以看到你的修改。
答案 1 :(得分:3)
是否分配了20个字节
是的,分配了20个字节,因为您告诉它这样做。只是使用字符串及其尾随NUL,数组的前12个字节将初始化,其他字节用零填充。但是,您仍然可以访问(读取和写入)数组的所有20个字节,即。即从ch[0]
到ch[19]
。
如果你写过
char ch[] = "some string";
然后ch
将被创建为12元素数组:
{ 's', 'o', m', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', 0 }
只有这样才会尝试读取或写入数组的边界,这是错误的。即ch[12]
和更高的索引会调用未定义的行为。
如果你写
char *ch = "some string";
这真的很糟糕,如果你需要一个字符串文字作为字符指针,你应该写
const char *ch = "some string";
在这种情况下,ch
指针指向一个12字节长的字符串,其中字符是常量,因此它们是只读的 - 尝试修改它们(除了读出界限之外,再次是未定义的行为。
答案 2 :(得分:2)
20个字节被分配给ch
,因为您声明它使用20个字节。是的你可以访问ch [18]。
的问题
char ch[20] = "some string";
ch[18] = 'b';
printf("%s",ch);
是存储文字“some string”,包括其NULL
终止符,因此当你打印它时,字符串只会打印到第一个空终止符。
答案 3 :(得分:1)
是的,你可以访问ch [18],你对数组和你的常量字符串之后的字节仍然存在,充满了未初始化的数据。查看内存位置。
答案 4 :(得分:1)
`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或不是,但在vc6中,它通常被初始化为0)。可以访问ch [18],但该值可能是未知的。因此,如果您想要访问它们,您可能需要自己将它们初始化为0。