如何将动态多维数组传递给函数?

7

我怎样在C/C++中传递一个多维数组给函数?

数组的维度在编译时不确定。


如果数组是基于用户输入动态分配大小的,则在编译时大小将是未知的。 - bta
9个回答

9

将数组起始位置的指针和维度传递给函数,然后在函数中进行数组运算是最常见的解决方案。

或者使用boost


3

传递数组很容易,难点在于在您的函数内部访问数组。正如其他答案中指出的那样,您可以将函数参数声明为指针,并传递每个数组维度的元素数量。

#define xsize 20
#define ysize 30
int array[xsize][ysize];
void fun(int* arr, int x, int y)
{
 // to access element 5,20
 int x = arr[y*5+20];
}

fun(array, xsize, ysize);

当然,我省略了分配数组的整个过程(因为不知道它的大小,你真的不能使用#define(有些人说它们不好))。

1

你可以传递指针和大小,或者使用std::vector。但是“真正”的解决方案是使用模板:

template <size_t N, size_t M>
void foo(int (&pArray)[N][M]);

这个函数模板接受一个 N 行 M 列的整数数组,通过引用传递。请注意,这是一个函数模板,而不是一个函数,因此您会得到每种数组类型的不同实例化函数。


当数组的维度在编译时不知道时,模板是无法帮助的。 - n0rd
@n0rd:哦,我跳过了那部分。不过问题要么非常琐碎,要么就是毫无意义的。 - GManNickG

1

我认为这是GCC的扩展(或者是相当现代的C特性),但它可以非常方便:

void foo(int bar[n][m], int n, int m) {...}

你不需要在编译时为n和m提供常量值吗?在我的C++Builder 2010上需要。(根据问题,dim在编译时是未知的。) - Tom

1

你可以传递指向多维数组初始内存位置的指针。你还应该传递数组的大小,即每个维度的限制。

i.e

int var [x][y][z];
func (var, x, y, z);

函数定义:

void func (int*, int, int, int);

1
使用一个向量的向量,你可以传递一个向量。

这是低效的,除了不规则数组(其中每行可能与另一行长度不同),或者当元素是字符串等情况下。此外,如果提问者正在寻找可变数量的维度(我们尚不知道),向量也无法解决该问题,因为向量是typedef'ed。 - rwong

0
一个简单的方法是将数组展开并使用维度进行迭代。
#include <stdio.h>

void print_array(int *arr,int row,int col)
{
     int i,j;
     for(i=0;i<row;i++){           
         for(j=0;j<col;j++){
             printf("%d ",*(arr+i*col+j));
         }
         printf("\n");
     }
}

int main()
{
int a[2][3] = {{1,0,2},{-1,3,1}};
int b[4] = {1,2,3,34};
print_array(a,2,3);
return 0;
}

这种技术是可行的,但是将数组展平可能会阻止编译器进行优化,从而导致执行速度变慢。


0

我只是在总结其他帖子中的选项。

如果维度数量(N维数组中的N)未知,则唯一的方法是使用C++多维数组类。有几种公开可用的实现,来自Boost或其他库。请参见Martin Beckett's 的帖子。

如果维数已知但数组大小是动态的,请参见Tom's 的答案以访问数组元素(将多个索引转换为元素指针)。数组本身必须使用malloc或new进行分配。

如果您要编写多维数组类,则需要了解行主序,{column-major-order}等知识。

换句话说,如果数组的维数为(Size1, Size2, Size3, ..., SizeN),则:

  • 数组中的元素数量为(Size1 * Size2 * Size3 * ... * SizeN)
  • 所需内存为sizeof(value_type) * numOfElements
  • 要访问元素(index1, index2, index3, ..., indexN),请使用
    • ptr[ index1 + (Size1 * index2) + (Size1 * Size2 * index3) + ... ],假设第一个数组索引是最快移动的维度

i1 + size1 * (i2 + size2 * (... ) ) ...) 更好地表示了 index1 + (Size1 * index2) + (Size1 * Size2 * index3) + ... - Alexandre C.
@Alexandre:同意。我知道http://en.wikipedia.org/wiki/Horner_scheme。我只是想以一种可以写入循环等的方式显示公式。 - rwong
抱歉,我的意思是“数学上的”。 - rwong

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接