《C++ primer plus》读书笔记二:基础语法(第五章)

 

C++ primer plus 第五章:循环和关系表达式


 

目录

C++ primer plus 第五章:循环和关系表达式

一、for循环

二、while循环

三、do while循环

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

五、嵌套循环和二维数组

六、循环和文本输入

 




一、for循环

  • for循环的组成:for(initialization;test-expression;update-expression)

        如:for (i = 1 ; i < 10 ; i++){body}

  • i 的声明可以在for中进行:for (int i = 1 ; i < 10 ; i++)

        这样声明的 i 是一个局部变量,只在for循环体内有效,后文会详述局部变量。

  • 赋值表达式有值,值为左边成员的值:

        22 + 27 的值是49

        x = 20 的值是20

        maids = (cooks = 4) + 3的值为7

  • <<运算符的优先级比算数运算符高,因此要使用括号:cout << (x = 4) << endl;
  • 修改步长:i ++ 和 i -- 的步长都是1,for允许用户使用其他表达式来代表步长,如

        int by = 2;

        for (int i =1; i < 10 ; i = i + by)

  • 递增运算符(++)和递减运算符(--)
  • 前缀格式和后缀格式(以++为例,--同理): ++ i 和 i ++

        一般来说,前缀格式意味着先对 i 加 1 ,再参与运算,

        如:int i = 10;

               cout << ++ i;

        输出值为11。

        后缀格式意味着先让 i 参与运算,再对 i 加 1。

        如:int i = 10;

               cout << i ++;

               cout << i;

        输出值为10和11.

        优先级:前缀递增(递减)和指针解除引用运算符优先级相同,以从右到左的方式进行结合;后缀递增(递减)比前缀运算符优先级高。

        例,声明:

                double arr[3] = [21.1,22.3,23.5];

                double *pt = arr;

        对于:*++pt;        先对pt递增一次,再将*运用于pt,值为22.3

        对于:++*pt;     先将*运用于pt,再对*pt递增一次,值为22.1

        对于:*pt++;     先对pt递增一次,再将*运用于pt,值为22.3

               

  • 副作用和顺序点

        副作用指表达式对变量做出了修改的行为,顺序点是程序执行时的一个点,要确保在每个顺序点前的副作用都发生了才能继续执行。

        如:int i = 9;

               while (i++ < 10)

                      cout << i ;

        在这里,while语句的末尾就是一个顺序点,在此之前i ++ 的副作用要确保发生了才会继续执行,因此 i 先以值 9 通过while循环条件判定,再执行 i ++让 i 加 1,然后才进入循环体,输出值为10。

        而对于这个例子:y = (4 + x--) + (6 + x++);

        顺序点在末尾,x将以当前值执行完这条语句后,先递减一次,再递增一次。所以也可以这么说,后缀格式的递增(递减)运算符将在顺序点之前的其他语句执行完后再依次执行。

  • 组合赋值运算符(略)
  • 复合语句块和局部变量

        复合语句块:for循环体内可以包含多条语句,用花括号包起来。

        在复合语句块中定义的变量有以下特点:

  1. 只在语句块内生效,循环结束后释放
  2. 若定义的变量名在之前已经使用了,那么在循环执行过程中将发生隐藏(新变量将旧变量藏起来),循环结束后还原。
  • 逗号运算符:允许将两条表达式放在同一位置

        如:for (i = 0,j = 99 ; i < j ; i ++,j++)

        ps : 逗号运算符是一个顺序点

  • 关系表达式(略)

二、while循环

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

        详细的说它们之间存在三个差别:

  1. 在for循环中,可使用初始化语句声明一个局部变量,但在while中不可以
  2. 在for循环中省略的测试条件时,将认为条件是true
  3. 如果循环体中包括continue,情况会有所不同。(看完第六章后回来补充)
  • 编写延时循环:函数clock()可返回程序开始执行后所用的系统时间。头文件ctime定义了一个符号常量CLOCK_PER_SEC,该常量为每秒钟包含的系统时间单位数。ctime将clock_t作为clock()返回类型的别名,这意味着可以将变量声明为clock_t类型。
#include<iostream>
#include<ctime>
int main()
{
	using namespace std;
	cout << "Enter the delay time,in seconds: ";
	float secs;
	cin >> secs;
	clock_t delay = secs * CLOCKS_PER_SEC;    //将延迟时间秒数转换为系统时间
	cout << "starting\a\n";
	clock_t start = clock();    //开始循环时的时间
	while(clock() - start < delay)
		;    //就算循环体为空也要写上分号
	cout << "done \a\n";
	return 0;	
} 

        该程序以系统时间单位为单位(而不是以秒为单位)计算延迟时间,避免了在每轮循环中将系统时间转换为秒。


三、do while循环

  • do while循环是出口条件循环,至少会执行一次,其他地方与while循环一致

        格式为:do

                      {

                                body;

                       }while(test-expression);


 


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

  • C++ 11新增了一种基于范围的for循环,这简化了一类常见循环问题:对数组(或者容器类,如vector、array)的每个元素执行相同操作。如:

        int prices[5] = {1,2,3,4,5};

        for (int x : prices)

                cout << x << std::endl;

        x表示数组prices的第一个元素,之后每执行一次循环体x将表示后一位的元素。

  • 如果要修改数组的元素,则应使用以下形式:

        for (int &x : prices)

                x = x*2;

  • 还可以与初始化列表结合:

        for (int x : {1,2,3,4,5})

                cout << x << " ";

        这种循环将在16章中用于讨论各种模板容器类。

 


       

五、嵌套循环和二维数组

  • 二维数组:int maxtemps[4][5];        //表示一个具有4个元素的二维数组,每个元素都是一个具有5个整数的一维数组
  • 二维数组的初始化:

        int maxtemps[3][4] = 

        {

                {1,2,3,4},

                {5,6,7,8},

                {9,10,11,12}

        };

  • 指针数组:char* cities[2] = {"china city","america city"};

        这样声明使得该数组中的每一个元素都是一个char指针,指向一个字符串的首地址。

  • 嵌套循环

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

        {

                for (int j = 0;j < n ; j ++)

                {

                        body;

                }

        }


六、循环和文本输入

        本节讨论循环完成的最常见的一项任务:逐字符地读取来自文件或者键盘的文本。在C++中cin对象支持3中不同模式的单字符输入,其用户接口各不相同。

  • 使用原始的cin进行输入 
#include<iostream>
int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cout << "Enter characters;enter # to quit:\n";
	cin >> ch;
	while(ch != '#')
	{
		cout << ch << endl;
		++count;
		cin >> ch;
	}
	cout << count << " characters read";
} 

这段代码实现一个这样的功能:从用户端得到输入字符,并回显在屏幕上,直到读取到'#'字符(这种字符称为哨兵字符)停止。这种方式有两个特点:

  1. cin会忽略空格和换行符,且不会将二者计数。
  2. 发送给cin的输入会被缓冲,只有按下回车之后才会将输入的内容发送给程序。
  • 使用cin.get(char)对上述第一点改进

       

#include<iostream>
int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cout << "Enter characterslenter # to quit:\n";
	cin.get(ch);
	while(ch != '#')
	{
		cout << ch << endl;
		++count;
		cin.get(ch);
	}
	cout << count << " characters read";
} 

cin.get(ch)将会读取输入的下一个字符,包括空格。

  • 文件尾条件

        上述两种输入方式都存在一个问题,就是哨兵字符可能本身就是输入的一部分。若输入来自于文件,C++提供了一种功能更为强大的技术——检测文件尾(EOF)。

#include<iostream>
int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cout << "Enter characters:\n";
	cin.get(ch);
	while (cin.fail()== false)
	{
		cout << ch;
		++count;
		cin.get(ch);
	} 
	cout << endl << count << "characters read\n" ;
	return 0;
}

        当cin识别到文件尾EOF后,eofbit位和failbit位将被设置为1,通过函数eof()和fail()可以判断这两位是否被设置,若被设置为1,则函数返回true,否则返回false。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值