多维数组的传递也不是今天才遇到的了,之前也花了很多力气去查资料,结果现在又遇到的时候还是忘记了。所以就想干脆一劳永逸的解决此事。
一、各维度为常数(已知)的多维数组
如果各维度为常数,(比如使用宏定义)那么解决方法相对简单。
就是使用 void fun1(int arr[][COL])的形式,在形参定义的时候就带上第二维,如果是更高维度就要带上除了第一维以上的所有维度,都要写在函数头。这里的第一维可带可不带,但是若无必要,勿增实体,所以我们就暂且不带了。
e.g.
#include<stdio.h>
#define ROW 3
#define COL 4
void fun1(intarr[][COL]);
int main( void )
{
int a[ROW][COL] = {0};
fun1(a);
for (int i = 0;i < ROW;++i)
{
for (int j = 0;j < COL;++j)
{
printf("%d",a[i][j]);
}
putchar('\n');
}
return 0;
}
void fun1(intarr[][COL])
{
for (int i = 0;i < ROW;++i)
{
for (int j = 0;j < COL;++j)
{
arr[i][j] = 1;
}
}
}
二、各维度可变的多维数组
这里“可变”指的是可以直接创建用户输入的维度的数组,而不是常数阶的数组。
虽然C99支持了变长数组,但是以下代码可能在某些老版本的编译器上运行不通过:
introw,col;
scanf("%d%d",&row,&col);
inta[row][col];
目前为止我所找到的方法共有2种:
1. 使用malloc手动开辟数组
2. 使用多级指针 或者 降维
1. 使用malloc手动开辟数组
因为在函数头中并没有所谓数组,传递数组也传递的是指针,所以完全可以用指针替代数组,然后在另外的参数里传递维度,这样就实现了多维数组的传递。
优点:可以直接在函数里使用a[i][j]的形式来使用数组元素,而不需要手动选址。
缺点:手动开辟,手动释放,很麻烦..
e.g.
#include<stdio.h>
#include<malloc.h>
void fun2(introw,int col,int **arr);
int main( void )
{
int row,col;
scanf("%d%d",&row,&col);
//
int **a =(int **)malloc(row * sizeof (int *));
for (inti = 0;i < row;++i)
{
a[i]= (int *)malloc(col * sizeof (int *));
}
//手动创建多维数组(也可以做成函数)
for (int i = 0;i < row;++i)
{
for (int j = 0;j < col;++j)
{
scanf("%d",&a[i][j]);
}
}
fun2(row,col,a);
for (int i = 0;i < row;++i)
{
for (int j = 0;j < col;++j)
{
printf("%d",a[i][j]);
}
putchar('\n');
}
//
for (inti = 0;i < row;++i)
{
free(a[i]);
}
free(a);
//手动销毁数组
return 0;
}
void fun2(introw,int col,int **arr)
{
for (int i = 0;i < row;++i)
{
for (int j = 0;j < col;++j)
{
arr[i][j] = 2;
}
}
}
2. 使用变长数组或者降维
如果使用变长数组,即维度是变量的多维数组,那么基本上已经否定了在函数中使用array[i][j]这种用法,因为形参不能是数组。也就是说,编译器不能帮你选址了,你只能手动选址,模仿编译器的做法。
如果在主函数中无法传递参数,请善用强制类型转换。
除了降维,直接使用多维的方法是:
*((int *)m + i * size + j)
另外还有一个问题是有的老版本编译器并不支持变长数组..总之这个东西不怎么好用。
优点:不用手动创建销毁的动态数组
缺点:不能在创建使初始化
在函数中要手动选址
版本过低的编译器不支持
e.g.
#include<stdio.h>
void fun3(introw,int col,int *arr);
int main( void )
{
int row,col;
scanf("%d%d",&row,&col);
int a[row][col]; // 两个维度都是变量
for (int i = 0;i < row;++i)
{
for (int j = 0;j < col;++j)
{
scanf("%d",&a[i][j]);
}
}
fun3(row,col,&a[0][0]);//这里是把数组降成了一维,传递第一个元素的地址
for (int i = 0;i < row;++i)
{
for (int j = 0;j < col;++j)
{
printf("%d",a[i][j]);
}
putchar('\n');
}
return 0;
}
void fun3(introw,int col,int *arr)
{
for (int i = 0;i < row;++i)
{
for (int j = 0;j < col;++j)
{
*(arr + col * i + j) =3;//注意这里加的是" 列 "
}
}
}
总之,暂且还没有发现完美传递多维动态数组的方法。。稍微好用 点的就是手动创建或是常数数组阶。
希望如果有更好用的方法能够告诉我,感激不尽!