内容正文:
第 2 章 简单程序设计之一
运算符和表达式
顺序结构程序设计
选择结构程序设计
简单循环结构程序设计
内容概述
教学目标
掌握常量与变量的定义和使用方法;
学会三种结构的简单程序设计;
从整体上把握和了解C程序的基本结构,对C语言程序开发设计有初步的感性认识。
C语言程序的控制结构
顺序结构
选择结构
循环结构
2.1 顺序结构程序设计
顺序结构程序设计就是根据问题要求设计的程序,其执行过程是按程序书写的顺序,从上到下,逐条语句顺序地执行,没有跳转,一直到最后一条语句,程序才算执行完毕,退出程序。
基本的算术运算符
运算符 名称 举例 说明
+ 加法运算符 a+3 加法
- 减法运算符 c-4 减法
* 乘法运算符 a*3 乘法
/ 除法运算符 c/d 除法
% 模运算符 e%4 求余数、取模
算术表达式和运算符的优先级与结合性
表达式是由常量、变量、函数和运算符组合起来的式子。
如:
a + b
(a * 2) / c
(x + r) * 8 - (a + b) / 7
运算符的优先级和结合性
优先级 (从高到低)
( )
* / %
+ (加) – (减)
结合方向
+ (加) – (减) * / %:从左向右
若在运算量两侧的运算符有相同的优先级,则按它们的结合方向顺序处理。
例: a b / c – 1 + a – d e;
两点说明
两个整数相除,结果也为整数
直接舍去商的小数部分,而不会“四舍五入”
如果需要得到精确的运算结果,可以把其中一个操作数转换为浮点数。
举例:5/3(=1)、5.0/3(=1.66666…)
模运算符的两个操作数都必须是整数
举例:5%3(=2)
【例2.1】由键盘输入两个整数给变量a和b,输出a和b的和差积商及余数。
定义变量:
int a,b;
int sum, difference,product, quotient, remainder;
算法:
sum=a+b;
difference=a-b;
product=a*b;
quotient=a/b;
remainder=a%b;
#include "stdio.h"
void main()
{
int a,b,sum, difference,product, quotient, remainder;
printf("请输入a和b的值:");
scanf("%d%d",&a,&b);
sum=a+b;
difference=a-b;
product=a*b;
quotient=a/b;
remainder=a%b;
printf("和=%d,差=%d,积=%d,商=%d,余数=%d
",sum,difference,product,quotient,remainder);
}
问题分4个步骤来处理:
(1)输入两个整数给变量a和b;
(2)输出a和b的值;
(3)交换a和b的值;
(4)输出a和b的值。
【例2.2】由键盘输入两个整数给变量a和b,然后输出a和b。在交换a和b的值后,再输出a和b,验证两个变量中的数值是否正确地进行了交换。
#include <stdio.h>
void main()
{
int a,b,t;
printf("Enter a and b:
");
scanf("%d %d",&a,&b); /*输入两个整型变量a和b*/
printf("a=%d,b=%d
",a,b); /* 输出a和b的值 */
t=a; /* 交换a和b的值 */
a=b;
b=t;
printf("a=%d,b=%d
",a,b); /* 输出a和b的值 */
}
2.2.1关系运算符和关系表达式
关系运算:比较运算,比较两个操作数,看是否满足给定的关系。
如: a>3 为一比较运算,
若a=5,a>3 成立,结果为“真”;
否则,若a=1,a>3 不成立,结果为假。
在C语言中,用非零值表示真,零表示假。
表达式: a>3 称为关系表达式。
2.2 选择结构程序设计
C语言提供了六种关系运算符
<: 小于 , 5<3, 3<5
<=: 小于等于,5<=3, 3<=5
>: 大于, 5>3, 3>5
>=: 大于等于,5 >=3, 3 >=5
==: 等于, 5==3
!=: 不等于, 5!=3
关系运算符的优先次序
关系运算符优先级低于算术运算符。
c>a+b c > (a+b)
a+b==2*c (a+b) == (2*c)
关系表达式
关系表达式: 用关系运算符将两个表达式连接起来的式子。
如:
a>b
a+b>b+c
关系表达式的值为1或0
1表示结果为真,也就是关系成立。
0表示结果为假,也就是关系不成立。
例 关系运算符
#include <stdio.h>
int main()
{
int a, b, c;
a = 5; b = 3; c = 4;
printf("a>b: %d
", a>b);
printf("a+b>b+c : %d
", a+b>b+c);
printf("(a>b)>(b<c) : %d
", (a>b)>(b<c));
return(0);
}
运行结果为:
a>b: 1
a+b>b+c : 1
(a>b)>(b<c) : 0
!:逻辑非,一元运算符
运算规则:取反,真 假,假 真
&&:逻辑与 。又称逻辑乘。
运算规则:两个操作数均为真,结果为真。
||:逻辑或 。又称逻辑加。
运算规则:只要两个操作数有一个为真,结果为真。
2.2.2 逻辑运算符和逻辑表达式
逻辑运算符
用逻辑运算符将表达式连接起来的式子。其值是一个逻辑量“真”或“假”。
优先级
结合性
!:自右向左
&&、||:自左向右
!(非)
算术运算符
关系运算符
&&和 ||
赋值运算符
高
低
逻辑表达式
注意:逻辑表达式的C语言编译系统在给出逻辑结果时,以数值1代表“真”,以0代表“假”;但是在判断一个量是否为“真”时,以非0代表“真”,以0代表“假”。
课堂练习4:
若x=3,y=7求逻辑表达式!(1<x)||2<9-y的值.
① 括号()优先级最高,先计算1<x,值:1;
② !优先级高于其它算符,计算!①,值:0
③ -优先级高于其余算符,计算9-y,值:2
④ <运算优先级高于逻辑或||,计算2<③,值:0
⑤ ||最后运算,②||④,值:0
所以,表达式!(1<x)||2<9-y的值是0。
逻辑运算符特点
在逻辑表达式的求解中,并不是所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。例如:
(1)a && b && c
求解方法:只有a为真(非0),才需要判断b的值,只有a和b都为真,才需要判断c的值。只要a为假,就不必判断b和c,运算立即中止。
例如: 若 a=0; b=1; c=2;
执行 d=a++&&b++&&- -c;之后,a,b,c,d的值各是什么?
运算结果: d=0,a=1,b=1,c=2
(2)a || b || c
求解方法:只要a为真(非0),就不必判断b和c;只有a 为假,才判断b;a和b都为假,才判断c。
例如:
若 a=0; b=1; c=2;
执行 d=a++||b++||- -c; 后a,b,c,d的值各是什么?
运算结果: d=1,a=1,b=2,c=2
设a=5、b=3、c=2、d=1、x=1、y=1,求表达式(x=a<b)&&(y=c<d)的值及变量x和y的值。
分析:求表达式(x=a<b)&&(y=c<d)的值,首先计算表达式(x=a<b)的值,因为a<b为假,变量x的值为0,表达式(x=a<b)的值为假。对于运算符&&,当其左边的运算对象为0时,右边的表达式(y=c<d)不被执行,所示整个表达式的值为0,y的值不变。
2.2.3 if分支结构
用if语句可以构成分支结构。它根据给定的条件进行判断,以决定执行某个分支程序段。
if语句有三种基本形式:
if
if-else
if-else-if
第一种形式为基本形式,形式为:
其语义是:
如果表达式的值为真,则执行其后的语句,否则不执行该语句。其过程可表示为右图。
if (表达式) 语句
【例2.3】由键盘输入两个不同的整数给变量a和b,然后输出a和b中较大的数。
#include <stdio.h>
int main()
{
int a,b,max;
printf("Input two numbers: ");
scanf("%d%d", &a, &b);
max=a;
if (max<b) max=b;
printf("max=%d
", max);
return(0);
}
运行结果为:
Input two numbers: 5 12
max=12
第二种形式为: if-else
if(表达式)
语句1;
else
语句2;
其语义是:
如果表达式的值为真,则执行语句1,否则执行语句2 。
其执行过程可表示为下图。
【例】用if-else语句改写例2.3
#include <stdio.h>
int main()
{
int a, b;
printf("Input two numbers: ");
scanf("%d%d", &a, &b);
if(a>b)
printf("max=%d
", a);
else
printf("max=%d
", b);
return(0);
}
运行结果为:
Input two numbers: 5 12
max=12
复杂条件下的if条件结构
【例2.4】从键盘输入一个年份,判断是否闰年。
什么是闰年?
复合条件可表示为:
(year%4==0)&&(year%100!=0)||(year%400==0)
闰年是指能被4整除而不能被100整除,或能被400整除的年份。
void main()
{
int year;
printf("请输入年份:");
scanf("%d",&year);
if((year%4==0)&&(year%100!=0)||(year%400==0))
printf("%d年是闰年
",year);
else printf("%d年不是闰年
",year);
}
第三种形式为: if-else-if
前两种形式的if语句一般都用于两个分支的情况。当有多个分支选择时,可采用if-else-if语句。
其语义是:依次判断表达式的值,当出现某个值为真时,则执行其对应的语句。然后跳到整个if语句之外继续执行程序。 如果所有的表达式均为假,则执行语句n。然后继续执行后续程序。
if(表达式1)
语句1;
else if(表达式2)
语句2;
else if(表达式3)
语句3;
…
else if(表达式m)
语句m;
else
语句n;
一般形式为:
【例2.4】个人年收入低于5万元,可免个人所得税;年收入在5万~10万元之间,超过5万元的部分交5%的个人所得税;年收入在10万元以上则交总收入的7%的个人所得税。请编写一个程序,根据个人年收入计算个人所得税(精确到元)。
个人年收入和个人所得税分别用整型变量x、y保存。根据题意,个人所得税与个人年收入的关系可用一个分段函数表示:
#include"stdio.h"
void main()
{
int x,y;
printf("请输入个人年收入:");
scanf("%d",&x); /*输入个人年收入*/
if (x <=50 000) /*个人年收入低于5万元*/
y= 0;
else if (x<=100 000) /*5万~10万元之间*/
y =(x-50 000)*5/100;
else /*个人年收入高于10万元*/
y =x*7/100;
printf("个人所得税=%d元
",y);
}
【例2.6】编写程序,对学生成绩进行等级评定。将成绩分为几个等级:0~59分为不及格,60~69分为及格,70~79分为中等,80~89分为良好,90~100分为优秀。要求输入一个成绩,输出其对应的等级。
将成绩分成几个区间判断
不及格
及格
中等
良好
优秀
因每个分数段之间没有交叉,可以用多分支的if-else if形式的语句来进行多次比较,确定其对应的等级。
#include"stdio.h"
void main()
{
int score, grade;
printf("请输入成绩:");
scanf("%d",&score); /*输入成绩*/
if(score>89) /*90~100分,积点5*/
grade=5;
else if(score>79) /*80~89分,积点4*/
grade=4;
else if(score>69) /*70~79分,积点3*/
grade=3;
else if(score>59) /*60~69分,积点2*/
grade=2;
else /*59~0分,积点0*/
grade=0;
printf("成绩%d的对应积点是%d
",score,grade);
}
在使用if语句中还应注意以下问题
在三种形式的if语句中,在if关键字之后均为表达式。该表达式通常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表达式等,甚至也可以是一个变量。
例如:
if (a=5) 语句;
if (b) 语句;
都是允许的。只要表达式的值为非0,即为“真”。
在if语句的三种形式中,所有的语句应为单个语句,如果要想在满足条件时执行一组(多个)语句,则必须把这一组语句用{}括起来组成一个复合语句。但要注意的是在}之后不能再加分号。
if (x>y)
{ x = x+5;
y = y+10;
}
else
{ x = 10;
y = 5;
}
例如:
在if语句中,条件判断表达式必须用括号括起来,在语句之后必须加分号。
例如:if (b) 语句;
当if语句中的执行语句又是if语句时,则构成了if 语句嵌套的情形。
其一般形式可表示如下:
if(表达式)
if语句;
或者为
if(表达式)
if语句;
else
if语句;
在嵌套内的if语句可能又是if-else型的,这将会出现多个if和多个else重叠的情况,这时要特别注意if和else的配对问题。
例如:
if(表达式1)
if(表达式2)
语句1;
else
语句2;
其中的else究竟是与哪一个if配对呢?
应该理解为:
if(表达式1)
if(表达式2)
语句1;
else
语句2;
还是应理解为:
if(表达式1)
if(表达式2)
语句1;
else
语句2;
为了避免这种二义性,C语言规定,else 总是与它前面最近的if配对,因此对上述例子应按前一种情况理解。
if-else-if解决多分支问题
-----程序冗长而且可读性差
解决办法:
------switch开关语句
2.2.4 switch多分支结构
1、switch语句形式:
switch (表达式)
{
case 常量1: 语句1;
case 常量2: 语句2;
case 常量3: 语句3;
.......
case 常量n: 语句n;
default : 语句n+1;
}
根据表达式的不同值,选择不同的程序分支,又称开关语句。
数值型
或
字符型
常量表达式的值必须互不相同,否则执行时将出现矛盾,即同一个开关值,将对应多种执行方案。
千万不能接(;)号
2、语句执行流程:
指语句的最后一条是否为break
简单语句或复合语句
case语句出
现的次序并
不影响执行
结果。
break
break
有
break
有
有
计算表达式
常量1
常量2
常量n
=
语句1
…
=
=
=
语句2
语句n
其它
=
语句n+1
值
void main()
{ int n;
printf("请输入成绩:");
scanf("%d",&n);
switch ((int)(n/10))
{
case 10:
printf("成绩%d的等级为优秀
",n);
case 9:
printf("成绩%d的等级为优秀
",n);
case 8:
printf("成绩%d的等级为良好
",n);
case 7:
printf("成绩%d的等级为中等
",n);
case 6:
printf("成绩%d的等级为及格
",n);
default:
printf("成绩%d的等级为不及格
",n);
}
}
出错啦!?
【例2.7】改写例2.6,用switch语句实现对学生成绩进行等级评定。
在“switch”语句中,“case 常量表达式”只相当于一个语句标号,表达式的值和某标号相等则转向该标号执行,但不能在执行完该标号的语句后自动跳出整个switch 语句,因此会继续执行所有后面语句的情况。
为此,C语言提供了一种break语句,其功能是可以跳出它所在的switch语句。
将上面的例2.7修改如下:
void main()
{ int n;
printf("请输入成绩:");
scanf("%d",&n);
switch ((int)(n/10))
{
case 10:
printf("成绩%d的等级为优秀
",n);break;
case 9:
printf("成绩%d的等级为优秀
",n); break;
case 8:
printf("成绩%d的等级为良好
",n); break;
case 7:
printf("成绩%d的等级为中等
",n); break;
case 6:
printf("成绩%d的等级为及格
",n); break;
default:
printf("成绩%d的等级为不及格
",n);
}
}
使用switch语句时还应注意以下几点
switch后面圆括号内表达式的值和case语句中常量表达式的值,都必须是整型的、枚举型的或字符型的,不允许是浮点型的。在case后的各常量表达式的值不能相同。
每个case子句既可以是一条语句,也可以是多条语句。当是多条语句时,不需要用花括号括起来。
各个case子句和default子句的先后顺序可以变动,而不会影响程序执行结果。
default子句可以省略不用。
多个case的后面可以共用一组执行语句 。如例2.7中等级为优秀的判断程序可改为:
switch((int)(n/10))
{
case 10:
case 9:
printf("成绩%d的等级为优秀
");
break;
…
}
$$