Reputation: 1457
I am trying to understand the special relationship that exists between array and pointers i.e. an array name without the brackets always points to the first element of the array.
On a Linux system, I get this with a C program:
char name[7] = "unique";
printf("\nAddress stored of name: %p", name);
printf("\nAddress stored of name: %s", name); //Conflict
printf("\nAddress of name[0]: %p", &name[0]);
//dereferencing the pointer
printf("\nValue of name[0]: %c", *name);
printf("\nValue of name[1]: %c", *(name+1));
The output is:
Address stored of name: 0xbff68131
Address stored of name: unique
Address of name[0]: 0xbff68131
Value of name[0]: u
Value of name[1]: n
I understand everything in the above output except the output of the line of code which as //Conflict. In other words, if name is equivalent to &name[0] as per the special relationship between array and pointers, then why simply changing the format specifier (from %p to %s) prints the actual value of the array. If that is truly the case, then does that mean name, &name[0] and *name are all equivalent?
I would at least expect it (//Conflict) to print some other (garbage?) value but not the actual value of the array.
Upvotes: 3
Views: 337
Reputation: 31952
%s
This tells printf
to treat the argument as a pointer to a memory location which contains an array of characters, and prints each one until the \0
is encountered.
%p
This treats the arguement as a memory location and prints its value in hex, as you have seen.
What you are terming as "Conflict" is actually by far the more important use, and is the correct way to print c-strings.
Upvotes: 2
Reputation: 15642
When an array expression is used in place of a pointer expression, the array expression is converted to a pointer to the first element. The pointer to the first element is array+0
or &array[0]
, and the first element is *(array+0)
or array[0]
.
In printf("\nAddress stored of name: %p", name);
, the array expression is converted to a pointer to the first element. Likewise for printf("\nAddress stored of name: %s", name);
, name is converted to a pointer to name[0]
. Adding 1 results in a pointer to name[1]
. Adding 2 results in a pointer to name[2]
, etc.
It might be worthwhile noting that the array[n]
operator is actually a pointer[n]
operator, that array
gets converted to a pointer to the first expression. n gets added to the pointer to yield a pointer to the nth element, which is then dereferenced to yield the nth element from it's pointer. This occurs as a result of the %s
format specifier. However, the %p
format specifier doesn't do any dereferencing at all.
If that is truly the case, then does that mean name, &name[0] and *name are all equivalent?
No. name
is an array expression: sizeof name
will result in 7. &name[0]
is a pointer expression that translates to "the pointer to name[0]": sizeof &name[0]
will result in sizeof (char *)
. *name
is a char expression that translates to "the char pointed to by name". sizeof *name
will result in 1.
Upvotes: -1