C语言程序设计 第四章

笔记

马上就要期末考试啦,抓紧时间复习~

第4章 选择结构程序设计

1、选择结构和条件判断

C语言有两种选择语句

  • if语句,用来实现两个分支的选择结构

  • switch语句,用来实现多分支的选择结构

【例4.1】在例3.5的基础上对程序进行改进。题目要求解得ax2+bx+c=0方程的根。由键盘输入a,b,c。假设a,b,c的值任意,并不保证b2-4ac≥0。需要在程序中进行判别,如果b2-4ac≥0,就计算并输出方程的两个实根,如果b2-4ac<0,就输出“此方程无实根”的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
#include<math.h> //程序中要调用求平方根函数sqrt
int main()
{ double a,b,c,disc,x1,x2,p,q; //disc是判别式sqrt(b*b-4ac)
scanf("%lf%lf%lf",&a,&b,&c); //输入双精度浮点型变量的值要用格式声明"%lf"
disc=b*b-4*a*c;
if(disc<0) //若b*b-4ac<0
printf("This equation hasn't real roots\n"); //输出“此方程无实根”
else //b*b-4ac≥0
{ p=-b/(2.0*a);
q=sqrt(disc)/(2.0*a);
x1=p+q;x2=p-q; //求出方程的两个根
printf("real roots:\nx1=%7.2f\nx2=%7.2f\n",x1,x2); //输出方程的两个根
}
return 0;
}

2、用if语句实现选择结构

【例4.2】输入两个实数,按由小到大的顺序输出这两个数。

解题思路

只要做一次比较,然后进行一次交换即可。用if语句实现条件判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
int main()
{
float a,b,t;
scanf("%f,%f",&a,&b);
if(a>b)
{ //将a和b的值互换
t=a;
a=b;
b=t;
}
printf("%5.2f,%5.2f\n",a,b);
return 0;
}

【例4.3】输入3个数a,b,c,要求按由小到大的顺序输出。

算法步骤

S1: if a>b,将a和b对换

(交换后,a是a、b中的小者)

S2: if a>c,将a和c对换

(交换后,a是a、c中的小者,因此a是三者中最小者)

S3: if b>c,将b和c对换

(交换后,b是b、c中的小者,也是三者中次小者)

S4: 顺序输出a,b,c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
int main()
{
float a,b,c,t;
scanf("%f,%f,%f",&a,&b,&c);
if(a>b)
{ t=a; //借助变量t,实现变量a和变量b互换值
a=b;
b=t;
} //互换后,a小于或等于b
if(a>c)
{ t=a; //借助变量t,实现变量a和变量c互换值
a=c;
c=t;
} //互换后,a小于或等于c
if(b>c) //还要
{ t=b; //借助变量t,实现变量b和变量c互换值
b=c;
c=t;
} //互换后,b小于或等于c
printf("%5.2f,%5.2f,%5.2f\n",a,b,c); //顺序输出a,b,c的值
return 0;
}

if语句的一般形式

1
2
if (表达式) 语句1
[ else 语句2 ]

【例4.5】任务要求:有一函数如下。编程序,要求输入一个x值后,输出y值。:

$$
y=
\begin{cases}
&-1\quad(x\lt0)\
&0\quad(x=0)\
&1\quad(x\gt1)
\end{cases}
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main()
{ int x,y;
printf("enter x:");
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);
return 0;
}

3、选择结构中的关系运算

关系运算符及其优先次序

1
2
3
4
5
6
<	(小于)
<= (小于等于)
> (大于)
>= (大于等于)
== (等于)
!= (不等于)
  • 前4种关系运算符的优先级别相同,后2种也相同。前4种高于后2种。
  • 关系运算符的优先级低于算术运算符。
  • 关系运算符的优先级高于赋值运算符。
  1. c>a+b 等效于c>(a+b) (关系运算符的优先级低于算术运算符)
  2. a>b==c等效于(a>b)==c (大于运算符>的优先级高于相等运算符==)
  3. a==b<c等效于a==(b<c) (小于运算符<的优先级高于相等运算符==)
  4. a=b>c等效于a=(b>c) (关系运算符的优先级高于赋值运算符)

