多维数组的传递

多维数组的传递也不是今天才遇到的了,之前也花了很多力气去查资料,结果现在又遇到的时候还是忘记了。所以就想干脆一劳永逸的解决此事。

 

一、各维度为常数(已知)的多维数组

 

如果各维度为常数,(比如使用宏定义)那么解决方法相对简单。

就是使用 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;//注意这里加的是" 列 "
                  }
         }
}


 总之,暂且还没有发现完美传递多维动态数组的方法。。稍微好用 点的就是手动创建或是常数数组阶。

希望如果有更好用的方法能够告诉我,感激不尽!


 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值