Array designators are immutable lvalues. That is you may not change an array designator such a way that ir would define another array.
Consider array designators as named memory extents.
As for your example then this function declaration
void test(char c[]);
is adjusted by the compiler the following way
void test(char *c);
that is a parameter having an array type is adjusted by the compiler to pointer. Thus for example these function declarations
void test(char c[100]);
void test(char c[10]);
void test(char c[1]);
void test(char c[]);
are equivalent and declare this one function
void test(char *c);
You nay include all these declarations in your program though they will be redundant.
For example
#include <stdio.h>
void test(char c[100]);
void test(char c[10]);
void test(char c[1]);
void test(char c[]);
void test( char *c)
{
c=c+2;
c--;
printf("%c",*c);
}
int main( void )
{
char ch[5]={'p','o','u','r'};
test(ch);
}
To make it evident consider the following program
#include <stdio.h>
void test( char c[] )
{
printf( "sizeof( c ) = %zu\n", sizeof( c ) );
}
int main( void )
{
char ch[5]={'p','o','u','r'};
test( ch );
printf( "sizeof( ch ) = %zu\n", sizeof( ch ) );
}
Its output is
sizeof( c ) = 8
sizeof( ch ) = 5
That is within the function sizeof( c )
is equal to the size of a pointer (in used system it is equal to 8). While in main sizeof( ch )
is the size of the array.
When you pass an array to such a function then the array designator is implicitly converted to pointer to its first element. So these calls
test( ch );
test( &ch[0] );
are equivalent.
This means that within the function you deal with a pointer and you can change the value of the pointer using the pointer arithmetic.