Fundamentals

C++ arrays: the whole picture

Short answer: int a[5] reserves five consecutive int slots and names them a[0] … a[4]. The size is fixed at compile time and C++ does not check your indices at runtime.

Memory is a row, not a grid

An array is one contiguous block. a[3] is not a lookup with a name — it is "start of the block, plus three elements' worth of bytes". That is why indexing is O(1): one multiplication, one add.

#include <iostream>
using namespace std;

int main() {
    int a[5] = {10, 20, 30, 40, 50};

    cout << "first:  " << a[0] << endl;
    cout << "third:  " << a[2] << endl;
    cout << "last:   " << a[4] << endl;
    return 0;
}

There is no a[5]. Writing it compiles, runs, and reads whatever happens to sit next in memory — that is undefined behaviour, not an error message.

Why zero?

Because the index is an offset. The first element is zero slots away from the start of the block. Languages that start at 1 have to subtract before every access; C++ makes that subtraction free by writing it into your code.

Sizing: pick a ceiling, not the exact count

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int a[100];                 // declare a ceiling
    for (int i = 0; i < n; i++) cin >> a[i];

    cout << "read " << n << " values" << endl;
    return 0;
}

You cannot resize a C++ array. In real code you either declare a generous ceiling (as here), or use std::vector which grows. Compare them in vector vs array.

The three patterns worth memorising

1. Sum — initialise the accumulator to zero.

#include <iostream>
using namespace std;

int main() {
    int a[5] = {1, 2, 3, 4, 5};
    int sum = 0;
    for (int i = 0; i < 5; i++) sum += a[i];
    cout << sum << endl;   // 15
    return 0;
}

2. Maximum — seed with the first element, never with zero.

#include <iostream>
using namespace std;

int main() {
    int a[4] = {-9, -3, -7, -1};
    int best = a[0];
    for (int i = 1; i < 4; i++) {
        if (a[i] > best) best = a[i];
    }
    cout << best << endl;   // -1, not 0
    return 0;
}

3. Count — one counter per category.

#include <iostream>
using namespace std;

int main() {
    int a[6] = {4, 7, 10, 3, 8, 1};
    int even = 0, odd = 0;
    for (int i = 0; i < 6; i++) {
        if (a[i] % 2 == 0) even++;
        else odd++;
    }
    cout << "even " << even << ", odd " << odd << endl;
    return 0;
}

Two-dimensional arrays are rows of rows

#include <iostream>
using namespace std;

int main() {
    int g[3][2] = {{1, 2}, {3, 4}, {5, 6}};

    for (int r = 0; r < 3; r++) {
        for (int c = 0; c < 2; c++) {
            cout << g[r][c] << " ";
        }
        cout << endl;
    }
    return 0;
}

The first index is the row, always. Reversing them silently transposes your data — the bug behind Matrix Transpose exercises.

Bugs that do not announce themselves

Practice: Array Maximum, Even and Odd Count, Sum a Matrix. Next: Big O notation explains why a nested loop over this array is O(n²).