⚙️ C++

Двумерные массивы в C++17: подробное руководство

Двумерные массивы в C++

Что такое двумерный массив и зачем он нужен?

Представь себе таблицу или шахматную доску. У каждой клетки есть две координаты: номер строки и номер столбца. Двумерный массив — это именно такая таблица в памяти компьютера. Он позволяет хранить данные, которые удобно представлять в виде сетки: карта острова, схема кинозала, таблица с оценками учеников, данные о землетрясениях в разных регионах.

В C++ двумерный массив — это, по сути, «массив массивов». Сначала мы указываем количество строк (рядов), потом количество столбцов (мест в ряду).

Как объявить и заполнить двумерный массив?

Самый простой способ объявить двумерный массив — указать его размеры в квадратных скобках:

// Массив из 3 строк и 4 столбцов
int matrix[3][4];

Можно сразу задать значения при объявлении:

#include <iostream>
using namespace std;

int main() {
    // Таблица 2x3 с числами
    int table[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };
    
    // Выводим элемент из первой строки, второго столбца
    cout << table[0][1]; // Выведет 2
    return 0;
}

Как пройтись по всем элементам?

Для работы с двумерным массивом используют вложенные циклы. Внешний цикл перебирает строки, внутренний — столбцы.

#include <iostream>
using namespace std;

int main() {
    int rows = 2, cols = 3;
    int arr[2][3] = {{10, 20, 30}, {40, 50, 60}};
    
    for (int i = 0; i < rows; i++) {      // i — номер строки
        for (int j = 0; j < cols; j++) {  // j — номер столбца
            cout << arr[i][j] << " ";
        }
        cout << endl; // Переход на новую строку
    }
    return 0;
}

Вывод:

10 20 30
40 50 60

Ввод данных с клавиатуры

Часто массив нужно заполнять с клавиатуры. Сначала вводим размеры, потом каждый элемент в цикле.

#include <iostream>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m; // Вводим количество строк и столбцов
    
    int data[n][m]; // Можно так, если n и m известны (в C++17 работает)
    
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> data[i][j];
        }
    }
    
    // Выводим всё, что ввели
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << data[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

Пример ввода:

2 3
1 2 3
4 5 6

Вывод:

1 2 3
4 5 6

Разбор типичных задач

Задача «Кинозал Уют»

Нужно создать схему зала. Пусть будет 3 ряда по 4 места. Свободное место обозначим 'O', занятое — 'X'.

#include <iostream>
using namespace std;

int main() {
    char hall[3][4] = {
        {'O', 'O', 'X', 'O'},
        {'X', 'O', 'O', 'X'},
        {'O', 'X', 'O', 'O'}
    };
    
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            cout << hall[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

Задача «Данные землетрясений»

Массив 2x2 с магнитудами. Заполним с клавиатуры и найдём среднее.

#include <iostream>
using namespace std;

int main() {
    double quakes[2][2];
    
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            cin >> quakes[i][j];
        }
    }
    
    double sum = 0;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            sum += quakes[i][j];
        }
    }
    
    cout << "Средняя магнитуда: " << sum / 4;
    return 0;
}

Задача «Популярность постов»

Дано: количество блогеров (строки) и постов (столбцы). Заполняем лайками, выводим.

#include <iostream>
using namespace std;

int main() {
    int bloggers, posts;
    cin >> bloggers >> posts;
    
    int likes[bloggers][posts];
    
    for (int i = 0; i < bloggers; i++) {
        for (int j = 0; j < posts; j++) {
            cin >> likes[i][j];
        }
    }
    
    for (int i = 0; i < bloggers; i++) {
        cout << "Блогер " << i+1 << ": ";
        for (int j = 0; j < posts; j++) {
            cout << likes[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

Частые ошибки новичков

  • Путаница с индексами: В C++ счёт начинается с 0. Первая строка — индекс 0, первый столбец — тоже 0. arr[1][2] — это вторая строка, третий столбец.
  • Выход за границы массива: Если массив размером 3x4, то последний допустимый индекс — [2][3]. Обращение к [3][0] вызовет ошибку.
  • Перепутанные циклы: Внешний цикл должен идти по строкам, внутренний — по столбцам. Если их поменять местами, массив будет обходиться «по столбцам», что может привести к путанице.
  • Забыли про вложенные фигурные скобки: При инициализации int a[2][3] = {1,2,3,4,5,6}; — это сработает, но лучше писать {{1,2,3},{4,5,6}} для наглядности.

Итоговый пример: задача «Замена товара на складе»

У нас есть склад 3x4. Нужно заменить все товары с количеством меньше 5 на 0 (списать).

#include <iostream>
using namespace std;

int main() {
    int warehouse[3][4] = {
        {10, 3, 7, 2},
        {1, 15, 4, 8},
        {6, 0, 9, 2}
    };
    
    // Заменяем маленькие количества
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            if (warehouse[i][j] < 5) {
                warehouse[i][j] = 0;
            }
        }
    }
    
    // Выводим обновлённый склад
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            cout << warehouse[i][j] << "\t";
        }
        cout << endl;
    }
    return 0;
}

Вывод:

10	0	7	0
0	15	0	8
6	0	9	0

Заключение

Двумерные массивы — мощный инструмент для работы с табличными данными. Главное — запомнить: первый индекс — строка, второй — столбец, счёт начинается с нуля, а для обхода нужны два вложенных цикла. Потренируйся на задачах про кинозал, землетрясения и посты — и ты быстро освоишь эту тему!