16. C Primer Plus 7.1及7.2

7.1 if语句及7.2

7.1if语句

下面示例程序演示了if语句:


输出结果如下:

该程序读取一列数据,每个数据都表示每日的最低温度(℃),然后打印统计的总天数和最低温度在0℃以下的天数占总天数的百分比。程序中的循环通过 scanf()读入温度值。while循环每迭代一次,就递增计数器增加天数,其中的 if语句负责判断0℃以下的温度并单独统计相应的天数。

while循环的测试条件利用scanf()的返回值来结束循环,因为scanf()在读 到非数字字符时会返回0。temperature的类型是float而不是int,这样程序既可以接受-2.5这样的值,也可以接受8这样的值。

while循环中的语句:

if 语句指示计算机,如果刚读取的值(remperature)小于 0,就把 cold_days 递增 1;如果temperature不小于0,就跳过cold_days++;语句,while 循环继续读取下一个温度值。

并且,该程序又使用了两次if语句控制程序的输出。如果有数据,就打印结果;如果没有数据,就打印一条消息。

在上述示例程序中,为避免整数除法,该程序示例把计算后的百分比强制转换为 float类 型。其实,也不必使用强制类型转换,因为在表达式100.0 * cold_days / all_days中,将首先对表达式100.0 * cold_days求值,由于C的自动转换类型 规则,乘积会被强制转换成浮点数。

但是,使用强制类型转换可以明确表达转换类型的意图,保护程序免受不同版本编译器的影响。

if语句

if语句被称为分支语句或选择语句,因为它相当于一个交叉点,程序要在两条分支中选择一条执行。

if语句的通用形式如下:

if(expression)

statement

如果对expression求值为真(非0),则执行statement;否则,跳过 statement。

与while语句或者for语句相同,statement可以是一条简单语句或复合语句。

if语句的结构与while语句结构很相似,它们的主要区别是:如果满足条件可执行的话,if语句只能测试和执行一次,而while语句可以测试和执行多次。

通常,expression 是关系表达式,即比较两个量的大小(如,表达式 x > y 或 c == 6)。如果expression为真(即x大于y,或c == 6),则执行 statement。否则,忽略statement。概括地说,可以使用任意表达式,表达式 的值为0则为假。

总结:expression部分可以是任何表达式,表达式的值若不为0即表达式为真,则执行statement部分;若表达式的值为0即表达式为假的,就忽略statement部分,直接跳过statement部分的执行。

statement部分可以是一条简单语句,或者是一条用花括号括起来的复合语句(或块),如下图所示:

注意:即使if语句由复合语句构成,整个if语句仍被视为一条语句。**

7.2if else 语句

简单形式的if语句可以让程序选择执行一条语句,或者跳过这条语句。 C还提供了if else形式,可以在两条语句之间作选择。

下列示例程序用if else语句修正程序清单7.1中的程序段:

如果程序发现all_days不等于0,那么它应该知道另一种情况一定是 all_days等于0。用if else形式只需测试一次。

重写上面程序段如下:

如果if语句的测试表达式为真,就打印温度数据;如果为假,就打印警告消息。

注意:if else语句的通用形式为:

if(expression)

statement1

else

statement2

如果expression为真(非0),则执行statement1;如果expression为假或 0,则执行else后面的statement2。

statement1和statement2可以是一条简单语句或复合语句。

C并不要求一定要缩进,但这是标准风格。缩进让根据测试条 件的求值结果来判断执行哪部分语句一目了然。

如果要在if和else之间执行多条语句,必须用花括号把这些语句括起来成为一个块。

下面的代码结构违反了C语法,因为在if和else之间只允许有一 条语句(简单语句或复合语句):

编译器把printf()语句视为if语句的一部分,而把x++;看作一条单独的语 句,它不是if语句的一部分。然后,编译器发现else并没有所属的if,这是错误的。

上面的代码应该这样来写:

if语句用于选择是否执行一个行为,而else if语句用于在两个行为之间选择。

下图比较了这两种语句:

7.2.3多重选择else if

现实生活中我们经常有多种选择。在程序中也可以用else if扩展if else结 构模拟这种情况。如电力公司通常根据客户的总用电量来决定电费,下图为某电力公司的电费清单,单位为千瓦时:


下列示例程序演示了计算电费:

输出结果如下:

程序分析:上述程序用符号常量表示不同的费率和费率分界点,以便把常量统 一放在一处。这样,电力公司在更改费率以及费率分界点时,更新数据非常 方便。BASE1和BASE2根据费率和费率分界点来表示。一旦费率或分界点发 生了变化,它们也会自动更新。预处理器是不进行计算的。程序中出现 BASE1的地方都会被替换成0.13230*360.0。不用担心,编译器会对该表达 式求值得到一个数值(47.628),以便最终的程序代码使用的是47.628而不是一个计算式。

程序流简单明了。该程序根据kwh的值在3个公式之间选择一个。特别 要注意的是,如果kwh大于或等于360,程序只会到达第1个else。因此,else if (kwh <= BREAK2)这行相当于要求kwh在360~482之间,如程序注释所 示。类似地,只有当kwh的值超过720时,才会执行最后的else。最后,注意 BASE1、BASE2和BASE3分别代表360、468和720千瓦时的总费用。因此, 当电量超过这些值时,只需要加上额外的费用即可。

实际上,else if 是已学过的 if else 语句的变式。例如,可以用下面的代码替换该程序的核心部分:

该程序由一个ifelse语句组成,else部分包含另一个if else语句,该if else语句的else部分又包含另一个if else语句。第2个if else语句嵌套 在第 1个if else语句中,第3个if else语句嵌套在第2个if else语句中。整个if else语句被视为一条语句,因此不必把嵌套的if else语句用花括号 括起来。当然,花括号可以更清楚地表明这种特殊格式的含义。

这两种形式完全等价。唯一不同的是使用空格和换行的位置不同,不过 编译器会忽略这些。尽管如此,第1种形式还是好些,因为这种形式更清楚地显示了有4种选择。在浏览程序时,这种形式让读者更容易看清楚各项选 择。在需要时要缩进嵌套的部分,例如,必须测试两个单独的量时。本例中,仅在夏季对用电量超过720kWh的用户加收10%的电费,就属于这种情况。

可以把多个else if语句连成一串使用,如下所示(当然,要在编译器的限制范围内):

(这可能是一个游戏程序的一部分,bonus表示下一局游戏获得的光子 炸弹或补给。)

对于编译器的限制范围,C99标准要求编译器最少支持127层套嵌。

7.2.4else与if配对

如果程序中有许多if和else,编译器如何知道哪个if对应哪个else?例如下面的程序:


上列示例中else与第2个if匹配。,则输出结果如下:

在C语言中,规则是,如果没有花括号,else与离它最近的if匹配,除非最近的if被花括号括起来。

if else匹配规则如下图:

注意:要缩进“语句”,“语句”可以是一条简单语句或复合语句。

第1个例子的缩进使得else看上去与第1个if相匹配,但是记住,编译器 是忽略缩进的。如果希望else与第1个if匹配,应该这样写:

这样改动后,响应如下:

posted @ 2022-02-06 23:47  喻雅芬  阅读(71)  评论(0)    收藏  举报