4、选择结构中的逻辑运算

逻辑运算符及其优先次序

运算符 含义 举例 说明
! 逻辑非(NOT) !a 如果a为假,则!a为真;如果a为真,则!a为假
&& 逻辑与(AND) a && b 如果a和b都为真,则结果为真,否则为假
|| 逻辑或(OR) a || b 如果a和b有一个以上为真,则结果为真,二者都为假时,结果为假

优先次序:!(非)→&&(与)→‖(或), 即“!”为三者中最高的; 逻辑运算符中的“&&”和“‖”低于关系运算符,“!”高于算术运算符

1
2
3
4
5
6
if (x!=0) 语句1			//括号内的表达式是关系表达式,如果x不等于0,执行语句1
if (x>0 && y>0) 语句2 //表达式是逻辑表达式,如果x和y都大于0,执行语句2
if (x) 语句3 //表达式是变量,如果x不等于0,则条件判断结果为真,执行语句3
if (1) 语句4 //表达式是非0整数, 条件判断结果为真,执行语句4
if (0) 语句5 //表达式是整数0,条件判断结果为假,不执行语句5,接着执行下一语句
if(x+3.5) 语句6 //表达式是实数表达式,若x+3.5不等于0,则条件判断结果为真,执行语句6

例如:判别用year表示的某一年是否闰年,可以用一个逻辑表达式来表示。闰年的条件是符合下面二者之一: ①能被4整除,但不能被100整除,如2008。②能被400整除,如2000。

1
2
3
4
5
6
//对应的逻辑表达式:
(year % 4 == 0 && year % 100 != 0) ‖ year % 400 == 0

//若判别非闰年,则对应的逻辑表达式:
!((year % 4 == 0 && year % 100 != 0) ‖ year % 400 == 0)
(year % 4 != 0) || (year % 100 == 0 && year % 400 != 0)

5、条件运算符和条件表达式

1
表达式1 ? 表达式2 : 表达式3

条件运算符由两个符号(?和:)组成,必须一起使用。要求有3个操作对象,称为三目(元)运算符,它是C语言中唯一的一个三目运算符。

条件运算符的执行顺序: 先求解表达式1,若为非0(真)则求解表达式2,此时表达式2的值就作为整个条件表达式的值。若表达式1的值为0(假),则求解表达式3,表达式3的值就是整个条件表达式的值。

1
2
3
4
5
6
7
if (a>b)
max=a;
else
max=b;
//可转换成
max=(a>b) ? a : b;
a>b ? (max=a) : (max=b); //表达式2和表达式3是赋值表达式

【例4.4】输入一个字符,判别它是否为大写字母,如果是,将它转换成小写字母;如果不是,不转换。然后输出最后得到的字符。

解题思路

用条件表达式来处理,当字母是大写时,转换成小写字母,否则不转换。

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main()
{
char ch;
scanf("%c",&ch);
ch=(ch>='A'&&ch<='Z')?(ch+32):ch;
printf("%c\n",ch);
return 0;
}

6、选择结构的嵌套

if与else的配对关系

else总是与它上面的最近的未配对的if配对。

1
2
3
4
5
if()
if() //语句1
else
if() //语句2
else //语句3

编程序者把else写在与第1个if(外层if)同一列上,意图是使else与第1个if对应,但实际上else是与第2个if配对,因为它们相距最近。

如果if与else的数目不一样,为实现程序设计者的思想,可以加花括号来确定配对关系。

1
2
3
4
5
if()
{
if() //语句1 内嵌if
}
else //语句2

【例4.5】有一阶跃函数如下。编一程序,输入一个x值,要求输出相应的y值。

