<MyRusakov.ru />

WordPress 6 с Нуля до Гуру

WordPress 6 с Нуля до Гуру

Этот курс научит Вас созданию самых разных сайтов на самой популярной в мире CMS - WordPress. Вы увидите установку и настройку локального сервера, разбор каждой настройки, каждой кнопки и каждого пункта меню в панели WordPress.

Также Вы получите и всю практику, поскольку прямо в курсе с нуля создаётся полноценный Интернет-магазин, который затем публикуется в Интернете. И всё это прямо на Ваших глазах.

Помимо уроков к курсу идут упражнения для закрепления материала.

И, наконец, к курсу идёт ценнейший Бонус по тому, как используя ChatGPT и создавая контент для сайта, можно выйти на пассивный доход. Вы наглядно увидите, как зарегистрироваться в ChatGPT (в том числе, и если Вы из России), как правильно выбрать тему для сайта, как правильно генерировать статьи для него(чтобы они индексировались поисковыми системами) и как правильно монетизировать трафик на сайте.

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

std::vector в C++: понятное руководство для начинающих с примерами и советами

std::vector в C++: понятное руководство для начинающих с примерами и советами

Если вы начинаете путь в C++, умение уверенно работать со std::vector — один из важнейших навыков. Вектор сочетает динамический массив, безопасность и удобные алгоритмы. Ниже — практическое руководство для запроса «std::vector в C++: руководство с примерами» с акцентом на повседневные задачи и ошибки, которые совершают новички.

Что такое std::vector и когда его использовать

std::vector — динамический массив: элементы лежат подряд в памяти, а размер может расти по мере добавления данных. Подходит для списков, буферов, коллекций сущностей, когда нужен быстрый произвольный доступ по индексу и эффективная итерация.

#include <vector>
#include <iostream>

int main() {
    std::vector<int> v;            // пустой вектор
    v.push_back(10);                // добавить элемент в конец
    v.emplace_back(20);             // сконструировать элемент на месте

    std::vector<int> a(5, 42);      // 5 элементов со значением 42
    std::vector<int> b = {1, 2, 3}; // список инициализации

    std::cout << v[0] << " " << v[1] << "\n"; // 10 20
}

Доступ к элементам: operator[] vs at()

operator[] не проверяет границы (быстро, но потенциально опасно). at() бросает исключение std::out_of_range — безопаснее при отладке.

std::vector<int> v = {1, 2, 3};
int x = v[2];           // OK, без проверки
int y = v.at(2);        // OK, с проверкой
// int z = v.at(5);     // std::out_of_range

Итерация без лишних копий

В range-based for выбирайте ссылку, чтобы не копировать элементы. Для чтения — const&.

std::vector<std::string> names = {"Ann", "Bob", "Cara"};
for (const auto& s : names) {
    // читаем без копий
}
for (auto& s : names) {
    s += "!"; // изменяем на месте
}

size, capacity, reserve и shrink_to_fit

size — число элементов. capacity — выделенная память (может быть больше size). Добавления могут вызывать перераспределение памяти (reallocation), которое инвалидирует указатели, итераторы и ссылки на элементы.

std::vector<int> v;
std::cout << v.size() << " " << v.capacity() << "\n";
v.reserve(1000);                 // заранее выделяем память под ~1000 эл-тов
for (int i = 0; i < 1000; ++i) v.push_back(i);
std::cout << v.size() << " " << v.capacity() << "\n";
v.shrink_to_fit();               // пытаемся ужать capacity до size (не обяз.)

Совет: если примерно знаете конечное количество элементов — вызовите reserve. Это уменьшит число реаллокаций и ускорит программу.

push_back vs emplace_back

push_back добавляет уже готовый объект. emplace_back конструирует объект прямо в памяти вектора — полезно для сложных типов.

struct User { std::string name; int age; };
std::vector<User> users;
users.push_back(User{"Ann", 20});        // конструирование + перемещение/копия
users.emplace_back("Bob", 30);            // конструирование на месте (обычно быстрее)

Удаление элементов: erase и идиома erase-remove

erase удаляет по итератору или диапазону, сдвигая хвост. Чтобы удалить все элементы по условию, используйте std::remove_if + erase.

#include <algorithm>

