In C, there are strong relationships between pointers and arrays. For any one-dimensional array A and integer x, the following relationships are always true:
&A[0] == A
The address of the first element of the array A is value of A itself. In other words, A is a pointer, it points to the first element in the array.
&A[x] == A + x
The address of the x'th element of A is the value of A + x.
This is one of the great truths (and a defining characteristic) of the C programming language. The first relationship is a special case of this more general relationship.
This equality defines part of the nature of pointer arithmetic, which defines how the addition operator works when it is computing the sum of a pointer and an integer. Instead of doing ordinary arithmetic (treating A as though it was an ordinary integer and adding x to it), C takes into consideration the size (in bytes) of the type pointed to by A. The actual arithmetic performed (behind your back by the compiler) is to compute A + (x * sizeof(t), where t is the type pointed to by A.
For example, if A points to address 1000, and is a pointer to an int, then A + 1 evaluates to a pointer to address 1004 on the course machines (because on the course machines, an int consists of 4 bytes). Similarly, if B points to address 2000, and is a pointer to a char, then B + 3 evaluates to 2003 (because on the course machines, a char consists of a single byte).
(Note that you can also subtract an integer from a pointer, which allows you to index backwards off the front of an array. For example, A - 1 gives a pointer to the ``-1'th'' element of A. There are precious few situations where it makes any sense to do this, but it can be useful.)
A[x] == *(A + x)
This is basically the same as the previous relationship, but adds the reassuring fact that this relationship still holds if we dereference both sides of the equality.
(&A[x] - &A[y]) == (x - y)
This relationship defines subtraction of pointers. The subtraction of two pointers to type t is the number of elements of type t that would fit between them.
For example, if A is an array of ints, starting at
address 5000, and x is 10 and y is 4, then then
(again on the course machines, where the size of an int
is 4) &A[x] == 5040
and &A[y] == 5016
. The
difference between 5040 and 5016 is 24. Dividing 24 by the
size of an int gives 6, which is indeed x - y.
Note that if the two pointers being subtracted are not of the same type, the result of the subtraction is not defined. Most C compilers will not permit you to do this, but by abusing pointer casts, you can get most compilers to let you- but when you do this, the bugs that may result are your own fault.
These relationships allow us to treat arrays like pointers, and treat pointers like arrays. Both of these treatments can be very useful, particularly when dealing with dynamically allocated memory, as we will see in the next section.