Processing math: 5%
NOIP学习小站
西安交通大学附属中学航天学校

for循环与do...while循环

使用循环结构编程解决问题时,while循环和算法的流程图是一一对应的,最容易理解。除了while循环,C++还有高度结构化的for循环和与while相似的do...while循环。

一、for循环

首先来看两段功能相同的while循环和for循环程序:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int i;
i = 1;
while(i<=5){
cout<<"Hello"<<endl;
i++;
}
return 0;
}
#include<iostream> using namespace std; int main() { int i; i = 1; while(i<=5){ cout<<"Hello"<<endl; i++; } return 0; }
#include<iostream>
using namespace std;
int main()
{
    int i;
    i = 1;
    while(i<=5){
        cout<<"Hello"<<endl;
        i++;
    }
    return 0;
} 
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int i;
//for比while更精简,高度结构化
for(i=1;i<=5;i++){
cout<<"Hello"<<endl;
}
return 0;
}
#include<iostream> using namespace std; int main() { int i; //for比while更精简,高度结构化 for(i=1;i<=5;i++){ cout<<"Hello"<<endl; } return 0; }
#include<iostream>
using namespace std;
int main()
{
    int i;
    //for比while更精简,高度结构化
    for(i=1;i<=5;i++){
        cout<<"Hello"<<endl;
    }
    return 0;
} 

for循环的使用格式与while循环的对应关系如下(注意for循环()中是两个分号隔开了三条语句):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for(①;②;③){
④;
}
for(①;②;③){ ④; }
for(①;②;③){
    ④;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
①;
while(){
④;
③;
}
①; while(②){ ④; ③; }
①;
while(②){
    ④;
    ③;
}

可见for循环和while循环是相通的,不过for循环整合得更精简,其执行流程如右图所示,对①②③④语句具体功能描述后,for循环的使用格式如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for(控制变量初始化;循环条件;控制变量改变语句){
循环体;
}
for(控制变量初始化;循环条件;控制变量改变语句){ 循环体; }
for(控制变量初始化;循环条件;控制变量改变语句){
    循环体;
}

可见for循环是一种“高度结构化”的循环语句,就像一个功能模块一样,for循环不同位置的语句在其自动执行的流程图中发挥不同的作用。而且for循环中涉及到循环控制变量的语句集中在for后面的()中,所以读了for循环的头部就能够明确循环执行的具体流程,而while往往要读到循环体中修改控制变量值的语句才行,这也是for循环比较while循环的优势。

for循环和while循环是相通的,可以将for循环改写成while循环,也可以将while循环改写成for循环。一般地,要解决的问题循环次数明确的时候,习惯使用for循环;循环条件明确的时候,习惯使用while循环。

来看一个例子,计算1+2+3+...+100(也就是\sum\limits_{i=1}^{100}i)的结果。如果不使用高中数学的“等差数列求和公式”,大家应该能联想到前面介绍的累加器:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int s = 0;
s += 1;
s += 2;
s += 3;
//...
s += 100;
cout<<s;
return 0;
}
#include<iostream> using namespace std; int main() { int s = 0; s += 1; s += 2; s += 3; //... s += 100; cout<<s; return 0; }
#include<iostream>
using namespace std;
int main()
{
    int s = 0;
    s += 1;
    s += 2;
    s += 3;
    //...
	s += 100;
	cout<<s; 
    return 0;
}

这里的100条累加语句很显然应该借助循环结构实现,累加语句的形式都是 s += ?;,那么这样的语句应该作为重复执行100次的for循环的循环体(可以很容易总结出重复执行n次的for循环头部可以写出for(i=1;i<=n;i++)):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int i,s = 0;
for(i=1;i<=100;i++){
s += ?;
}
cout<<s;
int i,s = 0; for(i=1;i<=100;i++){ s += ?; } cout<<s;
int i,s = 0;
for(i=1;i<=100;i++){
	s += ?;
}
cout<<s;

那么循环体中的s += ?;中?处应该填写什么内容呢?再来分析100次循环执行语句:第1次循环是 s += 1; 第2次循环是 s += 2;第3次循环是 s += 3;……第100次循环是 s += 100;,那么第i次循环应该是 s += i;。大家要注意这一个找规律并抽象归纳的过程,以后我们再探讨循环执行流程就应该说第i次循环执行什么操作,而不是停留在分析具体的第1次、第2次……循环执行什么操作。这样完整的程序代码如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int i,s = 0;
for(i=1;i<=100;i++){
s += i; //第i次循环:s累加上i
}
cout<<s;
return 0;
}
#include<iostream> using namespace std; int main() { int i,s = 0; for(i=1;i<=100;i++){ s += i; //第i次循环:s累加上i } cout<<s; return 0; }
#include<iostream>
using namespace std;
int main()
{
	int i,s = 0;
	for(i=1;i<=100;i++){
		s += i;     //第i次循环:s累加上i
	}
	cout<<s; 
    return 0;
} 

分析变量i的作用,可知其首先作为循环的控制变量,控制循环的执行流程;此外在循环体中变量i还参加了计算。

再来看一个例子:指定正整数n,计算n的阶乘: n! = 1 \times 2 \times 3 \times ... \times n(也就是 n! = \prod\limits_{i=1}^{n}i

分析:这里应该使用累乘器来计算n!。首先输入正整数n,累乘器变量t初值赋值为1,使用for实现n次循环,循环体中实现累乘:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int n;
//计算n!,n值即使不大,但n!可能很大,最好使用long long
long long t = 1;
cin>>n;
for(int i=1;i<=n;i++){
t *= i; //第i次循环:t累乘上i
}
cout<<t;
return 0;
}
#include<iostream> using namespace std; int main() { int n; //计算n!,n值即使不大,但n!可能很大,最好使用long long long long t = 1; cin>>n; for(int i=1;i<=n;i++){ t *= i; //第i次循环:t累乘上i } cout<<t; return 0; }
#include<iostream>
using namespace std;
int main()
{
    int n;
    //计算n!,n值即使不大,但n!可能很大,最好使用long long 
    long long t = 1; 
    cin>>n;
    for(int i=1;i<=n;i++){
    	t *= i;     //第i次循环:t累乘上i
	}
	cout<<t;
    return 0;
} 

参照上面的程序,尝试编程完成下面的计算:

  1. 计算1^2+2^2+3^2+...+100^2(也就是\sum\limits_{i=1}^{100}i^2)的结果
  2. 计算1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{100}(也就是\sum\limits_{i=1}^{100}\frac{1}{i})的结果(注意累加器变量的数据类型,注意整数/整数结果是整数!)

二、do...while循环

首先来对比while循环和do...while循环的流程图:

while循环执行流程图
do...while循环执行流程图

从流程图可以看出来,while循环是先判断条件是否成立,条件成立才执行循环体;do...while循环是先执行循环体,然后判断条件是否成立,如果成立继续执行循环体然后再判断。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int i;
i = 1;
while(i<=5){
cout<<"Hello"<<endl;
i++;
}
return 0;
}
#include<iostream> using namespace std; int main() { int i; i = 1; while(i<=5){ cout<<"Hello"<<endl; i++; } return 0; }
#include<iostream>
using namespace std;
int main()
{
    int i;
    i = 1;
    while(i<=5){
        cout<<"Hello"<<endl;
        i++;
    }
    return 0;
} 
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int i;
i = 1;
do{
cout<<"Hello"<<endl;
i++;
}while(i<=5); //;不能少
return 0;
}
#include<iostream> using namespace std; int main() { int i; i = 1; do{ cout<<"Hello"<<endl; i++; }while(i<=5); //;不能少 return 0; }
#include<iostream>
using namespace std;
int main()
{
    int i;
    i = 1;
    do{
        cout<<"Hello"<<endl;
        i++;
    }while(i<=5);   //;不能少
    return 0;
} 

while循环是当条件成立时一直执行循环体,do...while循环是执行循环体后判断是否再次重复执行循环体。一般情况下,当循环控制变量初始值相同、循环条件相同、循环体相同时,while循环和do...while循环的效果几乎是相同的。while循环有可能不会执行循环体(循环的条件上来就不成立),而do...while循环会至少执行一次循环体。

三、goto语句实现循环

首先说明,这里只是兴趣扩展,简单介绍一下goto语句以及使用goto语句实现循环。在实际编程中,不要随意使用goto语句,并且应该避免使用goto语句。具体原因可以点击 这里 阅读一篇博文。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int i = 1;
label: //在这一行作了一个标记,标记名称为label
cout<<"Hello World"<<endl;
i++;
if(i<=5){
goto label; //goto意思是前往,语句的作用是跳转到label标记处
}
return 0;
}
#include<iostream> using namespace std; int main() { int i = 1; label: //在这一行作了一个标记,标记名称为label cout<<"Hello World"<<endl; i++; if(i<=5){ goto label; //goto意思是前往,语句的作用是跳转到label标记处 } return 0; }
#include<iostream>
using namespace std;
int main()
{
    int i = 1;
	label:             //在这一行作了一个标记,标记名称为label
	cout<<"Hello World"<<endl;
	i++;
	if(i<=5){
		goto label;    //goto意思是前往,语句的作用是跳转到label标记处
	} 
    return 0;
} 

四、循环控制变量的命名

仔细分析前面例题参考代码,循环控制变量习惯使用 i,j,k 这些变量。这只是惯例,就像符号常量一般全大写一样,遵循这样的惯例可以一定程度增强程序的可读性。

登录

注册