我今天看到一道C++考试题:
给定数组int Multi[2][3][2] = {14,11,13,10,9,6,8,7,1,5,4,2}
,求Multi[1][1][0]
的值?
难道不应该像这样初始化三维数组吗:{{{},{}},{{},{}},{{},{}}}
?如何找到具有这样下标的元素的值?这很令人困惑。
我今天看到一道C++考试题:
给定数组int Multi[2][3][2] = {14,11,13,10,9,6,8,7,1,5,4,2}
,求Multi[1][1][0]
的值?
难道不应该像这样初始化三维数组吗:{{{},{}},{{},{}},{{},{}}}
?如何找到具有这样下标的元素的值?这很令人困惑。
您可以以两种方式初始化数组,但是建议使用花括号来提高可读性。
查找未用大括号格式化的多维数组元素的最简单方法是通过分割该数组。例如,您的数组的尺寸为2x3x2:
首先将数组分成2组(2x3x2)
{14,11,13,10,9,6,8,7,1,5,4,2} --> {{14,11,13,10,9,6}, {8,7,1,5,4,2}}
然后将每组分成3组(2x3x2)
{{14,11,13,10,9,6},{8,7,1,5,4,2}} --> {{{14,11}, {13,10} ,{9,6}}, {{8,7}, {1,5}, {4,2}}}
现在,你可以看到每个较小集合(2x3x2)中都还剩下2个元素,因此你已经用大括号格式化了你的数组。
现在更容易找到索引为[1][1][0]
的元素的值。这个元素是第2个([1][1][0])较大集合的第2个([1][1][0])较小集合的第1个([1][1][0])元素,所以答案是1。
话虽如此,这样的考题显示出你的老师缺乏专业精神,更关注滥用编程语言的语法,而不是教授基本的初始化规则。
应该得到满分的正确答案是:使用所有警告启用编译代码,这样你就不会编写像这样糟糕的代码。
gcc test.c -std=c11 -pedantic-errors -Wall -Wextra
test.c: In function 'main':
test.c:6:3: warning: missing braces around initializer [-Wmissing-braces]
int Multi[2][3][2] = {14,11,13,10,9,6,8,7,1,5,4,2};
^
然而,我怀疑您的老师并不是很担心代码质量,而是更关注于C语言中的细节,即使花括号列表与正在初始化的结构不匹配,也允许数组(和结构)进行初始化。
就C语言而言,int Multi[2][3][2] = {14,11,13,10,9,6,8,7,1,5,4,2}
与以下内容完全等效:
// properly written initialization list for a 3D array
int Multi[2][3][2] =
{
{
{14, 11},
{13, 10},
{ 9, 6}
},
{
{ 8, 7},
{ 1, 5},
{ 4, 2}
}
};
第一个表单被允许的唯一理由是,它允许你编写类似于的内容。
int Multi[2][3][2] = {0};
这个语句显式地将第一个元素初始化为0,其余的元素表现得好像它们具有静态存储期(也是0)。这意味着所有元素都将被设置为零。
编写类似 int Multi[2][3][2] = {14,11,13,10,9,6,8,7,1,5,4,2}
的代码是滥用C语言。这是非常不好的做法。这样做被MISRA-C等禁止。
一个好的老师会关心教你如何启用所有编译器警告以及如何正确初始化多维数组,而不是让你解释模糊难懂的代码。
int Multi[2][3][2] = {14,11,13,10,9,6,8,7,1,5,4,2};
Multi[2][3][2]的内存映射如下:
Multi[0][0][0]=14;
Multi[0][0][1]=11;
Multi[0][1][0]=13;
Multi[0][1][1]=10;
Multi[0][2][0]=9;
Multi[0][2][1]=6;
Multi[1][0][0]=8;
Multi[1][0][1]=7;
Multi[1][1][0]=1;
Multi[1][1][1]=5;
Multi[1][2][0]=4;
Multi[1][2][1]=2;
因此,Multi[1][1][0]的值为1;这很简单
我们也可以像这样初始化:
int Multi[2][3][2] = {{{14,11},{13,10},{9,6}},{{8,7},{1,5},{4,2}}};