【C++ Primer Plus学习记录】for循环

很多情况下都需要程序执行重复的任务,C++中的for循环可以轻松地完成这种任务。

我们来从程序清单5.1了解for循环所做的工作,然后讨论它是如何工作的。

//forloop.cpp
#if 1
#include
using namespace std;

int main()
{
	int i;
	for (i = 0; i < 5; i++)
	{
		cout << i;
		cout << " C++ knows loops.\n";//循环体
	}
	cout << "C++ knows when to stop.\n";

	system("pause");
	return 0;
}
#endif

1.for循环的组成部分

for循环为执行重复的操作提供了循序渐进的步骤。for循环的具体工作步骤如下:

(1)设置初始值。

(2)执行测试,看看循环是否应当继续进行。

(3)执行循环操作。

(4)更新用于测试的值。

其结构为:

for(初始化;测试;更新)
    循环体

循环只执行一次初始化。

测试表达式决定循环体是否被执行。通常,这个表达式是关系表达式,即对两个值进行比较。C++并没有将测试的值限制为只能为真或假。可以使用任意表达式,C++将把结果强制转换为bool类型。因此,值为0的表达式将被转换为bool值false,导致循环结束。如果表达式的值非0,则被强制转换为bool值true,循环将继续进行。程序清单5.2通过将表达式i用作测试条件来演示了这一特点。

#if 1
#include
using namespace std;

int main()
{
	cout << "Enter the starting countdown value: ";
	int limit;
	cin >> limit;
	int i;
	for (i = limit; i; i--)
		cout << "i = " << i << endl;
	cout << "Done now that i = " << i << endl;

	system("pause");
	return 0;
}
#endif 

for循环是入口条件循环。这意味着在每轮循环之前,都将计算测试表达式的值,当测试表达式为false时,将不会执行循环体。例如,假设重新运行程序清单5.2中的程序,但将起始值设置为0,则由于测试条件在首次被判定时便为false,循环体将不被执行。这种在循环之前进行检查的方式可避免程序遇到麻烦。

更新表达式在每轮循环结束时执行,此时循环体已经执行完毕。通常,它用来对跟踪循环轮次的变量的值进行增减。然而,它可以是任何有效的C++表达式,还可以是其他控制表达式。

【C++ Primer Plus学习记录】for循环_第1张图片

1.1表达式和语句

 C++中,每个表达式都有值。通常值是很明显的。

#if 1
#include
using namespace std;

int main()
{
	int x;

	cout << "The expression x = 100 has the value ";
	cout << (x = 100) << endl;
	cout << "Now x = " << x << endl;

	cout << "The expression x < 3 has the value ";
	cout << (x < 3) << endl;

	cout << "The expression x > 3 has the value ";
	cout << (x > 3) << endl;

	cout.setf(ios_base::boolalpha);//调用设置了一个标记,该标记命令cout显示true和false,而不是1和0。

	cout << "The expression x < 3 has the value ";
	cout << (x < 3) << endl;

	cout << "The expression x > 3 has the value ";
	cout << (x > 3) << endl;

	system("pause");
	return 0;
}
#endif

1.2非表达式和语句

对任何表达式加上分号都可以成为语句,但是这句话反过来说就不对了。也就是说,从语句中删除分号,并不一定能将它转换为表达式。

1.3修改规则

C++循环允许像下面这样做:

for(int i = 0;i < 5;i++)

即在for循环的初始化部分中声明变量。 

2.回到for循环

程序清单5.4使用循环来计算并存储前16个阶乘。阶乘的计算方式如下:零阶乘写作0!,被定义为1。1!是1*0!,即1。依此类推。每个整数的阶乘都是该整数与前一个阶乘的乘积。该程序用一个循环来计算连续阶乘的值,并将这些值存储在数组中。然后,用另一个循环来显示结果。另外,该程序还在外部声明了一些值。

#if 1
#include
using namespace std;

const int ArSize = 16;

int main()
{
	long long factorials[ArSize];
	factorials[1] = factorials[0] = 1LL;
	for (int i = 2; i < ArSize; i++)
		factorials[i] = i * factorials[i - 1];
	for (int i = 0; i < ArSize; i++)
		cout << i << "! = " << factorials[i] << endl;

	system("pause");
	return 0;
}
#endif

