C++ <vector> функция at

класс контейнера C++ <vector>


Среди всех способов доступа к элементам vector,atявляется самым безопасным, поскольку обеспечиваетпроверку границ。

atявляется функцией-членом классов-контейнеров, используется длявозврата элемента в указанной позиции, при этом выполняя проверку границ. Если индекс выходит за границы, выбрасывает исключениеstd::out_of_rangeисключение.

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

Определения слов: atозначает «at», т.е. получает элемент в указанной позиции.


Базовый синтаксис и параметры

atявляется функцией-членом класса-контейнера, поэтому сначала нужно иметь объект контейнера, а затем использовать оператор точка.чтобы вызвать её.

Формат синтаксиса

reference at(size_type pos);
const_reference at(size_type pos) const;

Описание параметра

  • Параметр: pos
    • Тип:size_type(беззнаковый целочисленный тип, обычноsize_t)
    • Описание: Позиция (индекс) элемента, к которому нужно получить доступ. Индекс начинается с 0, а максимальный допустимый индекс —size() - 1。

Описание функции

  • Возвращаемое значение: возвращает ссылку на элемент в указанной позицииСсылка. Если контейнер является const-контейнером, возвращается const-ссылка.
  • Действие: Возвращает элемент в указанной позиции. Если индекс находится вне допустимого диапазона (pos >= size()), он выбросит исключениеstd::out_of_rangeисключение.
  • отличие от operator[]: atвыполняет проверку границ,operator[]не выполняет проверку границ (поведение при выходе за границы не определено).

Пример

Давайте тщательно освоим это с помощью серии примеров, от простого к сложномуatИспользование.

Пример 1: Базовое использование - доступ к элементам

Пример

#include <iostream>
#include <vector>
#include <stdexcept> // Содержит заголовочный файл обработки исключений

int main() {
    // 1. Создайте вектор и добавьте несколько элементов
    std::vector<int> numbers = {10, 20, 30, 40, 50};

    std::cout << "Размер вектора: " << numbers.size() << std::endl;

    ⟦⟧// 2. Использование для доступа к элементам
    std::cout << Первый элемент (at(0)): << numbers.at(0) << std::endl;
    std::cout << Второй элемент (at(1)): << numbers.at(1) << std::endl;
    std::cout << Третий элемент (at(2)): << numbers.at(2) << std::endl;
    std::cout << Последний элемент (at(4)): << numbers.at(4) << std::endl;

    // 3. Использование цикла для доступа ко всем элементам
    std::cout << "Все элементы: ";
    for(size_t i = 0; i < numbers.size(); ++i) {
        std::cout << numbers.at(i) << " ";
    }
    std::cout << std::endl;

    return 0;
}

Ожидаемый вывод:

vector的大小是: 5
第一个元素 (at(0)): 10
第二个元素 (at(1)): 20
第三个元素 (at(2)): 30
最后一个元素 (at(4)): 50
所有元素: 10 20 30 40 50

Анализ кода:

  1. numbers.at(0)Возвращает первый элемент10(индексы начинаются с 0).
  2. numbers.at(4)возвращает последний элемент50(потому чтоsize()равно 5, допустимые индексы — 0-4).
  3. используя циклы иatможно безопасно обойти все элементы.

Пример 2: перехват исключения выхода за пределы диапазона

atОсновное преимущество в том, что он может выбрасывать исключения, позволяя нам обрабатывать ошибки выхода за границы.

Пример

#include <iostream>
#include <vector>
#include <stdexcept>

int main() {
    std::vector<int> numbers = {10, 20, 30};

    // Попытка доступа к позиции за границами
    try {
        std::cout << Попытка доступа к at(10)... << std::endl;
        int value = numbers.at(10); // Это вызовет исключение
        std::cout << Значение: << value << std::endl;
    }
    catch(const std::out_of_range& e) {
        std::cout << Перехвачено исключение: << e.what() << std::endl;
    }

    // Обычный доступ
    try {
        std::cout << Доступ к элементу at(2): << numbers.at(2) << std::endl;
    }
    catch(const std::out_of_range& e) {
        std::cout << Перехвачено исключение: << e.what() << std::endl;
    }

    return 0;
}

Ожидаемый вывод:

尝试访问 at(10)...
捕获到异常: vector::_M_range_check: __pos (which is 10) >= this->size() (which is 3)
访问 at(2): 30

Анализ кода:

  • При доступеat(10)когда индекс выходит за пределы диапазона, выбрасывается исключениеstd::out_of_rangeисключение.
  • catch(const std::out_of_range& e)Перехватить исключение,e.what()возвращает описание исключения.
  • обычный доступ по индексу не выбрасывает исключений.

Пример 3: Сравнение at и operator[]

Сравнениеatиoperator[]Различия в поведении.

Пример

#include <iostream>
#include <vector>
#include <stdexcept>

int main() {
    std::vector<int> numbers = {10, 20, 30};

    std::cout << Используйте at() для доступа к элементам: << std::endl;
    // at() выполняет проверку границ
    for(size_t i = 0; i <= numbers.size(); ++i) {
        try {
            std::cout << "at(" << i << ") = " << numbers.at(i) << std::endl;
        }
        catch(const std::out_of_range& e) {
            std::cout << "at(" << i << ) Выход за пределы диапазона! << std::endl;
        }
    }

    std::cout << "\nИспользуйте operator[] для доступа к элементам: << std::endl;
    // operator[] не выполняет проверку границ; поведение при выходе за пределы не определено
    for(size_t i = 0; i <= numbers.size(); ++i) {
        std::cout << "numbers[" << i << "] = " << numbers[i] << std::endl;
    }

    return 0;
}

Анализ кода:

  • at()При выходе за пределы выбрасывается исключение, и вы можете перехватить и обработать его.
  • operator[]поведение при выходе за пределы не определено и может вернуть мусорные значения, вызвать сбой или привести к другим непредсказуемым результатам.
  • в рабочем коде для безопасности рекомендуется использоватьat()вместо этогоoperator[], особенно когда индекс поступает из пользовательского ввода или внешних данных.

Пример 4: изменение значений элементов

atОн возвращает ссылку, поэтому его можно использовать для изменения значения элемента.

Пример

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {10, 20, 30};

    std::cout << "До изменения: ";
    for(size_t i = 0; i < numbers.size(); ++i) {
        std::cout << numbers.at(i) << " ";
    }
    std::cout << std::endl;

    // Используйте at() для получения ссылки и изменения элемента
    numbers.at(0) = 100;
    numbers.at(1) = 200;
    numbers.at(2) = 300;

    std::cout << "After modification: ";
    for(size_t i = 0; i < numbers.size(); ++i) {
        std::cout << numbers.at(i) << " ";
    }
    std::cout << std::endl;

    return 0;
}

Ожидаемый вывод:

修改前: 10 20 30
修改后: 100 200 300

Анализ кода:

  • numbers.at(0) = 100;Значение первого элемента было изменено через ссылку.
  • Это демонстрируетat()возвращает изменяемую lvalue-ссылку.

класс контейнера C++ <vector>

Другие расширения