C++ 标准库`std::prev`介绍

std::prev 是 C++ 标准库中的一个函数模板,位于 <iterator> 头文件中。它用于获取一个迭代器的前一个位置,适用于双向迭代器和随机访问迭代器。以下是详细介绍:

函数原型

// 返回迭代器 it 的第 n 个前驱
template< class BidirIt >
BidirIt std::prev( BidirIt it, typename std::iterator_traits<BidirIt>::difference_type n = 1 );

参数说明

  • it:输入的双向迭代器。
  • n:要向前移动的步数,默认值为 1。

返回值

返回一个新的迭代器,指向 it 之前的第 n 个位置。

适用场景

  1. 双向迭代器:对于只能向前和向后移动一步的迭代器(如 std::list::iterator),std::prev 比手动多次调用 --it 更方便。
  2. 随机访问迭代器:对于支持直接跳跃的迭代器(如 std::vector::iterator),std::prev 会优化为一步计算,避免循环。
  3. 安全获取前驱:当需要获取容器末尾的前一个元素时(如 std::prev(v.end())),使用 std::prev 比手动计算更安全,可避免越界。

示例代码

#include <iostream>
#include <vector>
#include <list>
#include <iterator>

int main() {
    // 使用 vector(随机访问迭代器)
    std::vector<int> vec = {10, 20, 30, 40, 50};
    auto it = vec.end();
    auto prev_it = std::prev(it, 2); // 获取倒数第二个元素
    std::cout << *prev_it << std::endl; // 输出: 40

    // 使用 list(双向迭代器)
    std::list<char> lst = {'a', 'b', 'c', 'd'};
    auto lst_it = lst.begin();
    std::advance(lst_it, 3); // 移动到 'd'
    auto lst_prev = std::prev(lst_it); // 前一个元素
    std::cout << *lst_prev << std::endl; // 输出: 'c'

    return 0;
}

注意事项

  1. 迭代器类型要求it 必须至少是双向迭代器。如果使用单向迭代器(如 std::forward_list::iterator),会导致编译错误。
  2. 越界风险:如果 n 大于 it 到容器起始位置的距离,行为未定义(可能崩溃)。
  3. 性能差异:对于随机访问迭代器,std::prev 是 O(1) 操作;对于双向迭代器,是 O(n) 操作。

常见应用

  • 获取容器的倒数第 n 个元素:std::prev(container.end(), n)
  • 在循环中安全访问前一个元素:auto prev = std::prev(current_it)
  • std::next 配合,在迭代器范围内移动:std::prev(std::next(it, 5), 3) 等价于 std::next(it, 2)
### C++`std::prev` 函数的用法和示例 `std::prev`C++ 标准库中的一个函数模板,位于头文件 `<iterator>` 中。它返回给定迭代器向前移动指定步数后的迭代器[^1]。该函数的主要用途是简化对反向迭代或基于偏移量的操作。 #### 基本语法 ```cpp template< class InputIt > constexpr InputIt prev( InputIt it, typename std::iterator_traits<InputIt>::difference_type n = 1 ); ``` - 参数 `it` 表示输入的迭代器。 - 参数 `n`(可选)表示向前移动的步数,默认值为 1。 - 返回值是将迭代器 `it` 向前移动 `n` 步的结果。 #### 使用场景 1. **遍历容器时需要访问前一个元素**:当使用正向迭代器时,可以通过 `std::prev` 轻松获取前一个元素。 2. **结合 STL 算法**:在某些算法中需要操作相邻元素时,`std::prev` 提供了简洁的实现方式。 #### 示例代码 以下是一个简单的示例,展示如何使用 `std::prev`: ```cpp #include <iostream> #include <vector> #include <iterator> // 包含 std::prev int main() { std::vector<int> vec = {10, 20, 30, 40, 50}; if (!vec.empty()) { auto it = vec.end(); // 指向最后一个元素之后的位置 --it; // 移动到最后一个元素 std::cout << "Last element: " << *it << std::endl; // 使用 std::prev 获取前一个元素 if (it != vec.begin()) { auto prev_it = std::prev(it); // 移动到倒数第二个元素 std::cout << "Second last element: " << *prev_it << std::endl; } } return 0; } ``` #### 输出结果 ``` Last element: 50 Second last element: 40 ``` #### 注意事项 1. **迭代器有效性**:确保迭代器的有效性,避免越界访问。例如,在调用 `std::prev` 之前,应检查迭代器是否已经指向容器的起始位置。 2. **性能影响**:对于随机访问迭代器(如 `std::vector` 的迭代器),`std::prev` 的操作是 O(1)。但对于输入迭代器或双向迭代器(如 `std::list` 的迭代器),其复杂度为 O(n),因为需要逐步向前移动。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器人及自动驾驶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值