Passing a 2D array to a C++ function

2018-12-31 00:11发布

I have a function which I want to take, as a parameter, a 2D array of variable size.

So far I have this:

void myFunction(double** myArray){
     myArray[x][y] = 5;
     etc...
}

And I have declared an array elsewhere in my code:

double anArray[10][10];

However, calling myFunction(anArray) gives me an error.

I do not want to copy the array when I pass it in. Any changes made in myFunction should alter the state of anArray. If I understand correctly, I only want to pass in as an argument a pointer to a 2D array. The function needs to accept arrays of different sizes also. So for example, [10][10] and [5][5]. How can I do this?

12条回答
心情的温度
2楼-- · 2018-12-31 00:42

A modification to shengy's first suggestion, you can use templates to make the function accept a multi-dimensional array variable (instead of storing an array of pointers that have to be managed and deleted):

template <size_t size_x, size_t size_y>
void func(double (&arr)[size_x][size_y])
{
    printf("%p\n", &arr);
}

int main()
{
    double a1[10][10];
    double a2[5][5];

    printf("%p\n%p\n\n", &a1, &a2);
    func(a1);
    func(a2);

    return 0;
}

The print statements are there to show that the arrays are getting passed by reference (by displaying the variables' addresses)

查看更多
弹指情弦暗扣
3楼-- · 2018-12-31 00:42

You can create a function template like this:

template<int R, int C>
void myFunction(double (&myArray)[R][C])
{
    myArray[x][y] = 5;
    etc...
}

Then you have both dimension sizes via R and C. A different function will be created for each array size, so if your function is large and you call it with a variety of different array sizes, this may be costly. You could use it as a wrapper over a function like this though:

void myFunction(double * arr, int R, int C)
{
    arr[x * C + y] = 5;
    etc...
}

It treats the array as one dimensional, and uses arithmetic to figure out the offsets of the indexes. In this case, you would define the template like this:

template<int C, int R>
void myFunction(double (&myArray)[R][C])
{
    myFunction(*myArray, R, C);
}
查看更多
明月照影归
4楼-- · 2018-12-31 00:42

Surprised that no one mentioned this yet, but you can simply template on anything 2D supporting [][] semantics.

template <typename TwoD>
void myFunction(TwoD& myArray){
     myArray[x][y] = 5;
     etc...
}

// call with
double anArray[10][10];
myFunction(anArray);

It works with any 2D "array-like" datastructure, such as std::vector<std::vector<T>>, or a user defined type to maximize code reuse.

查看更多
忆尘夕之涩
5楼-- · 2018-12-31 00:43

anArray[10][10] is not a pointer to a pointer, it is a contiguous chunk of memory suitable for storing 100 values of type double, which compiler knows how to address because you specified the dimensions. You need to pass it to a function as an array. You can omit the size of the initial dimension, as follows:

void f(double p[][10]) {
}

However, this will not let you pass arrays with the last dimension other than ten.

The best solution in C++ is to use std::vector<std::vector<double> >: it is nearly as efficient, and significantly more convenient.

查看更多
忆尘夕之涩
6楼-- · 2018-12-31 00:47

One important thing for passing multidimensional arrays is:

  • First array dimension need not be specified.
  • Second(any any further)dimension must be specified.

1.When only second dimension is available globally (either as a macro or as a global constant)

`const int N = 3;

`void print(int arr[][N], int m)
{
int i, j;
for (i = 0; i < m; i++)
  for (j = 0; j < N; j++)
    printf("%d ", arr[i][j]);
}`

int main()
{
int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
print(arr, 3);
return 0;
}`

2.Using a single pointer: In this method,we must typecast the 2D array when passing to function.

`void print(int *arr, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
  for (j = 0; j < n; j++)
    printf("%d ", *((arr+i*n) + j));
 }

`int main()
{
int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int m = 3, n = 3;

// We can also use "print(&arr[0][0], m, n);"
print((int *)arr, m, n);
return 0;
}`
查看更多
呛了眼睛熬了心
7楼-- · 2018-12-31 00:52

Single dimensional array decays to a pointer pointer pointing to the first element in the array. While a 2D array decays to a pointer pointing to first row. So, the function prototype should be -

void myFunction(double (*myArray) [10]);

I would prefer std::vector over raw arrays.

查看更多
登录 后发表回答