转载:https://blog.csdn.net/lizi_stdio/article/details/74502986
一、情况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 这本身就是传参过程中的一个错误写法;即不可能先知道高维维度,不知低维维度
总结
形参/实参形式 | 二维数组(int a[3][3]) | 指针数组(int* a[3]) | 数组指针(int (*a)[3]) | 二维指针(int** a) |
---|---|---|---|---|
void print(int** a) | ⅹ | √ | ⅹ | √ |
void print(int* a[3]) | ⅹ | √ | ⅹ | √ |
void print(int (*a)[3]) | √ | ⅹ | √ | ⅹ |
void print(int a[3][3]) | √ | ⅹ | √ | ⅹ |
void print(int a[4][3]) | √ | ⅹ | √ | ⅹ |
void print(int a[3][4]) | ⅹ | ⅹ | ⅹ | ⅹ |
void print(int a[][3]) | √ | ⅹ | √ | ⅹ |
void print(int a[][]) | ⅹ | ⅹ | ⅹ | ⅹ |
void print(int a[3][]) | ⅹ | ⅹ | ⅹ | ⅹ |
5.1 单一降次
意思就是说,每次都可以将数组降为指针,但每次只能降一次。对于每次函数调用只能顺次降一级,多次下降必然报错;也就是说,对于二维数组,可以用数组指针传值,但是如果用二维指针传递就会报错。
5.2 实质:传递指针
记住,实参形参之间进行传递的实质:始终传递的是指针,不可能是数组。
对于二维数组实参,传递参数的时候,它已经将为数组指针;对于形式参数里面的[],每次转换只能转换其中的一个为指针,如果转换之后的指针,与传递过来实参参数的指针一致,则参数之间可以进行参数传递。
PS:真正在传递二维指针的时候,还需要考虑到二维数组的维度。