第4章 全能又好用的for语句

4.1 计数循环

如下图所示,循环总共包含三个步骤:
1.初始化循环计数器;
2.测试循环条件;
3.条件为真就执行语句并递增。除非条件为false,否则会一直从第2步重复。

如果能用更简洁的语句表达这些步骤,写数到10的循环将非常容易。

4.2 for循环入门

for语句允许用一行指定初始化列表、条件和递增,如下图所示。

for (i = 1; i <= 10; ++i)
	cout << i << " ";

在这里插入图片描述

C++14:
C++11和之后的版本提供了for关键字的一个新版本(称为“基于范围的for”),能自动处理集合所有成员,类似于其他语言的foreach。但使用该版本需要理解数组和容器。

4.3 大量例子

for (i = 1; i <= 5; ++i)
{
	cout << i << " ";
}

// 输出:
// 1 2 3 4 5
for (i = 10; i <= 20; ++i)
{
	cout << i << " ";
}

// 输出:
// 10 11 12 13 14 15 16 17 18 19 20
n1 = 32;
n2 = 38;
for (i = n1; i <= n2; ++i)
{
	cout << i << " ";
}

// 输出:
// 32 33 34 35 36 37 38
for (i  = 10; i >= 1; --i)
{
	cout << i << " ";
}

// 输出:
// 10 9 8 7 6 5 4 3 2 1
for (i = 1; i <= 11; i = i + 2)
{
	cout << i << " ";
}

// 输出:
// 1 3 5 7 9 11
for (j = 1; j <= 5; ++j)
{
	cout << j * 2 << " ";
}

// 输出:
// 2 4 6 8 10

for 和 while 的行为永远一样吗?
for是while的特例,行为和对应的while循环完全一样,但有一个例外。
这个例外涉及continue关键字。在循环中使用该关键字,单列为语句,从而“立即跳到下一次循环迭代”。

continue;
这是一种”直接跳转“语句,并不终止当前循环(那是break关键字的工作),只是加快一下速度。
行为上的区别是:在while循环中,continue语句会忽视递增(++i),直接跳到下一次循环迭代。但在for语句中,continue语句会在跳转前执行递增。第二个行为通常是你希望的,这是选择for的另一个理由。

例4.1:用for打印1到N

// count2.cpp
# include <iostream>
using namespace std;

int main()
{
	int n = 0;
	int i = 0; //for语句的循环计数器
	// 从键盘获取一个数并初始化n
	cout << "请输入一个数并按Enter:";
	cin >> n;

	for (i = 1; i <= n; ++i)
	{
		cout << i << " "; // 打印i
	}
	return 0;
}

练习 4.1.1

在程序中用for循环打印n1到n2的所有数,n1和n2由用户输入。提示:需要提示用户输入两个值,在for语句中将i初始化成n1,在循环条件中使用n2.

答案:

// 打印 n1到n2
# include <iostream>
using namespace std;

int main()
{
	int i = 0, n1 = 0, n2 = 0;

	cout << "请输入n1的值:";
	cin >> n1;
	cout << "请输入n2的值:";
	cin >> n2;

	for (i = n1; i <= n2; ++i)
	{
		cout << i << " ";
	}

	return 0;
}

练习4.1.2

更改本节的例子,逆序打印n到1的所有数,例如,用户输入5就打印 5 4 3 2 1.提示:在for循环中将i初始化为n,使用条件i > = 1, 然后使i递减1.

答案:

// 逆序打印n到1
# include <iostream>
using namespace std;

int main()
{
	int i = 0, n = 0;

	cout << "请输入一个数:";
	cin >> n;

	for (i = n; i >= 1; --i)
	{
		cout << i << " ";
	}

	return 0;
}

练习4.1.3

写程序打印从n1到n2的所有数,但只打印偶数或奇数。打印的每个数都比上个数大2.

答案:

// 打印n1到n2的所有数,每个数比上个数大2
# include <iostream>
using namespace std;

int main()
{
	int i = 0, n1 = 0, n2 = 0;

	cout << "请输入第一个数:";
	cin >> n1;
	cout << "请输入第二个数:";
	cin >> n2;

	for (i = n1; i <= n2; i = i + 2)
	{
		cout << i << " ";
	}

	return 0;
}

4.4 局部循环变量

for语句一个好处是可以声明只在循环内部有效的变量(for的局部变量)。例如:

for (int i = 1; i <= n; ++i)
	cout << i << " ";

