Also an array most of the times decays to a pointer for example arr[0]
is the same as (arr + 0)
arr[0]
is evaluated like *( arr + 0 )
that is the same as *arr
.
Function parameters having array types are adjusted by the compiler to pointers to the array element types.
On the other hand, an array used as an argument expression is implicitly converted to pointer to its first element.
So for example these function declarations
void f( char * s[100] );
void f( char * s[10] );
void f( char * s[] );
are equivalent and declare the same one function as
void f( char **s );
To make it clear just introduce a typedef name. For example
typedef char *T;
then you have
void f( T s[] );
So the function parameter is adjusted by the compiler to
void f( T *s );
Now change the typedef alias to its original type and you will get
void f( char * *s );
Pay attention to that the pointer s
knows nothing how many elements the array has used as a function argument.
Thus for example the function main is declared like
int main( int argc, char *argv[] );
That is it has one more parameter argc
that allows to determine the number of elements in the array of strings passed to the function. Though if to tell about main then in general the parameter argc
is redundant because the array of strings always contains the sentinel value NULL
. That is argv[argc]
is equal to NULL
.
But in general you have to pass also the number of elements in the array used as a function argument.