C/C++语言二维数组作为函数的参数总结
一、 情况1:实参为二维数组
比如 int a[3][3];
调用形式 print(a);
//指针形式
void print(int** a); //ERROR
void print(int* a[3]); //ERROR;这是一个数组,不能将数组直接传值;因此错误
void print(int (*a)[3]); //OK 二维数组转数组指针
//纯数组形式
void print(int a[3][3]); //OK 等同于void print(int(*a)[3]);
void print(int a[4][3]); //OK 等同于void print(int(*a)[3]);
void print(int a[3][4]); //ERROR 等同于void print(int(*a)[4]);
void print(int a[][3]); //OK 等同于void print(int(*a)[3]);
void print(int a[][]); //ERROR 类似于,但却不是void print(int** a);
void print(int a[3][]); //ERROR 类似于,但却不是void print(int (*a)[3]);
//这本身就是传参过程中的一个错误写法;即不可能先知道高维维度,不知低维维度
二、 情况2:实参为指针数组
比如
int* a[3]
int b[3][3] = { 0 };
for(int i = 0; i < 3; ++i){ a[i] = b[i]; }
调用形式 print(a);
//指针形式
void print(int** a); //OK
void print(int* a[3]); //OK
void print(int (*a)[3]); //ERROR
//纯数组形式
void print(int a[3][3]); //ERROR 等同于void print(int (*a)[3]);
void print(int a[4][3]); //ERROR 等同于void print(int(*a)[3]);
void print(int a[3][4]); //ERROR 等同于void print(int(*a)[4]);
void print(int a[][3]); //ERROR 等同于void print(int(*a)[3]);
void print(int a[][]); //ERROR 无法将其转化为void print(int** a);
void print(int a[3][]); //ERROR 这本身就是传参过程中的一个错误写法;即不可能先知道高维维度,不知低维维度
三、 情况3:实参为数组指针
比如 int (*a)[3];
int b[3][3] = {0};
a = b;
调用形式 print(a);
//指针形式
void print(int** a); //ERROR
void print(int* a[3]); //ERROR
void print(int (*a)[3]); //OK
//纯数组形式
void print(int a[3][3]); //OK 等同于void print(int(*a)[3]);
void print(int a[4][3]); //OK 等同于void print(int(*a)[3]);
void print(int a[3][4]); //ERROR 等同于void print(int(*a)[4]);
void print(int a[][3]); //OK 等同于void print(int(*a)[3]);
void print(int a[][]); //ERROR 无法将其转化为void print(int**a);
void print(int a[3][]); //ERROR 这本身就是传参过程中的一个错误写法;即不可能先知道高维维度,不知低维维度
四、 情况4:实参为二维指针
比如
int** a;
int b[3][3] = { 0 };
int* c[3];
for(int i = 0; i < 3; ++i){ c[i] = b[i]; }
a = c;
调用形式 print(a);
//指针形式
void print(int** a); //OK
void print(int* a[3]); //OK 等价于void print(int** a);
void print(int (*a)[3]); //ERROR
//纯数组形式
void print(int a[3][3]); //ERROR 等同于void print(int(*a)[3]);
void print(int a[4][3]); //ERROR 等同于void print(int(*a)[3]);
void print(int a[3][4]); //ERROR 等同于void print(int(*a)[4]);
void print(int a[][3]); //ERROR 等同于void print(int(*a)[3]);
void print(int a[][]); //ERROR 无法将其转化为void print(int**a);
void print(int a[3][]); //ERROR 这本身就是传参过程中的一个错误写法;即不可能先知道高维维度,不知低维维度
五、 总结
序号 | 实参形式 | 二维数组 | 指针数组 | 数组指针 | 二维指针 |
1 | void print(int** a); | ⅹ | √ | ⅹ | √ |
2 | void print(int* a[3]); | ⅹ | √ | ⅹ | √ |
3 | void print(int (*a)[3]); | √ | ⅹ | √ | ⅹ |
4 | void print(int a[3][3]); | √ | ⅹ | √ | ⅹ |
5 | void print(int a[4][3]); | √ | ⅹ | √ | ⅹ |
6 | void print(int a[3][4]); | ⅹ | ⅹ | ⅹ | ⅹ |
7 | void print(int a[][3]); | √ | ⅹ | √ | ⅹ |
8 | void print(int a[][]); | ⅹ | ⅹ | ⅹ | ⅹ |
9 | void print(int a[3][]); | ⅹ | ⅹ | ⅹ | ⅹ |
备注:√表示调用成功;ⅹ表示调用失败。
通过表格,可知:
(1) 1与2的形式完全等价;
(2) 3、4、5和7的形式完全等价
(3) 8和9属于非法形式
(4) 通过4,5,6,7,可知:
对于传数组,低维阶数一致是一个必要条件。6必然非法。
对于高阶维数的维度其实没有传递给函数,只是象征意义上的显示,没有实际意义。
5.1 单一降次
意思就是说,每次都可以将数组降为指针,但每次只能降一次。对于每次函数调用只能顺次降一级,多次下降必然报错;也就是说,对于二维数组,可以用数组指针传值,但是如果用二维指针传递就会报错。
5.2 实质:传递指针
记住,实参形参之间进行传递的实质:始终传递的是指针,不可能是数组。
对于二维数组实参,传递参数的时候,它已经将为数组指针;对于形式参数里面的[],每次转换只能转换其中的一个为指针,如果转换之后的指针,与传递过来实参参数的指针一致,则参数之间可以进行参数传递。
--------------------------------------------------------------------
PS:真正在传递二维指针的时候,还需要考虑到二维数组的维度。
比如:int a[10]; 正确的函数参数形式应该为void print(int* a, int n);
二维指针也是同理。三维指针也是。如果掌握以上知识,做到正确传参数,应该不是问题。