Storing and Retrieving Addresses in Pointer Variables

The previous example just used the addresses of the variables in the printf() function. Now you'll look at how to store these addresses in other variables.

As mentioned earlier, an address is really just a big number. However, you should not treat an address as a regular number and store it in an int or long variable. If you try to do this, the C compiler will complain and emit a warning message (Figure 9.4).

Figure 9.4. Addresses should not be stored in regular integer variables.


Instead of using the regular numeric variable types to hold addresses, C requires you to store them in a special type of variable called a pointer variable. They're called pointer variables because an address points to a piece of data.

A pointer variable can only be used to store addresses of a particular type of data. That is, an integer pointer variable can store the address of an integer, a char pointer variable can store the address of a char, and so on. You cannot store the address of an integer in a pointer variable that was defined to hold the address of a char. Again, if you do this, the program will still compile, but the compiler will issue a warning message, and you should fix the mix-up (Figure 9.5).

Figure 9.5. A pointer's type must match the type of variable to which it refers.


Type Safety

You might wonder why C does not allow you to store addresses of different types in the same pointer variable. After all, the addresses of objects in memory are all of the same size, so there is no technical difference between a pointer to an integer and a pointer to a char.

The reason is that explicitly giving a pointer a type allows the compiler to catch programmer mistakes. If the programmer stores the address of a char in a pointer variable that is defined to hold the address of an integer, it is highly likely that later on in the program, that stored address will be accessed as an integer, which will produce incorrect results or even crash the program.

If such an address assignment between different types is indeed the right thing to do, there's a special notation called a type cast that allows the programmer to indicate to the compiler explicitly that the conversion of pointers is correct and not a mistake. Type casting will be used in a couple of places to ensure that a pointer is of the right type.


To define pointer variables, you combine the variable types like int, char, and float with the asterisk:

int *x;

This creates a pointer variable that can hold the address of an integer variable. Defining pointer variables for other types of addresses works in a similar way:

unsigned long *x;
char *y;
float *z;

To work with the pointer variable's value, which is the address stored in the variable, you leave off the asterisk. You do that when you want to store a new value (address) into the pointer variable, as well as when you want to read out the currently stored address:

int a; // Integer
int *x; // Integer pointer
x = &a; /* x stores the address where the a variable data can be found. */
printf("Address of a: %p", x);

Our next example will better demonstrate the use of pointer variables.

To store addresses in pointer variables

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

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

/* pointer2.c - Script 9.2 */
#include <stdio.h>

Script 9.2. This application stores variable addresses in pointers.


3.
Begin the main function:

int main (void) {

4.
Define and initialize one int and one char variable:

int a = 456;
char b = 'J';

As with the previous example, these variables are for demonstration purposes, with no specific meaning.

5.
Define and initialize one int and one char pointer variable:

int  *x;
char *y;

The x variable will be a pointer used in conjunction with the integer a. The second pointer, y, is for storing b's address. Each pointer matches the type of variable it will point to.

6.
Store the addresses of the two variables in the pointer variable of the corresponding type:

x = &a;
y = &b;

To assign the address to a pointer, refer to the variable while using the address-of operator. The x pointer now stores the address in memory where a's value (456) is being stored. Similarly, y contains the address in memory where b's value (J) is stored.

7.
Print the addresses of the variables:

printf("Address of a: %p
", &a);
printf("Address of a: %p
", x);
printf("Address of b: %p
", &b);
printf("Address of b: %p
", y);

These lines demonstrate the two ways of accessing a variable's address. First, each is printed using the variable name and the address-of operator. Then, each address is printed by using the pointer. The %p signifier is used within printf() to properly print a pointer value.

8.
Complete the main function:

    getchar();
    return 0;
}

9.
Save the file as pointer2.c, compile, and debug as necessary.

10.
Run the application (Figure 9.6).

Figure 9.6. The addresses returned by the address-of operator and the ones stored in the pointer variables are identical.


The application now stores and retrieves the addresses using pointer variables.

✓ Tip

  • A program will probably still compile (depending on the compiler settings) and the program might run if you inadvertently mismatch the type of a pointer to its addressed variable. But compiler warnings are there for a reason and ignoring them is considered sloppy style, possibly leading to incorrect behavior and crashes during program execution.


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

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