In this declaration
int foo[5];
you declared an object of the array type int[5]
. The object foo
is not a pointer to the first element of the array. To see the difference consider the following demonstration program.
#include <stdio.h>
int main(void)
{
int foo[5];
int *foo_ptr = &foo[0];
printf( "sizeof( foo ) = %zu\n", sizeof( foo ) );
printf( "sizeof( foo_ptr ) = %zu\n", sizeof( foo_ptr ) );
return 0;
}
The program output is
sizeof( foo ) = 20
sizeof( foo_ptr ) = 8
Or consider another program
#include <stdio.h>
int main(void)
{
int foo[5];
int *foo_ptr = &foo[0];
int ( *p1 )[5] = &foo;
int **p2 = &foo_ptr;
printf( "sizeof( *p1 ) = %zu\n", sizeof( *p1 ) );
printf( "sizeof( *p2r ) = %zu\n", sizeof( *p2 ) );
return 0;
}
Again the program output is
sizeof( *p1 ) = 20
sizeof( *p2r ) = 8
There is even a difference between types of pointers p1
and p2
.
Moreover pointers may be assignable while arrays are not modifiable lvalues.
That is you may not write for example
int foo[5] = { 1, 2, 3, 4, 5 };
int bar[5] = { 5, 4, 3, 2, 1 };
foo = bar;
But you may write
int foo[5] = { 1, 2, 3, 4, 5 };
int bar[5] = { 5, 4, 3, 2, 1 };
int *foo_ptr = foo;
int *bar_ptr = bar;
for_ptr = bar_ptr;
But indeed an array designator with rare exceptions is converted to a pointer to its first element.
For example in this declaration
int *foo_ptr = foo;
the array designator used as an initializer is converted to a pointer to its first element.
From 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.
To label individual elements as you are suggesting
int foo0, foo1, foo2, foo3, foo4;
does not make a great sense.
For example an array can contain very many elements for example a thousand elements or even more.
Will you write such a declaration like?
int foo0, foo1, foo2, foo3, foo4, /*other variable declarations...*/, foo1000;
Another problem how to pass all the variables to a function?
You will need to list all the variables. And moreover when you pass an array to a function then in fact all elements of the array are passed by reference. That is the function will deal with the original elements of the array through a pointer to its first element. Passing all "labeled elements" to a function means that the function will deal with copies of the elements. You will need to pass each "labeled element" applying to them the address of operator.
Another problem is that the C Standard does not specify in each order the local variable will be placed in memory. For example the compiler may place the variables starting from foo0 or from foo1000.
One more problem is how to write a loop for processing the variables? You may not use a pointer to traverse all the variables because you may use a pointer to travers objects if they are belong to an array.
Or how to allocate dynamically all the variables and access them as an array?
If you will write for example
int *p0 = malloc( sizeof( int ) );
...
int p1000 = malloc( sizeof( int ) );
then there is no any guarantee that the allocated objects will be stored in adjacent extents of memory.