我有一个概念上的疑问。
char ch[20]="some string";
我想知道 ch 是如何存储的,即是否分配了 20 个字节或仅将字符串的长度分配给它?我们可以在此处访问类似 ch[18] 的内容吗?
ch
是如何存储的,即是否分配了20
个字节或只是分配了字符串长度?ch
的数组,长度为20
个字符,并用“some string”进行初始化。ch[18]
这样的内容吗?回答评论中的问题:
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
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
的输出中看到它。是否分配了20个字节
是的,因为您告诉它这样做。只是数组的前12个字节将使用您的字符串和其尾随的NUL进行初始化,其他字节填充为零。但是,您仍然可以访问(读取和写入)数组的所有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字节长的字符串,其中的字符是常量,因此它们是只读的 - 尝试修改它们(除了读取超出边界之外)会导致未定义的行为。由于您声明了使用20个字节,因此分配了20个字节给ch
。您可以访问ch[18]
。
问题在于
char ch[20] = "some string";
ch[18] = 'b';
printf("%s",ch);
字面意思是“some string”这个字符串被存储,包括它的NULL
终止符,所以当你打印它时,字符串只会打印到第一个空终止符。
`how ch is being stored` and `whether 20 bytes are allocated`
实际上分配了20个字节,并且分配的内存地址是恒定的。 这里的“ch”是指向分配内存的第一个字节(或字符)的指针。而“ch+1”则指向分配内存的第二个字节。
Can we access something like ch[18] here?
可以访问ch[18],您过度分配了数组,并且常量字符串后面的字节仍将存在,充满未初始化的数据。查看内存位置。