Because pointers are just integers that are used as addresses of other objects in memory, D provides a set of features for performing arithmetic on pointers. However, pointer arithmetic is not identical to integer arithmetic. Pointer arithmetic implicitly adjusts the underlying address by multiplying or dividing the operands by the size of the type referenced by the pointer.
The following D fragment illustrates this property:
int *x; BEGIN { trace(x); trace(x + 1); trace(x + 2); }
This fragment creates an integer pointer x
and then traces its value, its value incremented by one, and its
value incremented by two. If you create and execute this
program, DTrace reports the integer values 0
,
4
, and 8
.
Since x
is a pointer to an
int
(size 4 bytes), incrementing
x
adds 4 to the underlying pointer value.
This property is useful when using pointers to refer to
consecutive storage locations such as arrays. For example, if
x
was assigned to the address of an array
a
, similar to what is shown in
Figure 2.4, “Pointer and Array Storage”, the expression x
+ 1
would be equivalent to the expression
&a[1]
. Similarly, the expression
*(x + 1)
would refer to the value
a[1]
. Pointer arithmetic is implemented by
the D compiler whenever a pointer value is incremented by using
the +
, ++
, or
=+
operators. Pointer arithmetic is also
applied as follows; when an integer is subtracted from a pointer
on the left-hand side, when a pointer is subtracted from another
pointer, or when the --
operator is applied
to a pointer.
For example, the following D program would trace the result
2
:
int *x, *y; int a[5]; BEGIN { x = &a[0]; y = &a[2]; trace(y - x); }