开发者

How to send a 2-D array as a reference in C++, and back?

开发者 https://www.devze.com 2023-04-07 23:42 出处:网络
yet another beginner-to-intermediate question. I\'m trying to pass a 2-D array to a function in C++. I\'m aware that the array can\'t be sent directly to the function, so I first created a pointer (na

yet another beginner-to-intermediate question. I'm trying to pass a 2-D array to a function in C++. I'm aware that the array can't be sent directly to the function, so I first created a pointer (names edited but you'll get the idea):

double input[a][b] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
Class.calculate (*(input), a, b);

Then I try to use it in said function - but seemingly I'm unaware on how to dereference the pointer to be able to handle the 2-D array again. My code (more or less):

for (int x=0; x<=a; x++){
    for (int y=0; y<=b; y++){
        tmpInput[x][y]= (*input)[x][y];
    }
}

The compiler complains about an error, namely invalid types ‘double[int]’ for array subscript, but I still can't开发者_StackOverflow中文版 figure out the problem. My best bet is that I didn't dereference the 2-D array properly, but the other option is that C++ can't dereference 2-D arrays directly, instead relying in converting the array to 1-D before sending it. Any ideas?


Why the array cannot be sent directly to a function?

Call Class.calculate (*(input), a, b); is trying to dereference input which you can't do as it is not a pointer.

If the calculate is defined as:

Class::calculate(double *input[], size a, size b)

You can just call Class.calculate(input, a, b).


I'm aware that the array can't be sent directly to the function, so I first created a pointer (names edited but you'll get the idea)

Wrong. You can pass it. Just have the calculate member function's first argument to be pointer to a pointer.

calculate( double **ptr, int rows, int columns ){

   // Now access the array via ptr as usual with the [] operator. 
   // like ptr[0][1]
}

And call it like - Class.calculate (input, a, b);


No one said anything about templates yet? I'm disappointed!


You can actually pass it as a real reference without the need to pass the size as extra parameters in C++:

class Class{
public:
  // ...
  template<unsigned N, unsigned M>
  void calculate(double (&arr)[N][M]){
    // use it like normal, arr[x][y]
    // ...
  }
  // ...
};

Example on Ideone.

Even though this doesn't answer the exact question you asked, it's always good to know such stuff. :) Templates are an important part of C++ after all, no matter if you're beginner, intermediate or a pro. You use them, though maybe not knowingly, from day 1.


It's hard to say for sure without seeing the declaration of calculate(), but I'd guess it's an argument type mismatch. You can send your array as a double*, but not as a double** - it is an array of doubles (they're laid out linearly in memory, even if the compiler lets you treat them as a multidimensional array). But it is not an array of pointers to doubles, which is what the double** type actually means: Dereference a double** and you get a double*.

If you know that the second subscript is constant (in your case, 2), you can define calculate() to expect a N*2 array of doubles:

void calculate(double array[][2], int a)
{
    //Whatever
}

Or, if both dimensions can change, just take a straight double* and to the pointer math yourself (you'll probably have to cast your array to a double* when calling this, but it'll work):

void calculate(double* array, int a, int b)
{
    //To get array[i][j]:
    array[i * b + j];
}

Hope this helps!


Use Boost.MultiArray:

http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html

they support views, ranges, iterators and they abstract away memory management but still remain extremely configurable. You can pass multi_arrays by reference just like you'd expect.

if you want to learn about raw pointers (or you're writing an embedded application that needs to fit in 64k of memory or something), then it's a good idea write code that uses them. If you want to write maintainable production code, then it's a good idea to use STL/Boost and avoid raw pointers except in code that is unlikely to have to be read very much.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号