std::vector<int> v = {1,2,3,4,5,6};
// Удалить все чётные
v.erase(std::remove_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; }), v.end());

// Удалить один элемент по индексу i
size_t i = 2;
if (i < v.size()) v.erase(v.begin() + static_cast<ptrdiff_t>(i));

Инвалидированные ссылки и итераторы

При росте capacity вектор переносит элементы в новую память. Все указатели/итераторы/ссылки на элементы становятся недействительными. Пример ошибки:

std::vector<int> v;
v.reserve(1);
v.push_back(1);
int* p = &v[0];          // указатель на элемент
v.push_back(2);          // возможно reallocation! p теперь недействителен
// *p - неопределённое поведение

Решение: хранить индексы, а не указатели; заранее резервировать память; пере-вычислять итераторы после операций, меняющих capacity.

Передача std::vector в функции

  • Только читаем — передавать как const std::vector<T>&.
  • Изменяем — std::vector<T>&.
  • Забираем владение/перемещаем — std::vector<T>&& (с std::move при вызове).
int sum(const std::vector<int>& v) {
    int s = 0; for (int x : v) s += x; return s;
}

void fillZeros(std::vector<int>& v) {
    std::fill(v.begin(), v.end(), 0);
}

void take(std::vector<int>&& v) {
    // владеем временным вектором, можем переместить данные дальше
}

Правильная инициализация 2D-вектора

Чтобы создать матрицу r×c, используйте конструктор с размером и значением по умолчанию. Не путайте reserve и resize.

size_t r = 3, c = 4;
std::vector<std::vector<int>> m(r, std::vector<int>(c, 0));
m[1][2] = 5;

// Ошибка новичков: reserve не создаёт элементы!
std::vector<int> v;
v.reserve(10);
// v[0] = 1; // UB: нет элементов. Сначала resize:
v.resize(10);
v[0] = 1; // OK

Сортировка, уникализация и удаление дубликатов

Комбинация sort + unique + erase позволяет быстро убрать повторы.

#include <algorithm>

std::vector<int> v = {3,1,2,3,2,1,4};
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
// v: 1,2,3,4

Производительность: 8 коротких советов

  • Если знаете примерный размер — делайте v.reserve(N).
  • Используйте emplace_back для сложных объектов (меньше лишних копий).
  • Итерируйтесь по const auto& для избежания копирования крупных элементов.
  • Не используйте erase в середине вектора в горячих циклах — возможно, лучше другой контейнер.
  • После крупного clear можно v.shrink_to_fit(), если важна экономия памяти.
  • Не храните долгоживущие указатели/итераторы на элементы, если вектор растёт.
  • Для добавления многих элементов рассмотрите резервирование + вставку батчами (insert).
  • Передавайте вектор по ссылке, если не нужно копирование.

Мини-практика: читаем числа, фильтруем и считаем сумму

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> v; v.reserve(1000);
    int x; while (std::cin >> x) v.push_back(x);
    // Оставим только положительные
    v.erase(std::remove_if(v.begin(), v.end(), [](int t){ return t <= 0; }), v.end());
    std::sort(v.begin(), v.end());
    v.erase(std::unique(v.begin(), v.end()), v.end());
    long long sum = 0; for (int t : v) sum += t;
    std::cout << "count=" << v.size() << " sum=" << sum << "\n";
}

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

  • Путаница между reserve и resize: reserve выделяет память, но не создаёт элементов; resize — создаёт/удаляет элементы, меняет size.
  • Использование operator[] вне диапазона — неопределённое поведение; для проверки используйте at().
  • Хранение указателей/итераторов на элементы после увеличения объёма — они инвалидируются.
  • Удаление в цикле через erase без аккуратной работы с итераторами — легко пропустить элементы или получить UB. Пользуйтесь erase-remove или возвращаемым итератором erase.

Куда двигаться дальше

Освоив std::vector, вы быстрее поймёте остальные контейнеры STL и алгоритмы. Хотите системно прокачаться на практике? Посмотрите курс с заданиями и разбором ошибок — Пройти «C++ с Нуля до Гуру» и вывести навыки на новый уровень.

Итог: std::vector в C++ — базовый, но невероятно мощный инструмент. Зная различия между size и capacity, правила invalidate и паттерн erase-remove, вы пишете безопаснее и быстрее.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.