Arrays, Pointers, and Pointer Arithmetic

You've already learned about arrays (in Chapter 6, “Working with Arrays”) and how to use the square brackets to access individual elements (the square brackets are technically referred to as the subscription operator). Now that you have an understanding of pointers, you'll learn how to use them to access array elements by performing calculations on the base address of the array. Such address calculations are called address or pointer arithmetic.

What is an array's base address? The elements of an array are laid out sequentially in memory. An array's base address is simply the address of the array's first element (Figure 9.13).

Figure 9.13. An array's base address (stored in the pointer b) is the location of the array's first element. So the base address of the array a is 4.


As with any object, you can get the address of this first element by using the address-of operator:

char a[] = {3, 23, 14, 7, 12};
&a[0];

This is a bit inconvenient to write, so C provides an alternative: you can use the array name, a in this case, as shorthand for the &a[0] expression. So if you use the name of an array anywhere in your code, what you get is actually the array's base address. Thus, these two assignments to b are equivalent:

char *b;
b = &a[0];
b = a;

Both statements store the array's base address—and therefore the address of the array's first element—in the char pointer variable b.

Building on this concept, you know you can dereference the address stored in a pointer variable to get the value stored at that address. Thus the following two expressions will now give the same value:

*b
a[0]

Both return the value of the array's first element, the first using a pointer to the base address, the second using the subscription operator. But what do you do if you want to access, using a pointer, an element other than the first one? The answer is that you have to change the address value stored in the pointer variable before dereferencing it. This is exactly what pointer arithmetic is about.

For example, to access the next element of the array, you have to increment the address value stored in the pointer variable by 1 so that it points to the next address in memory:

b++;

*b will now refer to the second array element. Let's try this in a program.

To use pointer arithmetic to access arrays

1.
Create a new file or project in your text editor or IDE.

2.
Type the standard beginning lines of code (Script 9.7):

/* pointer7.c - Script 9.7 */
#include <stdio.h>

Script 9.7. Incrementing the address stored in the pointer variable b allows the application to access all of the elements in the a array.


3.
Define a C preprocessor constant called COUNT with the value 5:

#define COUNT 5

This value will be used to control the loop for accessing every array element.

4.
Begin the main function:

int main (void) {

5.
Define the required variables:

char a[] = {3, 23, 14, 7, 12};
char *b;
int i;

Define and initialize an array of chars a with five elements. Then define a char pointer variable b and an integer variable i. As you can guess from its name, i will be a loop control variable.

6.
Assign a's base address to the b pointer variable:

b = a;

a[0] and *b are now equivalent and refer to the first element's value.

7.
Use a for loop to print the values of all elements of the a array:

printf("Using subscript
");
for (i = 0; i < COUNT; i++) {
    printf("%d
", (int) a[i]);
}

This first loop uses the array subscript operator and the index of the elements to access every array value. This is very similar to methods you've already seen. i will be incremented from 0 to 4, giving the array the indexes of the five elements.

One new, minor addition is that a[i] is type casted to an integer value to avoid problems on some systems.

8.
Add a second for loop to print all elements again using pointer arithmetic:

printf("Using pointer
");
for (i = 0; i < COUNT; i++) {
    printf("%d
", (int) *b);
   b++;
}

In this loop, instead of using the subscription operator (the square brackets), pointers will access each element. Using the dereferencing operator (*), the value *b points to the value stored in a particular memory block. The first time the loop runs, *b points to a[0]. This value is printed and then b is incremented, so that it points to the next array element (a[1]). This process continues through the entire loop.

Again, the dereferenced value (*b) is type casted to avoid problems.

9.
Complete the main function:

    getchar();
    return 0;
}

10.
Save the file as pointer7.c, compile, and debug as necessary.

11.
Run the application (Figure 9.14).

Figure 9.14. Array subscripting and pointer arithmetic—two ways to access all of an array's elements—yield the same results.


✓ Tip

  • You can, of course, do other kinds of calculations rather than using the increment operator ++ on a pointer variable. For example, constructs like *(b + 3) are valid. If b is again a pointer variable containing the base address of an array a, this expression would give you the value of a's fourth element. And in the first for loop example above, you could replace a[i] with *(b + i).


Address Arithmetic Using Different Types

There is an interesting point regarding address arithmetic and arrays: Incrementing the pointer by 1 to access the next element does not mean the same thing for different data types.

For example, in an array of chars and an array of ints, the elements typically use 1 byte for the chars and 4 bytes for the ints, as Figure 9.1 illustrates. Thus when the address value (remember: a big number) stored in an integer pointer variable is incremented to point to the next integer value in memory, the address is actually incremented by 4 bytes. When a char pointer variable is incremented, the address changes by 1 byte.

It's useful to know this distinction, but you don't have to worry about it yourself because the C compiler will always take care to use the appropriate increment value.


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

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