# Thread: Array as an argument to a function

1. ## Array as an argument to a function

Hello All,

I have a question about function definitions and calls which accept arrays as their argument.

As far as I see the types of formal parameters and arguments match. For example if I define a function like this:

Code:
`int function(int x)`
I should call this function with an argument of int type (or even if I don't the compiler may convert it to int.) However when it comes to arrays I am a bit confused. If I define a function like this:

Code:
`int function(int x[][2])`
I can call this function with the name of the array. Let's say I want to use the array "array[3][2]" for the argument. I need to call the function like this:

Code:
`function(array)`
If I have learnt what has been told here well 'array' decays to a pointer, its value is the address of a[0][0] and it refers to the addresses of a[0][0], a[0][1] and a[0][2]

Is this an exception to the usual way of "both the argument and the formal parameter must be the same type" or by chance they are the same also in my example but I am missing something?

The question may sound a silly one but I really want to make sure I have the right information. Also I have one more silly (even sillier) question but I will ask it later, after I learn this one.

2. If I have learnt what has been told here well 'array' decays to a pointer, its value is the address of a[0][0] and it refers to the addresses of a[0][0], a[0][1] and a[0][2]
No the name of the array decays to the address of the first element not some other random element.

Is this an exception to the usual way of "both the argument and the formal parameter must be the same type"
No it is not an exception, the function prototype, function implementation, and function call must agree as to the type. Let's simplify things and just talk about one dimensional array for now. Do you realize that when talking about function parameters that the following are all equivalent?

Code:
```void someFunction(int *array);
void someFunction(int array[]);
void someFunction(int array[3]);   // The number in the brackets is actually ignored by the compiler (remember this is a single dimensional array).```
Do you realize that the following are also equivalent?

Code:
```int main()
{
...

someFunction(array);
someFunction(&array[0]);
...```
Multidimensional arrays just add the brackets with the sizes of all but the last dimension (array[][2], *array[2], or array[3][2]). All dimensions except the first must have the corresponding sizes.

3. Originally Posted by jimblumberg
No the name of the array decays to the address of the first element not some other random element.
I was thinking I was saying the same thing [I used the name 'a' instead of 'array' by mistake.] The first element of the array is array[0], the value of its address is the same as the adress of array[0][0] and it refers to the array composed of array[0][0], array[0][1] and array [0][2]. I may have worded it wrongly in the previous post. Could you please educate me if that one is wrong too?

Originally Posted by jimblumberg
Do you realize that the following are also equivalent?

Code:
```int main()
{
...

someFunction(array);
someFunction(&array[0]);
...```
Yes I understand that, the first one decays to the pointer to the first element and the second one is already the address of the first element. I would say both have the type int*.

Originally Posted by jimblumberg
Do you realize that when talking about function parameters that the following are all equivalent?

Code:
```void someFunction(int *array);
void someFunction(int array[]);
void someFunction(int array[3]);   // The number in the brackets is actually ignored by the compiler (remember this is a single dimensional array).```
This is where I am confused. I can clearly see the first one is a pointer to an int. But the others look like arrays to me. It is not clear to me they are pointers to int too. Could you please explain this a bit?

4. It is true that they use array notation, but in the context of a parameter they still are part of the declaration of a pointer, not an array.

5. Yes I understand that, the first one decays to the pointer to the first element and the second one is already the address of the first element. I would say both have the type int*.
Yes that is correct. Do you understand that you can pass partial arrays by using the address of some other element of the array, ie by calling the function like: someFunction(&array[1]); to pass the address of the second element of the array?

This is where I am confused. I can clearly see the first one is a pointer to an int. But the others look like arrays to me. It is not clear to me they are pointers to int too. Could you please explain this a bit?
All of those examples are using pointers, that is why they are equivalent. When you pass an array to a function you are passing a pointer to array.

But the others look like arrays to me.
That is usually the main reason you would use those methods, because they reinforce that you are working with an array not just a pointer to a single int. Realize that the compiler will let you pass the address of a single int or an array of int into that function no matter what method you use. And yes it can get confusing, multidimensional arrays can get even more confusing.

6. @jimblumberg and @laserlight

Thanks a lot for your answers. They did not only clarify things for me but also gave me good keywords to search on Google more. My search took me to C99 draft standards and it says "A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’

Therefore I understand a formal parameter like "int array[]" is adjusted to something like "int *pointer. Furthermore "int array[][3]" must be adjusted to "int *p[3]" as the array is 'an array of arrays of ints' and the type must be "an array of ints". If I my logic is correct I see why all the three in jimblumberg's example are equivalent.

Originally Posted by jimblumberg
Yes that is correct. Do you understand that you can pass partial arrays by using the address of some other element of the array, ie by calling the function like: someFunction(&array[1]); to pass the address of the second element of the array?
It is an interesting thing, I saw a similar one in an example which checks if a sub-string is present in another string yesterday. I just assumed I can do this (passing partial arrays) but your comment confirmed my assumption.

Thanks a lot again.

7. Originally Posted by GokhanK
Furthermore "int array[][3]" must be adjusted to "int *p[3]" as the array is 'an array of arrays of ints' and the type must be "an array of ints".
Just as a nitpick, "int array[][3]" is adjusted to "int (*p)[3]" (the parentheses change the meaning). "int *p[3]" means "p is an array of 3 pointers to int", whereas "int (*p)[3]" means "p is a pointer to an array of 3 ints".

8. Originally Posted by christop
Just as a nitpick, "int array[][3]" is adjusted to "int (*p)[3]" (the parentheses change the meaning). "int *p[3]" means "p is an array of 3 pointers to int", whereas "int (*p)[3]" means "p is a pointer to an array of 3 ints".
Thanks for your correction, it seems I will need to spend some time with these to gain familiarisation and get used to write my code properly.