3.修改步长

到现在为止,循环示例每一轮循环都将循环计数加1或减1。可以通过修改更新表达式来修改步长。

例如,程序清单5.5中的程序按照用户选择的步长值将循环计数递增。它没有将i++用作更新表达式,而是使用表达式i=i+by,其中,by是用户选择的步长值。

#if 1
#include
using namespace std;

int main()
{
	cout << "Enter an integer: ";
	int by;
	cin >> by;
	cout << "Counting by " << by << "s:\n";
	for (int i = 0; i < 100; i = i + by)
		cout << i << endl;

	system("pause");
	return 0;
}
#endif

4.使用for循环访问字符串

for循环提供了一种依次访问字符串中每个字符的方式。

例如:程序清单5.6让用户能够输入一个字符串,然后按相反的方向逐个字符地显示该字符串。在这个例子中,可以使用string对象,也可以使用char数组,因为它们都让您能够使用数组表示法来访问字符串中的字符。程序清单5.6使用的是string对象。string类的size()获得字符串中的字符数;循环在其初始化表达式中使用这个值,将i设置为字符串中最后一个字符的索引(不考虑空值字符)。为了反向计数,程序使用递减运算符(--),在每轮循环后将数组下标减1。另外,程序清单5.6使用关系运算符(>=)来测试循环是否到达第一个元素。

#if 1
#include
#include//要使用string类,必须在程序中包含头文件string
using namespace std;

int main()
{
	string str1;
	cout << "Enter a string: ";
	cin >> str1;

	for (int i = str1.size() - 1; i >= 0; i--)//string类的size()获得字符串中的字符数;循环在其初始化表达式中使用这个值,将i设置为字符串中最后一个字符的索引(不考虑空值字符)。
		cout << str1[i];
	cout << "\nBye.\n";

	system("pause");
	return 0;
}
#endif

5.递增运算符(++)和递减运算符(--)

递增运算符(++)和递减运算符(--):前缀版本位于操作数前面,如++x;后缀版本位于操作数后面,如x++。两个版本对操作数的影响是一样的,但是影响的时间不同。这就像吃饭前买单和吃饭后买单的最终结果是一样的,但是买单的时间不同。

程序清单5.7演示递增运算符(++)的这种差别。

//5.7
#if 1
#include
using namespace std;

int main()
{
	int a = 20, b = 20;
	cout << "a   = " << a   << ":   b = " << b << endl;
	cout << "a++ = " << a++ << ": ++b = " << ++b << endl;
	cout << "a   = " << a   << ":   b = " << b << endl;

	system("pause");
	return 0;
}
#endif

a++意味着使用a的当前值计算表达式,然后将a的值加1;而++b的意思是先将b的值加1,然后使用新的值来计算表达式。 

6.副作用和顺序点

 副作用(side effect)指的是在计算表达式时对某些东西(如存储在变量中的值)进行了修改;

顺序点(sequence point)是程序执行过程中的一个点,在这里,进入下一步之前将确保对所有的副作用都进行了评估。在C++中,语句中的分号就是一个顺序点,这意味着程序处理下一条语句之前,赋值运算符、递增运算符和递减运算符执行的所有修改都必须完成。另外,任何完整的表达式末尾都是一个顺序点。

7.前缀格式和后缀格式

虽然选择使用前缀格式还是后缀格式对程序的行为没有影响,但执行速度可能有细微的差别。对于内置类型和当代的编译器而言,这看似不是什么问题。然而,C++允许您针对类定义这些运算符,在这种情况下,用户这样定义前缀函数:将值加1,然后返回结果;但后缀版本首先复制一个副本,将其加1,然后将复制的副本返回。因此,对于类而言,前缀版本的效率比后缀版本高。

总之,对于内置类型,采用哪种格式不会有差别;但对于用户定义的类型,如果有用户定义的递增和递减运算符,则前缀格式的效率更高。

8.递增/递减运算符和指针

 

你可能感兴趣的:(学习,c++,数据结构,开发语言,软件工程)