4.2 if 语句
在生活中,每个人都要进行各种各样的选择。例如,吃什么菜?走哪条路?找什么人?那么当程序遇到选择时,该怎么办呢?这时需要使用选择结构语句。if 语句是最基础的一种选择结构语句,它主要有3 种形式,分别为if 语句、if…else 语句和if…else if…else 多分支语句,本节将分别对它们进行详细讲解。
4.2.1 最简单的if 语句

C# 中使用if 关键字来组成选择语句,其最简单的语法形式如下。

学习笔记
在使用if 语句时,如果只有一条语句,那么省略{} 是没有语法错误的,而且不影响程序的执行,但是为了程序代码的可读性,建议不要省略。
其中,表达式部分必须用() 括起来,它可以是一个单纯的布尔类型的变量(或常量),也可以是关系表达式(或逻辑表达式)。如果表达式的值为真,则执行 “语句块”,之后继续执行 “下一条语句”;如果表达式的值为假,则跳过 “语句块”,执行 “下一条语句”。这种形式的if 语句相当于汉语中的 “如果……那么……”,其流程图如图4.4 所示。

图4.4 if 语句流程图
示例1.判断输入的数字是不是奇数
使用if 语句判断用户输入的数字是不是奇数,代码如下。

学习笔记
第4 行代码使用Convert.ToInt32 方法将用户输入的数字强制转换成了int 类型,然后使用int 类型的变量进行记录。
奇数的条件是不能被2 整除,因此,第5 行代码判断用户输入的数字求余2 是否不等于0,以此来判断用户输入的数字是不是奇数。
运行上面代码,当输入5 时,结果如图4.5 所示;当输入6 时,结果如图4.6 所示。

图4.5 奇数运行结果

图4.6 不是奇数的运行结果
学习笔记
if 语句后面如果只有一条语句,那么可以不使用大括号({}),但是,不建议开发人员使用这种形式,不管if 语句后面有多少要执行的语句,都建议使用大括号括起来,这样方便代码的阅读。例如,下面的代码未使用大括号。

学习笔记
●if 语句后面多加了分号。例如,if 语句正确表示如下。

上面两行代码的本意是,当变量i 的值为5 时,执行下面的输出语句。但是,如果在if 语句后面多加了分号,下面的输出语句将会无条件执行,if 语句就起不到判断的作用,代码如下。

●在使用if 语句时,如果要将多个语句作为复合语句来执行,例如,程序的真正意图是如下语句。

那么,如果删去大括号,则代码如下。

在执行程序时,无论flag 是否为true,j++ 都会无条件执行,这显然与程序的本意是不符的,但程序并不会报告异常,因此这种错误很难发现。
4.2.2 if…else 语句

如果遇到只能二选一的情况,比如某个公司在发展过程中遇到了 “扩张” 和 “求稳” 的抉择,示意图如图4.7 所示。

图4.7 公司在发展过程中遇到了 “扩张” 和 “求稳” 的抉择示意图
C# 中提供了if…else 语句解决类似问题,其语法如下。

在使用if…else 语句时,表达式可以是一个单纯的布尔类型的变量(或常量),也可以是关系表达式(或逻辑表达式)。如果满足条件,则执行if 后面的语句块;否则,执行else 后面的语句块。这种形式的选择语句相当于汉语中的 “如果……否则……”,其流程图如图4.8 所示。

图4.8 if…else 语句流程图
学习笔记
if…else 语句可以使用条件运算符进行简化,如下面这段代码:

可以简写成:

上段代码主要实现求绝对值的功能,如果a > 0,就把a 的值赋给变量b;否则,将-a赋给变量b。使用条件运算符的好处是可以使代码简洁,并且有一个返回值。
示例2.根据分数划分优秀等级
使用if…else 语句判断用户输入的分数是不是足够优秀,如果大于90,则表示优秀;否则,输出 “希望你继续努力!”,代码如下。

运行上面代码,当输入一个大于90 的数时,如93,效果如图4.9 所示;当输入一个小于90 的数时,如87,效果如图4.10 所示。

图4.9 当输入93 时的运行结果

图4.10 当输入87 时的运行结果
学习笔记
在使用if…else 语句时,else 一定不可以单独使用,它必须和关键字if 一起使用。例如,下面的代码是错误的。

在程序中使用if…else 语句时,如果出现if 语句多于else 语句的情况,那么将会出现悬垂else 问题:究竟else 语句和哪个if 语句相匹配呢?例如,下面的代码。

如果遇到上面的情况,在没有特殊处理时,那么else 语句永远都与最后出现的if 语句相匹配,即上面代码中的else 语句是与if(y>x) 语句相匹配的。如果要改变else 语句的匹配对象,则可以使用大括号。例如,将上面代码修改如下。

这样,else 语句将与if(x>1) 语句相匹配。
学习笔记
建议在if 后面使用大括号将要执行的语句括起来,这样可以避免程序代码混乱。
4.2.3 if…else if…else 语句

大家平时在网上购物需要付款时通常都有多种选择,如图4.11 所示。
在图4.11 中,提供了多种付款方式,这时用户就需要从多个选项中选择一个。在开发程序时,如果遇到多选一的情况,则可以使用if…else if…else 语句。该语句是一个多分支选择语句,通常表现为 “如果满足某种条件,则进行某种处理;否则,如果满足另一种条件,则执行另一种处理……”。if…else if…else 语句的语法格式如下。



图4.11 网上购物时的付款页面
使用if…else if…else 语句时,表达式部分必须用() 括起来,它可以是一个单纯的布尔类型的变量(或常量),也可以是关系表达式(或逻辑表达式)。如果表达式为真,则执行语句;而如果表达式为假,则跳过该语句,进行下一个else if 的判断;只有在所有表达式都为假的情况下,才会执行else中的语句。if…else if…else语句的流程图如图4.12所示。
学习笔记
if 和else if 都需要判断表达式的真假,而else 则不需要判断;另外,else if 和else都必须跟if 一起使用,不能单独使用。

图4.12 if…else if…else 语句的流程图
示例3.根据用户输入的年龄输出相应的信息提示
使用if…else if…else 多分支语句实现根据用户输入的年龄输出相应的信息提示的功能,代码如下。

学习笔记
第5 行代码中的int.Parse() 方法用来将用户输入的数据强制转换成int 类型。
运行上面代码,输入一个年龄值,如35,按回车键即可输出相应的信息提示,结果如图4.13 所示。

图4.13 当输入35 时的运行结果
学习笔记
使用if 语句时,应尽量遵循以下原则。
● 使用bool 变量作为判断条件,假设bool 变量为falg,较为规范的书写格式如下。

不符合规范的书写格式如下。

● 当使用浮点类型的变量与0 值进行比较时,规范的书写格式如下。

不符合规范的书写格式如下。

● 使用if(1==a) 这样的书写格式可以防止错写成if(a=1) 这种形式,从而可以避免逻辑上的错误。
4.2.4 if 语句的嵌套

前面讲了3 种形式的if 语句,这3 种形式的语句之间都可以进行互相嵌套。例如,在最简单的if 语句中嵌套if…else 语句,形式如下。


学习笔记
if 语句可以有多种嵌套方式,在开发程序时,可以根据自身需要选择合适的嵌套方式,但一定要注意逻辑关系的正确处理。
示例4.判断输入的年份是不是闰年
通过使用嵌套的if 语句实现判断用户输入的年份是不是闰年的功能,代码如下。


学习笔记
判断闰年的方法是 “四年一闰,百年不闰,四百年再闰”。程序使用嵌套的if 语句对这3 个条件进行逐一判断,第5 行代码首先判断年份能否被4 整除(iYear%4==0),如果不能被4 整除,则输出字符串 “这不是闰年”;如果能被4 整除,则第7 行代码继续判断能否被100 整除(iYear%100==0)。如果不能被100 整除,则输出字符串 “这是闰年”;如果能被100 整除,则第9 行代码继续判断能否被400 整除(iYear%400==0)。如果能被400 整除,则输出字符串“这是闰年”;如果不能被400 整除,则输出字符串“这不是闰年”。
运行上面代码,当输入一个闰年年份时,如2000,结果如图4.14 所示;当输入一个非闰年年份时,如2017,结果如图4.15 所示。

图4.14 当输入年份为2000 时的运行结果

图4.15 当输入年份为2017 时的运行结果
学习笔记
在使用if 语句嵌套时,注意else 关键字要和if 关键字成对出现,并且遵守临近原则,即else 关键字总是和离自己最近的if 语句相匹配。
在进行条件判断时,应该尽量使用复合语句,以免产生二义性,导致运行结果和预想的不一致。