8.8 Pointer Expressions and Pointer Arithmetic

This section describes the operators that can have pointers as operands and how these operators are used with pointers. C++ enables pointer arithmetic—a few arithmetic operations may be performed on pointers. Pointer arithmetic is appropriate only for pointers that point to built-in array elements.

A pointer may be incremented (++) or decremented (--), an integer may be added to a pointer (+ or +=) or subtracted from a pointer (- or -=), or one pointer may be subtracted from another of the same type—this particular operation is appropriate only for two pointers that point to elements of the same built-in array.

Portability Tip 8.3

Most computers today have four-byte or eight-byte integers. Because the results of pointer arithmetic depend on the size of the memory objects a pointer points to, pointer arithmetic is machine dependent.

Assume that int v[5] has been declared and that its first element is at memory location 3000. Assume that pointer vPtr has been initialized to point to v[0] (i.e., the value of vPtr is 3000). Figure 8.15 illustrates this situation for a machine with four-byte integers. Variable vPtr can be initialized to point to v with either of the following statements (because a built-in array’s name implicitly converts to the address of its zeroth element):


int * vPtr{v};
int* vPtr{&v[0]};

Fig. 8.15 Built-in array v and a pointer variable int* vPtr that points to v.

8.8.1 Adding Integers to and Subtracting Integers from Pointers

In conventional arithmetic, the addition 3000 + 2 yields the value 3002. This is normally not the case with pointer arithmetic. When an integer is added to, or subtracted from, a pointer, the pointer is not simply incremented or decremented by that integer, but by that integer times the size of the memory object to which the pointer refers. The number of bytes depends on the memory object’s data type. For example, the statement


vPtr += 2;

would produce 3008 (from the calculation 3000 + 2 * 4), assuming that an int is stored in four bytes of memory. In the built-in array v, vPtr would now point to v[2] (Fig. 8.16). If an integer is stored in eight bytes of memory, then the preceding calculation would result in memory location 3016 (3000 + 2 * 8).

Fig. 8.16 Pointer vPtr after pointer arithmetic.

If vPtr had been incremented to 3016, which points to v[4], the statement


vPtr -= 4;

would set vPtr back to 3000—the beginning of the built-in array. If a pointer is being incremented or decremented by one, the increment (++) and decrement (--) operators can be used. Each of the statements


++vPtr;
vPtr++;

increments the pointer to point to the built-in array’s next element. Each of the statements


--vPtr;
vPtr--;

decrements the pointer to point to the built-in array’s previous element.

Error-Prevention Tip 8.5

There’s no bounds checking on pointer arithmetic. You must ensure that every pointer arithmetic operation that adds an integer to or subtracts an integer from a pointer results in a pointer that references an element within the built-in array’s bounds.

8.8.2 Subtracting Pointers

Pointer variables pointing to the same built-in array may be subtracted from one another. For example, if vPtr contains the address 3000 and v2Ptr contains the address 3008, the statement


x = v2Ptr - vPtr;

would assign to x the number of built-in array elements from vPtr to v2Ptr—in this case, 2. Pointer arithmetic is meaningful only on a pointer that points to a built-in array. We cannot assume that two variables of the same type are stored contiguously in memory unless they’re adjacent elements of a built-in array.

Common Programming Error 8.4

Subtracting or comparing two pointers that do not refer to elements of the same built-in array is a logic error.

8.8.3 Pointer Assignment

A pointer can be assigned to another pointer if both pointers are of the same type. Otherwise, a cast operator (normally a reinterpret_cast; discussed in Section 14.8) must be used to convert the value of the pointer on the right of the assignment to the pointer type on the left of the assignment. The exception to this rule is the pointer to void (i.e., void*), which is a generic pointer capable of representing any pointer type. Any pointer to a fundamental type or class type can be assigned to a pointer of type void* without casting. However, a pointer of type void* cannot be assigned directly to a pointer of another type—the pointer of type void* must first be cast to the proper pointer type.

Common Programming Error 8.5

Assigning a pointer of one type to a pointer of another (other than void*) without using a cast is a compilation error.

8.8.4 Cannot Dereference a void*

A void* pointer cannot be dereferenced. For example, the compiler “knows” that an int* points to four bytes of memory on a machine with four-byte integers. Dereferencing an int* creates an lvalue that is an alias for the int’s four bytes in memory. A void*, however, simply contains a memory address for an unknown data type. You cannot dereference a void* because the compiler does not know the type of the data to which the pointer refers and thus not the number of bytes.

Common Programming Error 8.6

The allowed operations on void* pointers are: comparing void* pointers with other pointers, casting void* pointers to other pointer types and assigning addresses to void* pointers. All other operations on void* pointers are compilation errors.

8.8.5 Comparing Pointers

Pointers can be compared using equality and relational operators. Comparisons using relational operators are meaningless unless the pointers point to elements of the same builtin array. Pointer comparisons compare the addresses stored in the pointers. A comparison of two pointers pointing to the same built-in array could show, for example, that one pointer points to a higher-numbered element of the built-in array than the other pointer does. A common use of pointer comparison is determining whether a pointer has the value nullptr, 0 or NULL (i.e., the pointer does not point to anything).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset