一、 情况1:实参为二维数组
在main函数中 int a[3][3];
调用形式 print(a);
//形参支持和不支持的形式
void print(int** a); //ERROR;当调用形式为 print( (int **) a)时,这种定义,对应int a[3][3]没有问题OK;
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]);
//这本身就是传参过程中的一个错误写法;即不可能先知道高维维度,不知低维维度
//不论多少维数组,第一维都可省略,但最低维不可省略
//注意: print( (int **) b);//实参不能为数组名!*与上面相反*!有两个 * !//(注意)print(b)或print((int *)b)不可以!
//第三种形参为二级指针
//声明
void function(int **a,int n);//n表示第二维数组长度,即列宽
//调用
function( (int **)a,int n);//实参不能为数组名!有两个 * !
//(注意)function(a)或function((int *)a)不可以!
二、 情况2:实参为指针数组
在main函数中:
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:实参为数组指针
在main函数中:
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:实参为二维指针
在main函数中:
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) 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);
二维指针也是同理。三维指针也是。如果掌握以上知识,做到正确传参数,应该不是问题。
————————————————
版权声明:本文为CSDN博主「lizi_stdio」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lizi_stdio/article/details/74502986
==============================================================================================
在函数中使用数组
声明定义(分三种)。
二维数组,数组指针,二级指针。(都是指针)
调用(一对一,二对二)
数组指针,二维数组就写一级指针即 数组名.
二级指针就写二级指针即 (int**)数组名
在函数中操作元素(注意二级指针,只能用最后的方法)
1. *(a[i] + j) //代表第 i 行 第 j 列
2. *(*(a+i) + j) //同上
3. *((int *)a +i*n +j )//同上,n表示第二维数组长度,即列宽;注意二级指针,只能用该方法
//不管怎么样,a[i][j]不被允许。也是由编译器的寻址方式决定。
原文1链接:https://blog.csdn.net/lizi_stdio/article/details/74502986
原文2链接:https://blog.csdn.net/qq_43868654/article/details/84641383