C++ 11 for 循环和容器

Range-Based for 循环

C++为 for 提供 for range 的用法。对于 STL(vector/list/map)的遍历带来了极
大的书写便利。

(range for)语句遍历给定序列中的每个元素并对序列中的每个值执行某种操作,
其语法形式是:

for (declaration : expression)
    statement</code>
        

expression 部分是一个对象,必须是一个序列,比方说用花括号括起来的初始值
列表、数组或者 vector 或 string 等类型的对象。这些类型的共同特点是拥有能返回迭
代器的 begin 和 end 成员。
declaration 部分负责定义一个变量,该变量将被用于访问序列中的基础元素。每
次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值。确
保类型相容最简单的办法是使用 auto 类型说明符。
#include <iostream>
using namespace std;

int main(){
    int arr[10] = {1,2,3,4,5,6,7};
    for(auto &i: arr)
    {
        cout<<i<<endl;
    }
    string str = "china"; //OK
    char  str[] = "china"; //OK
    char  * str = "china"; //ERROR
    for(auto & ch: str)
    {
        cout<<ch<<endl;
    }
    return 0;
}

for STL


#include <iostream>
#include <vector>
using namespace std;

int main(){
    // 定义一个长度为10的数组,并初始化前7个元素为1, 2, 3, 4, 5, 6, 7,其余元素默认为0
    int arr[10] = {1, 2, 3, 4, 5, 6, 7};

    // 使用数组arr的首地址和尾地址(arr+10)初始化一个vector<int>,即vi
    // arr是数组的首地址,arr+10表示数组的尾地址(即数组最后一个元素的下一个地址)
    vector<int> vi(arr, arr + 10);

    // 定义一个vector<int>的迭代器it
    vector<int>::iterator it;

    // 使用迭代器遍历vector<int> vi
    for (it = vi.begin(); it != vi.end(); ++it) {
        // 输出迭代器指向的元素值,并换行
        cout << *it << endl;
    }


    for (auto & i : vi){
        i+=5;
    }
    for (auto i : vi){
        cout<<i<<endl;
    }
    return 0;
}


#include <iostream>
#include <map>
using namespace s
<think>好的,我现在需要帮助用户了解如何使用C++for循环来遍历并打印标准容器元素。根据用户的问题,他们希望看到示例代码以及相关的解释。我需要结合用户提供的引用内容,尤其是引用[1]、[3]、[4],这些涉及C++for循环的不同用法,特别是基于范围的循环。 首先,用户可能已经了解传统的for循环,但可能对C++11引入的新特性不太熟悉。根据引用[1],C++for循环有三种用法:传统的for(int i=0; i<N; i++),for_each函数,以及基于范围的for循环。而用户的问题主要针对第三种,即如何用基于范围的for循环来遍历容器。 接下来,我需要确保回答中包含不同类型的for循环示例,特别是基于范围的循环,因为这是C++11的新特性,如引用[4]中提到的。同时,要注意到引用[3]中的警告,不要在遍历容器时修改容器,这可能会导致未定义行为。所以在示例代码中需要提醒用户避免这种情况。 然后,我需要构造示例代码,展示如何用传统for循环、基于范围的for循环以及for_each来遍历打印容器元素。例如,对于vector<int>这样的容器,使用不同的方法遍历,并输出每个元素。要注意代码的正确性,比如使用正确的迭代器,正确的循环结构等。 此外,引用[2]提到了标准库容器算法,可能在回答中可以提到使用标准库中的容器如vector,并配合for循环使用。但用户的问题更侧重于循环本身,所以重点应放在循环结构上。 在组织回答时,需要分步骤解释每种方法,并给出对应的代码示例。同时,指出不同方法的优缺点,比如基于范围的循环更简洁,传统循环更灵活,for_each可以使用函数对象或lambda表达式等。 还需要注意用户提到的不可见指令中的要求,如行内数学公式使用$...$,但这个问题可能不涉及数学公式,所以可能不需要处理。另外,生成相关问题,需要围绕C++for循环使用,可能的优化,注意事项等。 最后,确保引用正确,每个引用的内容在回答中适当的位置标注,例如在提到不要在遍历时修改容器时引用[3],在提到基于范围的循环时引用[4]引用[1]。 总结步骤: 1. 介绍三种遍历方法:传统循环、基于范围的循环for_each。 2. 给出每种方法的示例代码。 3. 指出注意事项,如修改容器的风险。 4. 生成相关问题,如优化方法、不同循环的区别等。 5. 正确引用提供的资料。</think>以下是通过C++标准容器元素遍历及打印的三种主要方法,结合代码示例注意事项说明: ### 一、传统索引循环(适用于顺序容器) ```cpp #include <vector> #include <iostream> int main() { std::vector<int> vec = {1, 3, 5, 7, 9}; // 传统索引循环 for (size_t i = 0; i < vec.size(); ++i) { std::cout << vec[i] << " "; } return 0; } ``` *优点*:直接控制索引,可访问相邻元素 *缺点*:不适用于关联容器(如map)[^2] ### 二、基于范围的循环C++11特性) ```cpp for (const auto& elem : vec) { // 推荐const引用避免拷贝 std::cout << elem << " "; } ``` *特性*: 1. 自动推导元素类型(使用`auto`) 2. 支持所有标准容器(vector/list/set等)[^4] 3. 隐藏迭代器操作,代码更简洁 ### 三、使用for_each算法 ```cpp #include <algorithm> // 使用lambda表达式 std::for_each(vec.begin(), vec.end(), [](int val) { std::cout << val << " "; }); ``` ### █ 注意事项 1. **禁止遍历时修改容器结构** 例如执行`vec.push_back()`会导致迭代器失效[^3] ```cpp // 错误示例(导致未定义行为) for (auto elem : vec) { vec.pop_back(); // 危险操作! } ``` 2. 需要写访问时使用引用 ```cpp for (auto& elem : vec) { elem *= 2; // 修改元素值 } ``` 3. 结构化绑定(C++17) ```cpp std::map<int, std::string> m; for (const auto& [key, value] : m) { // 解构键值对 std::cout << key << ":" << value; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

可能只会写BUG

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

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

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

打赏作者

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

抵扣说明:

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

余额充值