初始化后分配给数组中的特定索引

时间:2018-09-21 08:50:34

标签: c arrays initialization c-strings

在分配了第26个元素后,尽管我为第26个索引分配了一个字符,但仍打印出“ Computer”。我期望这样的东西:“计算机K”

原因是什么?

#include <stdio.h>
int main()
{
  char m1[40] = "Computer";
  printf("%s\n", m1);   /*prints out "Computer"*/
  m1[26] = 'K';
  printf("%s\n", m1);   /*prints out "Computer"*/
  printf("%c", m1[26]); /*prints "K"*/
}

6 个答案:

答案 0 :(得分:4)

char s[100] = "Computer";

基本相同
char s[100] = { 'C', 'o', 'm', 'p', 'u','t','e','r', '\0'};

由于printf在字符串以0结尾时停止,因此不会打印字符26

答案 1 :(得分:3)

在C中,字符串以0结尾。 您的初始化将'r'之后的所有数组元素都填充为0。 如果将非0字符放置在数组的任何随机字段中,则不会更改该元素之前或之后的字段中的任何内容。

这意味着您的字符串在'r'之后仍然以0结尾。 任何函数应该如何知道在该字符串之后可能跟随其他字符串?

答案 2 :(得分:3)

在该字符串的 8th 索引处找到\0字符,%s仅打印直到找到\0(字符串的结尾,用\0)-在 26th 处出现了字符k,但由于之前已经找到\0而不会打印。

答案 3 :(得分:3)

那是因为在"Computer"之后,您的数组中有一个null terminator\0)。如果您在此\0之后添加字符,将不会打印该字符,因为printf()在遇到空终止符时会停止打印。

答案 4 :(得分:3)

每当部分初始化数组时,其余元素都将填充为零。 (这是C标准C17 6.7.9§19中的规则。)

因此char m1[40] = "Computer";最终在内存中像这样:

[0] = 'C'
[1] = 'o' 
... 
[7] = 'r'
[8] = '\0' // the null terminator you automatically get by using the " " syntax
[9] = 0    // everything to zero from here on
... 
[39] = 0

当然,\00的含义相同,值为0。这两种情况都将被解释为空终止符。

如果继续进行操作并覆盖索引26,然后将数组打印为字符串,它将一直打印直到遇到索引8处的第一个空终止符。

但是,如果您这样做:

#include <stdio.h>

int main()
{
  char m1[40] = "Computer";
  printf("%s\n", m1); // prints out "Computer"
  m1[8] = 'K';
  printf("%s\n", m1); // prints out "ComputerK"
}

您覆盖了空终止符,而恰好在数组中的下一个零将被视为空终止符。这段代码之所以有效,是因为我们部分初始化了数组,所以我们知道后面还有更多的零。

您改写了

int main()
{
  char m1[40];
  strcpy(m1, "Computer");

这不是初始化,而是运行时分配。 strcpy仅将索引0设置为8(“计算机”,在索引8处为空)。其余元素将保留为未初始化的垃圾值,并且写入m1[8] = 'K'将破坏该字符串,因为该字符串将不再可靠地以null终止。尝试打印时会出现未定义的行为:类似垃圾输出或程序崩溃。

答案 5 :(得分:-1)

作为其他用户答案的​​补充-您应该通过更加主动地学习来尝试回答您的问题。编写一个简单的程序足以了解正在发生的事情。

int main()
{
  char m1[40] = "Computer";
  printf("%s\n", m1);   /*prints out "Computer"*/
  m1[26] = 'K';


  for(size_t index = 0; index < 40; index++)
  {
      printf("m1[%zu] = 0x%hhx ('%c')\n", index, (unsigned char)m1[index], (m1[index] >=32) ? m1[index] : ' ');
  }

}