When you declare the array of int
s, as you did int array[] = { 1, 2, 3 };
etc, what the compiler has done there is reserve space for (in this case) three integers in a row "on the stack" (the memory space where local variables are kept during the execution of a function). The name for that space is array
.
Taking the address of the first element, like &array[0]
, gives you the address of the first of those integers, as you expect. That address points to the small chunk of memory within the function's stack frame.
In the second case, you're asking for the address of "the variable called array
", right? Well, that variable is... those same three integers on the stack. And the address of that thing is the same as the address of the first element. That's why those values are the same.
You note that your textbook says that the latter version is actually unknown. I'm not a standards expert on this, but that makes some sense-- it's not really idiomatic to use that second form, because you can just say array
which also represents the same thing and is more sensible.
However, things change if you allocate that array dynamically. If you do this:
int * dynamic_array = malloc(3 * sizeof(int));
... then you've still created an "array" in practice, but the storage for those three integers is not on the stack anymore; it's been allocated dynamically from the heap. In this case, &dynamic_array[0]
will still give you the address of the first element. That address is the same as the value which is contained inside the variable dynamic_array
. Note in this case this is not the same as saying &dynamic_array
. Taking the address of the pointer dynamic_array
here would give you the address of the pointer on the stack, (i.e., an int **
).