Элементы массива могут быть любого типа данных, даже массива!
Многомерные массивы
Массив массивов называется многомерным массивом:
1 |
int array[2][4]; // 2-элементный массив из 4-элементных массивов |
Поскольку у нас есть 2 индекса, то это двумерный массив.
В двумерном массиве первый (левый) индекс принято читать как количество строк, а второй (правый) как количество столбцов. Массив выше можно представить следующим образом:
[0][0] [0][1] [0][2] [0][3] // строка №0
[1][0] [1][1] [1][2] [1][3] // строка №1
Чтобы получить доступ к элементам двумерного массива, просто используйте два индекса:
1 |
array[1][3] = 7; // без приставки int (типа данных) |
Инициализация двумерных массивов
Для инициализации двумерного массива проще всего использовать вложенные фигурные скобки, где каждый набор значений соответствует определенной строке:
1 2 3 4 5 6 |
int array[3][5] = { { 1, 2, 3, 4, 5 }, // строка №0 { 6, 7, 8, 9, 10 }, // строка №1 { 11, 12, 13, 14, 15 } // строка №2 }; |
Хотя некоторые компиляторы могут позволить вам упустить внутренние фигурные скобки, все же рекомендуется указывать их в любом случае: улучшается читабельность и уменьшается вероятность получения незапланированных нулевых элементов массива из-за того, что C++ заменяет отсутствующие инициализаторы значением 0
:
1 2 3 4 5 6 |
int array[3][5] = { { 2, 4 }, // строка №0 = 2, 4, 0, 0, 0 { 1, 3, 7 }, // строка №1 = 1, 3, 7, 0, 0 { 8, 9, 11, 12 } // строка №2 = 8, 9, 11, 12, 0 }; |
В двумерном массиве со списком инициализаторов можно не указывать только левый индекс (длину массива):
1 2 3 4 5 6 |
int array[][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, { 11, 12, 13, 14, 15 } }; |
Компилятор может сам вычислить количество строк в массиве. Однако не указывать два индекса — это уже ошибка:
1 2 3 4 5 |
int array[][] = { { 3, 4, 7, 8 }, { 1, 2, 6, 9 } }; |
Подобно обычным массивам, многомерные массивы можно инициализировать значением 0
следующим образом:
1 |
int array[3][5] = { 0 }; |
Обратите внимание, это работает только в том случае, если вы явно объявляете длину массива (указываете левый индекс)! В противном случае, вы получите двумерный массив с 1 строкой.
Доступ к элементам в двумерном массиве
Для доступа ко всем элементам двумерного массива требуется два цикла: один для строк и один для столбцов. Поскольку доступ к двумерным массивам обычно выполняется по строкам, то левый индекс используется в качестве внешнего цикла:
1 2 3 |
for (int row = 0; row < numRows; ++row) // доступ по строкам for (int col = 0; col < numCols; ++col) // доступ к каждому элементу в строке std::cout << array[row][col]; |
Многомерные массивы более двух измерений
Многомерные массивы могут быть более двух измерений. Например, объявление трехмерного массива:
1 |
int array[4][3][2]; |
Трехмерные массивы трудно инициализировать любым интуитивным способом с использованием списка инициализаторов, поэтому лучше инициализировать весь массив значением 0
и явно присваивать элементам значения с помощью вложенных циклов.
Доступ к элементам трехмерного массива осуществляется так же, как и к элементам двумерного массива:
1 |
std::cout << array[3][2][1]; |
Пример двумерного массива
Рассмотрим пример использования двумерного массива:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <iostream> int main() { // Объявляем массив 10x10 const int numRows = 10; const int numCols = 10; int product[numRows][numCols] = { 0 }; // Создаем таблицу умножения for (int row = 0; row < numRows; ++row) for (int col = 0; col < numCols; ++col) product[row][col] = row * col; // Выводим таблицу умножения for (int row = 1; row < numRows; ++row) { for (int col = 1; col < numCols; ++col) std::cout << product[row][col] << "\t"; std::cout << '\n'; } return 0; } |
Эта программа вычисляет и выводит таблицу умножения от 1 до 9 (включительно). Обратите внимание, при выводе таблицы в цикле for мы начинаем с 1 вместо 0. Это делается с целью предотвращения вывода нулевой строки и нулевого столбца, содержащих одни нули!
Результат выполнения программы:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
Двумерные массивы обычно используются в играх типа tile-based, где каждый элемент массива представляет собой один фрагмент/плитку. Они также используются в компьютерной 3D-графике (в виде матриц) для вращения, масштабирования и отражения фигур.
Как задать двумерный массив, в котором количество строк и столбцов задаёт пользователь?
типо, вот так:
З новим роком!
Дякую, і тебе з Новим роком!
Здорового времени суток, Юр! Процитирую тебя:
"Трёхмерные массивы трудно инициализировать любым интуитивным способом с использованием списка инициализаторов, поэтому лучше инициализировать весь массив значением 0 и явно присваивать значения с помощью вложенных циклов."
Кинь, пожал-ста, примерчик каким обрезом явно присваивать значения с помощью вложенных циклов, а я вот свою ответку на первую половину мэсседжа шлю:
Добрый день, Юрий.
Прочитав комментарий к этому уроку и информацию на других сайтах я понял, что если надо получить многомерный массив int array[ ][5] заполненный нулями, то можно инициализировать все элементы массива следующим образом.
Насколько это корректно?
Можно ли использовать цикл
Или этот цикл будет лишними строчками кода?
инициализировать массивы через = {0}; довольно плохая идея. Так возникает иллюзия (особенно у совсем начинающих), что число в скобках задает значение для ВСЕХ элементов массива. Лучше вообще не указывать ничего в скобках и писать = {};
А еще лучше подчеркивать уровень массива и писать = {{}}; для двумерных.
Ну и стоит отметить, что в двумерных массивах не совсем очевидная адресация памяти, что часто приводит к выносящим мозг новичкам ошибкам, типа подхвата чисел из соседних строк при обращении к текущей.
Как по мне, лучше пользоваться одномерными массивами вместо двумерных везде, где это возможно (и быстрее, и проще, и меньше ошибок)