Welcome to another C Tutorial! This time we’re going to delve into arrays in C programming.
Arrays are important features in many programs. They enable you to store several items of related information in a convenient way. They’re good for collecting data, pin numbers (i.e. for Arduino), storing variables and more.
Let’s start by talking about what an array in C actually is.
Intro to Arrays in C Programming
What is an array?
People use computers for tasks such as tracking monthly expenses, daily rainfall, quarterly sales, and weekly weights. Businesses use computers to manage payrolls, inventory, and customer transactions. When you write a program, you may have to deal with large quantities of related data. Often, arrays offer the best way to handle such data in an efficient, convenient manner.
Arrays are data structures consisting of related data items of the same type. In other words, an array is a series of values of the same type, such as 10 chars or 15 ints stored sequentially in memory.
The whole array bears a single name, and you access the individual items, or elements, by using an integer index (a.k.a. subscript).
For example
int geeks[25];
tells us that geeks is an array of 25 elements which hold integers.
Arrays in C: Some Pitfalls
So, we now know that an array is a sequential block of memory which holds things like integers and floats. That’s great, but there are some common pitfalls people (including me) often fall prey to.
First, we need to be sure we stay within the boundaries of our array. What do I mean?
Become the Maker you were born to be. Try Arduino Academy for FREE!
Let’s say we want to call up and use one of the values in the array geeks[ ] from earlier.
To do that, we may say something like
printf(geeks[24]);
which prints the last element of that array.
However, if we were to write
printf(geeks[25]);
instead, who knows what we’ll get. In the interest of speed of execution, C doesn’t check to see whether you use a correct subscript. The compiler doesn’t look for such errors. When the program runs, this statement would place data in a location possibly used for other data, potentially corrupting the output of the program or even causing it to abort.
But wait, is that a typo? Shouldn’t writing
printf(geeks[25]);
print the last element?
The answer is no, and you’ll see why in a minute…
Another pitfall is that while an array can be of any data type, we must stick with the same data type once we declare the array.
For example, if our program tries to assign the value Pi to any element in the geeks[ ] array, as in the following, it wouldn’t work
geeks[13] = 3.14;
because we’re trying to set the 14th element of the array to Pi (again, that’s not a typo, it’s the 14th element. More on this in a sec), but the array can only hold integers.
The numbers used to identify the array elements are called subscripts, indices, or offsets. From now on, we’ll just refer to them as indices. These indices must be integers, and, as we now know, the compiler stores them next to each other (sequentially) in memory. But there’s a catch.
The numbering of array indices starts with 0, not 1.
That’s why
geeks[13];
refers to the 14th element.
If we want to refer to the first element, we need to write
geeks[0];
because an array index starts with 0 and this is the first element of the geeks[ ] array.
This catches many, many folks (me too) and causes what programmers call off-by-one errors. Worse yet, the compiler won’t check for off-by-one errors, so incorrectly referring to an array element can cause strange logic errors that can be tough to crack.
This is perhaps one of the most confusing and troublesome things about arrays, at least for C programming newbies.
For clarification, have a gander at figure 1.
Figure 1: array elements vs array indices. Here we have a 6 integer array named Num[ ] with consecutive numbers in it. Notice how we need to reference index position 2 though if we want to refer to element 3 of the array – Num[2], indeed is 3.
Figure 1 sports and array called Num with six elements which are simply the numbers 1-6. Note that since the index of the array starts at 0, we need to use an index of 2 to refer to the third element, which is the number 3. In other words, if I want to use the third element of Num in some calculation, I need to refer to Num[2].
Writing Num[3] instead produces an off-by-one error the compiler will not catch. This probably will fubar the calculation.
Don’t let the fact that the numbers in Num[ ] are consecutive confuse you, it doesn’t matter what their value is. If we put 45 into element three and need to reference it, the above still holds true. Only this time Num[2] == 45.
Declaring and Initializing Arrays in C
Declaring an array tells the compiler how many elements the array contains and what the data type is for the elements. Below are some examples.
float freezing[32]; //an array of 32 floats char broil[100]; //an array of 100 characters int dollars[1000]; //an array of 1000 integers
The brackets identify freezing, broil, and dollars as arrays, and the number enclosed in the brackets indicates the number of elements in the array during declaration.
And, as we now know, to access elements in an array, you identify an individual element by using its index or subscript. The numbering starts with 0 (sorry to beat this to death but it’s really important).
You can also pre-load an array with values if you know ahead of time what they’ll be. For example, the statement below
int lottery[6] = {15, 29, 7, 22, 31, 19};
declares an array of integers called lottery with 6 elements. We specify what the elements are in the curly braces.
Of course, if you know the winning lottery numbers ahead of time, you should stop reading this and go buy a ticket.
Sometimes you may want the array to be read-only. In this case, you can, and should, use the const keyword when you declare and initialize the array. Below is our lottery example with this method.
const int lottery[6] = {15, 29, 7, 22, 31, 19};
Perhaps you want to play the same lottery numbers every time and don’t want them to change…
Some Caveats with Initializing Arrays
When initializing an array, the number of items in the list should match the size of the array.
But what if it doesn’t?
Let’s use our lottery example again and pretend that we forgot to initialize the last value.
int lottery[6] = {15, 29, 7, 22, 31};
If we were to print the data in lottery[ ] we’d get 15, 29, 7, 22, 31, 0 on our screen.
If you partially initialize an array, the remaining elements are set to 0.
Note that you can let the compiler match the array size to the list by omitting the size from the brackets. So, something like
int lottery[] = {15, 29, 7, 22, 31, 19};
creates an array with six elements even though there is no number in the brackets. This is perfectly sane and logical.
What if we don’t initialize it at all and our program doesn’t either anywhere in the code?
Consider the code fragment below.
int bad_array[4]; //an array with 4 uninitialized elements for (i = 0; i < 4; i++) printf (bad_array[i]); /* d’oh! We never gave values to any elements in the array anywhere in the code! */
What would the output look like?
It would be something, but not anything you can use.
Arrays are just like ordinary variables—if you don’t initialize them, they might have any value.
The compiler just uses whatever values were already present at those memory locations, which is why I can’t tell you exactly what the output is — results will vary. What’s clear is that the output will be garbage.
You know what they say: garbage in, garbage out…
What if the number of initializers is bigger than the array, as in below?
int lottery[5] = {15, 29, 7, 22, 31, 19};
Here we have an array with 5 elements, but we’re trying to stuff 6 numbers into it.
In a situation like this, the compiler is finally on your side. Doing something like the above will produce a syntax error.
Arrays and for Loops: A Match Made in Heaven
You’ll notice the code fragment above uses a for loop to print the contents of our array.
This is actually quite common, and arrays are used with for loops all the time.
For example, the code fragment below assigns even numbers to an array.
#include <stdio.h> #define SIZE 50 int main(void) { int counter, evens[SIZE]; for (counter = 0; counter < SIZE; counter++) evens[counter] = 2 * counter; ... }
The uses for for loops coupled with arrays are endless.
For example, let’s say we want to keep track of the temperature for 10 different days. We could create a variable for each day (i.e. int day1; int day2; etc.) but by using an array we avoid this tedious redundant work and write neater code.
With a little imagination, I’m sure you’ll find a thousand other uses for this powerful pair.
Intro to Arrays in C: Wrapping Up
There’s more to say about arrays, so they’ll make an appearance again in the future.
But since this is an introduction to arrays in C, we’re going to stop here to avoid information overload.
If you’re an Arduino enthusiast, you’ll see arrays all over the place and they work pretty much the same.
Speaking of Arduino, drop a comment and share some info on your latest Arduino (or PIC, or whatever) project or C/C++ program. I’d love to hear about it!
Become the Maker you were born to be. Try Arduino Academy for FREE!
Electronics Tips & Tutorials Sent Directly to Your Inbox
Submit your email & you'll get:
- Exclusive content that I don't put on the blog
- The checklist 10 mistakes all electronics enthusiasts make (& how to avoid them)
- And more!
Phil says
Great write up on arrays. Can’t wait to see part 2 (and maybe 3??).
Brian says
Thanks Phil, there’s definitely more to say about arrays so keep your eyes peeled for more tutorials.
Ray says
Nice tutorial. plain and simple. Love it.
Brian says
Thanks!