在 C++ 编程里,for 循环是极为常用的控制结构,大都是在我们初学编程语言的时候最早学习的基础内容,它能让代码依据特定条件重复执行。但初学的时候我们一般不会很全面的来学习它的用法,最常见的就是学习了for循环的传统用法。其实for还有其他的典型用法能够给我们的编程带来便利。这里我会全方位介绍 C++ 里 for 循环的各类使用方式,还会搭配实例代码便于大家更好的理解。

一、三种典型循环

(一)、传统 for 循环

1、 基本语法

传统 for 循环包含初始化、条件判断与迭代三个部分,语法如下:

for (initialization; condition; iteration) {
    // 循环体
}
  • initialization:用于初始化循环变量。
  • condition:是循环继续执行的条件。
  • iteration:每次循环结束后对循环变量进行的操作。

2、示例代码

#include <iostream>

int main() {
    for (int i = 0; i < 5; i++) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}

3、代码解释

这种用法是我们初学的时候最早学习到的for的用法。所以这里不做多余的解释。

(二)、基于范围的 for 循环(类似foreach)

1、基本语法

从 C++11 开始引入了基于范围的 for 循环,可简洁地遍历可迭代对象中的每个元素,语法如下:

for (declaration : range) {
    // 循环体
}
  • declaration:声明一个变量,该变量会依次表示 range 里的每个元素。
  • range:是可迭代对象,像数组、std::vector 等。

2、示例代码

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

3、代码解释

该代码运用基于范围的 for 循环遍历 std::vector 容器中的元素并输出。num 会依次代表 numbers 里的每个元素。

4、使用场合

上述代码中,我们使用的是vector容器,其实基于范围的for循环,可以使用在一切序列式容器的和无序集合的数据结构体上,如:
C++ 标准库提供了以下几种序列式容器:
vector:动态数组,支持随机访问,在尾部插入和删除元素效率较高。
deque:双端队列,支持在头部和尾部高效插入和删除元素,也支持随机访问。
list:双向链表,支持在任意位置高效插入和删除元素,但不支持随机访问。
forward_list:单向链表,只支持单向遍历和在头部高效插入和删除元素。
array:固定大小的数组,支持随机访问,大小在编译时确定。
unordered_set:无序集合,使用哈希表实现,存储唯一元素。
unordered_multiset:无序多重集合,允许存储重复元素,基于哈希表。
unordered_map:无序映射,以键值对形式存储元素,键唯一,使用哈希表。
unordered_multimap:无序多重映射,允许键重复的键值对存储,基于哈希表。
除此外,还有自定义的数组、map 、multimap、set、multiset、initializer_list等。
注意,实现了 begin() 和 end() 迭代器相关接口的用户自定义容器或数据结构,比如自定义链表、树等数据结构,只要符合规则都能使用。而堆和栈没有实现begin()和end(),所以堆和栈不能用。

(三)、使用迭代器的 for 循环

1、基本语法

在 C++ 中,很多容器都提供了迭代器,可使用迭代器来遍历容器元素,一般形式如下:

for (auto it = container.begin(); it != container.end(); ++it) {
    // 循环体
}
  • container 是容器对象,begin() 返回指向容器首元素的迭代器,end() 返回指向容器尾后位置的迭代器。

2、示例代码

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    return 0;
}

3、代码解释

此代码使用迭代器遍历 std::vector 容器中的元素。it 是迭代器,从容器首元素开始,只要未到达容器尾后位置,就继续循环,每次循环结束后 it 指向下一个元素,*it 用于访问当前迭代器指向的元素。

4、传统for循环的迭代器用法

其实,传统循环中也是可以使用迭代器的,只不过使用起来稍显麻烦,c++11后都使用上面的形式了。

  1. 传统 for 循环搭配迭代器
    传统 for 循环可以结合迭代器来遍历容器,在循环初始化部分初始化迭代器,条件判断部分检查迭代器是否到达容器末尾,迭代部分移动迭代器。
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // 使用传统for循环和迭代器遍历vector
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    return 0;
}
代码解释:

std::vector::iterator it = vec.begin():初始化一个迭代器 it,使其指向 vec 容器的首元素。
it != vec.end():这是循环的终止条件,当迭代器 it 不等于 vec.end()(指向容器尾后位置)时,循环继续执行。
++it:每次循环结束后,将迭代器 it 向后移动一个位置。
*it:通过解引用操作符 * 访问迭代器所指向的元素。

很明显,这里我传统用法要麻烦一些,而且表达式中包涵一个迭代器iterator,老的代码老的教程中这种传统for的迭代方式依然可以看到,比如菜鸟教程网站(runoob.com)中就是这种。

二、循环表达式的特殊书写

(一)、逗号表达式在 for 循环中的使用

1、基本语法

在传统 for 循环中,可使用逗号表达式同时执行多个初始化操作、多个迭代操作。逗号表达式会从左到右依次计算,并返回最后一个表达式的值。

2、 示例代码

#include <iostream>

int main() {
    for (int i = 0, j = 10; i < j; i++, j--) {
        std::cout << "i: " << i << ", j: " << j << std::endl;
    }
    return 0;
}

3、代码解释

在这个例子中,初始化部分同时初始化了 ij,迭代部分 i 递增 1,j 递减 1。
我们可以看到,这里的i和j两个变量是同步的,实际应用中意义并不大,但我们可以让他们的自加步长不一样也是可以的。

(二)、省略部分表达式的 for 循环

1、基本语法

传统 for 循环的初始化、条件判断、迭代三个部分都能省略,但分号不能省略。

2、示例代码

#include <iostream>

int main() {
    int i = 0;
    for (; i < 5;) {
        std::cout << i << std::endl;
        i++;
    }
    return 0;
}

3、代码解释

此代码省略了初始化部分,因为 ifor 循环之前已初始化;省略了迭代部分,将迭代操作 i++ 放到了循环体内部。
这个有点类似while的操作了,只不过仍然在表达式中保留了两个分号“;”。

(三)、无限循环的 for 循环

1、基本语法

通过省略条件判断部分,可创建无限循环的 for 循环,通常需在循环体内部使用 break 语句跳出循环。

2、示例代码

#include <iostream>

int main() {
    for (;;) {
        std::cout << "This is an infinite loop. Press Ctrl+C to stop." << std::endl;
    }
    return 0;
}

3、代码解释

由于省略了条件判断部分,这个 for 循环会一直执行,除非手动终止程序。
这个方式,就是while(TRUE)的for循环版本了,表达式中保留两个分号。

本文对for的使用方法就介绍到这里,如果您发现还有其他的有趣的用法,其留言,我随时补充到博文中去。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