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:
#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:
int data[] = {4, 7, 1};sets up a row of three houses holding4,7and1.- The call
sum(data, 3)passes a slip with the address of the first house and the house count3. - Inside
sum, the loop runsifrom0to2and adds updata[0],data[1]anddata[2]. - The program prints
12, that is4 + 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 + iis the address of the number with indexi;data[i]is the number with indexiitself, short for*(data + i);&data[i]is also the address of the number with indexi, the same asdata + i.
int data[] = {4, 7, 1};
int* p = data + 2;
std::cout << *p << ' ' << data[2] << '\n'; // 1 1
std::cout << (p == &data[2]) << '\n'; // 1Let's go through it line by line:
int* p = data + 2;counts two steps from the first house and writes the address of the number with index2on the slipp.*panddata[2]denote the same number, so the program prints1 1.p == &data[2]compares two addresses. They are equal, andstd::coutprints1, 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 <:
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, anddatapassed to anint*parameter becomes a pointer to the first of them.data[i]is*(data + i), and&data[i]is the same asdata + i.- Indices run from
0ton - 1; readingdata[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.