Tutorial - Pointers in C

Main Page
Helpful Links
Downloads
Tutorials
Grades
Syllabus
Contact Me

This lesson, we start to seriously cover the use of pointers.  We do this so that we can learn to write functions that can modify variables passed to them (albeit indirectly).  Of course, there's far more to do with pointers, which we'll get into in later lessons.  Study them well, because pointers will be crucial to most C topics from here on out.

Understanding Pointers

   As you'll recall, pointers are a type of variable that hold the address of a position in memory.  Pointers are declared with a type.  This is only important so the pointer knows the size of the data it points to.

Declaration

   Pointers are declared like this:

int* pInt;     // declare a pointer to an int
char* pInitial;     // declare a pointer to a char
double* pAverage;     // declare a pointer to a double

   This should not be confused with multiplication, which also uses the asterisk (*).  Here, it's being used to declare a pointer variable.  The context is totally different, so there's never any confusion.
   Remember that like all variables, when a pointer variable is first declared, it's value is garbage.  It must be initialized to something meaningful.

The & (Address-Of) Operator

   We can use the & operator to retreive the address of a variable.  For example:

int x;     // declare an integer
int* ptox;     // declare a pointer to an integer
ptox = &x;     // assign the address of x to ptox

   After we do this, ptox holds the address in memory of x.  Think of & as returning a pointer.

The Indirection Operator (* yet again)

   Now, we need a way to manipulate the memory a pointer addresses using just the pointer.  We do this by using the indirection operator, *.  When applied to a pointer, * causes our operations to affect the memory the pointer addresses rather than the pointer itself.  Here's an example:

int x = 5;     // declare x and initialize it
int* ptox = &x;     // declare ptox and initialize it to point to x

printf("%d", *ptox);     // prints out 5

*ptox = 6;     // sets x to 6

printf("%d", x);  // prints out 6

   So using the indirection operator (*), we can read from and write to the memory a pointer addresses.  Again, don't confuse this use of * with multiplication or pointer declaration.  The context is totally different, so it shouldn't be a problem.


Putting It All Together With Functions

   Now, we have the tools we need to write functions that can modify variables.  Suppose we have a program where we want to write a function to increment an integer.  Lets call it x:

int x = 0;

   This function definition would be wrong:

void increment( int var ){
   var = var + 1;
}

   Calling increment(x) will not increment or even affect x.  This is because arguments to functions are copies.  The value of x is passed, modified, and discarded, and x is unchanged.
   To make a function that can modify a variable, we have to apply what we've learned about pointers.  Here's a correct version:

void increment( int* pvar )     // pass the address of an integer variable
{
   *pvar = *pvar + 1;     // use indirection to read and modify the variable's memory
}

   And we would call it like this:

increment(&x);     // pass the address of x

   We don't pass x, but the address of x.  This should give some insight into why scanf requires the addresses of variables rather than the variables themselves.  There's no way it could modify them without their addresses.

A Note on Style

   You'll notice that everytime I've declared a pointer variable above, I've made the first letter of the name a p.  This isn't necessary, but it's a possible stylistic choice, to make it easy to quickly identify that a variable is a pointer.
   It's often helpful in programming projects, especially when working with a team, to make use of a consistant style, including naming conventions.  One popular style is called Hungarian Notation.  In it, all variables are given a set of prefixes to clarify what they are.  It has its criticisms, but is often encountered when dealing with Microsoft code.