This question may seems quite duplicated; however, I indeed have had a serious survey on this site and still cannot quite understand.
char str[] = "test";
printf("%p\n", str);
printf("%p\n", &str);
I know str
itself is a pointer which points to the starting location that stores "t". Therefore I expect that printf("%p\n", str);
shows this address (say 000000FFE94FFC34
). Next, I wish to know in my OS, at what memory location that stores the exact information 000000FFE94FFC34
. (i.e. the address of str
itself.)
However, the output of the third line is the same as the previous one. It seems quite a weird behavior. And how can I figure out the address of str
itself? I guess this can be achieved by using another new pointer that points to the pointer I want, i.e. char **super_pointer = str;
but I think it is an unnecessarily complicated way.
I know str itself is a pointer which points to the starting location that stores "t".
As you wrote "str itself" is not a pointer it is an array. But used in expressions array designators with rare exceptions are converted to pointers to their first elements.
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.
In this call
printf("%p\n", str);
the array designator str
used as an argument expression is converted to a pointer to its first element. In fact this call is equivalent to
printf("%p\n", &str[0]);
That is this call outputs the starting address of the extent of memory occupied by the array.
This call
printf("%p\n", &str);
that is better to write as and the previous call like
printf("%p\n", ( void * )&str);
also outputs the starting address of the extent of the memory occupied by the array.
What is the difference?
The expression str
used in the call of printf
has the type char *
while the expression &str
has the type char ( * )[5]
.
The both expressions is interpreted by the call as expressions of the type void *
.
To make this more clear consider a two dimensional array
char str[2][6] = { "test1", "test2" };
The addresses of the array as whole and of its first "row" and of its first character of the first "row" are coincide.
That is the expression &sgtr
that has the type char ( * )[2][6]
and the expression &str[0]
that has the type char ( * )[6]
and the expression &str[0][0]
that has the type char *
yield the same value: hhe starting address of the extent of memory occupied by the array..