I’m new to C and trying to understand the following code
#include <stdio.h>
int main() {
int i[3] = {1, 2, 3};
int* p = &i;
printf("%d\n", *p);
printf("%d\n", *(&i));
return 0;
}
What I thought was i is a pointer to first element of the array, then ‘&i’ must be a pointer to pointer. But here we have an assignment
int* p = &i;
C still allows it with a warning of int\* differs in levels of indirections from int(\*)\[3\]. I thought this assignment shouldn’t be allowed since it kinda weird.
Then the result of *p is 1, and it differs from *(&i) which gives the address of the first element. I don’t understand why it became like that. I tried to google for the warning above, assignment from pointer to address of array to int pointer, etc. but haven’t found what I need.
Thank you for your time.
>Solution :
What I thought was ‘i’ is a pointer to first element of the array …
No. The variable i may decay to a pointer to the first element under many circumstances (such as when you pass it to a function) but i itself is the integer array {1, 2, 3}.
And, since there is no padding before the 1, the address of i is the same as the address of that 1. The warning appears because you’re using the pointer in a way that may be problematic.
More specifically, the ISO C17 standard (see 6.3.2.1 Lvalues, arrays, and function designators) has this to say:
Except when it is the operand of the
sizeofoperator, 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.
This is very much a "unary & operator" scenario hence it does not decay.