2

The normal method I use to pass one-dimensional array to a function is as follows.

#include <stdio.h>
#define ARRAY_SIZE 5 

void function(int *ptr_array, int size) 
{
  int index;
  printf("Destination array contents: ");
  for(index=0;index<size;index++)
  {
     printf("%d ",ptr_array[index]);
  }
}

int main()
{
   int array[ARRAY_SIZE]={1,2,3,4,5};
   function(array,ARRAY_SIZE);
   printf("\n");
   return 0;
}

I did realize that the function accepting the argument can also follow as void function(int ptr_array[],int size) (or) void function(int ptr_array[5],int size).In this scenario the arguement passed is a int * but received in int []. So the questions are

  • It looks to me that compiler must do a cast of the accepted argument in the function.How does the array index impacts on the cast?
  • If it was a 2D array's base address that is passed to the function, what is the correct type for accepting the arguments in int[][] form
Vivek Maran
  • 2,623
  • 5
  • 38
  • 52

3 Answers3

2

In the context of a function parameter declaration, T a[] and T a[N] are synonymous with T *a; a is a pointer type, not an array type, regardless of whether you use [] or [N] or *.

Chapter and verse:

6.7.6.3 Function declarators (including prototypes)

...
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

Why would that be the case? This is why:

6.3.2.1 Lvalues, arrays, and function designators

...
3 Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

In the call to function, the expression array has type "5-element array of int"; by the rule in 6.3.2.1/3, it is converted ("decays") to an expression of type "pointer to int", and its value is the address of the first element (&array[0]); this pointer value is what gets passed to function.

If array had been declared as int array[5][5], then the expression array would be converted from "5-element array of 5-element array of int" to "pointer to 5-element array of int", or int (*)[5], and your function declaration would look like

void function(int (*array)[5], int size)

which could also be written as

void function(int array[][5], int size)

or

void function(int array[5][5], int size)

Note that in this case, the size of the outer dimension is not optional; it must be specified so that the compiler knows the size of the type being pointed to.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Thanks for the answer. I get the context now, except the **"type qualifier"** stuff that is explained in the standards. – Vivek Maran Oct 18 '12 at 07:19
1

All arrays can be implicitly casted to pointers of the same type as the array, but not the other way around. That's why it works to pass an array to a function accepting a pointer or assigning an array to a pointer, but you can't assign a pointer to an array.

As for your second question, you either has to have the argument as a double array (i.e. type array[][]) or a pointer to an array (i.e. type (*array)[]). In this case a pointer to a pointer will not work as it's something else.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I am so glad for this simple, concise explanation. I keep seeing C code that does this and not being able to understand why it's acceptable - no longer. :) – Winfield Trail Aug 06 '13 at 23:36
1

It looks to me that compiler must do a cast of the accepted argument in the function.How does the array index impacts on the cast?

Except in some situations (utilisation as operand of the sizeof, _Alignof and unary & operators, according to C11 standard), an array is evaluated as a pointer to its first element. Moreover, the following forms are equivalent (in the case of function parameters):

void function(int ptr_array[], int size);
void function(int *ptr_array, int size);

Therefore, there is no really "cast" of the arguments; the array is implicitly converted to a pointer, and it matches with the argument type.

If it was a 2D array's base address that is passed to the function, what is the correct type for accepting the arguments in int[][] form?

The following forms are among other correct:

void f(int t[][SIZE]);
void f(int (*t)[SIZE]);
md5
  • 23,373
  • 3
  • 44
  • 93