Using Pointers with Arrays

Arrays and pointers are intimately linked in C. To use arrays effectively, you have to know how to use pointers with them. Fully understanding the relationship between the two probably requires several days of study and experimentation, but it is well worth the effort.

Let's start with a simple example of arrays in C:

#define MAX 10

int main()
{
    int a[MAX];
    int b[MAX];
    int i;
    for(i=0; i<MAX; i++)
        a[i]=i;
    b=a;
    return 0;
}

Enter this code and try to compile it. You will find that C will not compile it. If you want to copy a into b, you have to enter something like the following instead:

for (i=0; i<MAX; i++)
    b[i]=a[i];

Or, to put it more succinctly:

for (i=0; i<MAX; b[i]=a[i], i++);

Better yet, use the memcpy utility in string.h.

Arrays in C are unusual in that variables a and b are not, technically, arrays themselves. Instead they are permanent pointers to arrays. a and b permanently point to the first elements of their respective arrays -- they hold the addresses of a[0] and b[0] respectively. Since they are permanent pointers you cannot change their addresses. The statement a=b; therefore does not work.

Because a and b are pointers, you can do several interesting things with pointers and arrays. For example, the following code works:

#define MAX 10

void main()
{
    int a[MAX];
    int i;
    int *p;

    p=a;
    for(i=0; i<MAX; i++)
        a[i]=i;
    printf("%d\n",*p);
}

The state of the variables right before the for loop starts executing.

HowStuffWorks.com

The statement p=a; works because a is a pointer. Technically, a points to the address of the 0th element of the actual array. This element is an integer, so a is a pointer to a single integer. Therefore, declaring p as a pointer to an integer and setting it equal to a works. Another way to say exactly the same thing would be to replace p=a; with p=&a[0];. Since a contains the address of a[0], a and &a[0] mean the same thing.

Now that p is pointing at the 0th element of a, you can do some rather strange things with it. The a variable is a permanent pointer and can not be changed, but p is not subject to such restrictions. C actually encourages you to move it around using pointer arithmetic . For example, if you say p++;, the compiler knows that p points to an integer, so this statement increments p the appropriate number of bytes to move it to the next element of the array. If p were pointing to an array of 100-byte-long structures, p++; would move p over by 100 bytes. C takes care of the details of element size.

You can copy the array a into b using pointers as well. The following code can replace (for i=0; i<MAX; a[i]=b[i], i++); :

p=a;
q=b;
for (i=0; i<MAX; i++)
{
    *q = *p;
    q++;
    p++;
}

You can abbreviate this code as follows:

p=a;
q=b;
for (i=0; i<MAX; i++)
    *q++ = *p++;

And you can further abbreviate it to:

for (p=a,q=b,i=0; i<MAX; *q++ = *p++, i++);

What if you go beyond the end of the array a or b with the pointers p or q? C does not care -- it blithely goes along incrementing p and q, copying away over other variables with abandon. You need to be careful when indexing into arrays in C, because C assumes that you know what you are doing.

You can pass an array such as a or b to a function in two different ways. Imagine a function dump that accepts an array of integers as a parameter and prints the contents of the array to stdout. There are two ways to code dump:

void dump(int a[],int nia)
{
    int i;
     for (i=0; i<nia; i++)
        printf("%d\n",a[i]);
}

or:

void dump(int *p,int nia)
{
    int i;
     for (i=0; i<nia; i++)
        printf("%d\n",*p++);
}

The nia (number_in_array) variable is required so that the size of the array is known. Note that only a pointer to the array, rather than the contents of the array, is passed to the function. Also note that C functions can accept variable-size arrays as parameters.