i在for语句的初始化列表中声明,这使i称为for的局部变量。在for循环中修改i不会影响循环外面声明的i。

// count3.cpp
# include <iostream>
using namespace std;

int mian()
{
	int n = 0;
	//从键盘获取一个数并初始化n
	cout << "输入一个数并按Enter:";
	cin >> n;
	for (int i = 1; i <= n; ++i)
	{
		cout << i << " ";
	}
	return 0;
}

例4.2:用for进行质数测试

// prime2.cpp
# include <iostream>
# include <cmath>
using namespace std;

int main()
{
	int = 0;
	bool is_prime = ture;

	cout << "输入一个数并按Enter:";
	cin >> n;

	//用2到sqrt(n)的所有整数来除它,看是否能整除
	for (int i = 2; i <= sqrt(n); ++i)
	{
		if (n % i == 0)
		{
			is_prime = false;
		}
	}
	
	//打印结果
	if (is_prime)
	{
		cout << "是质数。" << endl;
	}
	else
	{
		cout << "不是质数。" << endl;
	}

	return 0;
]

练习4.2.1

对例4.2进行优化。目前电脑CPU速度都很快,所以优化后除非测试相当大的数(比如10亿以上),否则看不出多大差异。另外,即使测试那么大的数,也要恰好是质数才行。大质数可不好找。但无论如何,以下优化措施都能提高测试大数时的效率。

  • n的平方根只计算一次。声明变量square_root_of_n,在进入循环前就算好它的值。该变量应为double。
  • 找到n的整除数,循环就可以退出了。不需要再找更多的整除数。在循环主体的if语句中,将is_prime设为false后就用break语句中断循环。

答案:

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

int main()
{
	int n = 1;
	double square_root_of_n = 0;
	bool is_prime = true;

	cout << "请输入一个数并按Enter:";
	cin >> n;
	square_root_of_n = sqrt(n);

	for (int i = 2; i <= square_root_of_n; ++i)
	{
		if (n % i == 0)
		{
			is_prime = false;
			break;
		}
	}

	if (is_prime)
	{
		cout << "是质数。" << endl;
	}
	else
	{
		cout << "不是质数。" << endl;
	}

	return 0;
}

4.5 语言对比:Basic语言的For语句

用Basic语言或Fortran语言写过程序,应该看到过和C++语言for相似的语句。作用同样是数数。

For i = 1 To 10
	Print i
Next i

Basic语言的For语句优点是表达清楚、易于使用。无可否认,它比C++语言的For要少打一些字。但C++的for更灵活。

C++语言的for的一个灵活性是可以和任意三个有效的C++表达式配合使用。条件(中间的表达式)甚至不一定是i < n这样的逻辑表达式(虽然最好是)。在if, while 和for中对条件进行求值,任何非零结果都被视为true。

for还不要求写完全部三个表达式(初始化、条件和递增)。初始化和递增表达式如缺少将被忽略。条件表达式如缺少将默认为true,相当于创建一个无限循环。

for (;;)
{
	// 无限循环
}

小结

  • for语句常用于重复执行操作,直至计数到特定值。语法如下:
for(初始化列表;条件;递增)
	语句
// 等价于以下while循环:
初始化列表;while(条件){
	语句
	递增;
}
  • for 循环的行为和 while 循环一样,但有一个例外:在 for 循环中使用 continue 语句,会在循环变量递增之后,才跳到下一次循环迭代。
  • 和其他控制结构一样,可在for中使用大括号({ })来包含复合语句(代码块)。许多程序员都推荐该风格,因为有助于以后添加语句,而且在复杂程序中,大括号有助于澄清程序结构
for(初始化列表;条件;递增){
	语句
  • 下例中的变量1称为循环变量:
for(i = 1;i <= 10;++i)
cout << i << " ";
}
  • 可以在初始化列表中动态声明变量。这会使变量具有局部于 for 循环本身的作用域。换言之,在循环内修改变量不影响循环外声明的同名变量。
for(int i = 1;i <= 10;++i){
cout << i << " ";
  • 和 if 及 while 一样,for语句的循环条件可以是任何求值为 true/false 或数值的有效C++表达式;任何非零值都被视为true.
  • for语句圆括号内的三个表达式均可省略(初始化、条件和递增)。省略条件,循环会无条件执行(即无限循环),要用break语句中断。
for(; ;){
	// 无限循环
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值