char ch[]="some string";

3
我有一个概念上的疑问。
char ch[20]="some string";

我想知道 ch 是如何存储的,即是否分配了 20 个字节或仅将字符串的长度分配给它?我们可以在此处访问类似 ch[18] 的内容吗?

5个回答

3
我想知道ch是如何存储的,即是否分配了20个字节或只是分配了字符串长度?
它创建了一个名为ch的数组,长度为20个字符,并用“some string”进行初始化。
是的,该数组的大小为20个字节。
我们可以访问ch[18]这样的内容吗?
是的,我们可以。甚至可以修改其内容。
好文章: char a[] = “string”; 和 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循环逐个输出每个字符,则可以看到您的修改。

我尝试过这个,但没有得到编辑后的ch字符串。 char ch[20] = "some string"; ch[18] = 'b'; printf(ch); - MasterWayne
2
如果字符串比数组短,则用0字节填充它。printf打印到它找到的第一个0字节,即ch[11]。更改ch[18]有效,但无法通过printf看到。 - Jens
1
@MasterWayne:修改了答案以回应您在评论中的问题。希望有所帮助。 - Alok Save

3

是否分配了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字节长的字符串,其中的字符是常量,因此它们是只读的 - 尝试修改它们(除了读取超出边界之外)会导致未定义的行为。

2

由于您声明了使用20个字节,因此分配了20个字节给ch。您可以访问ch[18]

问题在于

char ch[20] = "some string";
ch[18] = 'b';
printf("%s",ch);

字面意思是“some string”这个字符串被存储,包括它的NULL终止符,所以当你打印它时,字符串只会打印到第一个空终止符。


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或不为0,但在vc6中通常初始化为0)。可以访问ch [18],但其值可能未知。因此,如果您想访问它们,可能需要自己将它们初始化为0。

我尝试了这个,但没有得到编辑后的ch字符串。 char ch[20] =“一些字符串”; ch [18] ='b'; printf(ch); 问题可能是什么? - MasterWayne
1
"printf()"会在遇到'\0'时停止输出,如果你想要的效果是将其他字节初始化为' '(空格),并将'\0'作为最后一个字节。 - Al2O3

1

可以访问ch[18],您过度分配了数组,并且常量字符串后面的字节仍将存在,充满未初始化的数据。查看内存位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接