问题产生
我们先看一个传递二维数组的例子:
#include
void foo(int a[][], int m, int n) {
int i = 1;
int j = 1;
printf("a[%d][%d]=%d\n", i, j, a[i][j]);
}
int main() {
int a[2][3] = {
{1,2,3},
{4,5,6}
};
foo(a, 2, 3);
}
编译:
$ gcc test.c
test.c:3:14: error: array type has incomplete element type ‘int[]’
void foo(int p[][], int m, int n) {
^
test.c: In function ‘main’:
test.c:12:9: error: type of formal parameter 1 is incomplete
foo(a, 2, 3);
程序看起来没问题,但是在处理二维数组参数a时,编译器失败并报出类型不兼容的错误。
原因分析
C语言中二维数组的存储按一维数组处理,二维数组以行展开的方式顺序存储,例如上面的例子:
二维数组a的定义:
int a[2][3] = {
{1,2,3},
{4,5,6}
};
它等价于一维值的定义:
int b[6] = {
{1,2,3,4,5,6}
};
因为他们的空间存储分配是一样的。
---+-0-+-1-+-2-+-3-+-4-+-5--
---+---+--+---+--+--+-------
a: | 1 | 2 | 3 | 4 | 5 | 6
b: | 1 | 2 | 3 | 4 | 5 | 6
--+---+--+---+--+--+-------
因此,在传递二维数组作为参数时,必须指定二维数组的列数,否则函数无法勾勒出二维数组的组织形式。 只要有了列长,就可以通过下标a[i][j]得到正确的下标地址,即:
a[i][i] = a[ (i-1) * COLNUM + j ]
让我们更改上面的 foo 函数定义:
void foo(int a[][3], int m, int n) {
int i = 1;
int j = 1;
printf("a[%d][%d]=%d\n", i, j, a[i][j]);
}
编译并运行:
$ gcc test.c
$ ./a.out
a[1][1]=5
现在正常了。
传递二维数组的三种方式
参数如上所列。
void foo(int a[][3])
#include
void foo(int (*a)[3], int m, int n) {
int i = 1;
int j = 1;
printf("a[%d][%d]=%d\n", i, j, a[i][j]);
}
int main() {
int a[2][3] = {
{1,2,3},
{4,5,6}
};
foo(a, 2, 3);
}