通过多维变长数组功能 [英] Passing a multidimensional variable length array to a function

查看:396
本文介绍了通过多维变长数组功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有万吨类似的问题,但我仍然无法找到相关的C99 / C11变长数组的功能的任何答复。

There are tons of similar questions, but still I could not find any answer relevant for the feature of variable length arrays in C99/C11.

如何通过多维变量长度数组以在C99 / C11功能?

How to pass multidimensional variable length array to a function in C99/C11?

例如:

void foo(int n, int arr[][]) // <-- error here, how to fix?
{
}

void bar(int n)
{
    int arr[n][n];
    foo(n, arr);
}

编译器( G ++ - 4.7 -std = GNU + 11 )说:结果
错误:的改编作为多维数组必须为所有的维界除了第一个声明

如果我将其更改为为int * ARR [] ,编译器仍然抱怨:结果
错误:无法转换'INT(*)(((sizetype)(((ssizetype)N)+ 1))+ 1)]'到'诠释**'的说法2至无效美孚(INT,INT **)

If I change it to int *arr[], compiler still complains:
error: cannot convert ‘int (*)[(((sizetype)(((ssizetype)n) + -1)) + 1)]’ to ‘int**’ for argument ‘2’ to ‘void foo(int, int**)’

下一个问题,如何按值传递它,以及如何通过引用传递吗?显然,通常你不想当你把它传递给一个函数来复制整个数组。搜索结果

Next question, how to pass it by value and how to pass it by reference? Apparently, usually you don't want the entire array to be copied when you pass it to a function.

使用固定长度的数组很简单,因为,作为常数所暗示的,你应该知道的长度时,您声明函数:

With constant length arrays it's simple, since, as the "constant" implies, you should know the length when you declare the function:

void foo2(int n, int arr[][10]) // <-- ok
{
}

void bar2()
{
    int arr[10][10];
    foo2(10, arr);
}

我知道,路过阵列功能,如这不是最好的做法,我不喜欢它。这可能是更好的做平的指针或对象(如STD:向量),或在某种程度上别的。但尽管如此,我有点珍玩,答案是什么在这里从理论的角度来看。

I know, passing arrays to functions like this is not a best practice, and I don't like it at all. It is probably better to do with flat pointers, or objects (like std:vector) or somehow else. But still, I'm a bit curios what is the answer here from a theoretical standpoint.

推荐答案

传递阵列的功能是在C和C有点滑稽++。有没有数组类型的右值,所以你实际上是传递指针。

Passing arrays to functions is a bit funny in C and C++. There are no rvalues of array types, so you're actually passing a pointer.

要解决一个二维数组(一个真实的,而不是数组的数组),你需要通过2块的数据:

To address a 2D array (a real one, not array of arrays), you'll need to pass 2 chunks of data:


  • 指针,它开始的地方

  • 一行有多宽

这是两件不同的价值观,无论是C或C ++或VLA或没有,或诸如此类的东西。

And these are two separate values, be it C or C++ or with VLA or without or whatnot.

最简单,作品无处不在,但需要更多的体力劳动

Simplest, works everywhere but needs more manual work

void foo(int width, int* arr) {
    arr[x + y*width] = 5;
}

VLA,C99标准

VLA, standard C99

void foo(int width, int arr[][width]) {
    arr[x][y] = 5;
}

VLA瓦特/反转参数,前进参数声明(GNU C扩展)

VLA w/ reversed arguments, forward parameter declaration (GNU C extension)

void foo(int width; int arr[][width], int width) {
    arr[x][y]=5;
}

C ++瓦特/ VLA(GNU C ++的扩展,非常难看)

C++ w/ VLA (GNU C++ extension, terribly ugly)

void foo(int width, int* ptr) {
    typedef int arrtype[][width];
    arrtype& arr = *reinterpret_cast<arrtype*>(ptr);
    arr[x][y]=5;
}

大备注:

在[X] [Y]符号用二维数组的作品,因为数组的类型包含宽度。没有VLA =数组类型必须固定在编译时。

Big remark:

The [x][y] notation with a 2D array works because the array's type contains the width. No VLA = array types must be fixed at compile-time.

因此​​:如果你不能使用VLA,然后...

Hence: If you can't use VLA, then...


  • 有没有办法来处理它在C,

  • 有没有办法来处理它没有一个代理类W /重载运算符重载C ++中。

如果你可以使用VLA(C99或GNU C ++扩展),然后...

If you can use VLA (C99 or GNU C++ extensions), then...


  • 您是在C中的绿色,

  • 您还需要在C ++中一片狼藉,用类来代替。

对于C ++,的boost :: multi_array的是一个坚实的选择。

For C++, boost::multi_array is a solid choice.

有关二维数组,可以让两个独立的分配:

For 2D arrays, you can make two separate allocations:


  • 指针一维数组 T (A)

  • T的二维数组(B)

  • a 1D array of pointers to T (A)
  • a 2D array of T (B)

然后设置在(A)中的指针指向到的各行(B)。

Then set the pointers in (A) to point into respective rows of (B).

有了这个设置,你可以通过(A)左右为一个简单的 T ** ,它将与表现良好[X] [ Y] 索引。

With this setup, you can just pass (A) around as a simple T** and it will behave well with [x][y] indexing.

这解决方案是2D不错,但需要更多的和更多的样板更高的层面。它也比因为间接的附加层的VLA解决慢。

This solution is nice for 2D, but needs more and more boilerplate for higher dimensions. It's also slower than the VLA solution because of the extra layer of indirection.

您也可以运行与每 B 的行单独分配一个类似的解决方案。在C语言中,这看起来像一个malloc-IN-A-循环,类似的C ++的矢量的矢量。然而,这带走有一个块中的整个阵列的利益。

You may also run into a similar solution with a separate allocation for every B's row. In C this looks like a malloc-in-a-loop, and is analogous of C++'s vector-of-vectors. However this takes away the benefit of having the whole array in one block.

这篇关于通过多维变长数组功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