选择程序设计
大家应该还记得我们上一节课做过一个题目,这个题目是用来求一元二次方程的根的,原来的程序如下:
#include<stdio.h>
#include<math.h> //程序中要调用求平方根函数 sqrt
int main(){
double a,b,c,disc,x1,x2,p,q;
scanf("%lf%lf%lf",&a,&b,&c);
disc = b * b - 4 * a * c;
p = -b / (2.0 * a);
q = sqrt(disc) / (2.0 * a);
x1 = p + q,x2 = p - q;
printf("x1=%7.2f\nx2=%7.2f\n",x1,x2);
return 0;
}
这个程序我们并没有加入一个 b^2-4ac
是否大于等于 0 的一个判断,现在我们对这个程序做出一些改动,加入判断语句,输入以下代码:
#include<stdio.h>
#include<math.h> //程序中要调用求平方根函数 sqrt
int main(){
double a,b,c,disc,x1,x2,p,q;
scanf("%lf%lf%lf",&a,&b,&c);
disc = b * b - 4 * a * c;
if(disc<0)
printf("This equation hasn't real root!\n");
else{
p = -b / (2.0 * a);
q = sqrt(disc) / (2.0 * a);
x1 = p + q,x2 = p - q;
printf("x1=%7.2f\nx2=%7.2f\n",x1,x2);
}
return 0;
}
输入以下命令编译并运行
gcc -o 6-1 6-1.c -lm
./6-1
我们运行两次,分别输入 a,b,c 不同的值。
会看到以下结果:
程序分析
这就是一个选择结构,if 对给定的条件 disc<0 进行判断后,形成了两条路径,如果 disc<0 成立,执行 printf("This equation hasn't real root!\n");,如果 disc<0 不成立,执行 else{} 中的内容。
知识点:
- 可以把几个语句放在一个 {} 中,这样如果 disc<0 不成立,就会执行 else{} 里面所有的内容;
- 假如没有 {} 同时 disc<0,这个时候执行完 printf("This equation hasn't real root!\n");;
- 语句以后会从 q=sqrt(disc)/(2.0*a);;
- 接着往下执行,大家可以自己思考下加不加 {} 的影响。
用 if 语句实现选择结构
在 C 语言中选择结构最常用的就是 if 语句,为了了解 if 语句的应用,我们举一个例子进行说明。
编写源程序 6-2.c:
#include<stdio.h>
int main(){
int number=0;
printf("\nPlease enter an integer between 1 and 10:");
scanf("%d",&number);
if(number>5)
printf("You entered %d which is greater than 5\n",number);
if(number<6)
printf("You enter %d which is less than 6\n",number);
return 0;
}
运行两次,分别输入 6 和 2.结果如下:
程序分析
- main() 函数体的前三个语句如下:
int number=0;
printf("\nPlease enter an integer between 1 and 10:");
scanf("%d",&number);
这段代码声明一个整型变量 number,并初始化为 0,接着提示用户输入一个 1~10 的数字。使用 scanf() 函数读取这个数值,并存储在变量 number 中。
- 下一条语句就是一条测试输入值的 if 语句
if(number>5)
printf("You entered %d which is greater than 5\n",number);
比较 number 变量的值和 5,如果 number 大于 5,就执行下一条语句,然后进入程序的下一个部分。如果 number 不大于 5,就跳过 printf()。
- 接下来这条语句和上一条语句意义相同
if(number<6)
printf("You enter %d which is less than 6\n",number);
我完善了6-2的程序,使之更为合理:
#include<stdio.h>
int main(){
int n=0;
printf("请输入一个介于0到10的数");
scanf("%d",&n);
if(n>5&&n<11) //逻辑运算符&&表示并且
printf("你输入的数大于5");
if(n<6&&n>0)
printf("你输入的数小于等于5");
if(n>10||n<0) //逻辑运算符||表示或者
printf("你的输入有误,请重新输入");
return 0;
}
通过上面的两个例子,我们可以初步的了解怎样使用 if 语句去实现选择结构了。
例如:
if (number>500) cost=0.15;
else if (number>300) cost=0.10;
else if (number>100) cost=0.07;
else if (number>50) cost=0.05;
else cost=0;
程序分析
- 我们 6-1.c 的例子便是上面你的第二种形式,6-2.c 的例子便是第一种形式。
- 整个 if 语句可以写在多行上,也可以写在一行上面。如:
if (x>0) y=1;else y=-1;
但是为了程序的清晰,我们很少用上面的形式,而是采用锯齿的形式。
关系运算符和关系表达式
C 语言提供 6 种关系运算符,如下所示:
运算符 | 名称 | 示例 | 功能 |
< | 小于 | a<b | a 小于 b 时返回真;否则返回假 |
<= | 小于等于 | a<=b | a 小于等于 b 时返回真;否则返回假 |
> | 大于 | a>b | a 大于 b 时返回真;否则返回假 |
>= | 大于等于 | a>=b | a 大于等于 b 时返回真;否则返回假 |
== | 等于 | a==b | a 等于 b 时返回真;否则返回假 |
!= | 不等于 | a!=b | a 不等于 b 时返回真;否则返回假 |
关系运算符的值只能是 0 或 1。 关系运算符的值为真时,结果值都为 1。 关系运算符的值为假时,结果值都为 0。
逻辑运算符和逻辑表达式
有时要求判断的条件不是一个简单的条件,是有几个条件组合而成的复合条件。比如“如果周六下雨,我在实验楼做一个项目课”,这就是有两个条件组合而成的符合条件,需要同时满足两个条件:(1)是否周六(2)是否下雨,只有满足是周六又在下雨,才来实验楼做项目课。
C 语言中提供了三种逻辑运算符:
运算符 | 含义 | 举例 | 说明 |
&& | 逻辑与 | a&&b | 如果 a 和 b 都为真,则为真,否则为假 |
|| | 逻辑或 | a||b | 如果 a 和 b 有一个或一个以上为真,则为真,二者都是为假,结果为假 |
! | 逻辑非 | !a | 如果 a 为假,则!a 为真,如果 a 为真,则!a 为假 |
之前我们做过用户输入一个大写字母,命令行显示与之对应小写字母的程序。但是在当时我们并没有去判断输入的字符是否是一个大写字母,现在我们从新编写程序。
编写源程序 6-3.c:
#include<stdio.h>
int main(){
char letter;
printf("Enter an upper case letter:");
scanf("%c",&letter);
if((letter>='A') && (letter<='Z'))
{
letter += 'a' - 'A'; //等同于 letter=letter+'a'-'A';
printf("You entered an uppercase %c.\n",letter);
}
else
printf("You did not enter an uppercase letter.\n");
return 0;
}
运行结果如下:
程序分析
if((letter>='A')&&(letter<='Z')){
letter += 'a' - 'A'; //等同于 letter=letter+'a'-'A'; printf("You entered an uppercase %c.\n",letter);
}
else
printf("You did not enter an uppercase letter.\n");
在这段程序中 if((letter>='A')&&(letter<='Z')) 检查输入的字符是否大于等于 'A',且小于等于 'Z'。两者同时满足才会执行后面的语句。
条件运算符和条件表达式
有一种 if 语句,当被判别的表达式的值为“真”或“假”时,都执行一个赋值语句且向同一个变量赋值。如:
if(a>b)
max=a;
else
max=b;
程序分析
当 a>b 时将 a 的值赋值给 max,当 a<=b 时将 b 的值赋给 max,可以看到无论 a>b 是否满足,都是给同一个变量赋值。
C 语言提供的条件运算符和条件表达式来处理这类问题可以把上面的 if 语句改写为 max=(a>b)?a:b;。(a>b)?a:b;是一个“条件表达式”。?是条件运算符。
如果 (a>b) 为真,则表达式的值等于 a,否则取值为 b。条件运算符由两个符号(?和:)组成,必须一起使用。要求三个对象,成为三目运算符,它是 C 语言唯一的一个三目运算符。
条件表达式的一般形式为:
表达式 1?表达式 3:表达式 2
这次我们列举一个打折的例子。
假定产品的单价是 3.5,提供 3 个级别的折扣:数量超过 50,折扣为 15%;数量超过 20,折扣为 10%;数量超过 10,折扣为 5%。下面是代码。
编写源程序 6-4.c:
#include<stdio.h>
int main(){
double unit_price = 3.5;
double discount1 = 0.05;
double discount2 = 0.1;
double discount3 = 0.15;
double total_price = 0.0;
int quantity = 0;
printf("Enter the number that you want to buy:");
scanf("%d",&quantity);
total_price=quantity*unit_price*(1.0-
(quantity>50?discount3:(
quantity>20?discount2:(
quantity>10?discount1:0.0))));
printf("The price for %d is %7.2f\n",quantity,total_price);
return 0;
}
运行结果如下:
程序分析
比较有趣的是根据输入的数量计算产品的总价的语句。该语句包含额三个条件运算符,所以有点难以理解:
total_price = quantity*unit_price*(1.0-
(quantity>50?discount3:(
quantity>20?discount2:(
quantity>10?discount1:0.0))));
把它分解为各个部分,就容易理解它是如何得出正确结果的。
总价是用表达式 quantity*unit_price 计算出来的,它只是将单价乘以订购数量。其数量必须乘以由数量决定的折扣因子
- 如果数量超过 50,总价必须乘以 (1.0-discount3),这用下面的表达式 (1.0-quantity>50?discount3:something_else)
- 如果 quantity>50 表达式就乘以 (1.0-discount3),完成赋值运算符右边的运算
- 否则,表达式乘以 (1.0-something_else),其中 something_else 是另一个条件运算符的结果。
用 switch 语句实现多分支选择结构
if
语句只有两个分支可供选择,而实际中常常用到多分支选择。例如成绩分类(85 分以上为 A,70-85 为 B,60-69 为 C 等),人口的分类(可以分为老、中、青、少、儿童),工资统计分类等等,如果我们使用 if 语句就会嵌套很多层数,影响可读性。C 语言提供的 switch
语句直接处理多分支选择。
我们首先用一个例子说明,编写 6-5.c 程序:
#include<stdio.h>
int main(){
char grade;
scanf("%c",&grade);
printf("you score:");
switch(grade){
case 'a':printf("85~100\n");break;
case 'b':printf("70~84\n");break;
case 'c':printf("60~69\n");break;
case 'd':printf("<60\n");break;
default:printf("error!\n");
}
return 0;
}
运行结果:
程序分析
- 等级 grade 定义为字符变量,从键盘输入一个小写字母,赋给变量 grade,switch 得到 grade 的值并和各 case 中给定的值('a''b''c''d'之一)相比较,如果和其中之一相同,则执行该 case 后面的语句(即 printf 语句)。如果输入的字符与'a''b''c''d'都不相同,就执行 default 后面的语句,输出 error!信息。
- 注意每个 case 语句中,后面都有一个 break 语句,该语句的作用是使得当前流程跳转到闭括号 '}' 后面的语句。
假如去掉程序中所有 break 语句,用户从键盘输入 b 以后,输出 7084 并换行以后,程序将执行 `case 'c':printf("6069\n");` 语句,并且还要执行下去,结果如下:
通过上例我们已经基本了解了 switch 语句。其一般形式如下:
switch(表达式) { case 常量 1:语句 1 case 常量 2:语句 2 . . . case 常量 n :语句 n default : 语句 n+1 }
说明:
- switch 括号内的“表达式”,其值的类型应为整数类型或者字符类型,不可以是其他数据类型。
- default 语句为选择项,可有可无。另外,default 后面可以不加 break 语句。