第3章 分支结构程序设计
运行环境以Dev-C++、Visual Studio 2022、MacOS的命令行和Xcode为主
1.关系表达式和逻辑表达式
-
1.1 关系运算
-
对两个数据值的大小进行比较的运算。判断它们是否符合给定条件:若符合,则结果为1(即真);否则结果为0(即假)
-
用关系运算符连接两个表达式组成的式子称为关系表达式。一般情况下,关系运算符的优先级(6 7)低于算术运算符(1 3 4),高于赋值运算符(14)
-
同优先级的关系运算符同时出现时从左向右进行运算,如
a != b == c等价于(a != b) == c -
表达式的值为真时结果为1,表达式的值为假时结果为0,例如
x=(3>2);x的值为1;x=(3<2);x的值为0。
关系运算符 含义 优先级 < 小于 6 <= 小于或等于 两者满足其一即可 6 > 大于 6 >= 大于或等于 两者满足其一即可 6 == 等于 7 != 不等于 7 -
案例分析
- 1.假设整型变量
a、b、c的值为1 2 2,分析关系表达式a < b < c的执行结果
// 1.在数学中,表达式 a < b < c 中是不成立的,因为1 < 2 < 2不成立 // **2.在C语言中,表达式 a < b < c 中存在两个优先级相同的关系运算符 < ,会按照从左往右的顺序计算** // 2.1 首先计算 a < b 的值,即1 < 2,结果为真,这样表达式 a < b < c 就转换为 1 < c // 2.2 然后计算 1 < c 的值,即1 < 2,结果为真 // 2.3 综上,表达式 a < b < c 的执行结果为真,即1![]()
- 2.现有变量age,若age在18-28之间为"青年",用关系表达式表示"青年"的年龄范围
// 正确写法:age >= 18 && age <= 28 // 错误写法:18 <= age <= 28,当 age=10 时,不符合"青年"的标准,但程序会打印青年。具体原因可参考上一题![]()
- 3.关于"=="的代码书写技巧
int num = 3; if(num == 5) { printf("Y\n"); } // 上述代码若将"=="误写为"=",编译器不会报错,但存在逻辑错误,因为程序的本意为判断num与5的值是否相等 int num = 3; if(num == 5) { printf("Y\n"); } // 如何避免上述错误,在写带有"=="的简单关系表达式时(只有一个变量和一个值),左边写常量,右边写变量。这样如果"=="误写为"=",编译器会直接报错 int num = 3; if(num == 5) { printf("Y\n"); } - 1.假设整型变量
-
-
1.2 逻辑运算
运算符 含义 优先级 结合方向 备注 ! 逻辑非 2 右 单目运算符 && 逻辑与 11 左 双目运算符 逻辑或 逻辑或 12 左 双目运算符 -
用逻辑运算符连接若干个表达式组成的算式称为逻辑表达式,根据运算符的优先级确定表达式的运算顺序
-
基本运算特征
-
A&&B只有在A和B均为真时结果才为真,否则结果为假 -
A||B只有在A和B均为假时结果才为真,否则结果为真 -
!A若A为真,则结果为假,否则结果为真
-
-
短路运算特征
-
若A为假,则
A&&B的结果一定为假,B不会参与运算(注意B含++、--的场景)- 例如
int a = 0, b = 4; a&&++b;执行完后b的值仍为4
- 例如
-
若A为真,则A||B的结果一定为真,B不会参与运算(注意B含++、--的场景)
- 例如
int a = 1, b = 0; a||b++;执行完后b的值仍为0
- 例如
-
-
2.条件语句
-
2.1 if语句
- 一般形式
if (表达式) { 语句; } // 空语句 if (表达式) { ; } // 与上述空语句等价 if (表达式) ;-
执行逻辑:先对"表达式"求值,如果计算结果非0(为真),则执行其后的"语句",否则(即表达式的值为0)跳过其后的"语句"
-
注意事项
-
1."表达式"的类型可以为任何类型的表达式,理论上只要有值就可以
-
if(a == b) { 语句; }只有在变量a和b的值相等时,才会执行"语句" -
if(a = b) { 语句; }将b的值赋值给a,整个"表达式"的值即a的值。若b = 0,则不执行"语句";若b != 0,则执行"语句" -
if(a) { 语句; }若a = 0,则不执行"语句";若a != 0,则执行"语句"
-
-
2.区分表达式的值和变量的值,两个不一定相同。如表达式a=0的值为0,变量a的值也为0
-
3.无论"语句"是单条语句还是复合语句,建议都把
{}加上,以提升程序可读性,尤其是在后面复杂的选择结构中 -
4.空语句,在一般格式部分已说明
-
-
案例分析
- 1.输入一个成绩
score,如果成绩大于60,则显示"通过",否则不显示
// 课本上的代码结构不严谨,按照以下代码书写 #include <stdio.h> int main(){ int score = 0; printf("input score:"); scanf("%d", &score ); if(score >= 60) { printf("通过\n"); } } - 1.输入一个成绩
-
2.2 if...else语句
- 一般格式
if (表达式) { 语句1; } else { 语句2; } // 空语句 if (表达式) { ; } else { ; } // 与上述空语句等价 if (表达式) ; else ; if (condition) { return x; } return y; // 与上述不带else的代码段等价 if (condition) { return x; } else { return y; }-
执行逻辑:先对"表达式"求值,如果计算结果非0(为真),则执行"语句1",否则(即表达式的值为0)执行"语句2"
-
注意事项
-
1."语句1"和"语句2"可以是简单语句或复合语句,两者若有多条(不低于2)语句,应当加上
{}。否则可能会报错,'else' without a previos 'if'(else 找不到前方的if) -
2.建议使用
{}并使用缩进格式,以提高程序可读性 -
3.空语句即花括号中只有一个分号
;,没有其他内容
-
-
案例分析
- 1.输入一个成绩
score,如果成绩大于60,则显示"通过",否则显示"未通过"
#include <stdio.h> int main(){ int score = 0; printf("input score:"); scanf("%d", &score); if(score >= 60) { printf("通过!\n"); } else { // 执行此分支的前提为:score < 60 printf("未通过, 继续努力!\n") } }- 2.输入年龄的值,如果低于18岁,打印未成年;否则打印已成年,可以打游戏
// 错误示例,即使age = 10也会打印"可以打游戏",通过调试找出程序的bug #include <stdio.h> int main(){ int age = 0; scanf("%d", &age); if(age < 18) printf("未成年!\n"); else printf("已成年!\n"); printf("可以打游戏!\n"); } // 原因在于最后一条printf()语句不属于if...else结构,是独立的 - 1.输入一个成绩
-
2.3 if语句的嵌套
- 一般格式
if (表达式1) { 语句1; } else if (表达式2) { 语句2; } else if (表达式3) { 语句3; } else { 语句4; } // 空语句 if (表达式1) { ; } else if (表达式2) { ; } else if (表达式3) { ; } else { ; } // 与上述空语句等价 if (表达式1) ; else if (表达式2) ; else if (表达式3) ; else ;-
执行逻辑
-
1.先对
表达式1求值,如果计算结果非0(为真),则执行"语句1",随后执行if嵌套后方的语句;否则进入第2步 -
2.计算
表达式2的值,如果计算结果非0(为真),则执行"语句2",随后执行if嵌套后方的语句;否则进入第3步 -
3.计算
表达式3的值,如果计算结果非0(为真),则执行"语句3",随后执行if嵌套后方的语句;否则进入第4步 -
4.执行"语句4"
-
-
注意事项
-
1."语句1"到"语句4"只有可能执行其中一个,因为表达式本身就是互斥的
-
2.建议使用
{}并使用缩进格式,以提高程序可读性 -
3.在嵌套的if语句中,else与其上最接近的不曾与else配对的if配对,除非用花括号来改变,如以下程序段
// 程序段1 else与内层if配对 if (x > 7) { if(x < 13) { // 执行前提:x > 7 && x < 13 printf("Left!\n"); } else { //执行前提:x >= 13 printf("Right!\n"); } } // 程序段2 else与外层if配对 if (x > 7) { if(x < 13) { // 执行前提:x > 7 && x < 13 printf("Left!\n"); } } else { // 执行前提:x <= 7 printf("Right!\n"); } -
-
案例分析
- 1.现有分段函数,当
x < 1时,y = x;当1 =< x < 10时,y = 2x - 1;当x >= 10时,y = 3x - 10。编写程序输入x的值,输出对应y值
// 题目共有3种不同的情况,应当选择if...else if...else多分支结构 #include<stdio.h> int main(){ float x = 0.0f, y = 0.0f; printf("input x:"); scanf("%f", &x ); if(x < 1) { y = x; } else if(x < 10) { //隐含条件:x >= 1 y = 2 * x -1; } else { //隐含条件:x >= 10 y = 3 * x -10; } printf("y值为:%.2f\n", y ); } - 1.现有分段函数,当
-
2.4 条件表达式:又称三目运算符,由
?和:组成,要求有三个运算对象- 一般格式:
表达式1 ? 表达式2 : 表达式3;
t = A ? B : C // 若A的结果为真(或非0),则将B的值赋值给t;若A的结果为假(或0)则将A的值赋值给t-
执行逻辑
-
若表达式1的结果为真或非0,则条件表达式的值等于表达式2的值
-
若表达式1的结果为假或零,则条件表达式的值为表达式3的值
-
-
注意事项
-
1.一条语句实现求两个数中较大的数:
m = (x > y) ? x : y;若x > y,则将x的值赋值给变量m,否则将y的值赋值给变量m。实际上就是简化版的if...else...语句 -
2.优先级:条件运算符的优先级(13)高于赋值运算符(14),低于关系运算符(6 7)和算术运算符(1 3 4)
-
3.结合性:右结合性,即自右向左,可理解为先从右边开始加括号。如
a == b ? (c = 0) : a > b ?(c = 2) : (c = -2)等价于a == b ? (c = 0) : (a > b ? (c = 2) : (c = -2))
-
-
案例分析
- 1.输入一个字母,判断它是否为大写英文字母,若是则转换为小写字母
#include <stdio.h> int main() { char ch = 0; printf("input ch:"); scanf("%c", &ch); ch = (ch >= 'A' && ch <= 'Z'? ch + 32 : ch); // (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122) printf("%c\n", ch); // putchar(ch); return 0; }
- 一般格式:
3.多分支语句
- 3.1 一般格式
switch (表达式) {
case 常量表达式1: // 'A' 2 3 4 2+3 'A'+1
语句部分1;
[break;]
case 常量表达式2:
语句部分2;
[break;]
case 常量表达式n:
语句部分n;
[break;]
[default: // 前面的n个实例都没匹配,就执行default语句
语句部分n+1;]
}
-
3.2 执行逻辑
-
1.计算
switch语句括号中的表达式 -
2.将计算的结果依次与各
case后的值比较-
一旦匹配成功,则马上执行相应的“语句部分”,若遇
break,结束switch语句 -
若均不匹配,则执行
default(若有的话)后的语句部分
-
-
-
3.3 注意事项
-
1.
[]内的语句为可选部分,switch后方的表达式一般是整形表达式或字符型表达式 -
2.
case标号是整型数(包括字符型)或整型常量表达式,不能是变量,每一个case常量表达式的值必须互不相同,以下示例均错误
case 1.5: printf("hello"); // 1.5是浮点数,C语言中的浮点数大都是约数 case 2: case 1+1: // 即case 2 int n = 4; case n: // n为变量,不是常量-
3.执行
break后,程序流程跳出(结束)switch结构,转而执行switch结构后面(右花括号}之后)的第一条语句 -
4.若程序中相匹配的分支部分没有
break语句,将会继续执行下一个case语句后面的程序段(即使此时case后方的常量表达式与switch后方的表达式结果不同),一直到出现break语句或switch结束为止 -
5.
case作为程序数据流的入口,break作为程序数据流的出口 -
6.若没有
default语句,最后一个case语句建议加上break,防止后续再加case语句导致不能跳出的情况;建议写上default语句,同时后方也加上break -
7.
switch语句允许嵌套
-
-
3.4 案例分析
- 1.根据考试成绩的等级(A、B、C、D),输出“优秀”“良好”“及格”和“不及格”等评语
// 分析:由于本题共有4种情形,属于多分支,故选用switch结构 // 错误代码示范 #include <stdio.h> int main() { char grade = 0; printf("input grage A、B、C or D:"); scanf("%c", &grade); switch(grade) { case 'A': printf("优秀\n"); case 'B': printf("良好\n"); case 'C': printf("及格\n"); case 'D': printf("挂科\n"); } return 0; } // 输入:C // 输出为:及格 // 挂科 // 当匹配上某条case语句中的常量后,因为不存在break,所以会按照顺序执行后面的所有语句,直到遇到break或者程序末尾才结束程序 // 输入的C会先与case 'C'语句块匹配上,后面会继续匹配上case 'D'及其语句块,因此"挂科"也会被打印 // 正确代码示范 #include <stdio.h> int main(){ char grade = 0; printf("input grage A、B、C or D:"); grade = getchar(); // scanf("%c", &grade); switch (grade) { case 'A': printf("优秀 \n"); break; case 'B': printf("良好 \n"); break; case 'C': printf("及格 \n"); break; default: printf("不及格 \n"); break; } return 0; }- 2.多个switch标号共用一组语句
#include <stdio.h> int main() { char grade = 0; printf("input grage A、B、C or D:"); grade = getchar(); // scanf("%c", &grade); switch (grade) { case 'A': case 'B': // 只管匹配,不管打印 case 'C': printf("及格\n"); break; case 'D': printf("不及格\n"); break; default: printf("输入数据错误\n"); break; } return 0; }- 3.输入一个1-7的正整数,打印星期几。如输入3,打印星期三。若超出范围,则提示"输入错误"
// 分析:由于本题共有7种情形,属于多分支,故选用switch结构 #include <stdio.h> int main() { int day = 0; scanf("%d", &day); switch(day) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; case 5: printf("星期五\n"); break; case 6: printf("星期六\n"); break; case 7: printf("星期天\n"); break; default: printf("输入错误\n"); break; } return 0; }- 4.输入一个1-7的正整数,如果输入的是1、2、3、4、5,则打印"weekday",输入6、7则打印weekend。若超出范围,则提示"输入错误"
// 分析:由于本题共有2种情形,但输入情况有7种,选用switch结构。多个switch标号共用一组语句 #include <stdio.h> int main() { int day = 0; scanf("%d", &day); switch(day) { case 1: case 2: case 3: case 4: case 5: printf("weekday\n"); break; case 6: case 7: printf("weekend\n") default: printf("输入错误\n"); break; } return 0; }
4.分支结构程序设计
- 1.从键盘输入两个整数,输出其中最大者
// 方法1:使用if...else...语句(推荐)
#include <stdio.h>
int main(){
int a = 0, b = 0, max = 0;
printf("input a、b:");
scanf("%d %d", &a, &b);
if (a > b) {
max = a;
}
else {
max = b;
}
printf("两者中最大值为:%d", max );
return 0;
}
// 方法2:使用条件表达式(推荐)
#include <stdio.h>
int main(){
int a = 0, b = 0, max = 0;
printf("input a、b:");
scanf("%d %d", &a, &b);
max = a > b? a : b;
printf("两者中最大值为:%d", max );
return 0;
}
// 方法3:使用两个并列的if语句(不推荐)
#include <stdio.h>
int main(){
int a = 0, b = 0, max = 0;
printf("input a、b:");
scanf("%d %d", &a, &b);
if (a > b) {
max = a;
}
if (a <= b) {
max = b;
}
printf("两者中最大值为:%d", max );
return 0;
}
- 2.从键盘输入两个整数,从小到大输出
#include <stdio.h>
int main() {
int a = 0, b = 0, tmp = 0;
printf("input a、b:");
scanf("%d %d", &a, &b);
if (a > b) {
tmp = a;
a = b;
b = tmp;
}
printf("%d, %d", a, b);
return 0;
}
// 代码借助中间变量tmp完成变量a、b值的交换。除此之外,还可以直接基于变量a、b作“加减”的方式完成,代码为:a = a + b; b = a - b; a = a - b;
- 3.编写一个程序,判断一个字符是否为英文字母
#include <stdio.h>
int main() {
char ch = 0;
printf("input ch:");
scanf("%c", &ch); // ch = getchar();
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
printf("%c是英文字母\n", ch );
}
else {
printf("%c是其他字符\n", ch );
}
return 0;
}
-
4.已知区域A是由半径为1的圆和半径为2的圆所围成的圆环。编写程序,输入x、y,若点(x, y)在圆环内,则输出TRUE;否则输出FALSE
-
分析:题目的重点在于如何用数学表达式来表示圆环区域A
- 圆心在原点,半径为r的圆的标准方程为
x^2+y^2=r^2,因此圆心为原点,半径为1和2的圆可用方程x^2+y^2=1和x^2+y^2=4来表示 - 又因为区域A在内圆之外
(x^2+y^2>=1),且在外圆之内(x^2+y^2<=4),则A可用1 <= x^2+y^2 <= 4来表示,转换为C语言表达式即为(x * x + y * y >= 1)&&( x * x + y * y <=4)
- 圆心在原点,半径为r的圆的标准方程为
![image]()
-
#include <stdio.h>
int main() {
int b = 0;
float x = 0.0f, y = 0.0f, z = 0.0f;
printf("input x、 y:");
scanf("%f %f", &x, &y);
z = x * x + y * y;
b = (z >= 1) && (z <= 4);
if(b){
printf("TRUE\n");
}
else{
printf("FALSE\n");
}
return 0;
}




浙公网安备 33010602011771号