Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ pass an array by reference

is this allowed to pass an array by reference ?

 void foo(double& *bar) 

Seems that my compiler says no. Why? What is the proper way to pass an array by reference? Or a work around? I have an array argument that my method should modify and that I should retrieve afterwards. Alternatively, I could make this array a class member, which works fine, but it has many drawbacks for other part of my code (that I would like to avoid).

Thanks and regards.

like image 349
kiriloff Avatar asked Apr 04 '12 09:04

kiriloff


People also ask

Can you pass an array by reference in C?

The C language does not support pass by reference of any type. The closest equivalent is to pass a pointer to the type.

Can you pass arrays by reference?

The only reason for passing an array explicitly by reference is so that you can change the pointer to point to a different array. If a function only looks at the contents of an array, and does not change what is in the array, you usually indicates that by adding const to the parameter.

How can you reference array in C?

In your first function() what gets passed is the address of the array's first element, and the function body dereferences that. Infact, the compiler is treating the function prototype as this: void function(int* array /*you wrote int array[]*/){ array[0] = 4; array[1] = 5; array[2] = 6; } function(&array[0]);

How can you pass an array to a function in C?

To pass an entire array to a function, only the name of the array is passed as an argument. result = calculateSum(num); However, notice the use of [] in the function definition. This informs the compiler that you are passing a one-dimensional array to the function.


4 Answers

Arrays can only be passed by reference, actually:

void foo(double (&bar)[10])
{
}

This prevents you from doing things like:

double arr[20];
foo(arr); // won't compile

To be able to pass an arbitrary size array to foo, make it a template and capture the size of the array at compile time:

template<typename T, size_t N>
void foo(T (&bar)[N])
{
    // use N here
}

You should seriously consider using std::vector, or if you have a compiler that supports c++11, std::array.

like image 81
jrok Avatar answered Oct 17 '22 04:10

jrok


Yes, but when argument matching for a reference, the implicit array to pointer isn't automatic, so you need something like:

void foo( double (&array)[42] );

or

void foo( double (&array)[] );

Be aware, however, that when matching, double [42] and double [] are distinct types. If you have an array of an unknown dimension, it will match the second, but not the first, and if you have an array with 42 elements, it will match the first but not the second. (The latter is, IMHO, very counter-intuitive.)

In the second case, you'll also have to pass the dimension, since there's no way to recover it once you're inside the function.

like image 28
James Kanze Avatar answered Oct 17 '22 04:10

James Kanze


As you are using C++, the obligatory suggestion that's still missing here, is to use std::vector<double>.

You can easily pass it by reference:

void foo(std::vector<double>& bar) {}

And if you have C++11 support, also have a look at std::array.

For reference:

  • http://de.cppreference.com/w/cpp/container/vector
  • http://de.cppreference.com/w/cpp/container/array
like image 33
moooeeeep Avatar answered Oct 17 '22 04:10

moooeeeep


If you want to modify just the elements:

void foo(double *bar);

is enough.

If you want to modify the address to (e.g.: realloc), but it doesn't work for arrays:

void foo(double *&bar);

is the correct form.

like image 21
Naszta Avatar answered Oct 17 '22 06:10

Naszta