Arrays

Introduction

An array stores several values of the same type next to each other in memory. int marks[5] makes room for five ints, numbered 0 to 4.

Many values of the same kind belong together: the marks of a class or the temperatures of a week. An array keeps them next to each other in memory, which is what makes a computer so fast at going through them.

How it works

Past the end

C does not check indexes. marks[5] is outside the array, but real C will read or overwrite whatever memory comes next, which causes some of the hardest bugs to find. StepVioz stops at that line and says how big the array is:

#include <stdio.h>

int main(void) {
    int squares[4];
    for (int i = 0; i <= 4; i++) {
        squares[i] = i * i;
    }
    printf("%d\n", squares[3]);
    return 0;
}
Open in compiler

The classic cause is <= in the loop condition where < was meant.

Two dimensions

int grid[2][3] is 2 rows of 3. grid[r][c] is the element in row r, column c:

#include <stdio.h>

int main(void) {
    int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int total = 0;
    for (int r = 0; r < 2; r++) {
        for (int c = 0; c < 3; c++) {
            total += grid[r][c];
        }
    }
    grid[1][2] = 60;
    printf("total %d, corner %d\n", total, grid[1][2]);
    return 0;
}
Open in compiler

Syntax

int a[5];
int b[3] = {1, 2, 3};
int zeros[100] = {0};
int grid[2][3];
for (int i = 0; i < 5; i++) {
    a[i] = i * i;
}

Example

#include <stdio.h>

int main(void) {
    int marks[5] = {72, 85, 64, 90, 58};
    int sum = 0, best = marks[0];
    for (int i = 0; i < 5; i++) {
        sum += marks[i];
        if (marks[i] > best) best = marks[i];
    }
    marks[4] = 60;
    printf("Total %d, best %d, average %.1f\n", sum, best, sum / 5.0);
    return 0;
}
Open in compiler

In the memory panel, the array appears as a row of cells with their indexes. Each marks[i] = ... lights up the one cell that changed. Notice:

  • The first element is marks[0], the last is marks[4].
  • The loop runs while i < 5, so i goes 0, 1, 2, 3, 4.

Line by line

  1. marks has five values, at indexes 0 to 4.
  2. sum starts at 0, and best starts as the first mark.
  3. The loop goes through i from 0 to 4.
  4. Each round adds one mark, and updates best if this mark is higher.
  5. marks[4] = 60 changes one element, after the totals have been worked out.
  6. sum / 5.0 is a double, so the average keeps its decimal.

Expected result

Total 369, best 90, average 73.8

In the real world

Images, sound and sensor readings are stored as large arrays. Reading past the end of an array, called a buffer over-read, was the cause of the famous Heartbleed security bug in 2014.

Common mistakes

  • Indexes start at 0: an array of n elements ends at index n - 1.
  • int a[5]; a = ... is not allowed: change the elements one by one, or use a loop.
  • A local array is not set to zero. Write int a[5] = {0}; to start with all zeros.

Best practices

  • Keep the size in a named constant, and use it in every loop.
  • Always use i < n rather than i <= n.
  • Initialise arrays with = {0} when you need zeros.

Summary

An array holds elements of one type next to each other, indexed from 0. C trusts your indexes and does not check them, so loops must stay within bounds. Two-dimensional arrays are arrays of rows.

Quick check

1. int a[10]; Which index is the last element?
2. What does int a[4] = {7, 8}; hold?
3. Which loop visits every element of int a[n]?

Key takeaways

  • An array of n elements has indexes 0 to n - 1.
  • C does not check indexes.
  • Give an array a starting value, or it holds garbage.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.