$$
y=
\begin{cases}
&-1\quad(x\lt0)\
&0\quad(x=0)\
&1\quad(x\gt1)
\end{cases}
$$

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main()
{
int x,y;
scanf("%d",&x);
if(x>=0)
if(x>0) y=1;
else y=0;
else y=-1;
printf("x=%d,y=%d\n",x,y);
return 0;
}

7、多分支选择结构

利用switch语句实现多分支选择结构

【例4.6】任务要求:要求按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分,C等为60~69分,D等为 60分以下。成绩的等级由键盘输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main()
{
char grade;
scanf("%c",&grade);
printf("Your 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("enter data error!\n");
}
return 0;
}

等级grade定义为字符变量,从键盘输入一个大写字母,赋给变量grade,switch得到grade的值并把它和各case中给定的值(′A′,′B′,′C′,′D′之一)相比较,如果和其中之一相同(称为匹配),则执行该case后面的语句(即printf语句)。
如果输入的字符与′A′,′B′,′C′,′D′都不相同,就执行default后面的语句,
注意在每个case后面后的语句中,最后都有一个break语句,它的作用是使流程转到switch语句的末尾(即右花括号处)。

1
2
3
4
5
6
7
8
switch(表达式)
{
case 常量1 : 语句1
case 常量2 : 语句2
⋮ ⋮ ⋮
case 常量n : 语句n
default : 语句n+1
}
  1. 括号内的“表达式”,其值的类型应为整数类型(包括字符型)。
  2. 花括号内是一个复合语句,内包含多个以关键字case开头的语句行和最多一个以default开头的行。case后面跟一个常量(或常量表达式),它们和default都是起标号作用,用来标志一个位置。执行switch语句时,先计算switch后面的“表达式”的值,然后将它与各case标号比较,如果与某一个case标号中的常量相同,流程就转到此case标号后面的语句。如果没有与switch表达式相匹配的case常量,流程转去执行default标号后面的语句。
  3. 可以没有default标号,此时如果没有与switch表达式相匹配的case常量,则不执行任何语句。
  4. 各个case标号出现次序不影响执行结果。
  5. 每一个case常量必须互不相同;否则就会出现互相矛盾的现象。
  6. case标号只起标记的作用。在执行switch语句时,根据switch表达式的值找到匹配的入口标号,在执行完一个case标号后面的语句后,就从此标号开始执行下去,不再进行判断。因此,一般情况下,在执行一个case子句后,应当用break语句使流程跳出switch结构。最后一个case子句(今为default子句)中可不加break语句。
  7. 在case子句中虽然包含了一个以上执行语句,但可以不必用花括号括起来,会自动顺序执行本case标号后面所有的语句。当然加上花括号也可以。
  8. 多个case标号可以共用一组执行语句。

Switch语句举例

【例4.7】用switch语句处理菜单命令。在许多应用程序中,用菜单对流程进行控制,例如从键盘输入一个′A′或′a′字符,就会执行A操作,输入一个′B′或′b′字符,就会执行B操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
int main()
{ void action1(int,int),action2(int,int); //函数声明
char ch;
int a=15,b=23;
ch=getchar();
switch(ch)
{ case 'a':
case 'A': action1(a,b);break; //调用action1函数,执行A操作
case 'b':
case 'B': action2(a,b);break; //调用action2函数,执行B操作

default: putchar('\a'); //如果输入其他字符,发出警告
}
return 0;
}
void action1(int x,int y) //执行加法的函数
{ printf("x+y=%d\n",x+y);
}

void action2(int x,int y) //执行乘法的函数
{ printf("x*y=%d\n",x*y);
}

本文作者:WindsorWu

本文链接: https://blog.nekolin.top/2022/12/03/StudyC-04/

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。

评论

您所在的地区可能无法访问 Disqus 评论系统,请切换网络环境再尝试。