In C, for any type T
, we can
form a corresponding type for variables that contain addresses in memory
where objects of type T
reside. One way to
look at variables like this is that they actually “point to” the
objects. Thus, these variables are called pointers.
Pointers are very important in C, but in many ways, they are a blessing
and a curse. On the one hand, they are a powerful means of building data
structures and precisely manipulating memory. On the other hand, they
are easy to misuse, and their misuse often leads to unpredictably buggy
software; thus, they come with a great deal of responsibility.
Considering this, it is no surprise that pointers embody what some
people love about C and what other people hate. Whatever the case, to
use C effectively, we must have a thorough understanding of them. This
chapter presents several topics on pointers and introduces several of
the techniques using pointers that are employed throughout this
book.
This chapter covers:
Including one of the best techniques for understanding pointers: drawing diagrams. Another fundamental aspect of pointer usage is learning how to avoid dangling pointers.
The process of reserving space in memory. Understanding pointers as they relate to storage allocation is especially important because pointers are a virtual carte blanche when it comes to accessing memory.
In C, aggregates are structures and arrays. Pointer arithmetic defines the rules by which calculations with pointers are performed. Pointers to structures are important in building data structures. Arrays and pointers in C use pointer arithmetic in the same way.
The means by which C simulates call-by-reference parameter passing. In C, it is also common to use pointers as an efficient means of passing arrays and large structures.
Pointers that point to other pointers instead of pointing to data. Pointers to pointers are particularly common as parameters to functions.
Mechanisms that bypass and override C’s type system. Generic pointers let us point to data without being concerned with its type for the moment. Casts allow us to override the type of a variable temporarily.
Pointers that point to executable code, or blocks of information needed to invoke executable code, instead of pointing to data. They are used to store and manage functions as if they were pieces of data.