1. | Welcome | ToC | FAQ | Resources | Courses | Projects | Mail Lists | Members | Misc |
2. | Fundamentals | Languages | Tools | Net | Core | Advanced |
3. | EoC | Java |
4. | Lessons |
5. | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |


Essence of C
5 - POINTERS

Pointers, Pointer Operators, Pointer Expressions, Pointers and Arrays, Multiple Indirection, Pointer to Functions

A pointer is a variable which holds a memory address, that address usually being the address of another variable. Pointers provide the means by which functions may modify their calling parameters. They also support C's dynamic allocation functions and improve the efficiency of certain routines.

If a variable is going to hold a pointer, it must be declared as such. The general form of declaration is:

type *name;

where type is any valid C data type and name is the name of the pointer variable. The base type defines what type of variables the pointer can point to. All pointer arithmetic is done relative to the base type.

Pointer Operators

The & Operator

The & operator is a unary operator (ie, an operator which requires only one operand) which returns the memory address of the operand. For example:

 

    m = &count;

places the memory address of count into m.


The * Operator

The * operator is the complement of & in that it returns the value of the variable at the address which follows. For example:

 

    q = *m;

places the value of count into q.

Pointer Expressions

Pointer Assignments

As with any variable, a pointer may be used on the right side of an assignment operator to assign its value to another pointer.


Pointer Arithmetic

The only arithmetic operations which may be used on pointers are addition and subtraction. When, say, an int pointer is incremented (eg, p++;), the address held by the pointer will be incremented by four, not by 1, the reason being that integers are (normally) four bytes long. That is, pointers are incremented and decremented relative to the length of their base type.

Arithmetic operations are not limited to the increment and decrement operators. Integers may be added to, or subtracted from, pointers, as in:

 

    p = p + 12;


Pointer Comparisons

Pointers may be compared in a relational expression, as in:

 

    if(p < q)
   printf("p points to lower memory than q");

Pointers and Arrays

C provides two methods for accessing array elements, namely, array indexing and pointer arithmetic. Pointer arithmetic can be faster than array indexing.

In the following, p is set to point to the first element of str:

 

    char str[80], *p;
    p = str;

Two ways to access the fifth element of str are as follows:

 

    str[4]; // Array indexing.
    *(p+4); // Pointer arithmetic.

The following examples illustrate the two methods:

    // Index s as an Array

    void puts(char *s)
    {
      register int t;

      for(t=0;s[t];t++) }
        putchar(s[t]);
    }

    // Access s as a Pointer

    void puts(char *s)
    {
      while(*s)
        putchar(*s++);
    }

Most professional C programmers would find the second method easier to read and understand.


Arrays of Pointers

Pointers may be arrayed like any other data type, e.g.:

 

    int *x[10];

Assigning the address of an int variable to the third element of this pointer array is achieved by:

 

    x[2] = &var;

Finding the value of var is achieved by:

 

    a = *x[2];

An array of pointers may be passed to a function using the same method used to pass other arrays, i.e., by calling the function with the array name without any indexes, as in:

 

    void display_array(int *q[])
    {
      int t;

      for(t=0;t<10;t++)
        printf("%d ",*q[t]);
    }

in which q is not a pointer to integers but to an array of pointers to integers.

Pointer arrays are often used to hold pointers to strings, as in:

 

    void syntax_error(int num)
    {
      static char *err[] =
      {
        "Cannot open file\n",
        "Read error\n",
        "Write error\n",
      }
      printf("%s", err[num]);
    }

Multiple Indirection

Multiple indirection is where a pointer points to another pointer that points to a target value. A variable which is a pointer to a pointer must be declared as such, as in:

 

    float **balance;

Initializing Pointers

Before a pointer is assigned a value, it contains an unknown value. If used in this state, it could crash the operating system. The value null should be assigned to a pointer that points nowhere.

As previously illustrated, strings may be initialized as follows:

 

    char *p = "hello world\n";

The reason this sort of initialization works is because of the way the compiler operates. All C compilers create what is known as a string table. Therefore, the above declaration places the address of "hello world", as stored in the string table, into p. p can then be used like any other string, as in:

 

    printf(p);

Pointers to Functions

Even though a function is not a variable, it has a location in memory which may be assigned to a pointer. A variable which is a pointer to a function must be declared as such, as in:

 

    int (*p)();

The address of a function is assigned to this variable by using the function's name without parentheses or arguments, e.g.:

 

    p = function_name;

C's Dynamic Allocation Functions

Global variables are allocated storage at compile time and local variables use the stack. Neither can be added during program execution. Dynamic allocation is the means by which a program can obtain memory during execution. The core of the dynamic allocation system consists of the functions malloc() (allocates memory from the heap) and free() (frees that memory). malloc() returns a pointer to the first byte of the allocated memory.

Pointers provide the necessary support for C's dynamic allocation system.

The dynamic allocation system supports linked lists, binary trees and dynamically allocated arrays.

Dynamically Allocated Arrays and Pointers

Memory may be allocated using malloc() and operated on as if it were an array. Such &quotarrays"are known as dynamically allocated arrays . Since any pointer may be indexed as if it were a single-dimension array, the pointer returned by the malloc() function may be indexed in the normal way.

Multi-dimensional arrays, however, pose a problem. Since the dimensions have not been defined in the program, a trick must be used: The pointer is passed as a parameter to a function, which allows the function to define the dimensions of the parameter receiving the pointer, e.g.:

 

    p = malloc(40*sizeof(int));
    table(p);
    ...
    void table(int p[4][10]) // now the compiler has an array to work with
    {
      ...
    }

Prior Chapter · Index · Next Chapter


Copyright © 1996, 1997, 1998. Last Update to This Page: 1998/10/24
This Page Maintained by: radar pangaean * * * Original Author: K.J.Bricknell
The MOST web site is built and maintained by the voluntary efforts/donations of our members.