Chapter 12 Chapter 11 introduced pointers and showed

  • Slides: 15
Download presentation
Chapter 12 Chapter 11 introduced pointers and showed how they're used as function arguments

Chapter 12 Chapter 11 introduced pointers and showed how they're used as function arguments and as values returned by functions. This chapter covers another application for pointers. When pointers point to array elements, C allows us to perform arithmetic—addition and subtraction—on the pointers, which leads to an alternative way of processing arrays in which pointers take the place of array subscripts.

12. 1 Pointer Arithmetic Pointers can point to array elements, not just ordinary variables.

12. 1 Pointer Arithmetic Pointers can point to array elements, not just ordinary variables. For example, suppose that a and p have been declared as follows: int a [10], *p; We can make p point to a[0] by writing p = &a[0]; Graphically, here's what we've just done:

We can now access a[0] through p for example, we can store the value

We can now access a[0] through p for example, we can store the value 5 in a[0] by writing *p = 5; Here's our picture now:

Making a pointer p point to an element of an array a isn't particularly

Making a pointer p point to an element of an array a isn't particularly exciting. However, by performing pointer arithmetic (or address arithmetic) on p, we can access the other elements of a. C supports three (and only three) forms of pointer arithmetic: 1. adding an integer to a pointer 2. subtracting an integer from a pointer 3. subtracting two pointers The following examples assume the following declarations: int a[10], *p, *q, i;

Adding an integer j to a pointer p yields a pointer to the element

Adding an integer j to a pointer p yields a pointer to the element that is j places after the one that p points to. If p points to the array element a[ i ] then p + j points to a[ i + j ] (provided, a[ i + j ] exists). The following example illustrates pointer addition; int a[10], *p, *q, i;

Subtracting an Integer from a Pointer If p points to the array element a[

Subtracting an Integer from a Pointer If p points to the array element a[ i ] then p - j points to a[ i - j ] int a[10], *p, *q, i;

Subtracting Pointers If two pointers are subtracted, the result is the distance between the

Subtracting Pointers If two pointers are subtracted, the result is the distance between the pointers. Thus, if p points to a[ i ] and q points to a[ j ] then p - q is equal to i - j int a[10], *p, *q, i; p = &a[5]; q = &a[1]; i = p – q; i = q – q; /* i is 4 */ /* i is - 4 */ Note: Performing arithmetic on a pointer p gives a meaningful result only when p points to an array element. Furthermore, subtracting two pointers is meaningful only when both point to elements of the same array.

Comparing Pointers Compare pointers using: relational operators (<, <=, >, >=) and equality operators

Comparing Pointers Compare pointers using: relational operators (<, <=, >, >=) and equality operators (== and ! =) Note: Using the relational operators to compare two pointers is meaningful only when both point to elements of the same array. The outcome of the comparison depends on the relative position of the two elements in the array. For example, after the assignments int a[10], *p, *q, i; p = &a[5]; q = &a[1]; the value of p <= q is 0 and the value of p >= q is 1

12. 2 Using Pointers for Array Processing Pointer arithmetic allows us to visit the

12. 2 Using Pointers for Array Processing Pointer arithmetic allows us to visit the elements of an array by repeatedly incrementing a pointer variable. The following program sums the elements of an array a The pointer variable p initially points to a[0] Each time through the loop p is incremented p points to a [1] then a [2] and so forth The loop terminates when p steps past the last element of a #define N 10 int a[N], sum, *p; sum = 0; for (p = &a[0]; p < &a[N]; p++) sum += *p;

#define N 10 int a[N], sum, *p; sum = 0; for (p = &a[0];

#define N 10 int a[N], sum, *p; sum = 0; for (p = &a[0]; p < &a[N]; p++) sum += *p; End of first interation: End of second interation: End of third interation:

#define N 10 int a[N], sum, *p; sum = 0; for (p = &a[0];

#define N 10 int a[N], sum, *p; sum = 0; for (p = &a[0]; p < &a[N]; p++) sum += *p; The condition p < &a[N] in the for statement deserves special mention. In Standard C, it's legal to apply the address operator to a[N], even though this element doesn't exist (a is indexed from 0 to N - 1). Using a[N] is safe since the loop doesn't attempt to examine its value. The body of the loop will be executed with p equal to &a [0], &a [1], . . . , &a [N-1] but when p is equal to &a[N] the loop terminates.

* (indirection) and ++ operators can be combined in statements that process array elements.

* (indirection) and ++ operators can be combined in statements that process array elements. The following stores a value into an array element, then advancing to the next element. int a[10], *p, *q, i, j; Using array subscripting: a[ i++ ] = j; If p is pointing to an array element, the corresponding statement would be *p++ = j; The postfix version of ++ takes precedence over * the compiler sees this as *(p++) = j; The value of p++ is p since using the postfix version of ++ p won't be incremented until after the expression has been evaluated Thus, the value of * (p++) will be *p (the object to which p is pointing)

*p++ is not the only legal combination of * and ++ we could write

*p++ is not the only legal combination of * and ++ we could write (*p) ++ which returns the value of the object that p points to then increments that object (p itself is unchanged) Expression *p++ or *(p++) (*p)++ *++p or *(++p) ++ *p or ++(*p) Meaning (refer to Appendix B – C Operator Precedence) Value of expression is *p before increment - increment p later Value of expression is *p before increment - increment *p later Increment p first - value of expression is *p after increment Increment *p first - value of expression is *p after increment Note: The one seen most frequently is *p++ which is used in loops. For example, to sum the elements of the array a for (p = &a[0]; p < &a[N]; p++) sum += *p; or p = &a[0] ; while (p < &a[N]) sum += *p++;

The * and -- operators mix in the same way as * and ++

The * and -- operators mix in the same way as * and ++ An application that combines * and - - is the stack example. A pointer variable that points initially to element 0 of the contents array: int *top_ptr = &contents [0]; The push function: void push(int i) { if (is_full()) stack_overflow(); else *top_ptr++ = i; } The pop function: int pop(void) { if (is_empty()) stack_underflow(); else return *--top_ptr; } Note: *--top_ptr is not written *top_ptr-want pop to decrement top_ptr before fetching the value to which it points

12. 3 Using an Array Name as a Pointer The name of an array

12. 3 Using an Array Name as a Pointer The name of an array can be used as a pointer to the first element in the array In pointer arithmetic: a + i is the same as &a [ i ] *(a + i) is equivalent to a[ i ] (both represent a pointer to element i of a) (both represent element i itself) Array subscripting can be viewed as a form of pointer arithmetic. For example, suppose that a is declared as follows: #define N 10 int a[N], sum, *p; for (p = &a[0]; p < &a[N]; p++) sum += *p; To simplify the loop, we can replace &a[0] by a and &a [N] by a + N for (p = a; p < a + N; p++) sum += *p;