Скидка до 55% и курс по ИИ в подарок 2 дня 10 :28 :07 Выбрать курс
Код
#статьи

Векторы и строки в C++: что это и как их использовать

Учимся создавать, заполнять, изменять, перебирать и сортировать векторы.

Иллюстрация: Polina Vari для Skillbox Media

Почти любая программа работает не с одним значением, а сразу с целыми наборами данных. Например, ей может понадобиться хранить список оценок, названия файлов, сообщения пользователя или результаты вычислений. В C++ для таких задач часто используют строки и векторы.

std::string предназначен для работы с текстом, а std::vector — с последовательностями элементов одного типа. Оба инструмента входят в стандартную библиотеку C++ и используются повсеместно — от учебных программ до больших приложений.

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

Содержание


Что такое строки и векторы в C++

Программам часто приходится работать с текстом и наборами данных. Например, хранить название товара, список покупок или результаты вычислений. Для текста в C++ используют строки, а для последовательностей элементов одного типа — векторы.

Разберём оба понятия на примере списка покупок. Каждое название товара сохраним в отдельной строке, а затем объединим несколько строк в один вектор. Полную программу с #include и функцией main() напишем ниже.

Как работают строки

std::string — тип данных для хранения и работы с текстом в C++. Тип определяет, какие значения можно записывать в переменную и какие операции с ними доступны. Например, int используют для целых чисел, а std::string — для строк.

Строка состоит из символов, расположенных друг за другом. Это могут быть буквы, цифры, пробелы и знаки препинания. Например, строка «green tea» содержит девять символов: два слова и пробел между ними.

Создадим строку с названием товара:

std::string product = "bread";

Здесь создаётся переменная product, в которую записывается строка «bread».

Разберём запись по частям:

  • std: string указывает тип переменной;
  • product — имя переменной, по которому к ней можно обращаться в программе;
  • = присваивает переменной значение справа;
  • «bread» — строковое значение, двойные кавычки показывают, где начинается и заканчивается текст.

После создания строку можно вывести на экран, изменить, сравнить с другой строкой или обработать по отдельным символам. При этом весь текст хранится в одной переменной — product.

Как работает вектор

Представим, что нам надо записать в программе сразу три товара. Их можно сохранить в трёх строковых переменных:

std::string product1 = "bread";
std::string product2 = "milk";
std::string product3 = "apples";

Но тогда для каждого товара понадобится отдельная переменная. Если в список добавить четвёртый товар, придётся создать product4 и отдельно учитывать его в коде. И с каждым новым товаром количество кода будет увеличиваться.

Для работы с последовательностями данных в C++ используют вектор — std::vector. Он хранит несколько элементов одного типа и позволяет добавлять и удалять их во время работы программы.

Соберём названия товаров в один вектор:

std::vector<std::string> products = {
    "bread",
    "milk",
    "apples"
};

Разберём запись:

  • std::vector указывает, что мы создаём вектор;
  • <std::string> задаёт тип его элементов — строки;
  • products — имя переменной;
  • в фигурных скобках {} перечислены начальные элементы вектора.

Отдельное значение внутри вектора называют элементом. В нашем примере их три:

products: | "bread" | "milk" | "apples" |

Каждый элемент — отдельная строка. Вектор сохраняет порядок элементов: «bread» находится первым, «milk» — вторым, а «apples» — третьим.

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

std::string и std::vector входят в стандартную библиотеку C++. Чтобы использовать их в программе, нужно подключить соответствующие заголовочные файлы. Для строк это <string>, а для векторов — <vector>. Как это сделать, покажем в полной программе ниже.

Как подключить вектор и узнать количество элементов

Соберём короткую программу. Она создаёт список из трёх товаров и выводит количество элементов в нём:

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> products = {
        "bread",
        "milk",
        "apples"
    };

    std::cout << products.size() << '\n';
}

​Программа напечатает:

3

​Строки с #include подключают части стандартной библиотеки, которые нужны программе:

  • <iostream> — для вывода данных с помощью std::cout;
  • <string> — для работы с std::string;
  • <vector> — для работы с std::vector.

Выражение products.size() возвращает количество элементов в векторе products. В нашем случае их три, поэтому программа выводит 3.

size() — метод std::vector, то есть функция, которая относится к объекту вектора. Чтобы вызвать метод, после имени вектора ставят точку и пишут его название: products.size(). Пустые круглые скобки означают, что этому методу не нужно передавать дополнительные данные.

Как получить и изменить элемент по индексу

У каждого элемента есть номер — индекс. Важно, что C++ начинает считать индексы с нуля.

ИндексЭлемент
0"bread"
1"milk"
2"apples"

Поэтому первый элемент имеет индекс 0, второй — 1, а третий — 2.

Квадратные скобки помогают получить элемент по его индексу:

std::cout << products[0] << '\n'; // bread
std::cout << products[1] << '\n'; // milk

Запись products[1] читается так: «взять из products элемент с индексом 1». Это второй по счёту товар — «milk».

Через индекс можно заменить элемент:

products[1] = "coffee";

До этой команды вектор выглядел так:

| "bread" | "milk"   | "apples" |

​После команды:

| "bread" | "coffee" | "apples" |

Выражение products[1] указывает на нужный элемент, а оператор = присваивает ему новое значение.

У вектора из трёх элементов есть индексы 0, 1 и 2. Поэтому обращаться к products[3] нельзя: элемента с таким индексом не существует. При использовании квадратных скобок C++ не проверяет, находится ли индекс в допустимом диапазоне. Такое обращение приводит к неопределённому поведению: программа может выдать неверный результат, завершиться с ошибкой или повести себя как-то иначе.

Как добавить элемент и узнать размер вектора

Начнём с уже знакомого вектора:

| "bread" | "milk" | "apples" |

Добавим в него ещё один товар:

products.push_back("tea");

Теперь в векторе четыре элемента:

| "bread" | "milk" | "apples" | "tea" |

Метод push_back() добавляет новый элемент в конец вектора. В круглых скобках указывают значение, которое нужно добавить. В нашем случае это строка "tea".

Количество элементов в векторе можно узнать с помощью метода size():

std::cout << products.size() << '\n'; // 4

После добавления "tea" метод products.size() вернёт 4.

Важно различать количество элементов и их индексы. Если в векторе четыре элемента, его размер равен 4, но допустимые индексы — от 0 до 3.

Как удалить элементы из вектора

Метод pop_back() удаляет последний элемент вектора:

products.pop_back();

Если до команды вектор выглядел так:

| "bread" | "milk" | "apples" | "tea" |

То после команды останется:

| "bread" | "milk" | "apples" |

В круглых скобках ничего указывать не нужно: pop_back() всегда удаляет последний элемент.

Если вектор пуст, удалить из него последний элемент нельзя. Поэтому перед вызовом pop_back() можно проверить, есть ли в векторе элементы:

if (!products.empty()) {
    products.pop_back();
}

Разберём условие:

  • products.empty() проверяет, пуст ли вектор. Если элементов нет, метод возвращает tru.
  • ! означает «не» и меняет результат на противоположный.
  • поэтому !products.empty() означает «вектор не пуст».

Если условие выполняется, программа вызывает pop_back() и удаляет последний элемент.

Чтобы удалить сразу все элементы, используют метод clear ():

products.clear();

После этого products.size() вернёт 0, а products.empty() — true.

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

Три элемента вектора можно вывести по отдельности:

std::cout << products[0] << '\n';
std::cout << products[1] << '\n';
std::cout << products[2] << '\n';

Но для длинного вектора такой способ неудобен: придётся писать отдельную строку для каждого элемента. Вместо этого можно использовать цикл for, который по очереди обработает все элементы:

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> products = {
        "bread",
        "milk",
        "apples"
    };

    for (std::string product : products) {
        std::cout << product << '\n';
    }
}

Программа выведет:

bread milk apples

Запись for (std::string product: products) можно прочитать так: «Для каждого элемента вектора products выполнить код внутри фигурных скобок». На каждом проходе цикла очередное значение записывается в переменную product.

Цикл выполнится три раза:

первый проход:  product = "bread"
второй проход:  product = "milk"
третий проход:  product = "apples"

На каждом проходе std::cout выводит текущее значение product.

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

Как заполнить вектор с клавиатуры

Вектор можно заполнять не только значениями, записанными в коде, но и данными, которые вводит пользователь. Следующая программа создаёт пустой вектор, считывает три названия товаров и сохраняет их:

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> products;

    std::cout << "Enter three products:\n";

    for (int i = 0; i < 3; ++i) {
        std::string product;
        std::getline(std::cin, product);
        products.push_back(product);
    }

    std::cout << "Your list:\n";

    for (std::string product : products) {
        std::cout << product << '\n';
    }
}

​std::cin — стандартный поток ввода. В этой программе данные поступают в него с клавиатуры. Функция std::getline(std::cin, product) считывает всю введённую строку и сохраняет её в переменной product.

Например, пользователь может ввести:

bread
milk
green 

Сначала вектор products пуст. Цикл for (int i = 0; i < 3; ++i) выполняется три раза. На каждом проходе программа:

  • Считывает очередное название товара в переменную product.
  • Добавляет его в конец вектора products с помощью push_back().

Переменная product хранит только значение, считанное на текущем проходе цикла. Вектор products сохраняет все три введённых значения.

После завершения первого цикла второй цикл for перебирает элементы вектора и выводит их на экран.

Как хранить и сортировать числа

Вектор может хранить не только строки, но и числа. Для этого нужно указать другой тип элементов:

std::vector<int> prices = {120, 80, 150};

int — тип для целых чисел. Поэтому каждый элемент вектора prices содержит целое число, с которым можно выполнять арифметические операции.

Чтобы отсортировать элементы по возрастанию, используйте функцию std::sort():

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

int main() {
    std::vector<int> prices = {120, 80, 150};

    std::sort(prices.begin(), prices.end());

    for (int price : prices) {
        std::cout << price << ' ';
    }
}

Программа выведет:

80 120 150

Заголовочный файл <algorithm> нужен для работы с std::sort().

В вызове std::sort(prices.begin(), prices.end()) программа указывает диапазон элементов, который нужно отсортировать. prices.begin() обозначает начало вектора, а prices.end() — позицию сразу после его последнего элемента. Поэтому функция обрабатывает весь вектор prices.

std::sort() изменяет порядок элементов прямо в исходном векторе. После сортировки сначала идут меньшие числа, а затем большие.

Проверьте себя

Прочитайте программу и попробуйте определить результат до запуска:

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> products = {
        "bread",
        "milk"
    };

    products.push_back("apples");
    products[1] = "coffee";

    std::cout << products.size() << '\n';

    for (std::string product : products) {
        std::cout << product << '\n';
    }
}

Ответ:

3
bread
coffee
apples

Метод push_back() добавил третий элемент, поэтому size() вернул 3. Затем выражение products[1] = «coffee» заменило второй элемент вектора, а цикл вывел все элементы по порядку.

Если коротко, std::vector<std::string> products создаёт вектор строк с именем products. Метод push_back() добавляет новый элемент в конец, квадратные скобки позволяют получить или изменить элемент по индексу, а цикл — перебрать весь вектор по очереди.

Шпаргалка по основным командам

Повторим основные команды для работы со строками и векторами.

КомандаЧто происходит
std::vector<std::string> products;Создаёт пустой вектор строк
std::vector<std::string> products = {"bread", "milk"};Создаёт вектор и сразу добавляет в него элементы
products[0]Возвращает первый элемент вектора
products[1] = "coffee";Заменяет элемент с индексом 1
products.push_back("tea");Добавляет "tea" в конец вектора
products.size()Возвращает количество элементов
products.empty()Проверяет, пуст ли вектор
products.pop_back();Удаляет последний элемент
products.clear()Удаляет все элементы
for (std::string product : products)По очереди перебирает все элементы вектора
std::getline(std::cin, product)Считывает строку, введённую пользователем
std::sort(prices.begin(), prices.end())Сортирует все элементы вектора prices по возрастанию
std::vector<int> prices = {120, 80, 150};Создаёт вектор целых чисел

Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!

Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Курс с трудоустройством: «Профессия Разработчик С++
 с нуля + ИИ» Узнать о курсе
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована