Reputation: 9
Why wouldn't
char *name = "asd";
printf("%p\n%p", (void *)&name, (void *)&name[0]);
give the same output as
char name[] = "asd";
printf("%p\n%p", (void *)&name, (void *)&name[0]);
I've read that C takes strings as a pointer to their first char, till it reaches the '\0'
but the code above doesn't like it, so it is confusing for a C beginner.
Upvotes: 0
Views: 89
Reputation: 47923
First, let's give your two variables different names and contents, so we can clearly tell them apart.
char *namep = "asd";
char namea[] = "zxc";
These result in data structures which might look like this:
+-------+
namep: | * |
+---|---+
|
/
|
V
+---+---+---+----+
| a | s | d | \0 |
+---+---+---+----+
+---+---+---+----+
namea: | z | x | c | \0 |
+---+---+---+----+
Now let's look at your two printf
calls:
printf("%p\n%p", (void *)&namep, (void *)&namep[0]);
Now, &namep
gives you the address of the namep
pointer.
But &namep[0]
gives you the address of the first character in the pointed-to string (a
). If you had printed
printf("%p\n", (void *)namep);
you would have seen the same thing.
printf("%p\n%p", (void *)&namea, (void *)&namea[0]);
Here, &namea
gives you the address of the array.
And &namea[0]
gives you the address of its first character (z
) — which is the same place.
And in fact, due to the special handling (the "decay" of arrays into pointers), if you had said
printf("%p\n", (void *)namea);
you would also have seen the same thing.
You asked:
I've read that C takes strings as a pointer to their first char, till it reaches the
'\0'
.
That's correct.
Suppose you wrote the code
char *p;
for(p = namep; *p != '\0'; p++)
putchar(*p);
This would print your namep
string, asd
. There's no mystery here. namep
was already a pointer, pointing at the first character of the string, so this scrap of code takes its own pointer p
, which starts pointing where namep
points, and prints the pointed-to characters until it gets to the terminating \0
.
What's perhaps more surprising is that you can do exactly the same thing with namea
:
char *p;
for(p = namea; *p != '\0'; p++)
putchar(*p);
This works, too, printing zxc
, and if you don't believe me, I encourage you to type it into your C compiler and try it.
Now, you may be asking, if p
is a pointer and namea
is an array, how can the loop initialization p = namea
work? And this, again, is due to the "decay" of arrays to pointers. Again, when you try to use namea
's value like this, what you get — the value that gets assigned to p
— is automatically a pointer to namea
's first element. And of course that's just what you want. p
starts there, and prints characters 'til it finds a \0
, thus printing zxc
.
Upvotes: 5