C程序设计
第5章 选择结构程序设计 选择结构是三种基本结构之一。在大多数程序中都会包含选择结构。它的作用是,根据所指定的条件是否满足,决定从给定的两组操作选择其一。在本章中介绍如何用C语言实现选择结构。 在C语言中选择结构用if语句实现。if语句最常用的形式如下: if (关系表达式) 语句1 else 语句2 例如: if (x>0) y=1; else y=-1; 其中x>0是一个关系表达式。“>”是一个关系运算符。
5.1 关系运算符和关系表达式 关系运算是逻辑运算中比较简单的一种。“关系运算” 就是“比较运算”。将两个值进行比较,判断其比较的结果是否符合给定的条件。例如a>3是一个关系表达式。
5.1.1 关系运算符及其优先次序 C语言提供6种关系运算符: < <= > >= == != 关于优先次序: < <= > >= == != 关于优先次序: (1)前4种关系运算符的优先级别相同,后两种也相同。前4种高于后2种。 (2)关系运算符的优先级低于算术运算符。 (3)关系运算符的优先级高于赋值运算符。 !算术运算 关系运算 &&和|| 赋值预算 (高低) 举例: /*int a, b, c; a=1; b=2; c=3; //printf("%d\n", c>a+b); //printf("%d\n", a>b==c); //printf("%d\n", a==b<c); printf("%d\n", a=b>c);*/
5.1.2 关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式、逻辑表达式、赋值表达式、字符表达式)连接起来的式子,称关系表达式。 关系表达式的值是一个逻辑值,即“真”或“假”。C语言没有逻辑型数据,以1代表“真”,以0代表“假” 举例: /*int a, b, c, d, f; a=1; b=2; c=3; printf("%d\n", 5==3); printf("%d\n", 5>=0); printf("%d\n", a>b); printf("%d\n", (a>b)==c); printf("%d\n", b+c<a); printf("%d\n", d=a>b); printf("%d\n", f=a>b>c);*/
5.2 逻辑运算符和逻辑表达式 用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。
5.2.1 逻辑运算符及其优先次序 C语言提供三种逻辑运算符: (1)&&逻辑与 (2)||逻辑或 (3)!逻辑非
逻辑运算的“真值表” a b !a a&&b a||b 真 假
在一个逻辑表达式中如果包含多个逻辑运算符,如 !a&&b||x>y&&c 按以下的优先次序: (1)!(非)->&&(与)->||(或),即“!”为三者中最高的。 (2)逻辑运算符中的“&&”和“||”低于关系运算符,“!”高于算术运算符。 举例: /*int a, b, c, x, y; a=1; b=2; c=3; x=4; y=5; printf("%d\n", !a&&b||x>y&&c); // 0||0=0 printf("%d\n", a>b&&x>y); //0&&0=0 printf("%d\n", a==b||x==y); //0||0=0 printf("%d\n", !a||a>b); //0||0=0*/ //printf("%d\n", 'c'&&'d');
5.2.2 逻辑表达式 逻辑表达式的值应该是一个逻辑量“真”或“假”。C语言编译系统在给出逻辑运算结果时,以数值1代表“真”,以0代表“假”,但在判断一个量是否为“真”时,以0代表“假”,以非0代表“真”。即将一个非零的数值认作为“真”。 举例: //printf("%d\n", 'c'&&'d');
在逻辑表达式的求解中,并不是所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。 (1)a&&b&&c (2)a||b||c 举例: 1 /*int a=1, b=2, c=3, d=4, m=1, n=1; printf(“%d\n”, (m=a>b) && (n=c>d)); printf(“m=%d,n=%d\n”, m, n);* //由于a>b的值为0,因此m=0,而n=c>d不被执行,因此n的值不是0而是保持原值为1 2 /*int year; scanf("%d", &year); if(year%4==0 && year%100!=0 || year%400==0) { printf("%d是闰年\n", year); } else printf("%d不是闰年\n", year); }*/
5.3 if语句 if语句是用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。
5.3.1 if语句的3种形式 C语言提供了3种形式的if语句。 1、if (表达式) 语句 例如:if (x>y) printf(“%d”, x);
2、if (表达式) 语句1 else 语句2 例如: if (x>y) printf(“%d”, x); else printf(“%d”, y); 举例: 1 /*int x, y; x=2; y=1; if(x>y) printf("x=%d\n", x); else printf("y=%d\n", y);*/ 备注: 1、if (表达式) 语句A; 语句B; 解释:if 默认制动控制语句A的执行或不执行,if语句无法控制语句B的执行或不执行。或者讲:语句B一定会执行; 2、if(表达式) { } 此时if可以控制语句A和B 由此可见,if默认只能控制一个语句的执行或不执行。如果想控制多个语句的执行或不执行,就必须把这些语句用{}括起来。
3、 if (表达式1) 语句1 else if (表达式2) 语句2 else if (表达式3) 语句3 …… else if (表达式m) 语句m else 语句n 备注: C语言对真假的处理 非零是真,零就是假。 真用1表示,假用零表示。
补充程序 (1)
说明: (1)三种形式的if语句中在if后面都有“表达式”,一般为逻辑表达式或关系表达式。 (2)第二、第三种形式的if语句中,在每个else前面有一个分号,整个语句结束处有一个分号。 (3)在if和else后面可以只含一个内嵌的操作语句,也可以有多个操作语句,此时用花括号将几个语句括起来成为一个复合语句。 举例: 1、//if(3) printf("ok\n"); 2、//if('a') printf("%d", 'a'); /*float x=1.0; if(x>0) printf("%f", x); else printf("%f", -x);*/ 3、/*double a, b, c, s, area; scanf("a=%lf,b=%lf,c=%lf", &a, &b, &c); if(a+b>c&&b+c>a&&c+a>b) { s=(a+b+c)/2; area=sqrt(s*(s-a)*(s-b)*(s-c)); printf("area=%lf\n", area); } printf("三边不能组成一个三角形\n");*/
[5.1]输入两个实数,按代数值由小到大的顺序输出这两个数 #include <stdio.h> void main() { float a, b, t; scanf(“%f,%f”, &a, &b); if(a>b) t=a;a=b;b=t; } printf(“%5.2f,%5.2f\n”, a, b); 补充程序 补充程序(2)
[例5.2]输入3个数a、b、c,要求按由小到大的顺序输出 #include <stdio.h> void main() { float a, b, c, t; scanf(“%f,%f,%f”, &a, &b, &c); if(a>b) {t=a;a=b;b=t;} if(a>c) {t=a;a=c;c=t;} if(b>c) {t=b;b=c;c=t;} }
5.3.2 if语句的嵌套 在if语句中又包含一个或多个if语句称为if语句的嵌套。一般形式如下: if() if() 语句1 else 语句2 else if() 语句3 else 语句4
[例5.3]编程,输入x值,输出y值,函数: -1 (x<0) y = 0 (x=0) 1 (x>0) #include <stdio.h> void main() { int x, y; scanf(“%d”, &x); if(x<0) y=-1; else if(x==0) y=0; else y=1; printf(“x=%d,y=%d\n”,x,y); } if 常见问题解析: 补充程序(3) 1、空语句的问题 if (3>2);等价于 if (3>2) ; //这是一个空语句; 2、 if (表达式1) A; else B; 是正确的。 if (表达式1); 是错误的; 3、 if (表达式1) else if (表达式2) else if (表达式3) C; D; 即便表达式1和2都成立 ,也只会执行A语句。 4、 if (表达式1) else if (表达式 2) else if (表达式3) 这样写语法不会出错,但逻辑上有漏洞; 5、 if (表达式1) else if (表达式2) else if(表达式3) else (表达式4) //第7行 这样写是不对的,正确的写法是:要么去掉第7行的(表达式4),要么在抵7行的else后面加if 6、 if (表达式1) else if (表达式2) else (表达式4); 这样写语法不会错,但逻辑上是错误的。 else (表达式4); 等价于
5.3.3 条件运算符 若在if语句中,当被判别的表达式的值为“真”或“假”时,都执行一个赋值语句且向同一个变量赋值时,可以用一个条件运算符来处理。 条件运算符要求有3个操作对象,称三目(元)运算符。 条件表达式的一般形式为 表达式1?表达式2:表达式3
说明: (1)条件运算符的执行顺序:先求解表达式1,若为非0则求解表达式2,此时表达式2的值就作为整个条件表达式的值。若表达式1的值为0,则求解表达式3,表达式3的值就是整个条件表达式的值。 (2)条件运算符优先于赋值运算符。 (3)条件运算符的结合方向为自右至左。 (4)表达式不仅可以是数值表达式,还可以是赋值表达式或函数表达式。 (5)条件表达式中,表达式1的类型可以与表达式2和表达式3的类型不同。 举例: 1 /*if(a>b) max=a; else max=b;*/ /*int a, b, max; a=2; b=3; max=1; max= a>b ? a : b; printf("max=%d\n", max);*/ //max= a>b ? a : b; 2 //(a>b) ? a : b+1 等价于 (a>b) ? a : (b+1) 3 /*int a, b, c, d; a=1; b=2; c=3; d=4; printf(“%d\n”, a>b ? a : c>d ? c : d); //相当于a>b ? a: (c>d?c:d) */ 4 /*int a=2; int b=1; //printf("%d\n", a>b ? (a=100) : (b=200)); //a>b ? printf("%d\n", a) : printf("%d\n", b); 5 int x, y; x=1; y=0; x ? 'a' : 'b'; double d = x>y ? 1 : 1.5; //在此处需要将整形转变为double行 printf("d=%lf\n", d);*/
[例5.4]输入一个字母,判别它是否大写字母,如果是,将它转换成小写字母;如果不是,不转换。然后输出最后得到的字符 #include <stdio.h> void main() { char ch; scanf(“%c”, &ch); ch=(ch>=‘A’ && ch<=‘Z’) ? (ch+32) : ch; printf(“%c\n”, ch); }
5.4 switch语句 switch语句是多分支选择语句。一般形式: switch(表达式) { case 常量表达式1: 语句1 … case 常量表达式n: 语句n default: 语句n+1; } 补充程序: switch用法举例_电梯程序.cpp
说明: (1)switch后面括号内的表达式,ANSI标准允许它为任何类型。 (2)当表达式的值与某一个case后面的常量表达式的值相等时,就执行此case后面的语句,若所有的case中的常量表达式的值都没有与表达式的值匹配的,就执行default后面的语句。 (3)每一个case的常量表达式的值必须互不相同;否则就会出现相互矛盾的现象。 (4)各个case和default的出现次序不影响执行结果。 (5)执行完一个case后面的语句后,流程控制转移到下一个case继续执行。 (6)多个case可以共用一组执行语句。 举例: char grade; scanf("%c", &grade); switch(grade) { case 'A': case 'B': case 'C': printf(">=60\n"); break; case 'D': printf("<60\n"); default: printf("error\n"); }
5.5 程序举例 [例5.5]写程序,判断某一年是否闰年
[例5.6]求ax2+bx+c=0方程的解 (1)a=0 (2)b2-4ac=0 (3)b2-4ac>0 (4)b2-4ac<0
[例5.7]运输公司对用户计算运费 路程越远,每吨每千米运费越低。 标准如下: s<250 没有折扣 250≤s<500 2%折扣 500≤s<1000 5%折扣 1000≤s<2000 8%折扣 2000≤3<3000 10%折扣 3000≤s 15%折扣 设每吨每千米货物的基本运费为p,货物重为w,距离为s,折扣为d,则总运费f的计算公式为 f=p*w*s(1-d)
习题 5.3 写出下面各逻辑表达式的值。设a=3,b=4,c=5。 (1)a+b>c && b==c (2)a||b+c && b-c (4)!(x=a) && (y=b) && 0 (5)!(a+b)+c-1 && b+c/2 5.4 有3个整数a、b、c,由键盘输入,输出其中最大的数。
5.5 有一个函数: x x<1 y= 2x-1 1≤x<10 3x-11 10≤x 5.6 给出一百分制成绩,要求输出成绩等级A、B、C、D、E。90分以上为A,80~89分为B,70~79分为C,60~69分为D,60分以下为E。 5.9 输入4个整数,要求按由小到大的顺序输出。
5.10 有4个圆塔,圆心分别为(2,2)、(-2,2)、(-2,-2)、(2,-2),圆半径为1。这4个塔的高度为10m,塔以外无建筑物。今输入任意点的坐标,求该点的建筑高度(塔外的高度为零)。