This function declaration
void func(int v[]){
v[0] = 1;
}
is adjusted by the compiler to the declaration
void func(int *v){
v[0] = 1;
}
From the C Standard (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
On the other hand, in this call
func(v);
the array designator v is implicitly converted to a pointer to its first element.
The C Standard (6.3.2.1 Lvalues, arrays, and function designators)
3 Except when it is the operand of the sizeof 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.
That is the function call is equivalent to
func( &v[0] );
So in fact the first element of the array is passed to the function by reference through a pointer to it. Dereferencing the pointer by means of the subscript operator (the expression v[0] is equivalent to the expression *v)
v[0] = 1;
the referenced first element of the array is changed.
struct. Here the array decays to a pointer, and the function writes to the first element of the caller's array. Even when you define the argument asint v[]it is still not passed an array.int v[]is virtually synonymous toint *v.int (x[])[]is not allowed but the pointer declarationint (*x)[]is, because arrays must have complete element types but pointers can point to incomplete types. Another is that an array declaration can contain an expression in the brackets that will be evaluated, and a pointer declaration has no place for this.int (*x)[]is not an array declaration. It declares a pointer, and it is not compatible withint **x. The former is a pointer to an array, and the latter is a pointer to a pointer. E.g, the codevoid bar(int (*x)[]); void bar(int **x);will yield a diagnostic from the compiler that the types conflict.