bool数据类型
布尔表达式 是一种计算布尔值的表达式:true或者false
比较运算的结果是一个布尔值,保存布尔值的变量成为布尔变量,使用bool来声明
bool数据类型声明了一个变量,使用值true或者false
true和false是布尔文字,他们是关键字,不能在程序中用作标识符
如果在控制台中显示一个布尔值,true会显示为1,false会显示为0
布尔运算的等于判断是两个等号(==),而不是单个等号(=)。后者是赋值运算符
可以把任意一个数值赋给一个bool变量,任意不是0的值都是true,0代表false
if语句
if语句是一个结构,能使程序按照指定的路径之一执行
几种类型的分支语句:
单分支if语句
布尔表达式是封闭在括号里的,如
if(i>0){
cout<<"i is positive"<<endl;
}
如果布尔表达式的值为true,则框中的语句被执行
如果框中只有一个单一的语句,那么括号{}可以省略
双分支if-else语句
单分支语句在条件为假时什么也不做。双分支语句可以根据条件的真或假,执行不同的动作
if(i>0){
cout<<"i is positive"<<endl;
}
else{
cout<<"i is negative"<<endl;
}
与单分支语句一样,如果框中只有单一的语句,则大括号可以省略
嵌套if语句和多分支的if-else语句
一个if语句可以在另一个if语句中来形成一个嵌套if语句
以下两种写法是等价的:
if(score >= 90)
cout << "Grade is A";
else
if(score >= 80)
cout << "Grade is B";
else
if(score >= 70)
cout << "Grade is C";
else
if(score >= 60)
cout << "Grade is D";
else
cout << "Grade is F";
在多个if-else嵌套循环时,也可以这样写:
if (score >= 90)
cout << "Grade is A";
else if (score >= 80)
cout << "Grade is B";
else if (score >= 70)
cout << "Grade is C";
else if (score >= 60)
cout << "Grade is D";
else
cout << "Grade is F";
执行的流程为:
首先检查第一个条件,若为真,grade为A,若为假,
检查第二个条件,若为真,grade为B,若为假,
检查第三个条件,以此类推
如果所有条件都为假,则grade为F
**注意:**一个条件被检查到的前提,是它前面所有的条件均为假
switch语句
一个switch语句基于一个变量的值或者一个表达式来执行语句
例如一个根据变量status的值,有四种不同的计算税款的情况,为了处理所有的情况,须使用嵌套的if语句
但是过度嵌套的语句会使程序难以理解,switch语句可以简化多重条件情况,如下:
switch(status)
{
case0: compute with corressponding conditions;
break;
case1: compute with corressponding conditions;
break;
case2: compute with corressponding conditions;
break;
case3: compute with corressponding conditions;
break;
default: cout << "Error: invalide status" << endl;
}
依次检查status的值是否与0, 1, 2, 3匹配,如果与某个值匹配,根据对应条件进行计算。如果与所有值都不匹配,则输出一条信息
switch完成语法如下:
switch(switch-expression)
{
case value1: statement1;
break;
case value2: statement2;
break;
...
case valueN: statementN;
break;
default: statement-for-default;
}
switch语句需要遵守如下规则:
- switch表达式必须产生一个整型值,且必须放在括号内
- value1, … , valueN是整型常量表达式,即表达式中不能包含变量,如1+x就是非法的。这些值必须是整型值,不能是浮点型值
- 当某个case语句中的值与switch表达式的值相等,则从此case语句开始执行后续语句,直至遇到一个break语句或者到达switch语句末尾(default中的语句也会被执行)
- default情况是可选的,它用于指出,在任何指定情况均与switch表达式不匹配时,执行什么动作
- 关键字break是可选的,break语句会立刻终止switch语句
**警示:**在需要使用break的地方不要遗漏。当某个case语句被匹配时,会从这个case语句开始执行,直到遇到break或者达到switch语句的末尾。这种现象被成为直通行为(fall-through behavior)
条件表达式
条件表达式根据条件执行表达式
有时候需要将一个值赋予一个变量,但要求这个赋值在某个特定条件下才进行。
例如,如下语句在x大于0时将1赋予y,在x小于等于0时将-1赋予y:
if (x > 0)
y = 1;
else
y = -1;
与下面的例子一样,我们可以用一个条件表达式达到相同的目的:
y = x > 0 ? 1: -1
很明显,条件表达式与前面的语句有着完全不同的形式,其中没有显示的if语句。
条件表达式的语法如下所示:
boolean-expression ? expression1 : expression2;
如果布尔表达式的值为真,条件表达式的值为expression1的值,否则就取expression2的值
例如:
想让变量num1和num2中的较大者赋予变量max,那么可以用条件表达式这样写:
max = num1 > num2 ? num1 : num2;
另一个例子,下面语句在num为偶数时输出信息"num is even",否则输出"num is odd"
cout << (num % 2 == 0 ? "num is even":"num is odd") << endl;
**提示:**符号?和:一起出现在条件表达式中,它们一起构成了条件运算符。此运算符被称为三元运算符,因为它有三个运算对象,这也是c++中唯一的一个三元运算符
常见的错误和陷阱
常见错误1:忘记必须的括号
当语句块只有一个语句的时候,括号是可以被省略的。然而,在需要括号来包含多行语句的时候,忘记括号是一个常见的编程错误。
常见错误2:if行错误的分号
if(boolean-expression)后不需要添加分号或冒号。
如果在其后添加分号,这个错误是很难查找的,因为它既不是编译错误,也不是运行时错误。这是一个逻辑错误
等价于if后{}中是空代码段
常见错误3:错误使用=代替==
是否相等的操作符是两个等号(==),考虑下面的代码:
if (count = 3)
cout << "count is zero" << endl;
else
cout << "count is not zero" << endl;
它将一直显示count is zero。 因为count = 3这一句把3赋值给了count,赋值语句的值是3,是一个非零值,所以if语句的条件就是true
常见错误4:布尔值的冗余测试
例如布尔变量even,如下的两种写法
if (even == true)
if (even)
是完全等价的
常见错误5:else位置歧义
例如这样的代码:
int i = 1, j = 2, k = 3;
if (i > j)
if (i > k)
cout << "A";
else
cout << "B";
从缩进上来看,else是与第一个if子句搭配的。然而,这个else是和第二个if搭配的。
else子句通常和同意程序段中最近的子句配套
为了强制else子句和第一个id子句配套,这里可以添加一对大括号,如下:
int i = 1, j = 2, k = 3;
if (i > j)
{
if (i > k)
cout << "A";
}
else
cout << "B";
常见错误6:两个浮点值的相等性测试
浮点数有限制的精度,涉及浮点数的计算会导致舍入误差。
因此,两个浮点数之间的相等性测试是不可靠的。
举个例子,我们希望下面的代码显示 x is 0.5,但是出乎意料的是,它显示 x is not 0.5
double x = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1;
if (x == 0.5)
cout << "x is 0.5" << endl;
else
cout << "x is not 0.5" << endl;
这里,x不完全是0.5,但是非常接近0.5。我们不能认为对两个浮点数进行相等性测试是可靠的。然而,可以通过比较两个数之间的差距是不是小于一个临界条件来比较他们是否足够接近。也就是说,如果 |x-y|< ε,ε(epsilon)是一个非常小的数值,则x和y非常接近。
(这不就是极限嘛…)通常,在比较两个double的时候将其设置为1 * 10^-14,float设置为1 * 10^-7
那么上述代码可以这样写
const doublt EPSILON = 1E-14
double x = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1;
if (abs(x - 0.5) < EPSILON)
cout << "x is approximately 0.5" << endl;
常见陷阱1:简化布尔变量赋值
初学者在写代码时,很容易这样写:
if (number % 2 == 0)
even == true;
else
even == false;
然而,完全可以这样写
bool even = number % 2 == 0
常见陷阱2:避免在不同分支中的相同语句
if (inState){
tution = 5000;
cout << "the tution is " << tution << endl;
}
else{
tution = 15000;
cout << "the tution is " << tution << endl;
}
这并不是一个错,但是最好写为如下形式
if (inState){
tution = 5000;
}
else{
tution = 15000;
}
cout << "the tution is " << tution << endl;
新代码移除了重复的部分,让代码更方便维护
常见陷阱3:整数值可以被用作布尔值
一个布尔值的true被看作1,false看作0。一个数值可以被用作一个布尔值
c++被一个非零的数值转换成true,把0转换成false。一个布尔值可以被用作一个整数
这可能会导致潜在的逻辑错误,如下:
if (!amount <= 50)
cout << "Amount is more than 50";
如果amount的值为40,代码会显示"Amount is more than 50",因为!amount的值为0,(0 <= 50)是成立的
正确的写法如下:
if (!(amount <= 50))
cout << "Amount is more than 50";
随机数
可以使用rand()函数来获得随机整数
该函数包含在cstdlib头文件中。这个函数会返回一个0 ~ RAND_MAX之间的随机整数,RAND_MAX由平台决定
rand()生成的是伪随机数,即每次在同一个系统上执行这个函数的时候,rand()函数会生成同一序列的数。
因为rand()算法使用种子(seed)来控制生成数字,默认情况下,种子的值为1。如果改变种子的值为不同的值,随机数也将会不同。
可以使用cstdlib头文件中的srand(seed)函数来改变种子的值。为了保证程序中每次种子的值都不相同,可以使用time(0)
如下代码可以获得一个0 ~ 9 之间的随机整数。
srand(time(0));
int ra = rand() % 10;
cout << ra << endl;
运算符的优先级
运算符的优先级和结合律决定着运算符的执行顺序
逻辑运算符的优先级低于关系运算符,关系运算符的优先级低于算数运算符