Pointer Usage
You need to be able to perform certain actions to make pointers useful. These include:
- You must be able to get a pointer to a value. For example, you should be able to get a pointer to a value stored in a variable.
- Once you have a pointer value, you must be able to follow that pointer to its value so that you can:
- Read the value it points to.
- Store a value at the location pointed to.
What is the pointer value?
Memory is laid out as a sequence of bytes, into which values can be stored. The bytes can be thought of as being in a long line, with each being given numbered based on its position in that line. So the first byte would be byte 0, the next is byte 1, the next byte 2, and so on. This number is then the address of that byte. So byte 975708474 is next to byte 975708475, which is next to byte 975708476, etc. This number is also unique, so there is only one byte 975708474. It is this number that is used in a pointer’s value, the number of the byte that it is pointing to.
Figure x.y shows an example of memory used by an array of three values. Each value is a double, so each one occupies 8 bytes. If the first is at address 975708474, then the second starts at address 975708482 (975708474 + 8 bytes). This figure also shows a pointer, p
, that points to this value. That means that p
has the value 975708474, the address of this value, stored within it.
C and C++ have a feature called pointer arithmetic. When you add, or subtract, a value from a pointer the compiler will work in terms of the pointer type. So in Figure x.y p
is a pointer to a double, this means that when you add one to p you get the value 975708482, which is 1 double past p
. Therefore, p + 2
would be 2 doubles past p
, at 975708490, and so on.
In C/C++
C and C++ provides a number of pointer operators that allow you to get and use pointers.
Name | Operator | Example | Description |
---|---|---|---|
Address Of | & | &x | Gets a pointer to the variable/field etc. |
Dereference | * | *ptr | Follow the pointer, and read the value it points to. |
-> | ptr -> field_name | Follow a pointer to a struct or union, and read a field value. |
You can get a pointer to a value using the ampersand operator (&
). This operator lets you get the address of a variable, field, etc.
To follow the pointer, and read its value, you use the *
operator. With structs, and unions, you can access a field using (*ptr).field
but C/C++ introduced a special ->
operator to simplify this. I think this is one of the nice parts of the C/C++ syntax. To access the field you would use ptr->field
, which looks nice and connects with the visual pointer metaphor.
Example
Pointer notation in C / C++
As final word on the usage of pointers in C and C++, we should note that reading the notation for pointers can sometimes be a bit confusing at first, since similar looking syntax can mean different things depending on how we format the code and the context in which it occurs.
Consider the following sample code:
The *pointer1
and *pointer2
notation looks exactly the same in lines 6 and 7 (int *pointer1
and int *pointer2
) as it is in line 10 (val = *pointer1 * *pointer2;
). However, the former are declarations of integer pointer variables, and the latter are the dereferencing of these two variables. Further complicating matters, is that the *
is also used as a multiplication operator in the val = *pointer1 * *pointer2;
statement.
To avoid confusion, we can use braces to group the pointer variables in the arithmetic statement as follows: (refer to comments in the code below)
The output of the code in both cases is: