简体   繁体   English

使用C ++的2D数组

[英]2D arrays with C++

I have a function that takes a pointer to a pointer an as argument. 我有一个函数,它将指针指针作为参数。

func(double **arr, int i);

where in the main function the array is defined as follows: 在main函数中,数组的定义如下:

double arr[][] = //some initialization here;

How can I call this function from my main code. 如何从主代码中调用此函数。 I tried the following but it gives an error 我尝试了以下但它给出了一个错误

func (&arr);

Doesn't work. 不行。 Any help would be much appreciated. 任何帮助将非常感激。 Thanks 谢谢

The type of arr is double[X][Y] - that is, an array of X arrays of Y doubles - where X and Y depend on your initializers. arr的类型是double[X][Y] - 也就是说,Y个X的X数组的数组 - 其中XY取决于你的初始化器。 This is not the same as pointer type. 这是一样的指针类型。 However, according to C conversion rules, an array can decay into a pointer to its element. 但是,根据C转换规则,数组可以衰减为指向其元素的指针。 In your case, the type resulting from such decay will be double(*)[Y] - a pointer to an array of Y doubles. 在你的情况下,由这种衰减产生的类型将是double(*)[Y] - 指向Y双精度数组的指针。 Note that this is a pointer to array , not an array of pointers , so it will not decay any further. 请注意,这是一个指向 数组的指针 ,而不是一个指针数组 ,所以它不会再进一步​​衰减。 At this point, you get a type mismatch, since your function expects double** . 此时,您会遇到类型不匹配,因为您的函数需要double**

The correct way to handle this is to treat the array as single-dimensional, and pass width along. 处理此问题的正确方法是将数组视为一维,并传递宽度。 So: 所以:

void func(double* arr, int w) {
   // arr[2][3]
   arr[2*w + 3] = ...;
}


double x[6][8] = { ... };
func(&x[0][0], 8);

In C++ in particular, if you always have statically allocated arrays of well-known (but different) types, you may be able to use templates and references like this: 特别是在C ++中,如果你总是拥有静态分配的众所周知(但不同)类型的数组,你可以使用这样的模板和引用:

template <int W, int H>
inline void func(const double (&arr)[W][H]) {
  arr[2][3] = ...;
}

double x[6][8] = { ... };
func(x); // W and H are deduced automatically

However, this won't work when all you have is a pointer (eg when the array is new -allocated, and its size is calculated at runtime). 但是,当你拥有的只是一个指针时(例如,当数组是new分配的,并且其大小是在运行时计算的时候),这将不起作用。 For the most general case, you should use C++ containers instead. 对于最常见的情况,您应该使用C ++容器。 With standard library only, one typically uses vector of vectors: 仅使用标准库,通常使用向量向量:

#include <vector>

void func(std::vector<std::vector<double> > arr) {
  arr[2][3] = ...;
}

std::vector<std::vector<double> > x(6, std::vector<double>(8));
x[0][0] = ...;
...
func(x);

If you can use Boost, it has a very nice MultiArray library in it: 如果你可以使用Boost,它有一个非常好的MultiArray库:

void func(boost::multi_array<double, 2> arr) { // 2 means "2-dimensional"
  arr[2][3] = ...;
}

boost::multi_array<double, 2> x(boost::extents[6][8]);
x[0][0] = ...;
...
func(x);

[EDIT] you say that you cannot change the definition of your function. [编辑]你说你不能改变你的功能定义。 If so, then it really is a function treating its argument as an array of pointers, so you should just allocate your data structure accordingly. 如果是这样,那么它实际上是一个将其参数视为指针数组的函数,因此您应该相应地分配您的数据结构。 For example: 例如:

double x1[8] = { 1, 2, ... };
double x2[8] = { 3, 4, ... };
...
double* x[6] = { x1, x2, ... };

func(x);

A double **p is not the same thing as a double[][] a , so you can't pass one as the other. double **pdouble[][] a ,所以你不能传递另一个。

In particular the two-dimensional array variable is a (single!) block of memory containing doubles which you can access with the [][] syntax. 特别是二维数组变量是包含双精度的(单个!)内存块,您可以使用[][]语法进行访问。 This requires that the compiler know the dimension of the array, so that it can compute the correct offset to each element. 要求编译器知道数组的维度,以便它可以计算每个元素的正确偏移量。 It can also decay transparently to an pointer to that block of memory, but doing so loses the understanding of how to access that memory as a two dimensional array: it becomes effectively a pointer to double. 它也可以透明地衰减到指向该内存块的指针,但这样做会失去对如何以二维数组访问该内存的理解:它实际上变成了一个指向double的指针。

+----+           +---------+---------+---------+
| (a---------->) | a[0][0] | a[0][1] | a[0][2] | ...
+----+           +---------+---------+---------+ 
                 | a[1][0] | a[1][2] | ...
                 +---------+---------+
                   ...

The thing expected by the function is a pointer to a block of memory which contains one or more pointers to additional blocks of memory containing doubles. 该函数所期望的是一个指向内存块的指针,该内存块包含一个或多个指向包含双精度的附加内存块的指针。

+---+       +------+      +---------+---------+
| p-------->| p[0]------->| p[0][0] | p[0][3] | ...
+---+       +------+      +---------+---------+
            | p[1]--\    
            +------+ \    +---------+---------+
             ...      --->| p[1][0] | p[1][4] | ...
                          +---------+---------+

While the syntax looks similar, these two structures have totally different semantics. 虽然语法看起来很相似,但这两种结构具有完全不同的语义。


For a more complete discussion, see my answer to a previous questions (which actually address c, but the issues are the same). 有关更完整的讨论,请参阅 之前问题的 答案 (实际上解决了c,但问题是相同的)。

func(double *arr[100])

You need to tell the compiler the size of the dimension so it can create the correct address 您需要告诉编译器维度的大小,以便它可以创建正确的地址

  arr[y][x]

turns into 变成

  arr[100*x+y]

If you define your function as func(double **a) then you are saying a pointer to an array of pointers as dmckee pointed out 如果你将函数定义为func(double ** a),那么你就是在指出一个指向数组的指针,因为dmckee指出了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM