C++ for循环,你真的学懂了吗

概念

for 循环是一种在编程语言中常用的控制结构,用于重复执行一段代码块,直到满足特定条件为止。它是一种迭代循环,可以根据给定的条件来控制循环次数。

组成部分

初始化表达式(Initialization Expression)

在循环开始之前,初始化表达式会被执行一次。它用于声明并初始化循环变量,并且只在第一次迭代时执行。

循环条件(Condition)

每次迭代开始之前,循环条件都会被判断。只有当循环条件为真(非零值)时,循环才会继续执行;当循环条件为假(零值)时,循环将终止。

增量/减量表达式(Increment/Decrement Expression)

在每次迭代完成后,增量/减量表达式会被执行。通常用于更新循环变量的值,以控制循环的进行。增量/减量表达式在循环体执行之后、循环条件判断之前执行。

循环体(Loop Body)

循环体是 for 循环中需要重复执行的代码块。它可以包含任意数量的语句或语句块。每次迭代时,循环体都会被执行一次。

执行过程

执行初始化表达式,初始化循环变量。
判断循环条件是否满足,若条件为真,则执行循环体;若条件为假,则跳出循环。
在循环体执行完毕后,执行增量/减量表达式。
回到第二步,继续判断循环条件并执行循环体,直到循环条件为假时退出循环。

种类

基本 for 循环

cpp
for (initialization; condition; increment/decrement) {
// 循环体
}
这是最常见的 for 循环形式。
initialization 是循环变量的初始化表达式
condition 是循环继续执行的条件表达式
increment/decrement 是循环变量的递增或递减表达式。

for 循环遍历数组

for (int i = 0; i < array_size; ++i) {
    
    
    // 循环体
}

这种 for 循环用于遍历数组。i 是循环变量,从 0 开始逐渐递增到 array_size - 1。

嵌套 for 循环

for (initialization; condition; increment/decrement) {
    
    
    for (inner_initialization; inner_condition; inner_increment/decrement) {
    
    
        // 循环体
    }
}

这是一种嵌套的 for 循环形式,可以在内部循环中执行更复杂的操作。注意内外循环使用不同的循环变量。

无限循环

for (;;) {
    
    
    // 循环体
}

这种 for 循环没有定义循环条件,因此会无限循环下去。通常需要在循环体中通过 break 或其他方式手动跳出循环。

范围基于范围的 for 循环

语法
for (element_declaration : range_expression) {
    
    
    // 循环体
}

这种 for 循环用于遍历容器或其他可迭代对象中的元素。element_declaration 是用于声明每个迭代元素的变量,range_expression 是要遍历的范围对象。

示例

#include
#include

int main() {
    
    
    std::vector<int> numbers = {
    
    1, 2, 3, 4, 5};

    // 使用范围基于范围的 for 循环遍历 vector 中的元素
    for (int number : numbers) {
    
    
        std::cout << number << " ";
    }

    return 0;
}

上述代码中,我们定义了一个 numbers 向量并初始化了一些整数值。然后,通过使用范围基于范围的 for 循环,我们可以以一种更简洁的方式遍历 numbers 向量中的每个元素,并将其输出到标准输出流中。输出结果将会是:1 2 3 4 5。

需要注意的是,在范围基于范围的 for 循环中,循环变量 number 的类型会被自动推断为与容器元素类型相同。这意味着你不需要显式地声明循环变量的类型,使得代码更加简洁和易读。

> 范围基于范围的 for 循环适用于几乎所有的容器类型,例如向量(vector)、数组、列表(list)、集合(set)、映射(map)等。它还可以被用于遍历自定义类型实现了迭代器的对象。

C++11 引入的使用范围迭代器的 for 循环

语法
for (auto& element : container) {
    
    
    // 循环体
}

这种形式与范围基于范围的 for 循环相似,但使用了自动类型推导(auto)来声明迭代元素的类型,并且使用引用来避免拷贝。

示例
#include <iostream>
#include <vector>

int main() {
    
    
    std::vector<int> numbers = {
    
    1, 2, 3, 4, 5};

    // 使用范围迭代器的 for 循环遍历 vector 中的元素,并使用引用
    for (auto& number : numbers) {
    
    
        number *= 2;  // 修改原始向量中的每个元素
    }

    // 输出修改后的 vector 中的元素
    for (const auto& number : numbers) {
    
    
        std::cout << number << " ";
    }

    return 0;
}

在上述示例中,我们定义了一个 numbers 向量并初始化了一些整数值。然后,通过使用范围迭代器的 for 循环,我们可以以一种更简洁的方式遍历 numbers 向量中的每个元素,并将其乘以 2。由于我们使用了引用(&)来声明循环变量 number,所以对 number 的修改会直接反映到原始向量中。

输出结果将会是:2 4 6 8 10,即原始向量中的每个元素都被乘以 2。

C++11 引入的带有初始化列表的 for 循环

语法
for (type variable : {
    
    value1, value2, value3, ...}) {
    
    
    // 循环体
}

这种形式允许在循环中遍历指定的初始化列表。

示例
#include <iostream>

int main() {
    
    
    // 使用带有初始化列表的 for 循环遍历指定的元素
    for (int number : {
    
    1, 2, 3, 4, 5}) {
    
    
        std::cout << number << " ";
    }

    return 0;
}

在上述示例中,我们使用带有初始化列表的 for 循环来遍历指定的整数元素 {1, 2, 3, 4, 5}。在每次迭代中,当前元素将被赋值给循环变量 number,然后循环体内的代码将执行一次。

输出结果将会是:1 2 3 4 5,即依次输出初始化列表中的每个元素。

带有初始化列表的 for 循环适用于需要遍历一组预定义元素的情况,无需显式定义容器。它提供了一种简洁、直观的方式来遍历固定的元素序列。

C++17 引入的结构化绑定 for 循环

语法
for (auto& [key, value] : map) {
    
    
    // 循环体
}

这种形式用于遍历关联容器(如 std::map)中的键值对,同时可以使用结构化绑定语法来将键和值分别绑定到变量 key 和 value。

示例
#include <iostream>
#include <map>

int main() {
    
    
    std::map<std::string, int> scores = {
    
    {
    
    "Alice", 90}, {
    
    "Bob", 80}, {
    
    "Charlie", 70}};

    // 使用结构化绑定的 for 循环遍历 map 的键值对
    for (const auto& [name, score] : scores) {
    
    
        std::cout << name << ": " << score << '\n';
    }

    return 0;
}

在上述示例中,我们定义了一个名为 scores 的 std::map,它将每个人的名字映射到他们的分数。通过使用结构化绑定的 for 循环,我们可以以一种更简洁的方式遍历 scores 中的每个键值对,并将键绑定到变量 name,将值绑定到变量 score。在循环体内部,我们可以使用这些变量进行相应的操作。

输出结果将会是:

Alice: 90
Bob: 80
Charlie: 70

结构化绑定的 for 循环提供了一种便捷的方式来同时访问关联容器中的键和值,并将它们绑定到相应的变量中。这使得代码更加清晰和简洁。

C++20 引入的带有协程的 for 循环

语法
for co_await (init; condition; increment) {
    
    
    // 循环体
}

这种形式用于支持异步协程编程模型,其中 co_await 关键字引入了挂起和恢复循环的能力。

示例
#include <iostream>
#include <experimental/coroutine>

struct Range {
    
    
    int start;
    int end;

    struct Iterator {
    
    
        int current;

        bool operator!=(const Iterator& other) const {
    
    
            return current != other.current;
        }

        Iterator& operator++() {
    
    
            ++current;
            return *this;
        }

        int operator*() const {
    
    
            return current;
        }

        std::experimental::suspend_always initial_suspend() {
    
     return {
    
    }; }
        std::experimental::suspend_always final_suspend() {
    
     return {
    
    }; }
    };

    Iterator begin() {
    
    
        return Iterator{
    
    start};
    }

    Iterator end() {
    
    
        return Iterator{
    
    end};
    }
};

Range count_to(int n) {
    
    
    co_return Range{
    
    1, n + 1};
}

int main() {
    
    
    auto range = count_to(5);

    for co_await (int number : range) {
    
    
        std::cout << number << " ";
    }

    return 0;
}

在上述示例中,我们定义了一个 Range 结构体,它表示一个整数范围,并提供了 begin() 和 end() 方法来返回迭代器。迭代器的 operator!=、operator++ 和 operator* 方法分别用于判断迭代是否结束、迭代器递增和获取当前值。

我们还定义了一个异步函数 count_to(),它返回一个协程类型 Range,用于遍历从 1 到指定整数的范围。

在 main() 函数中,我们使用带有协程的 for 循环来异步遍历 count_to(5) 返回的范围。在每次循环迭代中,当前的数字将会被赋值给变量 number,然后循环体内的代码将执行一次。

输出结果将会是:1 2 3 4 5,即依次输出从 1 到 5 的整数。

带有协程的 for 循环提供了一种支持异步编程模型的能力,并且可以在循环中挂起和恢复操作。这使得我们可以更方便地进行异步操作和处理。

猜你喜欢

转载自blog.csdn.net/m0_74921567/article/details/132162776