C++ 循环和关系表达式(四)下

1.while循环
while循环是没有初始化和更新部分的for循环
它只有测试条件和循环体:
while(测试表达式)
{
内容
}
C++ 循环和关系表达式(四)下
还可以将while循环内的内容改成name[i],当name[i]为空值字符,其编码将为0或false。对于这种情况,"笨拙"的编译器生成的代码的速度将更快,"聪明"的编译器对于这两个版本生成的代码将相同

2.for与while的区别

①for可以是空表达式,而while不行
C++ 循环和关系表达式(四)下
②while括号内只要输入测试表达式,但在首次测试之前需初始化条件,在条件被再次测试之前更新条件,但for循环的结构就提供上述这些要求。

3."错误"的标点符号

C++ 循环和关系表达式(四)下
while后面添加了标点符号,循环体变成空语句,永远不会被执行

4.类型别名
C++为类型建立别名的方式有两种:

一种是使用预处理器#define 别名 typename,以下zzz即char的别名
C++ 循环和关系表达式(四)下
一种是使用关键字typedef 来创建别名typedef typename 别名

C++ 循环和关系表达式(四)下
指针别名也是如此

C++ 循环和关系表达式(四)下
C++ 循环和关系表达式(四)下
但typedef和#define 区别在哪?可以看出typedef定义的别名是有高亮化的,#define其实是通过预处理器置换将该别名转换类型,而typedef创建的别名cout会把这个别名视为原来的类型,这可以说明typedef能够处理复杂的类型别名,这使得与使用#define相比,使用typedef是一种更佳的选择-有时候,这也是唯一的选择

5.do while循环

这是一个奇特的for循环,空测试条件永远被视为true,只要i递增到30循环就会被打破
C++ 循环和关系表达式(四)下
用do while来复现上述思路

C++ 循环和关系表达式(四)下
6.基于范围的for循环(C++11)

对容器的遍历

C++ 循环和关系表达式(四)下
对列表的遍历

C++ 循环和关系表达式(四)下
修改数组元素

C++ 循环和关系表达式(四)下
此时符号&表明x是一个引用变量,之后会提及

7.哨兵字符

再取自键盘的文本输入,可以选择某个特殊字符来想办法停止读取,该特殊字符就称为哨兵字符(sentinel character)

C++ 循环和关系表达式(四)下
此时#就是哨兵字符

C++ 循环和关系表达式(四)下
⭐你会发现空格被省略了,原因是cin,cin会忽略空格和换行符,因此输入中的空格没有被回显,也没有被包括在计数内。
⭐还有就是,发送给cin的输入被缓冲。这意味着只有在用户按下回车键后,他输入的内容才会被发送给程序。这就是在运行该程序时,可以在#后面输入字符的原因。按下回车键后,整个字符序列将被发送给程序,但程序在遇到#字符后将结束对输入的处理。

那么对空格还是有补救方式的,用istream类的成员函数get(char)

C++ 循环和关系表达式(四)下
如果你熟悉C语言,你会发现ch没加&,但在C++中,这里cin.get(ch)的参数声明为引用类型,你也许会问这是为什么,后面会提到C++函数重载的OOP特性。

8.文件尾条件

⭐EOF(检测文件尾):一种功能强大的技术,且是在文件iostream中定义的
⭐很多PC编程环境都将Ctrl+Z视为模拟的EOF

检查到EOF后,cin将两位(eofbit和failbit)都设置为1.可以通过成员函数eof()来查看eofbit是否被设置;如果检测到EOF,则cin.eof()将返回bool值true,否则返回false。同理cin.fail()也是一样

C++ 循环和关系表达式(四)下
其中enter字符也被纳入计数

还可以这样

C++ 循环和关系表达式(四)下

或是这样

C++ 循环和关系表达式(四)下
最后一种会更通用,因为它可以检测到其他失败原因,如磁盘故障
精简后为

C++ 循环和关系表达式(四)下

9.另一个cin.get()版本
一种与C风格的getchar()、putchar()相似的成员函数
cin.get()、cout.put()

C++ 循环和关系表达式(四)下
10.嵌套循环和二维数组

二维数组可以理解为一个表格,拥有数据行和数据列
嵌套循环:即是循环内还拥有循环,这里二维数组一个循环内含有一个循环就可以,外部循环一般表示第几行,内部循环表示第几列

C++ 循环和关系表达式(四)下