I am having difficulty understanding this guide\'s code on pointers in C. I thought that you needed an ampersand to reference the address of a pointer, but the guide\'s code
A pointer is simply a normal variable that holds the address of something else as its value. In other words, a pointer points to the address where something else can be found. Where you normally think of a variable holding an immediate values, such as int a = 5;
, a pointer would simply hold the address where 5
is stored in memory, e.g. int *b = &a;
.
Being a normal variable, a pointer itself has an address. It's address is the address for the variable itself, not the address it stores. For example, char buf[] = "foo", *p = buf;
creates an array buf
and assigns the address for the first character in buf
as the address held by p
(e.g. p
points to the first character in buf
). But p
itself has an address in memory. It is at the address for p
where the address for the first character in buf
is held in memory. A short example may help:
#include
int main (void) {
char buf[] = "foo",
*p = buf;
printf ("address for buf : %p\n"
"address of 1st char : %p\n"
"address held by p : %p\n"
"address for p itself : %p\n",
(void*)buf, (void*)&buf[0], (void*)p, (void*)&p);
}
Example Use/Output
$ ./bin/pointeraddr
address for buf : 0x7fffbfd0e530
address of 1st char : 0x7fffbfd0e530
address held by p : 0x7fffbfd0e530
address for p itself : 0x7fffbfd0e540
Now let's look closer at what a pointer holds and the pointer address (where what the pointer holds is held in memory) Let's just use the last three numbers in the addresses for simplicity.
Where is the array of char buf
stored in memory?
+---+---+---+---+
| f | o | o | \0| buf - array of char
+---+---+---+---+
5 5 5 5
3 3 3 3
0 1 2 3
When accessing an array, the array is converted to a pointer to the first element subject to the following:
(p3) Except when it is the operand of the
sizeof
operator, the_Alignof
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.
C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)
What is the first character in the array buf
? (answer: buf[0]
) What is the address of the first character (using the unary '&'
operator)? It is the same as the address of buf, but has the type pointer to char (as apposed to buf
which on access is a pointer to array of char[4]
)
What about p
? It has its own address where the address to the first character in buf
is stored, e.g.
+---+ p - pointer to char
| 5 |
| 3 | holds the address 0x7fffbfd0e530
| 0 |
+---+
5
4 stored at 0x7fffbfd0e540
0
How do you get the value (character) at the address held by p
? You use the unary dereference operator *p
. How do you get the address held by p
? p
is already a pointer, so simply evaluating p
itself gives the address held by p
, e.g.
char *q = p;
q
now holds the address held by p
stored at the new address where q
is created in memory.
Or, very simply, to print the address held by p
now also held by q
, simply cast p
(or q
) to (void*)
and print with the "%p"
conversion specifier, e.g.
printf ("address held by p & q : %p\n", (void*)p);
No magic. A pointer is simply a variable that holds the address of something else as its value. As with any variable, it has an address all its own. If you think about it that way, you can always figure out what you have -- and what you need to do to get the value stored at that address.
Look things over and let me know if you have further questions.