Programming In C: Arrays With Pointers

This article is part of a series – How to Program Anything: C Programming

Preface

In previuos articles (here, and here) we’ve discussed pointers and arrays.  In each article we discussed them generally separately, but in the C programming language arrays and pointers are actually commonly linked together.  This is because each piece of functionality offers a different way to look at much the same thing.  In this respect you can kind of view pointers and arrays as perspectives of the same subject: contiguous elements in memory.  As you hopefully recall, when an array is declared in C a continuous piece of memory is allocated and set aside for it.  If there are 12 elements in the array, then 12 chunks of memory all next to each other, each following the last, is set up and set aside in the program.  As you hopefully also recall, when you increment a pointer you access the next spot in memory equal to the size of the base type of the array.  From these two facts you can see how pointers and arrays are related.

Arrays And Pointers

Let’s say we specify a 10 element int array like so:

We can generate a pointer to the first element of the array by simply specifying the name of the array without an index.

This is equivalent to writing:

And in fact both are valid C programming, however, you will almost never see the second form in practice.  This is because it is clumsy to write, and involves more characters, which increases the chance of error.

This is possible because you can think of an array by itself, without indexing, as simply a pointer to the first element of the array.  In fact, the act of indexing could be considered shorthand for actual pointer arithmetic done “behind the scenes”.  For example, when you access myArray[3] you are in essence accessing the third int value in a series of int values.  In this way, if you had a pointer to the first element of the array, and then added 3 to it (pointer arithmetic) you would access the same address of memory as when you indexed myArray[3].  Remember that incrementing a pointer makes it point to the next memory address relative to its base type.  To make this more clear, see the diagram below:

In this example myArray[2] is equivalent to *(myPtr+2).  Remember that a pointer increments relative to it’s base data type, in this case an int.  So adding 2 to myPtr causes it to point two ints ahead in memory, likewise when you access myArray[2] you are accessing the third int stored in contiguous memory of the array.  These are two ways to access the same value in memory.  In fact it gets weirder…

Once you have a pointer of a base type same as your array and assign it to the address of the first element of the array as we did in the code block above, you can actually use the index mechanism on the pointer itself as if it was an array itself.  I think a piece of code may illustrate this further:

So, like above in the diagram, you can think of the index mechanism (myArray[#]) as short hand for *(myArrayPointer+#)

Multi-dimensional arrays are the same.  When C creates a multidimensional array, it essentially lays out each row one after another in memory, so the last element of row 1 is right next to the first element of row 2, and so on.  You can still use pointer arithmetic to access these arrays.  The shorthand simply grows a bit to accomodate the extra dimension:

Of course as you add more dimensions the more confusing and convoluted it gets, so we’ll stop at two dimensions.

The point of this is that arrays are simply sequences of values lined up one after the other in memory.  Because pointers and their arithmetic operate in the same fashion, adding one to a pointer jumps it to the next address of its base type in memory, they offer an alternative way to access arrays.

Array As Base Type of Pointer

It is possible to cause a pointer’s base type to actually be an array.  In this sense, if the pointer’s base type is of length 10, then each time we increment the pointer it will jump 10 elements ahead in memory.  This is done with a subtle change in our pointer declaration:

This is a multi-dimensional array pointer, meaning that at its base it points to each row of an array.  It is indexable just like you would index a two-dimensional array.  But if you perform pointer arithmetic on it, instead of jumping the size of one char in memory, it’ll jump the size of 10 chars in memory.  You can add more dimensions after the 10 to create even further arrays inside of arrays.  This is type of pointer is an example of how you could set up a pointer to deal with a multidimensional array.

The key here is that indexing the pointer as above still operates correctly as this code snippet demonstrates:

You can see then how you might define a pointer that is going to access a multi-dimensional array in the same fashion as the original array.  You can choose to access a multi-dimensional array with a straight up single dimension pointer as above, or use a multi-dimension pointer as demonstrated here.

Conclusion

Pointers and arrays are closely related in C.  Using indexes and pointers to access the contents of an array are simply two sides to the same coin.  They offer two perspectives that aim towards the same goal.  With pointer arithmetic (which we covered in the article on pointers), you can access each element in the array one after another or randomly.  With array indexing you can specify a short hand number that is easier to understand and read but does the same thing. This is possible because arrays are laid out in memory in one continuous block of data.  Using pointer arithmetic to access arrays is often employed in many professional C programs as a way to boost performance and as a way to work with data structures in more generic ways.

NOTE: The C compiler doesn’t check to see if your pointers or array indexes are actually valid.  It is a perfectly valid C program that may index outside of an array’s size, or move a pointer outside of an existing array.  This will cause unknown behavior and write or read from random spots in memory.  This can often cause disastrous results.  It is up to the programmer to make sure all his pointers and arrays are bound to their appropriate size before reading or writing data.

This article is part of a series – How to Program Anything: C Programming

If you appreciate this article you might consider supporting my Patreon.

But if a monthly commitment is a bit much, I get it, you might consider buying me a coffee.

photo credit: Owen Signalman Lowestoft via photopin (license)

kadar

I'm just a wunk, trying to enjoy life. I am a cofounder of http//originalpursuitssoc.com/ and I like computers, code, creativity, and friends.

You may also like...

1 Response

  1. October 16, 2017

    […] studied arrays extensively when we studied them with strings, and with pointers.  However, we only really touched upon the fact that the square brackets are operators in the […]

Leave a Reply

%d bloggers like this: