当您将具有多个维度的数组作为参数传递给函数时,只有 第一个(最左边)维度可以具有未知大小(空[])。这是必需的,因为计算给定元素的地址的方式。
例如,在这段代码中:
char array[10][20];
char b = array[3][2];
变量array 占用连续 200 (10 x 20) 字节长的内存块。元素array[0][0] 的地址(显然)与数组的基地址相同。要获得array[1][0] 的地址,编译器需要向该基地址添加一个值:在这种情况下,该值将是第二维(20)的size;同样,对于array[2][0],地址将是第二维大小的两倍,依此类推。
当我们开始更改 second 索引时,我们只需将该索引的实际值添加到为第一个索引计算的“偏移量”中。因此,如果我们调用数组的基地址ADDR,那么在上面的示例中,b 将在ADDR + 20 x 3 + 2 处被赋予char 的值。
但是,在您的 some_tab 函数中,编译器不知道 t 数组的第二维的大小是多少 - 那么它如何计算用于元素 t[i][j] 的适当地址偏移量? (请注意,编译器可以处理不知道第一维大小的问题,因为该大小从不用于计算元素的地址!)
为了解决这个问题,在您的情况下,最简单(尽管不一定是最佳)方法是给第二个维度一个固定大小 em> 即: (a) 大到足以处理代码必须处理的所有情况; (b) 在整个代码中100% 一致使用。所以,你可以使用这个:
int some_tab(int t[][100], int n, int m);
int main {
int tab[100][100], i, j, n, m;
//..
printf("\nla somme du tableau est %d : ", some_tab(tab, n, m));
但是,以下内容将严重失败,因为它中断了上面的 (b) 点:
int some_tab(int t[][200], int n, int m); // Change 100 to 200 for bigger space?
int main {
int tab[100][100], i, j, n, m; /// This is now WRONG because tab has different 2nd dimension size!
//..
printf("\nla somme du tableau est %d : ", some_tab(tab, n, m));
*注意:我在这里使用了一个char 数组来保持解释的简短,因为char 类型的大小正好 1 个字节。对于其他类型,任何元素的计算偏移量将简单地乘以该类型的大小。*
编辑:当我第一次发布时,我无法测试下面的(更好的)代码,因为我被“限制”使用 MSVC 本机 C 编译器(它使用了一个非常古老的语言标准,禁止它) .但是,现在我已经能够使用clang 进行测试,我可以确认以下代码可以按预期编译和工作。
这样做是使用 known 但 variable 维度的数组,在运行时传递给 some_tab 函数-时间(编译器仍然可以正确计算每个元素的偏移量,但是,它不是使用 fixed 乘数作为第二维,而是使用 variable(在这种情况下,论点m)。
请务必阅读我添加的 cmets,用三斜杠 (///) 标记:
#include<stdio.h>
int some_tab(int n, int m, int t[n][m]); /// We MUST pass the "n" and "m" arguments FIRST!
int main()
{
int i, j, n, m; /// NOTE: Declaration of "tab" MUST be moved ...
printf("\ndonner le nombre de lignes : ");
scanf("%d", &n);
printf("\ndonner le nombre des columns : ");
scanf("%d", &m);
int tab[n][m]; /// ... to AFTER we know the actual values of "n" and "m"!!
for (i = 0; i < n; i++) {
printf("\nLigne %d: \n", i + 1);
for (j = 0; j < m; j++) {
printf("\n donner le nombre numero %d : ", j + 1);
scanf("%d", &tab[i][j]);
}
}
printf("\nla somme du tableau est %d : ", some_tab(n, m, tab)); /// Change argument order!
return 0;
}
int some_tab(int n, int m, int t[n][m]) /// Note that this matches the pre-declaration!
{
int i, j, s = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
s = s + t[i][j];
}
return s;
}
请随时要求任何进一步的澄清和/或解释。