为什么这个程序打印 0 而不是来自指定数组的特定值集?

Why does this program print 0 instead of the specific set of values from a specified array?

我想知道为什么这个小程序中的 printf 函数 returns 0 而不是数字数组 3 2 2:

int main(){
    int mat[2][2][2] = {{3,1,1},{2,2,2}};

    printf("first x, 2nd y, 2nd z = %d\n",mat[0][1][1]);
}

虽然在 C 中使用 X × Y 矩阵检索任何值 XxY 是一件轻而易举的事,但是一旦我添加了另一个维度,我 运行 就陷入了这个问题。我想我一定是误解了 C 处理数组中坐标的方式。非常感谢!

这段代码会告诉你为什么你的结果是 0:

int main(){
    int mat[2][2][2] = {{3,1,1},{2,2,2}};

    for(int i = 0; i < 2; i++)
         for(int j = 0; j < 2; j++)
             for(int k = 0; k < 2; k++)
                 printf("mat[%d][%d][%d] = %d \n", i, j, k, mat[i][j][k]);
   return 0;
}

输出:

mat[0][0][0] = 3                                                                                                          
mat[0][0][1] = 1                                                                                                          
mat[0][1][0] = 1                                                                                                          
mat[0][1][1] = 0                                                                                                          
mat[1][0][0] = 2                                                                                                          
mat[1][0][1] = 2                                                                                                          
mat[1][1][0] = 2                                                                                                          
mat[1][1][1] = 0 

当您声明时:

int mat[2][2][2] = {{3,1,1},{2,2,2}};

这意味着你在程序中说谎,它是 2D 数组,而不是 3D。

int mat[2][2][2] = {{3,1,1},{2,2,2}};

你声明了一个 3D 数组,但你给出了一个 2D 的初始化,值没有放在你期望的地方

#include <stdio.h>

int main(){
  int mat[2][2][2] = {{3,1,1},{2,2,2}};

  for (int i = 0; i != 2; ++i)
    for (int j = 0; j != 2; ++j)
      for (int k = 0; k != 2; ++k)
        printf("%d %d %d -> %d\n", i, j, k, mat[i][j][k]);
  return 0;
}

执行: pi@raspberrypi:/tmp $ ./a.out

0 0 0 -> 3
0 0 1 -> 1
0 1 0 -> 1
0 1 1 -> 0
1 0 0 -> 2
1 0 1 -> 2
1 1 0 -> 2
1 1 1 -> 0
pi@raspberrypi:/tmp $ 

此外,因为您的数组有 8 个 int,但初始值只有 6,编译器用 0

初始化了两个未指定的条目

您有一个 3 维数组,但您正在初始化一个具有 1 个额外值的 2 级数组。考虑这样的事情:

#include <cstdio>

int main(){
    int mat[2][2][2] = {
       {{3, 3}, {1, 1}},
       {{1, 1}, {1, 1}}
    };

    printf("first x, 2nd y, 2nd z = %d\n", mat[0][1][1]);
}

您指定了一个具有三个维度的数组,但只指定了两个。此外,每个元素应该有两个条目,但你有三个。

如果您 turn on warnings 您应该会看到如下警告:

test.c:4:26: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    int mat[2][2][2] = {{3,1,5},{2,2,2}};
...more like that...
test.c:6:44: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]
    printf("z for first coordinate = %d\n",mat[0][2]);
                                     ~~    ^~~~~~~~~
test.c:6:44: warning: array index 2 is past the end of the array (which contains 2 elements)
      [-Warray-bounds]
    printf("z for first coordinate = %d\n",mat[0][2]);
                                           ^      ~
test.c:4:5: note: array 'mat' declared here
    int mat[2][2][2] = {{3,1,5},{2,2,2}};
    ^

int mat[2][2][2] 会像这样初始化。

int mat[2][2][2] = {
    {
        {3,1}, {1,1},
    },
    {
        {1,1}, {2,2},
    }
};

你永远不会从 mat[0][1][1] 得到 3 2 2。它只会 return 一个值。在这种情况下,1.


如果您希望存储 2 个 3D 坐标的列表,请改用 [2][3]。

int mat[2][3] = {{3,1,1},{2,2,2}};

问第一个 x 和第二个 y 的 z 是什么意思没有意义。这就像问新泽西州丹佛的海拔高度是多少(丹佛在科罗拉多州)。第一个 x 和第二个 y 是两个不同坐标的一部分,并且具有不同的 z。

相反,您可以像这样获得第一个坐标的 z。

printf("z for first coordinate = %d\n",mat[0][2]);

第一个坐标是mat[0],它的z是第3个属性,也就是第2个索引。 mat[0][2].

问题在于此数组元素 mat[0][1][1] 没有显式初始化程序。所以它是零初始化的。

那你就有这样的声明了

int mat[2][2][2] = {{3,1,1},{2,2,2}};

那么作为集合的数组mat[0]的第一个元素被这个列表初始化{3,1,1}并且数组mat[1]的第二个元素被这个列表初始化{2, , 2, 2 }.

至于元素mat[0]的元素依次聚合大括号不指定则mat[0]的元素依次初始化如

mat[0][0][0] = 3
mat[0][0][1] = 1
mat[0][1][0] = 1 

元素(数组)mat[0] 的所有其他元素都初始化为零。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    int a[2][2][2] = {{3,1,1},{2,2,2}};

    printf( "%d, %d, %d\n", a[0][0][0], a[0][0][1], a[0][1][0] );
    printf( "%d, %d, %d\n", a[1][0][0], a[1][0][1], a[1][1][0] );

    return 0;
}

它的输出是

3, 1, 1
2, 2, 2