PS-Group
Частьматериалавзятаизстатьи C++Arrays(programiz.com)
2
// общий синтаксис
DataType variableName[ARRAY_SIZE];
В C++ массивы статичны: вы не сможете изменить размер или тип элементов после объявления.
#include <iostream>
int main()
{
int ages[] = { 17, 18, 29, 30, 16, 27, 22 };
int main()
{
// Индексы элементов: 0, 1, 2
int ages[] = {1, 2, 3};
#include <iostream>
int main()
{
// Индексы элементов: 0, 1, 2
int ages[] = {1, 2, 3};
printArrayV1(ages, std::size(ages));
printArrayV2(ages);
}
#include <cassert>
#include <cstdlib>
#include <iostream>
size_t size = 0;
int data[MAX_SIZE] = { 0 };
};
Класс std::vector<T>
Стандартная библиотека C++ содержит шаблонный класс vector, который работает как динамический массив
произвольного размера. Размер может расти до тех пор, пока у операционной системы есть область памяти подходящего
размера (вплоть до нескольких гигабайт).
Класс является шаблонным, то есть при объявлении переменной потребуется параметризовать шаблон класса vector
типом элемента:
#include <vector>
int main()
{
std::vector<int> ages = { 10, 3, 7 };
}
#include <vector>
#include <iostream>
int main()
{
std::vector<int> ages = { 10, 3, 7 };
print(ages);
}
Вы можете практически всегда использовать push_back. Метод pop_back можно использовать для удаления элемента:
#include <vector>
#include <iostream>
int main()
{
// эквивалентно инициализации ages = { 10, 3, 7 }.
std::vector<int> ages;
ages.push_back(10);
ages.push_back(3);
ages.push_back(7);
Новая область находится уже другом месте, потому что менеджер динамической памяти не мог просто взять и
расширить старую область (ведь сразу за ней находилась чужая память). Поэтому все итераторы, ссылки и указатели на
элементы могут стать некорректными после любого изменения массива!
int main()
{
// эквивалентно инициализации ages = { 10, 3, 7 }.
std::vector<int> ages = { 10, 3, 7 };
print(ages);
}
14
Последствия перемещения элементов: ошибка в простом цикле с erase
Использование итератора, ссылки или указателя на элемент после перераспределения памяти в массиве является
неопределённым поведением: скорее всего произойдёт падение программы либо будет пропущено несколько элементов
коллекции. Это показано в примере ниже:
#include <vector>
#include <iostream>
int main()
{
// эквивалентно инициализации ages = { 10, 3, 7 }.
std::vector<int> ages = { 10, -33, 23, -18, 7, 38, 99 };
eraseNegativeAndPrint(ages);
}
15
Если вы запустите этот код, вы можете увидеть что угодно. Скорее всего программа выведет 10 38 99 , хотя должна
вывести 10 23 7 38 99 по замыслу автора.
Для решения этой проблемы метод erase возвращает новый, валидный итератор на элемент, следующий после
удалённого. Если элемент был последним, erase вернёт итератор end. Учитывая это, мы можем исправить код, чтобы
новое значение it либо получалось из erase, либо получалось путём инкремента:
#include <vector>
#include <iostream>
int main()
{
// эквивалентно инициализации ages = { 10, 3, 7 }.
std::vector<int> ages = { 10, -33, 23, -18, 7, 38, 99 };
eraseNegativeAndPrint(ages);
}
16
Программа корректно напечатает 10 23 7 38 99 .
int main()
{
// эквивалентно инициализации ages = { 10, 3, 7 }.
std::vector<int> ages = { 10, -33, 23, -18, 7, 38, 99 };
eraseNegativeAndPrint(ages);
}
PS-Group
PS-Group
sshambir@gmail.com
ps-group
sshambir