Discussions of pointers and arrays in C seem to be a holy war. On one side you have the people who say pointers are not arrays and that everybody must know that. On the other you have the people who say arrays are treated as pointers and so there shouldn’t be a distinction, it just confuses people. Turns out both sides are right.

Arrays are not pointers and pointers are not arrays. Pointers in C hold a single address in memory. Arrays are contiguous blocks of memory that hold multiple like kind objects. Check out my previous post on Memory Addresses in C for a deeper explanation. Where the confusion comes in is that, for the most part, arrays are treated like pointers in C.

Array Notation vs Pointer Notation

When we say that arrays are treated like pointers in C, we mean the following:

  1. The array variable holds the address of the first element in the array. It isn’t a pointer but it does act like a constant pointer that cannot be changed.
  2. Programs often interact with arrays using pointer notation instead of array notation.

Let’s look at some code:

We declare an int array with 5 ints and assign the array numbers variable to our int pointer, ptr1. The numbers variable holds the address of the first element in the array. Assigning it to ptr1 numbers is treated as an pointer. We then get the value of the first element in the array using array notation.

In the second example we get the address of the first element in the array using array notation and then we get the value of the first element by dereferencing the address of the of the first element in the array.

In the third example we use pointer math to assign the first address of the first element in the array and we dereference the same address to get the value.

Finally we print all of the addresses stored in the pointers and all of the int values at their addresses. Run that code and you should get similar output to this:

*ptr1 = 0x7fff6be1de60
*ptr2 = 0x7fff6be1de60
*ptr3 = 0x7fff6be1de60
val1 = 1
val2 = 1
val3 = 1

All of these notations are the same thing. Take a look at the following:

Run that code and you get the following:

numbers[0] = 1
numbers[1] = 2
numbers[2] = 3
numbers[3] = 4
numbers[4] = 5
*(numbers + 0) = 1
*(numbers + 1) = 2
*(numbers + 2) = 3
*(numbers + 3) = 4
*(numbers + 4) = 5
0, *ptr++ = 1
1, *ptr++ = 2
2, *ptr++ = 3
3, *ptr++ = 4
4, *ptr++ = 5

As you can see all produce the same output.

Array notation is pointer arithmetic. The C standard defines that numbers[0] is just syntactic sugar for *(numbers + 0). Anytime you write array notation such as numbers[2] the compiler switches that to *(numbers + 2), where numbers is the address of the first element in the array and + 2 increments the address through pointer math.

Array Variables

We have shown that arrays are often treated as pointers and that array notation is pointer math in the C compiler. Some people naturally make the assumption that since an array can be treated as a pointer that arrays can be assigned pointers. This is not true. Array variables cannot be changed. Let’s take a look at the following code:

This code will not compile. Try and you will get the following output:

incompatible types when assigning to type ‘int[5]’ from type ‘int *’
incompatible types when assigning to type ‘int[5]’ from type ‘int (*)[5]’
incompatible types when assigning to type ‘int[5]’ from type ‘int *’

Even though the array varible holds the address to the first element in the array, it acts like as a constant pointer in that it cannot be changed. It cannot be assigned a different array or a pointer to a different array. Think about it, if you have a variable A that points to an array and you were able to change the address of A to something else, what happens to the memory pointed to by the A array.

Now take a look at this code which will compile.

It produces the output:

numbers = 0x7fff5ea3d230
numbers2 = 0x7fff5ea3d250
ptr1 = 0x7fff5ea3d250
ptr2 = 0x7fff5ea3d250

Even though we can’t change the array variable directly, we can have a pointer to the array and then change that pointer. Here we create two arrays and two int pointers. We assign the numbers variable to ptr1 and numbers2 variable to ptr2. We then assign ptr2 to ptr1. Finally we print the output we can see that ptr1 and ptr2 are both pointing to the first element of the numbers2 array.

Conclusion

I hope you have enjoyed this overview of arrays and pointers in C. We haven’t covered everything there is to know about pointer and arrays but it should get you started. As always I am open to comments and suggestions.