Passing an array by reference in C? Passing an array by reference in C? c c

Passing an array by reference in C?


In C arrays are passed as a pointer to the first element. They are the only element that is not really passed by value (the pointer is passed by value, but the array is not copied). That allows the called function to modify the contents.

void reset( int *array, int size) {   memset(array,0,size * sizeof(*array));}int main(){   int array[10];   reset( array, 10 ); // sets all elements to 0}

Now, if what you want is changing the array itself (number of elements...) you cannot do it with stack or global arrays, only with dynamically allocated memory in the heap. In that case, if you want to change the pointer you must pass a pointer to it:

void resize( int **p, int size ) {   free( *p );   *p = malloc( size * sizeof(int) );}int main() {   int *p = malloc( 10 * sizeof(int) );   resize( &p, 20 );}

In the question edit you ask specifically about passing an array of structs. You have two solutions there: declare a typedef, or make explicit that you are passing an struct:

struct Coordinate {   int x;   int y;};void f( struct Coordinate coordinates[], int size );typedef struct Coordinate Coordinate;  // generate a type alias 'Coordinate' that is equivalent to struct Coordinatevoid g( Coordinate coordinates[], int size ); // uses typedef'ed Coordinate

You can typedef the type as you declare it (and it is a common idiom in C):

typedef struct Coordinate {   int x;   int y;} Coordinate;


To expand a little bit on some of the answers here...

In C, when an array identifier appears in a context other than as an operand to either & or sizeof, the type of the identifier is implicitly converted from "N-element array of T" to "pointer to T", and its value is implicitly set to the address of the first element in the array (which is the same as the address of the array itself). That's why when you just pass the array identifier as an argument to a function, the function receives a pointer to the base type, rather than an array. Since you can't tell how big an array is just by looking at the pointer to the first element, you have to pass the size in as a separate parameter.

struct Coordinate { int x; int y; };void SomeMethod(struct Coordinate *coordinates, size_t numCoordinates){    ...    coordinates[i].x = ...;    coordinates[i].y = ...;     ...}int main (void){    struct Coordinate coordinates[10];    ...    SomeMethod (coordinates, sizeof coordinates / sizeof *coordinates);    ...}

There are a couple of alternate ways of passing arrays to functions.

There is such a thing as a pointer to an array of T, as opposed to a pointer to T. You would declare such a pointer as

T (*p)[N];

In this case, p is a pointer to an N-element array of T (as opposed to T *p[N], where p is an N-element array of pointer to T). So you could pass a pointer to the array as opposed to a pointer to the first element:

struct Coordinate { int x; int y };void SomeMethod(struct Coordinate (*coordinates)[10]){    ...    (*coordinates)[i].x = ...;    (*coordinates)[i].y = ...;    ...}int main(void){    struct Coordinate coordinates[10];    ...    SomeMethod(&coordinates);    ...}

The disadvantage of this method is that the array size is fixed, since a pointer to a 10-element array of T is a different type from a pointer to a 20-element array of T.

A third method is to wrap the array in a struct:

struct Coordinate { int x; int y; };struct CoordinateWrapper { struct Coordinate coordinates[10]; };void SomeMethod(struct CoordinateWrapper wrapper){    ...    wrapper.coordinates[i].x = ...;    wrapper.coordinates[i].y = ...;    ...}int main(void){    struct CoordinateWrapper wrapper;    ...    SomeMethod(wrapper);    ...}

The advantage of this method is that you aren't mucking around with pointers. The disadvantage is that the array size is fixed (again, a 10-element array of T is a different type from a 20-element array of T).


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

Here is a contrived example in both languages

C++ style API

void UpdateValue(int& i) {  i = 42;}

Closest C equivalent

void UpdateValue(int *i) {  *i = 42;}