2

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?

5
  • void saveArray(int* arr) is the signature and saveArray(arr) is the call. Commented Apr 11, 2014 at 16:56
  • 1
    void saveArray(int *arr), call saveArray(arr), and &arr is int (*)[6] as pointer to int[6] Commented Apr 11, 2014 at 16:58
  • 'Is char a[] was identical to char *a.'? The entry in C-FAQ is pertinent. c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr Commented Apr 11, 2014 at 17:09
  • @Prabhu That depends on your definition of identical. It is identical in the sense that the expressions should yield the same values, it is not identical in that the compiler might (or might not) generate different code. Commented Apr 11, 2014 at 17:18
  • The C value of an array is a pointer to its first element, and C is pass-by-value. Commented Apr 11, 2014 at 17:35

5 Answers 5

3

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);
Sign up to request clarification or add additional context in comments.

5 Comments

Can we not pass value by reference in a function?
"In C, parameters passed in functions can only be passed by value."
@Rahul C doesn't support pass by reference. You can make it "look like" passing by reference, using pointers and passing them by value.
What is diff between fun(a,b) and fun(&a,&b)?
@Rahul fun(a,b) will create two local variables inside fun() and use them there. fun(&a,&b) will pass the addresses of a and b, so it will create two pointers to these addresses inside fun(). Thus, the changes will be visible from caller function too. This is not passing by reference though. It's passing the addresses by value.
1

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.

2 Comments

How does having arr[] in the function header differ? It's no longer a pointer, is it?
@DougSmith int arr[] is the same as int *arrin a function parameter. There is no difference at all.
1

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);

3 Comments

It is 0 terminated :-)
@mvw possible solution. But not what their comment suggests. They say they fill 0-5, and I presume that's all data.
It was not a serious suggestion. :)
0

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.

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.