为什么这个矩阵元素的值是未知的?

时间:2016-01-14 11:27:02

标签: c multidimensional-array initialization initializer-list

这是我练习册上的一个问题:

  

如果我们写int a[][3]={{0},{1},{2}};,则元素a[1][2]的值将为____。

关键是它的价值无法知晓。 由于该语句未被授予在函数外部写入,因此矩阵不应简单地视为全局变量,它将所有元素初始化为0.但是,我认为初始化器{{0},{1},{2}}等同于{{1} },所以{{0,0,0},{1,0,0},{2,0,0}}应该是0.谁错了,关键还是我?

PS:我写了这段代码:

a[1][2]

它的输出正好是0。

4 个答案:

答案 0 :(得分:5)

你是对的,其余的值被初始化为默认值,在这种情况下为0。

标准的相关引用:

  

6.7.9初始化

     
      
  1. 如果括号括起的列表中的初始值设定项少于元素或成员   用于初始化已知数组的字符串文字中的聚合或更少字符   大小比数组中的元素大,其余的聚合应该是   隐式初始化与具有静态存储持续时间的对象相同。
  2.   

答案 1 :(得分:2)

你的答案是正确的,关键是错误的。您未初始化的其余数组成员将被隐式初始化为0,这是由C标准保证的,无论数组是全局还是函数内部。

C11, 6.7.9

  

如果括号括起的列表中的初始值设定项少于此值   是聚合的元素或成员,或者是一个或多个字符   string literal用于初始化已知大小的数组   是数组中的元素,聚合的其余部分应为   隐式初始化与具有静态存储的对象相同   持续时间。

答案 2 :(得分:1)

两者都是对的。

如果未初始化本地非静态变量,则它将具有不确定的值。但是你初始化a变量,这就是“赋值”所做的,它初始化变量。如果你初始化一个数值少于声明值的数组,那么其余数据将被初始化为“零”。

答案 3 :(得分:1)

问题在于C对如何解释大括号有松懈的规则,大括号没有指定每个数组中有多少项。所以你最终会得到一个int [3][3];数组,这可能是你想要的,也可能不是你想要的。

根据数组初始化的规则,每个数组中未明确初始化的项目将被初始化,就像它们具有静态存储持续时间一样。也就是说,为零。

所以你是对的,你可以通过打印内存的原始内容轻松证明它,如下所示:

#include <stdio.h>
#include <inttypes.h>
#include <string.h>

void mem_dump (int a[3][3], size_t size);

int main()
{
  int a[][3]={{0},{1},{2}};
  printf("a is initialized like this:\n");
  mem_dump(a, sizeof(a));
  printf("\n"); 

  int rubbish[3][3];
  memset(rubbish, 0xAA, sizeof(rubbish)); // fill up with some nonsense character
  memcpy(a, rubbish, sizeof(a)); // a guaranteed to contain junk.
  printf("a is now filled with junk:\n");
  mem_dump(a, sizeof(a)); 
  printf("\n");

  memcpy(a, (int[][3]){{0},{1},{2}}, sizeof(a)); // copy back the initialized values
  printf("a now contains the initialized values once more:\n");
  mem_dump(a, sizeof(a));

  return 0;
}

void mem_dump (int a[3][3], size_t size)
{
  for (size_t i=0; i<size; i++)
  {
    printf("%.2" PRIx8 " ", ((uint8_t*)a)[i] );

    if( (i+1) % sizeof(int[3]) == 0) // if divisible by the size of a sub array
      printf("\n");
  }
}

输出:

a is initialized like this:
00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00
02 00 00 00 00 00 00 00 00 00 00 00

a is now filled with junk:
aa aa aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa aa aa

a now contains the initialized values once more:
00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00
02 00 00 00 00 00 00 00 00 00 00 00