循环

2.7k 词

for循环

for循环的组成部分

for循环的组成部分完成下面这些内容:

  1. 设置初始值
  2. 执行测试,看看循环是否应该继续进行
  3. 执行循环操作
  4. 更新用于测试的值
1
2
for(initialization; test-expression; update-experssion)
body

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
int main()
{
int arraySize = 16;
long long result[16];
result[0] = result[1] = 1LL;

for (int i = 2; i < arraySize; i++)
result[i] = i * result[i - 1];

for (int i = 0; i < arraySize; i++)
std::cout << i << "!: " << result[i] << std::endl;

return 0;
}

表达式和语句

在C++中,任何值或任何有效的值和运算符的组合都是表达式。

非表达式和语句

任何表达式加上分号都是语句,但反过来就不对了。

就目前介绍的语句而言,返回语句、声明语句和for语句都不满足表达式的要求。

但是,for循环是由三个表达式构成的,又允许用户在for中声明变量。这是通过定义一种新的表达式,声明语句表达式实现的,声明语句不带分号声明,只能出现在for语句中。

所以严格来讲,for的格式应该如下:

1
2
for(init_statement condition; update)
body

由于init_statement是一条声明语句,以及存在分号,所以for表面上看只有一个分号。

递增运算符与递减运算符

++,--分别代表对变量+1或-1.

这两种运算符都有两个变体,粗略来说:

  • 当运算符置于操作数前面时,在操作数参与其他运算前先+1/-1.
  • 当运算符置于操作数后面时,在操作数参与其他运算后+1/-1.

副作用和顺序点

副作用指的是在计算表达式时对某些东西进行了修改;顺序点是指程序执行过程的一个点。

在C++中,语句中的分号就是一个顺序点,这意味着程序处理下一条语句之前,赋值运算符、递增运算符和递减运算符执行的所有修改都必须完成。

另外,任何一个完整表达式的末尾都是一个顺序点。

1
2
++x>10; // (x+1)>10
x++>10; // x>10, x++

但在C++11中,为了更好地描述多线程编程,将顺序点改为顺序,它表示有些事件在其他事件前发生。

效率

前缀、后缀在执行速度上有细微的差别,尤其当用户自定义运算符时,前缀则将对应值+1,而后缀需要复制一个副本,将原变量+1,返回副本。

一般而言,使用前缀更快一些。

修改步长

在for循环更新数据时,当然可以选择增加变化的步长。

逗号运算符

逗号运算符允许将两个表达式放到C++句法只允许放在一个表达式的地方。

这在循环中非常方便,例如我们可以在循环的更新中,对两个变量同时处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
#include<string>
int main()
{
using namespace std;

string word;
cin >> word;

for (int j = 0, i = word.size() - 1; j < word.size() / 2; ++j, --i)
{
char temp = word[j];
word[j] = word[i];
word[i] = temp;
}

cout << word << endl;

return 0;
}

while循环

while循环是没有初始化和更新部分的for循环,它只有测试条件和循环体:

1
2
while(test-condition)
body

for与while

在C++中,for与while本质上是相同的,因此使用哪个只是风格上的问题。

他们之间存在三个差别:

  • 在for循环中省略了测试条件时,将认为条件为true.
  • 在for循环中,可使用初始化语句声明一个局部变量,但在while循环中不能这么做。
  • 如果循环体包含continue语句,情况将有所不同。

在设计循环时:

  • 指定循环终止的条件。
  • 在首次测试之前初始化条件。
  • 在条件被再次测试之前更新条件。

延时循环

while循环可用于等待一段时间。

1
2
3
long wait = 0;
while (wait < 10000)
wait++;

上述内容虽然可以延迟一定时间,但是当计算机处理的速度发生变化后,必须修改计数限制。

更好的方法是让系统时钟来完成这种工作。

函数clock()虽然能够返回系统时间,但返回的单位不一定是秒,在不同系统上数据类型也不一致。

头文件ctime提供了相应的解决方案,首先它定义了一个符号常量——CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数。因此将系统时间初一这个值,可以得到描述;ctime将clock_t作为clock()返回类型的别名,这意味着可以将变量声明为clock_t类型,编译器将把它转换为long、unsigned int或合适系统的其他类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<ctime>
int main()
{
using namespace std;

float sec;
cin >> sec;
clock_t delay = sec * CLOCKS_PER_SEC;
clock_t start = clock();

while (clock() - start < delay)
;

return 0;
}

do while 循环

1
2
3
do 
body
while(test-expression);

do while是出口条件循环,这意味着这种循环将首先执行循环体,然后再判断条件表达式。

基于范围的for循环(C++11)

C++11新增了一种循环:基于范围的for循环。这简化了一种常见的循环任务,对数组或容器类的每个元素执行相同的操作:

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
int main()
{
using namespace std;
double prices[3]{ 1.1, 1.2, 1.3 };

for (double price : prices)
cout << price << endl;

return 0;
}
留言