c-为什么这个程序打印0而不是指定数组中的特定值集



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

int main(){
int mat[2][2][2] = {{3,1,1},{2,2,2}};
printf("first x, 2nd y, 2nd z = %dn",mat[0][1][1]);
}

在C中处理X乘Y矩阵时,检索任何值XxY都是轻而易举的事,但一旦我添加了另一个维度,我就遇到了这个问题。我想我一定误解了C处理数组中坐标的方式。非常感谢!

在中

int mat[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 -> %dn", 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 $ 

此外,因为您的数组有8int,但init值只有6,所以编译器会用0 初始化两个未指定的项

问题是此数组元素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, %dn", a[0][0][0], a[0][0][1], a[0][1][0] );
printf( "%d, %d, %dn", a[1][0][0], a[1][0][1], a[1][1][0] );
return 0;
}

其输出为

3, 1, 1
2, 2, 2

这段代码将告诉您为什么结果是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}};

这意味着你们在程序中撒谎,说它是二维数组,而不是三维数组。

您有一个三维数组,但您正在初始化一个具有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 = %dn", mat[0][1][1]);
}

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

如果你打开警告,你应该看到这样的警告:

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 = %dn",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 = %dn",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。它只会返回一个值。在这种情况下,1。


如果要存储2个三维坐标的列表,请使用[2][3]。

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

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

相反,你可以像这样得到第一个坐标的z

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

第一个坐标是mat[0],其z是第三个属性,即第二个索引。CCD_ 10。

最新更新