C++入门第五章:循环和关系表达式
for循环
for循环的组成部分
- 设置初始值。
- 执行测试,看循环是否应该继续执行。
- 执行循环操作。
- 更新用于测试的值。
以上操作由括号括起,每个部分均是一个表达式,彼此分号隔开,控制部分后面的语句叫循环体,若测试表达式均为true,它被执行。
for(initialization;test-expression;update-expression)
body
C++将整个for循环看成一个语句。
循环只进行一次初始化。
for循环和后面的括号加一个空格,以区别函数调用。
表达式和语句
10;就是一个表达式,值为10。
C++规定赋值表达式的值为等号左边的部分。
如果加上分好,就变成一个语句。
修改规则
例:for (int i=1;i<5;i++) body
声明循环变量可在for循环中进行。
修改步长
i++也可变为i=2*i+1;i=i*I;
递增运算符(++)和递减运算符(++)
++x和—x代表先加1,后使用。
x—和x++代表先使用,后加1。
注:这两个操作符在不同的系统上使用结果可能不同。
y=(4+x++)+(6+x++);在不同的系统中,有可能是逐步加1或统一加1。
副作用和顺序点
副作用:计算表达式时对某些东西(如存储在变量中的值)进行修改。
顺序点是程序执行过程中的一个点,在这里,进入下一步之前将确保对所有副作用进行评估。C++中,分号就是一个顺序点,这意味着程序处理下一条语句之前将确保对所有的副作用都进行了评估。这意味着程序处理下一条语句之前,赋值运算符、递增运算符和递减运算符执行的所有操作都必须完成。
前缀格式和后缀格式
对内置类型,前缀和后缀表达式没有区别,但是对于用户定义的类型,往往前缀表带是比后缀表达式效率高。
组合运算符
操作符 |
作用(L为做操作数,R为右操作数) |
+= |
L=L+R |
-= |
L=L-R |
*= |
L=L*R |
/= |
L=L/R |
%= |
L=L%R |
复合语句(语句块)
可使用两个花括号来构造一条复合语句(代码块)。代码块由一对花括号和它们包含的语句组成,被视为一条语句。
逗号运算符
常用于for循环中的循环控制语句不止一个时。
逗号表达式的值是最后一个表达式的值。
关系运算符
操作符 |
含义 |
< |
小于 |
<= |
小于等于 |
== |
等于 |
> |
大于 |
>= |
大于或等于 |
!= |
不等于 |
字符串的比较
C-分隔字符串函数:strcmp(a,b);
a在b之前,返回赋值,a和b相同,返回0,a在b后,返回正值。
不可使用以下方式比较:
char name[20];
strcpy(name,"abc");
name=="abc"
但是可以这样:
string name;
name="abc";
name=="abc";
while循环
while (test-condition)
body;
测试条件为真时,则执行,否则不执行。
设计循环的指导原则:
- 指定循环终止的条件
- 在首次测试之前初始化条件
- 在条件再次测试之前更新条件
等待一段时间:编写延时循环
clock()函数,返回程序开始执行后所用的时间。
需载入头文件——ctime/time。这当中定义了一个符号常量——CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数。
程序示例:
#include<time>
……
clock_t(类型别名定义) start=clock();
while (clock()-start<delay)
;
类型别名
C++建立类型别名的方法有两种。
一种是使用预处理器:
#define BYTE char //预处理器将所有BYTE替换为char
第二种是使用C++关键字typeof来创建别名。
typeof char byte; //将byte作为char的别名
typeof typeName aliasName;
预处理器是完全替代,typeof更智能。
#define F_P float *;
F_P pa,pb;等价于float * pa,pb。即只对于pa有效。但是typeof则不会有这样的问题。
do-while循环
do
body
while(test-expression);
此循环为出口条件循环。
基于范围的for循环
C++11新增了一种循环:基于范围的for循环。这简化了一种常见的循环任务,对数组或者容器类的每个元素执行相同的操作。
例:double price={1.2,2.4,3.6,4.8,6.0};
for (double x:price)
cout<<x<<std::endl;
循环和文本输入
cin支持三种模式的单字符输入。
原始cin
如果程序要通过循环来读取来自键盘的文本输入,必须有办法知道何时停止读取。一种方法是选择某个某个特殊字符,我们称之为哨兵字符,将其作为停止标记。
例:
char ch;
int count=0;
cin>>ch;
while(ch!='#')
{
cout<<ch;
++count;
cin>>ch;
}
注意:上述程序会忽略空格和换行符。
使用cin.get(char)进行补救
char ch;
int count=0;
cin.get(ch);
while(ch!='#')
{
cout<<ch;
++count;
cin.get(ch);
}
文件尾操作
键盘模拟文件尾的快捷键:
Unix:Ctrl+D;
Windows:Ctrl+Z和Enter
VC++、Borland C++5.5、GNU C++ 能够识别Ctrl+Z。
通过cin的两个成员函数eof()和fail()来检测文件尾,若为文件尾哦,即检测到EOF,cin.eof()和cin.fail()均返回true,否则返回false。这两个函数返回的是最近读取的结果。
则,上述程序变为:
char ch;
int count=0;
cin.get(ch);
while(cin.fail==false)
{
cout<<ch;
++count;
cin.get(ch);
}
使用cin.clear()可清除EOF标记。
常见的字符输入做法
常用:cin.get(ch);
while (cin.fail()==false)
{
………
cin.get(ch);
}
简单方式:
cin.get(ch);
while (!cin.fail())
{
………
cin.get(ch);
}
或者
cin.get(ch);
while (cin)
{
………
cin.get(ch);
}
还可以:
cin.get(ch);
while (cin.get(ch))
{
………
}
注:EOF不是输入中的值,而是指没有字符。
由于EOF不是有效的字符编码,所以不能与char类型相互兼容,所及先将返回值赋给int型变量,输出时再进行类型转换。
例:
int ch;
int count=0;
while((ch=cin.get())!=EOF)
{
cout.put(char(ch));
++count;
}
嵌套循环与二维数组
二维数组:
int a[3][3]; //三行三列的二维数组
以行为单位进行保存数据。
a[0]是有3个元素的数组。
初始化二维数组:
int a[3][3]=
{
{1,2,3},
{4,5,6},
{7,8,9}
},