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.
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 2147478276which 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.