14.5 Dereferencing Pointers

The main use of a pointer value is to dereference it (access the data it points at) with the unary ‘*’ operator. For instance, *&i is the value at i’s address—which is just i. The two expressions are equivalent, provided &i is valid.

A pointer-dereference expression whose type is data (not a function) is an lvalue.

Pointers become really useful when we store them somewhere and use them later. Here’s a simple example to illustrate the practice:

{
  int i;
  int *ptr;

  ptr = &i;

  i = 5;

  

  return *ptr;   /* Returns 5, fetched from i.  */
}

This shows how to declare the variable ptr as type int * (pointer to int), store a pointer value into it (pointing at i), and use it later to get the value of the object it points at (the value in i).

Here is another example of using a pointer to a variable.

/* Define global variable i.  */
int i = 2;

int
foo (void)
{
  /* Save global variable i’s address.  */
  int *global_i = &i;

  /* Declare local i, shadowing the global i.  */
  int i = 5;

  /* Print value of global i and value of local i.  */
  printf ("global i: %d\nlocal i: %d\n", *global_i, i);
  return i;
}

Of course, in a real program it would be much cleaner to use different names for these two variables, rather than calling both of them i. But it is hard to illustrate this syntaxtical point with clean code. If anyone can provide a useful example to illustrate this point with, that would be welcome.