第3章 分 支 结 构 C语言中的分支结构有ifelse结构和switch结构。ifelse是常用的双分支结构,switch是多分支结构。 3.1ifelse结构 3.1.1if 单分支 if单分支语法: if(<表达式>) { <语句块A> } 图31单分支流程图 运行过程: 先判断表达式的值是“真”还是“假”,是“真”则运行语句块A,是“假”则什么都不运行。 流程图如图31所示。 说明: (1) 表达式一般使用条件表达式或逻辑表达式,表达式必须用一对小括号()括起来。 (2) 语句块A中如果只有一条语句,可以省略一对大括号{}。 (3) 语句块A中如果有多条语句,却没有写大括号{},则默认只有第一条语句属于分支结构。 3.1.2ifelse双分支 ifelse双分支语法: if(<表达式>) { <语句块A> } else { <语句块B> } 图32双分支流程图 运行过程: 先判断表达式的值是“真”还是“假”,是“真”则运行语句块A,是“假”则运行语句块B,两个语句块只能选择一个运行。流程图如图32所示。 说明: (1) 不管是语句块A还是语句块B,如果只有一条语句,都可以省略一对大括号{}。 (2) 再次说明,如果语句块中有多条语句,必须写大括号{},否则可能出现逻辑错误。 3.1.3ifelse嵌套 ifelse嵌套有两种语法,如表31所示。 表31ifelse嵌套语法 项目第一种语法第二种语法 语法 if(<表达式1>) { if(<表达式2>) { <语句块A> } else { <语句块B> } } else { if(<表达式3>) { <语句块C> } else { <语句块D> } } if(<表达式1>) { if(<表达式2>) { <语句块A> } else { <语句块B> } } else if(<表达式3>) { <语句块C> } else { <语句块D> } } 说明else与if都单独一行书写,注意每层语句缩进,以便清晰表示出层次对应关系 将else与if连写,可以不用多层缩进,但要自己分清ifelse对应关系 两种语法的流程图是相同的,如图33所示。 说明: (1) 不管是if分支还是else分支,都可以再嵌套if或ifelse语句。 (2) 允许多层嵌套,但不建议层次太多,否则程序的可读性差,运行效率低。 (3) 多层嵌套要注意if与else的匹配关系,每个else总是与在它上面、距它最近且尚未匹配的if配对。 (4) 程序书写应采用缩进方式,将同一层的分支结构对齐,可以增加程序的美观性和可读性。 (5) 避免遗漏大括号造成的程序错误,建议先写好大括号,再编写其中的语句。对于只有一条语句的分支也最好不要省略大括号,避免出现不必要的逻辑错误。 (6) ABCD四个语句块只能有一个被运行。 图33嵌套多分支流程图 3.2switch结构 switch语句是多分支语句结构,但不是所有多分支都能使用switch语句。 switch语法1: switch(<表达式>) { case <值1>:语句块1; break; case <值2>:语句块2; break; … case <值n>:语句块n; break; default:语句块n + 1; } 语法1流程图见图34。 图34switch分支流程图1 switch语法2: switch(<表达式>) { case <值1>:语句块1; case <值2>:语句块2; … case <值n>:语句块n; default:语句块n + 1; } 语法2流程图见图35。 图35switch分支流程图2 说明: (1) 语法1和语法2的区别在于break语句,有没有break语句运行效果明显不同。 (2) case后的值必须是常量或常量表达式,不可以是变量。 (3) case后的值必须是整型、字符型或枚举类型,不可以是浮点型或字符串。 (4) case后的语句块可以是一条语句,也可以是多条语句,但是都不需要用大括号括起来。 (5) 值1~值n必须各不相同,并且要与表达式计算结果的类型一致。 (6) case后的值仅起到标号作用,一旦找到入口标号,就从此标号开始运行,直到遇见break语句,或者运行到switch语句结束,其间不再进行标号判断。 (7) case语句块和default语句块如果都带有break语句,那么它们之间的顺序不影响运行结果,否则运行结果可能会与位置有关。 3.3程 序 示 例 【例31】输入一个0~100分的成绩,转换为五级制输出,成绩与等级的对应关系如表32所示。 表32分数与等级对应表 成绩成绩<6060≤成绩<7070≤成绩<8080≤成绩<90成绩≥90 等级不及格及格中等良好优秀 参考代码一(使用ifelse嵌套语句,程序流程图如图36所示)。 图36成绩等级转换程序流程图 #include int main( ) { int grade; printf("请输入分数:"); scanf("%d",&grade); if(grade<60) printf("不及格"); else if(grade<70) printf("及格"); else if(grade<80) printf("中等"); else if(grade<90) printf("良好"); else printf("优秀"); getchar( ); getchar( ); } 第1次运行结果: 第2次运行结果: 第3次运行结果: 请输入分数: 100请输入分数: 78请输入分数: 56 优秀中等不及格 程序说明: 成绩判断按照由低到高的顺序进行判断。 思考: 为什么 else if (grade<70)不需要写成 else if (grade>=60 && grade<70)? 参考代码二 (使用switch多分支语句): #include int main( ) { int grade; printf("请输入一个百分制分数:"); scanf("%d", &grade); switch(grade/10) //使用switch多分支语句,对grade/10的值判断 { case 10: //100分与90多分都是优秀,灵活利用break语句 case 9: printf("优秀"); break; case 8: printf("良好"); break; case 7: printf("中等"); break; case 6: printf("及格"); break; default: printf("不及格"); //不及格涉及的值比较多,放在default中 } } 程序说明: (1) 不是所有多分支都可以使用switch结构,case后必须是具体的离散值,不可以是grade>90这样的区间。本题通过grade/10表达式,利用整数相除结果为整数的特性,将区间转换为具体值。 (2) 合理利用break语句的功能,100分和90多分都是优秀,不需要写重复代码。 (3) 不及格涉及的值比较多,放到default中是个讨巧的方法。 参考代码三(使用ifelse嵌套语句的第二种写法): #include int main( ) { int grade; printf("请输入一个百分制分数:"); scanf("%d",&grade); if (grade>=0 && grade<=100) //加入判断成绩是否为0~100的语句 { if(grade>=90) //与参考代码一不同,此程序由高分到低分判断 printf("优秀"); else if(grade>=80) printf("良好"); else if(grade>=70) printf("中等"); else if(grade>=60) printf("及格"); else printf("不及格"); } else printf("成绩应该在0~100之间"); } 程序说明: (1) 不管是由高到低,还是由低到高,只要是有序的判断,就可以简写判断条件,如果无序就需要写完整的条件,比如写为: else if (grade>=80 && grade<90)。 (2) 代码三与代码一同样省略了大括号{},因为每个分支都是只有一条语句。 (3) 代码三与代码一的流程图不同,自己尝试画流程图。 参考代码四(使用switch+ifelse语句): #include int main( ) { int grade; printf("请输入一个百分制分数:"); scanf("%d", &grade); if (grade >= 0 && grade <= 100) //加入判断成绩是否为0~100的语句 { switch(grade/10) //使用switch多分支语句,对grade/10的值判断 { case 10: case 9: printf("优秀"); break; case 8: printf("良好"); break; case 7: printf("中等"); break; case 6: printf("及格"); break; default: printf("不及格"); //default分支没有break语句,只能放在最后 } } else printf("成绩应该在0~100之间"); //输入分数不符合,直接退出 } 程序说明: (1) switch结构和ifelse结构经常配合一起使用,此程序在ifelse中嵌入switch结构,先用ifelse判断分数是否有效,再对有效值判断等级。 (2) 也可以在switch结构的某个case分支中嵌入ifelse结构。 (3) 如果default分支也有break语句,则default分支可以放在任意位置。 3.4常 见 错 误 错误1: error C2181: illegal else without matching if(没有匹配 if 的非法 else)。 原因1: 可能if分支有多条语句,却没有用大括号{}括起来。 解决办法: 将该else前面的if分支所有语句用大括号{}括起来。建议即使分支中只有一条语句也不省略大括号。 原因2: 可能if语句后多了分号,写成了if(grade<60);。 解决办法: 去掉分号,正确写法为if(grade<60)。 错误2: error C2061: syntax error(语法错误),双击错误信息定位到if语句。 原因: 可能if后面的条件没有用小括号()括起来。 解决办法: 将if语句后面的所有条件都用小括号()括起来。建议先写好一对括号再向括号里填内容。 错误3: switch结构关键字书写都正确,编译时却显示一堆错误。 原因1: 可能switch后面的条件缺少小括号(),错误示例: switch grade/10。 解决办法: 将switch语句后面的所有条件都用小括号()括起来。语句修改为switch (grade/10)正确。 原因2: 可能switch后面的条件多了分号,例如写成switch (grade/10);。 解决办法: 去掉分号,正确写法为switch (grade/10)。 错误4: switch结构中漏掉了break,造成运行结果错误。 解决办法: 在需要退出的地方都加上break。 错误5: 关系表达式中用错=和==,一个等号=是赋值,两个等号==才是比较相等。 解决办法: 写完程序要运行检测结果是否正确。 错误6: 复合条件弄错了运算符的优先级。 解决办法: 复合条件中加入小括号(),明确优先级。 错误7: ifelse匹配错误。 解决办法: 尽量不省略语句块的大括号,让代码更清晰。每个else总是与在它上面、距它最近、且尚未匹配的if配对。 实验4分支结构练习1 一、 实验目的与要求 1. 掌握C语言逻辑值的表示方法(0表示假,1表示真)。 2. 学会正确使用关系表达式和逻辑表达式。 3. 掌握各种形式if语句语法和使用方法。注意if嵌套语句中if和else的匹配关系。 4. 用if语句解决简单的应用问题并上机实现。 二、 实验环境 Visual C++2010/Visual C++6.0。 三、 实验内容 1. 编程读入三个整数分别表示箱子的长、宽、高,判断并输出该箱子是正方体还是长方体。 43A 43B 43C 44A 44B 图37找最小数流程图 提示: 判断三个值是否相等需要两两判断,然后进行逻辑运算。 2. 计算表达式(b+b×b+2a)/(a-b)的值,其中,a,b从键盘输入。注意,如果分母等于0,则结果为0。 提示: (1) 所有变量均定义为双精度浮点数。 (2) 输入数据前显示器上要有提示。 (3) 计算平方根需要用sqrt()函数,该函数在math.h头文件中。 (4) 输出结果保留一位小数。 3. 找最小数: 参照如图37所示流程图,编写程序输入三个整数,找出最小数并打印输出。 拓展1: 请用另外的算法实现第3题程序。 拓展2: 编写程序输入三个整数x,y,z,把这三个数由小到大输出。(不是找最小值) 实验5分支结构练习2 一、 实验目的与要求 1. 掌握switch语句语法和使用方法。 2. 掌握switch语句中的break的用法及switch语句的嵌套。 3. 能够用if语句、switch语句解决简单的应用问题并上机实现。 二、 实验环境 Visual C++2010 / Visual C++6.0。 三、 实验内容 1. 用switch语句模拟简单的计算器,进行整数的加减乘除四则运算,输入一个表达式,输出表达式的计算结果。例如,输入3*5,输出3*5=15,特殊处理除法,商保留两位小数。 运行效果: 请输入表达式:6*9 6*9=54 请输入表达式:17/3 17/3=5.67 2. 将第1题改为用ifelse实现加减乘除四则运算计算器,比较两个程序的区别,哪一个容易读懂?考虑是否所有程序都可以用两种方法实现。 3. 输入一个时间(整数),时间为6~10点,输出“上午好”,时间为11~13点,输出“中午好”,时间为14~18点,输出“下午好”,其他时间输出“休息时间”。请用ifelse和switch结构分别实现,比较哪一个更好。 44C 运行效果: 请输入整数时间: 7 上午好! 请输入整数时间: 12 中午好! 请输入整数时间: 15 下午好! 请输入整数时间: 19 休息时间! 拓展: 用整数1~12表示1~12月,由键盘输入一个月份数,输出对应的季节英文名称(12~2月为冬季,3~5月为春节,6~8月为夏季,9~11月为春季)。要求用ifelse和switch结构分别实现。