众所周知啊,二维数组传参一直不是一个很方便的事情,尤其对于初学者,不太会利用指针的人来说尤其困难。
红色的下滑线代表错误,对于二维数组的传参如下图。
总是只能传递确定列的大小的二维数组。对于这个a数组a[m][n],m代表的是行,对应的是纵坐标,n代表的是列,对应的是横坐标。
但是不是任何时候我们都能够提前知道二维数组的列的大小。
例如矩阵的输入,输入的数据是不确定的,这就导致了在声明函数的时候不能确定列的大小,就会出现如第一张图的情况,错误。
那如果你说这好办,我直接声明一个足够大的列数不就行了,如下图。
如图所示,仍然是错误的。只有二维数组的列数与声明的函数里的形参大小相同时才不会报错。
可以看出来没有报错。
综上可以看出,当你是需要一个确定了列数的二维数组,你完全可以采用上述的方法,在声明函数时把对应的形参先行写入。
但是矩阵的输入往往是不能提前确定好行和列数的,而且代码写死了也没有意思,我们应该写的是灵活的代码。
进入正题,该怎么实现不定大小的二维数组,其实有一个取巧的办法。使用一个一维数组来代替二维数组,我们都知道(不知道的有必要了解一下)数组的空间是连续的,所以可以使用下标来表示第几个元素。例如一个int a[5],a是指向这个数组首地址的指针,a[1]代表第二个元素,其实就相当于把a指针的位置按照不同数据类型来移动不同的大小。(不同数据类型的字节数不同)
他们的输出是相同的,代表*(x+1)与x[1]是等价的。同理二维数组也只不过是一串连续的地址,本质与一维数组没有太大的区别 int a[5][5],a[0][0]指向的就是这个二维数组首地址。
关键来了如何用一维数组来代替二维数组呢?
int *x,row_x,col_x;//row代表行col代表列
scanf("%d %d",&row_x,&col_x);
x = (int *) malloc(sizeof (int)*row_x*col_x);
for(int i=0;i<row_x;i++){
for(int j=0;j<col_x;j++){
x[i*col_x+j] = i*col_x+j;
}
}
for(int i=0;i<row_x;i++){
for(int j=0;j<col_x;j++){
printf("%d ",x[i*col_x+j]);
}
printf("\n");
}
输入2 2时,代表创建了一个2*2的二维数组,需要四个元素空间,那我直接给一个指针申请这么大的空间不就得了。于此同时行数和列数可以自由得输入,如果小了,2*2不够,你需要3*3的,你又可以判断什么时候需要,需要的时候relloc就行了。
关键在哪里,关键就在于row和col有这两个数据,完全可以让这个一维数组像二维数组一样。代码段中的 i*col_x+j你的行数 i *列数 col 加上这一列的第几个元素 j 。下图帮助理解。
这样传参就很方便了,如下图。
把这个指针传进来,同时传入行数和列数row和col,就可以实现二维数组啦。