在C语言中实现选择结构用选择语句:
-
if语句
-
条件运算符 ? :
-
switch语句
一.if语句
- 单分支:if(表达式)语句
- 双分支:if(表达式) 语句1 else 语句2
- 多分支( if else嵌套语句 ,阶梯式的if-else-if语句)
1.单分支:if(表达式)语句
-
若表达式值为True(或非0),则执行表达式后面的语句,执行完该语句后继续执行if语句后的语句。
-
若表达式值为0,则不执行表达式后面的语句而直接执行if 语句后的语句。
if语句中的表达式可以是关系表达式、逻辑表达式,甚至还可以是数值表达式。在C语言中,表达式的值为非0时,系统均按真值处理。
“表达式”后面的语句可以是复合语句。复合语句是指用一对花括号}包含起来的若干条语句。被当作一条
语句来处理。
ps:复合语句
1. 在程序中应把复合语句看成是单条语句,而不是多条语句;
2.复合语句内的各条语句必须是以“;”结尾,最后一条语句的结尾也必须有分号“;”
3.复合语句还可以包含复合语句,即复合语句允许嵌套,但必须保证嵌套是完整的,不允许交叉嵌套。
应用样例:
例1:输入任意三个整数a、b、c,求三个数中的最大值。
思路:擂台法
首先取一个数预置为max(最大值),然后再用max依次与其余的数逐个比较,如果发现有比max大的,就用它给max重新赋值,比较完所有的数后,max中的数就是最大值。
代码如下:
#include <stdio.h>
void main()
{
int a,b,c,max;
printf("请输入三个整数a,b,c:");
scanf("%d%d%d",&a,&b,&c);
max=a;
if(max<b)
max=b;
if(max<c)
max=c;
printf("%d",max);
}
例2:输入3个数a,b,c,要求按由小到大的顺序输出这3个数。
思路:使用判断交换法
分析:对于3个数,有6种可能:
a<b<c b<a<c a<c<b
c<a<b b<c<a c<b<a
-
若a>b,则交换a,b,此时a是两者中较小的。
-
若a>c,则交换a,c,此时a是两者中较小的。
经过以上两步,得出a中存放的是三者中最小的。
- 若b>c,则交换b,c,此时b是两者中较小的。
经过这一步得出b是三者中,次小的。
综合以上三步,得出结果a<b<c。
代码如下:
#include <stdio.h>
void main()
{
int a,b,c,t;
printf("请输入三个整数a,b,c:");
scanf("%d%d%d",&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;}
printf("%d%2d%2d",a,b,c);
}
关于“单分支if语句”的常见错误:
错误1:关于分号的错误
刚接触if语句,不少初学者会在“if(表达式)”后面加分号,由于一个单独的分号属于一条空语句,会被if结合,造成本来应属于if的语句体不能被if结合。
错误2:关于复合语句的错误
当if的语句体有多条语句时,没有用花括号括起来,引起逻辑错误。
2.双分支结构:if .....…else
if(表达式)
<语句块1>
else
<语句块2>
else语句本身不能单独存在,必须与if配对使用。
-
如果表达式为真,执行 if 后面的语句块1;
-
如果表达式为假,则执行else 后面的语句块2。
if...else结构中的语句块1与语句块2都可以是复合语句。
在if...else结构中,语句块1与语句块2都可以是空语句。
应用样例:
例1:判断给出的一个三位整数是不是“回数”。
回数:所谓“回数”是指一个数正着读和反着读都一样。例如,121是回数,123则不是。
思路:我们当然可以定义一个变量来存放倒过来的数,但由于题目只要求是三位数,那么只需个位和百位相同。
代码如下:
#include<stdio.h>
#include<math.h>
void main()
{
int a;
printf("请输入一个三位数:");
scanf("%d",&a);
if(a/100==a%10)
printf("是回数");
else
printf("不是回数");
}
关于“双分支if语句”的常见错误:
错误1:关于分号的错误
else不能单独出现 max=b,一定执行
错误2:关于花括号的错误
else不能单独出现 printf语句一定执行
错误3:关于表达式的错误
else本身就是条件,后面不再有表达式
3.嵌套if语句
嵌套 if 语句就是将整个 if 块插入另一个if块(else块)中。
-
else总是与它前面最近的未配对的if配对使用。
-
可通过增加花括号{}来确定配对关系。
例:以下这个else部分属于哪个if。
if(x>0)
if (y>1)
z=1;
else
z=2;
初学时容易将与else对齐的if默认为是一对,而事实else必须和前面最近的未配对的if配对。
应用样例:
例1:求一元二次方程ax*2+bx+c=0的根。
思路:
(1)a等于0,方程只有一个实根
(2)a不等于0,又分为3种情况:
(1)判别式b*2-4ac等于0,方程有两个相等的实根;
(2)判别式b*2-4ac大于0,方程有两个不等的实根;
(3)判别式b*2-4ac小于0,方程无实根:
代码如下:
#include<stdio.h>
#include<math.h>
void main()
{
int a,b,c,x1,x2;
printf("请输入此一元二次方程:");
scanf("%dx*2+%dx+%d",&a,&b,&c);
if(a==0)
printf("有一个实根,且为%d",-c/b);
else
{
x1=(-b+sqrt(b*b-4*a*c))/(2*a);
x2=(-b-sqrt(b*b-4*a*c))/(2*a);
if(b*b-4*a*c==0)
printf("有两个相等的实根x1=x2=%d",x1);
else
{
if(b*b-4*a*c>0)
printf("有两个不相等的实根x1=%d,x2=%d",x1,x2);
else
printf("无实根");
}
}
}
4.多分支if语句
多分支if语句是嵌套if语句的另一种形式,这种形式也称为阶梯式 if-else-if 。
if(表达式1)
语句组1;
else if(表达式2)
语句组2;
else if(表达式3)
语句组3;
……
else
语句组n;
流程图:
应用样例:
例1:通过输入年级,得出你所处学段。
1~6年级 小学
7~9年级 初中
10~12年级 高中
13~16年级 大学
代码如下:
#include<stdio.h>
#include<math.h>
void main()
{
int a;
printf("请输入你的年级::");
scanf("%d",&a);
if(1<=a&&a<=6)
printf("小学");
else if(7<=a&&a<=9)
printf("初中");
else if(10<=a&&a<=12)
printf("高中");
else if(13<=a&&a<=16)
printf("大学");
}
二.条件表达式
主要解决两个分支为同一个变量赋值的问题,可使程序简洁。
条件表达式的一般形式为:
表达式1?表达式2:表达式3
-
先求出表达式1的值,若非0(真),则求出表达式2的值就是整个条件表达式的值。
-
否则,求出表达式3的值就是整个条件表达式的值。
流程图:
样例:
二者等价,且更加简洁。
ps:
- 条件运算符优先级仅高于逗号运算符和赋值运算符。
- 条件运算符的优先级比关系运算符与算术运算符都要低。
- 条件运算符的结合方向为“从右到左”。
三.switch语句
switch-case语句是多路判断语句,计算条件表达式并对照多个常数值进行检查。
用法:
-
各个case 和default出现的次序不影响执行结果。
-
每个case语句后一般情况下应有一个break语句,用于退出swith结构。
-
case后面的语句中如果没有break语句,则执行完本case后的语句会接着执行下面的case 。
-
多个case可共用一组语句。
-
每两个 case 标签之间的语句数不限,允许有多个语句,可以不用{ }括起来。
通常情况下,每个case子句后都会有一个break语句;如果case子句中没有break语句,则会在执行完匹配的case子句后,继续向下执行后面的case子句,直至switch语句结束。
例如输入的m为1,在此程序中,它在执行完case 1后会继续执行case 2,case 3,直到遇到break,才会终止。
应用样例:
例1:要求用户输入一个小写字母并检查它是否为元音字母。
代码如下:
#include<stdio.h>
#include<math.h>
void main()
{
char a;
printf("请输入一个小写字母:");
scanf("%c",&a);
switch(a)
{
case 'a': printf("是元音字母");break;
case 'o': printf("是元音字母");break;
case 'e': printf("是元音字母");break;
case 'i': printf("是元音字母");break;
case 'u': printf("是元音字母");break;
default: printf("不是元音字母");
}
}
四.多重if语句和switch 语句的比较
-
多重if语句和switch语句都可以用来实现多路分支。
-
switch语句一般只能实现等值的比较,多重if语句可以处理范围,某些范围问题也可以通过将范围通过某些方法转化为确定值从而通过switch来实现,而有些问题只能使用多重if语句来实现,例如要判断一个值是否处在某个区间的情况。
例1:要求按照百分制考试分数输出等级。分段原则如下:
90~100 为A级
80~89 为B级
70~79 为C级
60~69 为D级
其它为E级
1.用多分支if语句实现
利用多分支if的特点,只要判断出一个真值就不再执行下面的判断。那么其范围的右端,由上一个判断已经确定,完全可以不写。
代码如下:
#include <stdio.h>
void main()
{
int a;
printf("请输入你的分数a:");
scanf("%d",&a);
if(a<0||a>100)
printf("输入分数错误");
else if(a>=90)
printf("A");
else if(a>=80)
printf("B");
else if(a>=70)
printf("C");
else if(a>=60)
printf("D");
else
printf("E");
}
当然对于此题而言,就算在每个括号内加上每个的范围区间,也不能说是多此一举。这样写倒还可以显得跟加直观一些。
代码如下:
#include <stdio.h>
void main()
{
int a;
printf("请输入你的分数a:");
scanf("%d",&a);
if(a>=90&&a<=100)
printf("A");
else if(a>=80&&a<90)
printf("B");
else if(a>=70&&a<80)
printf("C");
else if(a>=60&&a<70)
printf("D");
else
printf("E");
}
像此种范围左右都确定的写法,将else if改为if,就变成多个单分支语句。由于篇幅不再赘述,可以自行复制后修改。会发现一样可以实现程序运行。其二者的区别在于,对于多分支if一旦判断出一个真值,以下分支将不再判断。而这种多个单分支if,互不影响,你出真值跟下一个无关,故每个都会进行判断。
2.用switch-case语句实现
case后面只能带一个常数,似乎不能直接实现,所以需要我们进行转换一下:
分析这些分数段可发现,分数段的变化点都是10的整数倍,如果将分数整除10,则可以转化为整数。
为使用switch语句,必须将分数段与等级的关系,转换成某些整数与等级的关系。
代码如下:
#include <stdio.h>
void main()
{
int a,b;
printf("请输入你的分数a:");
scanf("%d",&a);
b=a/10;
switch(b)
{
case 10:
case 9: printf("A");break;
case 8: printf("B");break;
case 7: printf("C");break;
case 6: printf("D");break;
default: printf("E");break;
}
}