第五章 选择语句
5.1 逻辑表达式
5.1.1 关系运算符
关系运算符可以用于比较整数和浮点数,也允许比较混合类型的操作数。
5.2 if语句
if表达式两边的圆括号是必需的,它们是if语句的组成部分,而不是表达式的内容。
5.2.1 复合语句
注意:每条内部语句仍然是以分号结尾的,但复合语句本身却不是。
5.2.3 级联式if语句
注意:级联式if语句不是新的语句类型,它仅仅是普通的if语句,只是碰巧有另外一条if语句作为else子句(而且这条if语句又有另外一条if语句作为它自己的else字句,依次类推)。
5.2.4 悬空else的问题
if (y != 0)
if (x != 0)
result = x / y;
else
printf("Error:y is epual to 0\n");
上面的else子句究竟属于哪一个if语句呢?缩进格式暗示它属于最外层的if语句。然而C语言遵循的的规则是else子句应该属于离他最近的且还未和其它else匹配的if语句。所以正确的缩进格式应该如下图所示:
if (y != 0)
if (x != 0)
result = x / y;
else
printf("Error:y is epual to 0\n");
5.2.5 条件表达式
我们通常会在条件表达式的两端加上圆括号,这是非常有必要的,因为除了赋值运算符,条件运算符的优先级低于先前介绍过的所有运算符。
5.2.6 C89中的布尔值
为了使程序更加便于理解,C89的程序员通常会使用TRUE和FALSW这样的名字定义宏。
#define TRUE 1
#define FALSE 0
同时还会定义一个可用作类型的宏:
#define BOOL int
5.2.7 C99中的布尔值
布尔变量可以声明为:
_Bool flag;
_Bool是整数类型(更准确的说是无符号整型),所以_Bool变量实际上就是整型变量;但是和一般的整型不同,_Bool只能赋值为0或1。一般来说,往_Bool变量中存储非零值会导致变量赋值为1。
对于_Bool变量来说,算术运算是合法的(不过不建议这样做),它的值也可以进行打印(显示0或者1)。
除了_Bool类型的定义,C99还提供了一个新的头<stdbool.h>,这使得操作布尔值更加容易。该头提供的bool宏,用来代替_Bool。如果程序中包含了<stdbool.h>,可以这样写:
bool flag;
<stdbool.h>头还提供了true和false两个宏,分别代表了1和0。于是可以写
flag = false;
flag = true;
5.3 switch语句
注意:switch语句往往可以比if语句执行更快,特别是在有许多情况要判定的时候。
switch语句的常用格式如下:
switch(表达式)
{
case 常量表达式:
语句;
···
case 常量表达式:
语句;
default:
语句;
}
下面逐一看一下它的组成部分.
- 控制表达式。switch后边必须跟着由圆括号括起来的整型表达式。C语言把字符当成整数来处理,因此在switch语句中可以对字符进行判定。但是,不能有浮点数和字符串。
- 常量表达式。case后面必须是常量表达式,不能包含变量和函数调用。常量表达式的值必须是整数(字符也可以)。
- 语句。每个分支标号的后边可以跟任意数量的语句。不需要用花括号把这些语句括起来。
问与答
-
问:当我用=代替==时我所用的编译器没有发出警告。是否有办法可以强制编译器注意这类问题?
答:把
if(i==0)
改写成
if(0==i)
因为不可能对0进行赋值操作,所以编译器将会产生一条错误信息。
许多编译器可以检测出if条件中=运算符的可疑使用。例如,GCC编译器会在选中-Wparentheses选项或-Wall(所有情况都警告)选项时执行这样的检查。GCC允许程序员通过在if条件外面增加一对圆括号的方式来抑制该警告:
if((i=j))
-
问:如果i是int型变量,而f是float型变量,那么条件表达式(i>0?i:f)是哪一种类型的值?
答:如问题中出现的那样,当int型和float型的值混合在一个条件表达式中时,表达式的类型为float型。如果i>0为真,那么变量i转化为float型后的值就是表达式的值。
-
问:为什么_Bool这个名字就不会影响已有的程序呢?
答:C89标准指出,以下划线后跟一个大写的字母开头的名字是保留字,程序员不应该使用。