Introduction to C Programming

Part 9: Introduction to Pointers in C

by Marshall Brain , brain@iftech.com
Interface Technologies, Inc.
(800) 224-4965, http://www.iftech.com, support@iftech.com
© Copyright 1995 by Marshall Brain. All rights reserved.
Version 2.0, 2/14/95
These tutorials are excerpted from the book "Motif Programming: The Essentials and More" , by Marshall Brain.

Pointers are used everywhere in C, and if you have a good understanding of them C should not pose a problem. If, however, you have never seen pointers before, or feel uncomfortable with them, you may want to read an extra book or two, or talk to someone who already understands them. C pointers are basically the same as Pascal pointers except they are used much more freely in C.

C uses pointers in three main ways. First, they are used to create dynamic data structures: data structures built up from blocks of memory allocated from the heap at run-time. This is the only visible way that Pascal uses pointers. Second, C uses pointers to handle variable parameters passed to functions. And third, pointers in C provide an alternative means of accessing information stored in arrays, which is especially valuable when you work with strings (see tutorial 13). There is an intimate link between arrays and pointers in C.

In many cases, C programmers use pointers because they make the code slightly more efficient. Sometimes, however, they simply seem to make the code harder to understand. Once you have mastered the three uses of pointers in C, however, you "know" C for all practical purposes.

Pointer Basics

A normal variable is a location in memory that can hold a value. For example, when you declare a variable i as an integer, four bytes of memory are set aside for it. In your program, you refer to that location in memory by the name i. At the machine level, that location has a memory address, at which the four bytes can hold one integer value.

A pointer is a variable that points to another variable. This means that it holds the memory address of another variable. Put another way, the pointer does not hold a value in the traditional sense; instead, it holds the address of another variable. It points to that other variable by holding its address.

Because a pointer holds an address rather than a value, it has two parts. The pointer itself holds the address. That address points to a value. There is the pointer and the value pointed to. This fact can be a little confusing until you get used to it.

The following example code shows a typical pointer:


#include <stdio.h> 

 

void main()  

{    

    int i,j;    

    int *p;   /* a pointer to an integer */ 

     p = &i;    

    *p=5;    

    j=i;    

    printf("%d %d %d\n",i,j,*p);  

} 

The line int *p declares a pointer. It asks the compiler to declare a variable p that is a pointer to an integer. The * indicates that a pointer is being declared rather than a normal variable. You can create a pointer to anything: a float, a structure, a char, and so on.

The line p = &i; will definitely be new to you. In C, & is called the address operator. The expression &i means ``the memory address of the variable i ." Thus, the expression p = &i; means "Assign to p the address of i." Once you execute this statement, p points to i. Before you do so, p contains a random, unknown address, and its use will likely cause a segmentation fault.

After the line p = &I;, p points to I. Once p points to i, the memory location i has two names. It is still known as i, but now it is known as *p as well. This is how C talks about the two parts of a pointer variable: p is the location holding the address, while *p is the location pointed to by that address. Therefore *p=5 means that the location pointed to by p should be set to 5. Because this location is also i, i also takes on the value 5. Consequently, j=i; sets j to 5, and the printf statement produces 5 5 5.

Try the following:


#include <stdio.h> 

 

void main()  

{    

    int i,j;    

    int *p;   /* a pointer to an integer */ 

     printf("%d %d\n",p,&i);    

    p = &i;    

    printf("%d %d\n",p,&i);  

} 

This code tells the compiler to print out the address held in p, along with the address of i. The variable p starts off with some crazy value or with 0. The address of i is generally a large value. For example, when I ran this code, I received the following output:


0   2147478276 

2147478276   2147478276 

which means that the address of i is 2147478276. Once the statement p = &i; has been executed, p contains the address of i. Try this as well:


#include <stdio.h> 

  

void main()  

{    

    int *p;   /* a pointer to an integer */ 

    

    printf("%d\n",*p);  

} 

This code tells the compiler to print the value p points to. However, p has not been initialized yet; it contains the address 0. A segmentation fault results, which means that you have used a pointer that points to an invalid area of memory. Almost always, an uninitialized pointer or a bad pointer address is the cause of segmentation faults.