Skip to content
Theory · References and Pointers · lesson 5 of 9

A pointer to numbers in a row

Let's go back to the memory street. Sometimes several houses stand right next to each other, each holding one number. To tell someone about the whole row, you don't need to write down the address of every house. Two things are enough:

  • a slip with the address of the first house;
  • the number of houses in the row.

From there, a person walks along the street from the first house and counts: zeroth, first, second… In the same way, a C++ function receives several numbers that lie in memory one after another.

How to get numbers in a row

The line int data[] = {4, 7, 1}; puts three int numbers into memory one after another. Such a row is called an array; arrays are covered in detail in a later theme. When data is passed to a function with an int* parameter, the function receives a pointer to the first number of the row:

C++
#include <iostream>

int sum(int* data, int n) {
    int total = 0;
    for (int i = 0; i < n; ++i) {
        total = total + data[i];
    }
    return total;
}

int main() {
    int data[] = {4, 7, 1};
    std::cout << sum(data, 3) << '\n';  // 12
}

Let's go through the example line by line:

  1. int data[] = {4, 7, 1}; sets up a row of three houses holding 4, 7 and 1.
  2. The call sum(data, 3) passes a slip with the address of the first house and the house count 3.
  3. Inside sum, the loop runs i from 0 to 2 and adds up data[0], data[1] and data[2].
  4. The program prints 12, that is 4 + 7 + 1.

Stepping along the row

If data points to the first number, then data + i points to the number with index i. Counting starts at zero, so the indices run from 0 to n - 1. There are three notations you need to be able to read:

  • data + i is the address of the number with index i;
  • data[i] is the number with index i itself, short for *(data + i);
  • &data[i] is also the address of the number with index i, the same as data + i.
C++
int data[] = {4, 7, 1};
int* p = data + 2;
std::cout << *p << ' ' << data[2] << '\n';  // 1 1
std::cout << (p == &data[2]) << '\n';  // 1

Let's go through it line by line:

  1. int* p = data + 2; counts two steps from the first house and writes the address of the number with index 2 on the slip p.
  2. *p and data[2] denote the same number, so the program prints 1 1.
  3. p == &data[2] compares two addresses. They are equal, and std::cout prints 1, meaning "true".

This is where the street analogy ends: there is no fence at the end of the row. The street goes on with other people's houses, and data + n already points past the last number of the row. Reading data[n] is undefined behavior.

Common mistake

The loop uses <= instead of <:

C++
int sum(int* data, int n) {
    int total = 0;
    for (int i = 0; i <= n; ++i) {
        total = total + data[i];  // ✗
    }
    return total;
}

The compiler gives neither an error nor a warning. But on its last step the loop reads data[n], the number past the end of the row, and that is undefined behavior. The last valid index is n - 1, so the loop condition is i < n.

Key points

  • Numbers in a row are passed to a function as two parameters: a pointer to the first number and their count.
  • int data[] = {…} puts numbers in a row, and data passed to an int* parameter becomes a pointer to the first of them.
  • data[i] is *(data + i), and &data[i] is the same as data + i.
  • Indices run from 0 to n - 1; reading data[n] is undefined behavior.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way