C:二维数组的嵌套循环给出了意想不到的结果
C: Nested loop over 2d array giving unexpected result
这是问题的最小可重现示例。
将高度和长度作为参数(而不是计算它们)是故意的。
typedef struct
{
int red;
} triple;
int main(void)
{
triple array[3][3] = {
{ {.red = 10}, {.red = 40}, {.red = 70}},
{ {.red = 110}, {.red = 120}, {.red = 130}},
{ {.red = 200}, {.red = 220}, {.red = 240}}
};
printarray(2, 2, array);
}
void printarray(int height, int length, triple array[][length])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < length; j++)
{
printf("red score at array[%i][%i] = %i\n", i, j, array[i][j].red);
}
}
}
我得到的输出是:
array[0][0] = 10
处的红色分数
array[0][1] = 40
处的红色分数
array[1][0] = 70
处的红色分数
array[1][1] = 110
处的红色分数
但我希望:
array[0][0] = 10
处的红色分数
array[0][1] = 40
处的红色分数
array[1][0] = 110
处的红色分数
array[1][1] = 120
处的红色分数
二维数组的索引显然没有像我预期的那样工作,但为什么?
您正在将 2,2
传递给 printarray
。这是 height,length
.
但是,数组是定义的,长度为3
。因此,您 必须 将 3
传递给 printarray
作为长度。
否则,printarray
中的索引不正确。如您所见,printarray
中的数组相当于 triple array[2][2]
和 而不是 triple array[3][3]
是必需的。
height
可以小于定义的高度,但length
必须匹配。这里,length
是 步幅 。这是给定行中的元素数。
因此,在 main
中调用:printarray(3,3,array)
如果您确实希望打印数组的一部分,您需要将一个单独的变量传递给printarray
以获取步长。
该函数必须声明为:
void printarray(int height, int length, int stride, triple array[][stride])
然后,在 main
中调用它:
printarray(2,2,3,array);
问题出在您对 printarray
的调用中:
printarray(2, 2, array);
你告诉函数数组有两行两列 - 但它没有,它有三行三列。编译器假设你没有说谎!
您 必须 使用 length
参数的正确值调用您的函数,因为编译器使用它来推断如何计算元素的偏移量array[i][j]
.
如果您只想打印该数组的 部分 ,您应该指定要打印的列数和行数作为函数的额外参数,如下所示:
void printarray(int height, int length, int nrows, int ncols, triple array[][length])
{
if (nrows > height) nrows = height;
if (ncols > width) ncols = width; // Prevent error conditions!
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < ncols; j++) {
printf("red score at array[%i][%i] = %i\n", i, j, array[i][j].red);
}
}
}
然后像这样调用函数:
printarray(3, 3, 2, 2, array);
注意:在使用 printarray
之前,您还遗漏了一个 function prototype,这在某些编译器上将是一个错误(但在其他编译器上只是一个警告);在 main
函数之前的某处添加此行:
void printarray(int height, int length, int nrows, int ncols, triple array[][length]);
这是问题的最小可重现示例。 将高度和长度作为参数(而不是计算它们)是故意的。
typedef struct
{
int red;
} triple;
int main(void)
{
triple array[3][3] = {
{ {.red = 10}, {.red = 40}, {.red = 70}},
{ {.red = 110}, {.red = 120}, {.red = 130}},
{ {.red = 200}, {.red = 220}, {.red = 240}}
};
printarray(2, 2, array);
}
void printarray(int height, int length, triple array[][length])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < length; j++)
{
printf("red score at array[%i][%i] = %i\n", i, j, array[i][j].red);
}
}
}
我得到的输出是:
array[0][0] = 10
处的红色分数
array[0][1] = 40
处的红色分数
array[1][0] = 70
处的红色分数
array[1][1] = 110
但我希望:
array[0][0] = 10
处的红色分数
array[0][1] = 40
处的红色分数
array[1][0] = 110
处的红色分数
array[1][1] = 120
二维数组的索引显然没有像我预期的那样工作,但为什么?
您正在将 2,2
传递给 printarray
。这是 height,length
.
但是,数组是定义的,长度为3
。因此,您 必须 将 3
传递给 printarray
作为长度。
否则,printarray
中的索引不正确。如您所见,printarray
中的数组相当于 triple array[2][2]
和 而不是 triple array[3][3]
是必需的。
height
可以小于定义的高度,但length
必须匹配。这里,length
是 步幅 。这是给定行中的元素数。
因此,在 main
中调用:printarray(3,3,array)
如果您确实希望打印数组的一部分,您需要将一个单独的变量传递给printarray
以获取步长。
该函数必须声明为:
void printarray(int height, int length, int stride, triple array[][stride])
然后,在 main
中调用它:
printarray(2,2,3,array);
问题出在您对 printarray
的调用中:
printarray(2, 2, array);
你告诉函数数组有两行两列 - 但它没有,它有三行三列。编译器假设你没有说谎!
您 必须 使用 length
参数的正确值调用您的函数,因为编译器使用它来推断如何计算元素的偏移量array[i][j]
.
如果您只想打印该数组的 部分 ,您应该指定要打印的列数和行数作为函数的额外参数,如下所示:
void printarray(int height, int length, int nrows, int ncols, triple array[][length])
{
if (nrows > height) nrows = height;
if (ncols > width) ncols = width; // Prevent error conditions!
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < ncols; j++) {
printf("red score at array[%i][%i] = %i\n", i, j, array[i][j].red);
}
}
}
然后像这样调用函数:
printarray(3, 3, 2, 2, array);
注意:在使用 printarray
之前,您还遗漏了一个 function prototype,这在某些编译器上将是一个错误(但在其他编译器上只是一个警告);在 main
函数之前的某处添加此行:
void printarray(int height, int length, int nrows, int ncols, triple array[][length]);