Exercise 8 of 10 · Arrays
Packing List
What you will make
A travel packing checklist with a banner, one tick-box line for every item on the list, and a footer that counts them for you.
The one new idea: An array holds several values of one type in order, indexed from zero with []
Real programs almost never hold one value at a time. They hold a run of them — orders, messages, students, readings — and walk through it doing the same thing to each one. An array and a for loop are how C does that, and it is a pairing you will reach for constantly.
Go straight to the code ↓An array is several values under one name, in order
Every variable so far has held exactly one thing. A packing list is not like that. It is one thing made of several things, kept in the order you wrote them down, all of the same type.
C writes that with square brackets and a comma between each value:
const char *items[] = {"Passport", "Charger"};const char * is the type of one item — a string, which in C is really a pointer to its first character —
and the empty [] says there will be a run of them, with the compiler counting how many from the list
between the braces. items[0] is "Passport", items[1] is "Charger", and that numbering starts at zero
for every array in C, always.
Measuring an array with sizeof
There is no built-in function that hands back an array's length. sizeof measures bytes, so sizeof(items)
is the total size of the whole array and sizeof(items[0]) is the size of one element — and one divided by
the other is the count.
#include <stdio.h>
int main(void) {
int values[] = {10, 20, 30, 40};
int count = sizeof(values) / sizeof(values[0]);
printf("%d values\n", count);
return 0;
}4 valuesAdd a fifth number to the braces and this prints 5 without another line of code changing, because the
division works it out fresh from whatever is actually in the array. That idiom, dividing an array's size by
its element's size, is worth recognising on sight — it is the closest C gets to asking a collection how long
it is.
Walking an array with a loop
A for loop from 0 up to, but not including, the count visits every element exactly once:
#include <stdio.h>
int main(void) {
const char *colours[] = {"red", "green", "blue"};
int count = sizeof(colours) / sizeof(colours[0]);
for (int i = 0; i < count; i++) {
printf("Paint the shed %s\n", colours[i]);
}
printf("%d tins on the shelf\n", count);
return 0;
}Paint the shed red
Paint the shed green
Paint the shed blue
3 tins on the shelfThree values in the array, three lines of output, then one line that counted them. Add a fourth colour to
the braces and you get a fourth line and a 4 at the bottom, with nothing else edited.
Your turn
The editor holds a checklist with two items on it. Press Run before changing anything.
The loop is already doing its job: two items in the array, two lines of output. But both lines read
[ ] item, because the line inside the loop prints the word item in plain quotes rather than the value at
items[i]. Quotes mean plain text, and plain text is exactly what came out.
Two things to do:
- Rewrite the line inside the loop so it prints
items[i]through%s, keeping the[ ]box and the space after it exactly as they are. - Add
"Socks"and"Towel"to the array, in that order, inside the braces.
The footer needs no attention at all. It is already counting the array with sizeof, so it will say 4 by
itself the moment the two new items are in place.
If something goes wrong
The likeliest slip is a missing %s in the printf call. You will spot it straight away, because the
output reads [ ] item word for word on every line. Nothing has broken; the placeholder simply needs adding,
with items[i] as the argument that follows it.
If the compiler stops with something like "excess elements in array initializer", the array was given an explicit size in its brackets earlier and then handed more values than that size allows. Leave the brackets empty and let the initialiser decide.
And if a row prints something that looks like garbage text instead of a real item, check the loop's
condition — i < count, not i <= count. C has no bounds checking at all, so reading one past the end of an
array does not crash here; it silently reads whatever happens to be in memory next and prints that instead.
Write your code
Runs in your browser. Press Run (or Ctrl/Cmd+Enter) and the output is checked for you.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.The runtime is starting in the background. You can type now — it will be ready before you are.
The answer appears here once you have run your code at least once.
Things that often go wrong here
- Leaving the printf line as printf("[ ] item\n");
- item in plain quotes is the four letters i, t, e, m — ordinary text, not a lookup — so every row prints identically instead of showing the array's own values. %s with items[i] as the argument is what actually reads the array.
- Writing i <= count instead of i < count in the loop's condition
- An array of count elements has valid indexes 0 through count - 1. i <= count reads items[count], one position past the end, and C does not stop you or even necessarily complain — you get whatever bytes happen to sit in memory just after the array, printed as if they were a real entry.
- Sizing the array explicitly, const char *items[2] = {...}, then trying to add two more names
- Once a size is written in the brackets it is fixed for good, and an initialiser with more values than that size is a compile-time error: too many initializers. Leaving the brackets empty, as the starter code does, lets the compiler count the entries for you and grow along with the list.
- Forgetting the comma between two items, as in {"Passport", "Charger" "Socks", "Towel"}
- Two string literals sitting next to each other with nothing between them are joined by the compiler into a single literal before anything else happens — "Charger" "Socks" silently becomes one twelve-character string "ChargerSocks", and the array ends up one entry short of what you meant.
Longer explanation: read the full lesson. Want a blank editor instead? Open the C playground.