Like any variable, a pointer variable must be declared before it is used, and its value can change in the course of a program. A pointer variable can have any legal variable name. Here is the pointer declaration from POINTER.C:
int *ptr;
This declaration states the program has a pointer variable named ptr that can point to a data object of the int type.
Notice the similarity to a simple variable declaration. As in other cases, the declaration gives a type (int) and name (ptr) for the variable.
The indirection operator (*) in front of the name ptr shows this variable is a pointer. This operator has two different uses in C. In declarations, such as the one above, it simply means “this is a pointer.” In other contexts, as we'll elaborate throughout this chapter, it means indirection—using the data object that a pointer points to.
Summary: A pointer declaration shows what type of data object a pointer references.
A pointer doesn't have a type in the same sense as other variables. When you declare a simple variable, the type specifier shows what type of value the variable stores. When you declare a pointer variable, the type specifier shows what type of data object the pointer points to.
Thus, in POINTER.C the declaration of the variable val indicates val stores a value of the type int,
int val = 25;
while the declaration of the variable ptr indicates it points to a data object of the type int:
int *ptr;
To declare pointers to other types of variables, you can use whatever type specifier is appropriate. These statements, for instance, declare pointers to char and float variables:
char *c_ptr, *ch;
float *f_pointer;
Note that if you declare more than one pointer variable in the same line, each name must be preceded by the indirection operator. The first line in the previous example declares two pointer variables: c_ptr and ch. Each pointer can point to an object of the char type. If you omit the second indirection operator from the first line,
char *c_ptr, ch;
the line declares a pointer variable named c_ptr and an ordinary char variable named ch.
Summary: A pointer declared with type void can point to any type of data object.
In most cases a pointer points to a particular type of object, such as an int. You can also declare a pointer with type void, which allows it to point to any type of object.
One use of void pointers is to write a general-purpose function, such as a sort, that can operate on data of more than one type. Each time you use a void pointer, you must perform an explicit type cast to show what type of object it points to on that occasion.
Figure 8.1 shows the relationship between val and ptr in POINTER.C, immediately after ptr has been declared. The figure shows that the variable val is stored at memory location 5308, as in the output shown above. Again, the actual address may differ when you run POINTER.C.
Figure 8.1 uses question marks to show that the contents of ptr are undefined at this stage in the program. Like any other variable that has been declared but not initialized, the contents of ptr are unknown. You must take special care not to use pointers that have not been initialized, since an uninitialized pointer might point anywhere in memory—including sensitive operating-system addresses.
WARNING:
Because a pointer can potentially access any memory address, using an uninitialized pointer can have drastic consequences.