Pointers

A pointer variable stores a single memory address and the data type found at that memory address. The * is used to indicate that a pointer variable is being declared. The are three parts to a pointer variable declaration:

  • The data type
  • The *
  • The variable name

    The statement

    int *pEmployeeNumber;

    defines a variable named pEmployeeNumber that stores the memory address of an integer. In C lingo, pEmployeeNumber is an integer pointer.

    Address  |  Assignment  |  Structures and Pointers  |  Arrays and Pointers

    Address

    A pointer variable stores one and only one memory address. A pointer variable also 'knows' the type of the variable to which it points.

    Here's some code that defines an integer pointer variable, assigns the memory address of an integer to the integer pointer variable using the & operator, and prints the address contained in the integer pointer variable.

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      int   EmployeeNumber;
      int *pEmployeeNumber;
    
      pEmployeeNumber = &EmployeeNumber;
      printf("The value of pEmployeeNumber is: %x\n", pEmployeeNumber);
      return 0;
    }
    
    Top

    Assignment

    To assign a value to EmployeeNumber, the dereferencing operator * is used. But wait, isn't the * used to define a pointer? Yes it is, but don't let that confuse you, typically it is not difficult to tell the difference between a declaration and a dereferencing.

    It would seem that the obvious way to assign a value to EmployeeNubmer would be with a statement like EmployeeNumber = 123;. Well, certainly that would work, but the point here is to demonstrate how pointers work. That doesn't mean you should go and define pointers and use them just to prove your mastery of the topic. Only use pointers as needed. Here's some code that displays the address stored in pEmployeeNumber, sets EmployeeNumber to 309 by dereferencing pEmployeeNumber, and displays the value of EmployeeNumber by dereferencing pEmployeeNumber.

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      int   EmployeeNumber;
      int *pEmployeeNumber;
    
      pEmployeeNumber = &EmployeeNumber;
      printf("The value of pEmployeeNumber is: %x\n", pEmployeeNumber);
      *pEmployeeNumber = 309;
      printf("The value of EmployeeNumber is: %d\n", *pEmployeeNumber);
      return 0;
    }
    
    Top

    Structures and Pointers

    When using a pointer to a structure, pointer notation must be used instead of the dot notation seen in the Structures topic. This program is the same as the first program in the Structures topic, except that a pointer to structure OnePoint is declared and initialized, then it uses pointer notation instead of dot notation.

    #include <stdio.h>
    
    struct Point
    {
      int  x;
      int  y;
      char OneCharacter;
    };
    
    int main(int argc, char *argv[])
    {
      int x;
      int y;
      struct Point OnePoint;
      struct Point *pPoint;
    
      pPoint = &OnePoint;
      pPoint->x = 37;
      pPoint->y = 21;
      pPoint->OneCharacter = 'g';
    
      x = pPoint->x;
      y = pPoint->y;
      printf("x is %d     y is %d\n", x, y);
      printf("and the character is %c\n", pPoint->OneCharacter);
    
      return 0;
    }
    
    Top

    Arrays and Pointers

    "In C, there is a strong relationship between pointers and arrays, strong enough that pointers and arrays should be discussed simultaneously. Any operation that can be achieved by array subscripting can also be done with pointers. The pointer version will in general be faster but, at least to the uninitiated, somewhat harder to understand." Quoted from The C programming Language by Brian W. Kernighan and Dennis M. Ritchie section 5.3

    Some plain code to demonstrate the above statement. A simple array of 3 integers is defined, loaded, and printed first using the array notation, then using pointer notation.

    Array notation

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      int   EmployeeNumber[3];
      int   Index;
    
      Index = 0;
      EmployeeNumber[Index] = 473;
      Index++;
      EmployeeNumber[Index] = 1001;
      Index++;
      EmployeeNumber[Index] = 25;
    
      for (Index = 0; Index < 3; Index++)
      {
        printf("Index is: %d and Employee Number is %d\n", Index, EmployeeNumber[Index]);
      }
    
      return 0;
    

    Pointer notation

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      int   EmployeeNumber[3];
      int *pEmployeeNumber;
    
      pEmployeeNumber = EmployeeNumber;
      *pEmployeeNumber = 473;
      pEmployeeNumber++;
      *pEmployeeNumber = 1001;
      pEmployeeNumber++;
      *pEmployeeNumber = 25;
    
      for (pEmployeeNumber = EmployeeNumber; pEmployeeNumber < EmployeeNumber+3; pEmployeeNumber++)
      {
        printf("pEmployeeNumber is: %x and Employee Number is %d\n", pEmployeeNumber, *pEmployeeNumber);
      }
    
      return 0;
    }
    

    "The correspondence between indexing and pointer arithmetic is very close. By definition, the value of a variable or expression of type array is the address of element zero of the array." Quoted from The C programming Language by Brian W. Kernighan and Dennis M. Ritchie section 5.3

    So referring to EmployeeNumber (highlighted in the statements above) is the same as referring to &EmployeeNumber[0] which is the memory address of the EmployeeNumber array.

    Notice that the value of pEmployeeNumber advances by 4 bytes(on most PCs anyway) each time it is incremented using pEmployeeNumber++. This is because the data type referenced by pEmployeeNumber is integer and therefore C understands EmployeeNumber++ to mean increment pEmployeeNumber by the size of type integer which is 4 bytes.

    If the size of a character variable is 1 byte, then a character pointer will advance by 1 byte when incremented.

    If the size of a double variable is 8 bytes, then a double pointer will advance by 8 bytes when incremented.

    Top