Doug Smith
Doug Smith

Reputation: 29314

How does passing an array to another C function work?

This is causing me a great deal of confusion.

If I have the following array:

int arr[6];
// I then fill indices 0-5 with ints

And I want to pass that to a function that uses the array as a parameter, what does the function header look like?

Would it be void saveArray(int *arr) or void saveArray (int arr)? And then how would I call the function? saveArray(arr) or saveArray(&arr)?

As I understand it, while that initial array is not a pointer, it effectively acts as one as it decays into a pointer to the first element. So my intuition it that I should pass it like saveArray(arr) and the header should be void saveArray(int *arr). Would that be right?

Why do I want a pointer to the initial array and not just the array itself? What does &arr even represent?

Upvotes: 2

Views: 143

Answers (5)

weston
weston

Reputation: 54781

Yes

void saveArray(int *arr)

But for it to be useful, pass the array length too.

void saveArray(int *arr, int len)

Otherwise how will you know how long it is?

Call then like so:

saveArray(arr, 6);

Upvotes: 1

Mr.C64
Mr.C64

Reputation: 42944

If you use this prototype:

void saveArray(int *arr)

you loose information about the array length (e.g. number of elements).

Unless your function is supposed to operate on arrays with fixed length (e.g. some functions doing 3D math calculations may just consider 3D vectors, with fixed size of 3 double elements), you should specify the array length (e.g. element count) as an additional parameter:

void saveArray(int * arr, int count);

If your function just observes the content of the input array and does not modify it, you can use const to make your code const-correct and more precise:

void saveArray(const int * arr, int count);

Sometimes size_t is used as a type to specify length/count parameters:

void saveArray(const int * arr, size_t count);

About the other option you listed in your question:

void saveArray(int arr)

That is wrong, since in this case arr is just a single integer (not an array). Instead, in the first (correct) case of passing [const] int*, you passed the address of the first item in the array, and since the array elements are stored in contiguous memory locations, just the address of the first item and the item count define the whole array.


At the call site, you can call your function like this:

int arr[<<some size here>>];
...
saveArray(arr, <<same size as above>>);

Or if you already have a pointer (e.g. since you allocated the array using malloc()), you can just specify the pointer itself:

int* arr;
arr = malloc( numberOfElements * sizeof(int) );
...
saveArray(arr, numberOfElements);

Upvotes: 0

ajay
ajay

Reputation: 9680

Why do I want a pointer to the initial array and not just the array itself?

That's because you cannot pass an array to a function. An array is not a first-class object in C unlike int, float, struct etc. This means an array is not copied to the function parameter. What actually gets passed is a pointer to the first element of the array. Therefore, the function parameter should be a pointer to the array element type. Also, you have to pass the length of the array to function as well since that information cannot be had in the function from the pointer that is passed to it.

An array is a different type than a pointer. There are some cases when it decays or is implicitly converted to a pointer to its first element. Therefore, your function should have the prototype

void saveArray(int *arr, int len);
// or 
void saveArray(int arr[], int len);

// in main, for example
int arr[6];
saveArray(arr, sizeof arr);
// equivalent to
saveArray(&arr[0], sizeof arr);

What does &arr even represent?

The address of operator & evaluates the address of its operand which must be an lvalue. Here arr is of type int[6], i.e., an array of 6 integers. Therefore &arr is of type int (*)[6], i.e., a pointer to an array of 6 integers. Please note that the value &arr is equal to the base address of the array but its type is not int *. It is a different type and has different pointer arithmetic. This is, in fact, one of the cases where an array does not decay into a pointer to its first element.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206607

The question "Would it be void saveArray(int *arr) or void saveArray (int arr)?" has already been answered. I am going to answer the question "What does &arr even represent?"

In your case, &arr has the same numerical value as &arr[0]. However, if you did something a bit different,

int* arr = malloc(sizeof(int)*6);

Then the numerical value of &arr will be different than that of &arr[0] even though you will be able to call saveArray(arr) without any difference in meaning for both cases.

In the first case, both &arr and &arr[0] are addresses on the stack.

In the second case, &arr is an address on the stack while &arr[0] is an address in the heap.

Hope that helps.

Upvotes: 0

chrk
chrk

Reputation: 4215

In C, parameters passed in functions can only be passed by value.

In addition to that, in C you can't pass an array as a parameter to a function. However, you can pass by value a pointer to the first cell of the array.

Thus, your function's prototype would be:

void saveArray(int *arr)

which you'd call by

saveArray(arr);

Upvotes: 3

Related Questions