Массивы в языке C++
Массив это структура данных, представленная в виде группы переменных одного типа, объединенных под одним единым именем и расположенная последовательно в памяти.
Объявление массива
int a[10]; // Объявляем массив из 10 целых чисел char b[20]; // Объявляем массив из 20 символов int* e[2] // Объявление массива указателей std::string d[10]; // Объявление массива объектов double c[4][2][3]; // Объявление многомерного массива
Инициализация одномерных массивов
int a[3]{ 1, 2, 3 }; // Универсальная инициализация int b[3] = { 1, 2, 3 }; // Инициализация массива списком значений int c[3] = { 1, 2, 3, 4 }; // Ошибка. В списке больше элементов int d[4] = { 1, 2 }; // Допустимо. Аналогично списку { 1, 2, 0, 0 } int e[3] = {0}; // Инициализация всех элементов массива значением 0 int f[3] = {}; // Инициализация всех элементов массива значением 0 int g[] = { 1, 2, 3, 4 }; // Размерность массива может вычисляться по списку значений char h[] = "text"; // Массив символов может инициализироваться строкой. Размерность массива = (длина строки + завершающий 0).
Инициализация многомерных массивов
int a[3][3] = { {1,2,3}, {4,5} }; // Инициализация массива размером 3х3 int b[][3] = { {1,2,3}, {4,5} }; // Первую размерность компилятор может вычислить по заданному списку int c[3][3] = {0}; // Инициализация массива значением 0 int d[3][3] = {}; // Инициализация массива значением 0
Обращение к элементам массива
int arr[] = { 1, 2 }; int v0 = arr[0]; // Индеск первого элемента массива равен 0 int v1 = arr[1]; // Второй элемент массива
Язык C++ не контролирует индекс массива. Контроль над правильностью указания индекса в массиве возложен на программиста. Если будет указан несуществующий индекс массива, то произойдет обращение за пределы массива.
int arr[] = { 1, 2, 3 }; int v1 = arr[-1]; // Выход за пределы массива int v2 = arr[3]; // Выход за пределы массива
Имя переменной массива является указателем, так что доступ к элементам массива можно получить через разыменование переменной.
int arr[] = { 1, 2, 3 }; int v0 = *arr; // Аналогично v0 = arr[0]; int *ptr = arr + 1; int v1 = *ptr; // Аналогично v1 = arr[1];
Перебор элементов массива
int arr[10]; for(int i = 0; i < 10; i++) arr[i] = i; // Классический вариант - через индекс массива for(int elem: arr) std::cout << elem; // С использованием стандартной бибилиотеки, через диапазонный for
Вычисление размера массива
int arr[5] = { 2, 4, 8 }; std::cout << sizeof(arr); // Размер массива в байтах = 20 std::cout << sizeof(arr) / sizeof(arr[0]); // Размерность массива = 5 std::cout << _countof(arr); // Размерность массива = 5 std::cout << std::size(arr); // Размерность массива = 5 (стандарт С++17)
При конвертации массива к типу указателя (например при передаче массива в функцию) информация о размере массива теряется.
int arr[5] = { 2, 4, 8 }; int *ptr = arr; std::cout << sizeof(arr); // Размер массива в байтах = 20 std::cout << sizeof(ptr); // Размер указателя в байтах = 4
Динамические массивы
Динамические массивы объявляются как обычный указатель. Память выделяется с помощью особой формы оператора new с квадратными скобками []. Освобождение памяти делается оператором delete[]. Динамический массив может инициализироваться с помощью универсальной инициализации.
int *arr = new int[10] { 1, 2, 3, 4, 5 }; for (int i = 0; i < 10; i++) { std::cout << arr[i] << std::endl; } delete[] arr;
Использование простого оператора delete для удаления массива приведет к утечке памяти.