1、第3章 深入C语言,谭晓华 计算机科学与技术学院,C语言程序设计,引例,按照考试成绩的等级输出百分制的分数段。 A等为85分以上, B等为7084分, C等为6069分, D等为60分以下。 成绩的等级由键盘输入。 要求用带else的if语句来实现。,void printMark(char mark) if (mark=A) printf(“85100n“);else if(mark=B)printf(“7084n“);else if(mark=C)printf(“6069n“);else if(mark=D)printf(“059n“);elseprintf(“错误输入n“); ,用 ife
2、sle语句描述有多种 选择的算法,显得非常 麻烦,而且容易把思路 搅浑,void main() char mark;printf(“请输入等级分(AD) “);scanf(“%c“, ,多分支选择语句,void printMark(char mark) switch(mark)caseA:printf(“85100n“);break;caseB:printf(“7084n“); break;caseC:printf(“6069n“); break;caseD:printf(“60n“); break;default:printf(“错误输入n“); ,void main() char mark
3、;printf(“请输入等级分(AD):“);scanf(“%c“, ,不好意思,我属于C级!(从键盘输入C),运行结果:6069,我的成绩应该是6069!(希望输出6069),多分支选择语句,switch 语句的一般形式: switch(sw) case c1:语句块1;break;case c2:语句块2;break;case cn:语句块n;break;default:语句块n+1; /*可缺省*/ ,c1,c2,cn,default,switch是语句的特征标志,其中的表达式sw的值为整型 或字符型。 case 后面跟一常量。当 switch 后的表达式等于某个 case 后的常量时,
4、运行该 case 以后的语句块。要注意,任意两个 case 后的常量不能相等,否则 switch 将不知道选择哪条路走。 default 表示当switch后的表达式没有匹配的 case时,默认(default)地运行它之后的语句块。 Break 退出 switch 语句。,多分支选择语句,void printMark(char mark) switch(mark)caseA:printf(“85100n“);caseB:printf(“7084n“);caseC:printf(“6069n“);caseD:printf(“60n“);default:printf(“错误输入n“); ,我的成
5、绩应该是6069!(希望输出6069),什么!“60”? “错误输入”?怎么会这样?!,不好意思,我属于C级!(从键盘输入C),运行结果:606960错误输入,不用break语句,void main() char mark;printf(“请输入等级分(AD):“);scanf(“%c“, ,练习一,编程设计一个简单的计算器程序,要求根据用户从键盘输入的表达式:操作数1 运算符op 操作数2 计算表达式的值,指定的运算符为加(+)、减(-)、乘(*)、除(/)如: 用户输入:5*4计算输出:5*4=20,switch (op) case +:/*处理加法语句*/case -:/*处理减法语句*
6、/case *:/*处理乘法语句*/case /:/*处理除法语句*/ ,op是用于存放运算符的字符变量,要求:用面向过程的思想,采用模块化方法,定义功能函数分别实现表达式的输入、表达式的运算和表达式结果的输出,将共享数据定义为全局变量。 定义main函数,求一个表达式的值,求10个表达式的值。,#include /定义全局变量 double a,b; char op;void input() /输入表达式 printf(“请输入表达式:“);scanf(“%lf%c%lf”, ,double compulate() /计算表达式的值 switch (op)case +:return a+b;
7、 break;case -:return a-b; break;case *:return a*b; break;case /:return a/b; break; ,void print() /输出表达式 printf(“%lf%c%lf=%lfn”,a,op,b,compulate(); void main() input();print(); ,求10个表达式呢?,练习二,按照百分制的分数段输出考试成绩的等级。 85分以上为A等, 7084分为B等, 6069分为C等, 60分为以下D等。 百分成绩由键盘输入。要求:用switch语句实现。,练习二,分析 这也是一个多分支结构。但 分支的
8、条件是某个范围而不是一个值。能不能使用 swith语句来描述这种范围型的多分支结构呢? 答案是否定的,但通过分析,我们发现主要起区分作用的是十位上的数。如果我们能把十位上的数取出来,根据十位数的值进行分支,那么最多也就只有十个分支。 象这种用已有的数据类型来描述难以表达的类型的方法称为数据的转换。,char printGrade(int mark) char c;switch(mark/10)case 0:case 1:case 2:case 3:case 4:case 5:c=D;break;case 6: c=C;break;,case 没有break,会运行到下一个 case 中,通过整
9、数运算,取得成绩的十位数,case 7:case 8:if(mark85)c=B;elsec=A;break;case 9:case 10: c=A; return c; ,8089有两个等级,仅靠十位数无法区分,void main() int mark;printf(“请输入成绩(0100) “);scanf(“%d“, ,输入一值,若其在0,7.5范围,按如下要求分级。0, 1.5) A1.5, 6) B6, 7.5 C,#include char printChange(float n) char c;switch(int)(n/1.5) case 0 : c=A; break ;cas
10、e 1 : case 2 :case 3 : c=B; break ;case 4 :case 5 : c=C; break ; return c; ,练习三,数据转换,将范围转换为整数。,void main() float n;printf(“input a number:“);scanf(“%f“, ,循环结构的另外两种形式,dowhile语句 一般形式 :先执行一次循环体,再判断条件。若条件为真再次执行循环体,直到条件为假时结束循环。,int n=0,sum=0;do sum+=n;+n; while (n=10000);,do循环体 while (条件表达式);,从键盘输入一个整数12
11、456,分析以下程序运行结果。,#include int reverse(int n) int c=0; do c=c*10;c=c+n%10; while(n/=10)0);return c; ,结果:65421 将各位数字反序显示出来,void main() int num; printf(“请输入一个整数:“);scanf(“%d“, ,循环结构的另外两种形式,for语句 一般形式 :表达式1: 循环开始时执行。整个循环中只执行1次,常用来对循环变量设置初值 条件表达式: 其值为非0时执行循环体,否则结束循环。 表达式3: 循环体的一部分,每次循环体执行完后执行一次,常用于循环变量值的更
12、新。,for (表达式1;条件表达式;表达式3) 循环体; ,求1+2+3+4+99+100,int i , s=0; i=1; While(i=100) s=s+i; i+; ,int i , s=0;for (i=1;i=100;i+) s=s+i;,选择三种循环的一般思路,如果循环次数已知,用for如果循环次数未知,用while如果循环体至少要执行一次,用do-while只是思路,不是定律,循环语句的中断,break语句退出一层循环或switch语句,continue中断此次循环体的执行,开始下一次,#include main() int i, n;for (i=1; i=5; i+)p
13、rintf(“Please enter n:“);scanf(“%d“, ,Please enter n:10 n = 10 Please enter n: -10 Program is over!,这个程序的功能是什么?,#include main() int i, n;for (i=1; i=5; i+)printf(“Please enter n:“);scanf(“%d“, ,Please enter n: 10 n = 10 Please enter n: -10 Please enter n: 20 n = 20 Please enter n: -20 Please enter n
14、: 30 n = 30 Program is over!,这个呢?,循环的嵌套,在一个循环语句中又包含其他的循环语句,称为循环的嵌套。其中最先遇到的循环语句称为外循环,后遇到的循环语句称为内循环。 循环的嵌套犹如时钟的运行方式:秒针走完一圈,分针走一小格,秒针走完60圈,分针才走完一圈。在循环的嵌套中,内循环就像秒针,而外循环就像是分针,它走得很慢,要等到内循环走完一圈它才走一格。,循环的嵌套,例如: int main() int n,i,j;for (i=0;i=3;i+)for (j=0;j=9;j+)n=i*10+j;printf(“%d “,n );printf(“n“);return
15、 0; ,外循环,内循环,固定外层i的值,根据内 层j的变化,分析内循环。 内循环结束,再改变外 层i的值。固定后,再分 析内循环。,输出039,循环的嵌套,分析下面程序的运行情况 #include void jiujiubiao() int i,j;for(i=1;i10;i+)for(j=1;j=i;j+)printf(“%d*%d=%dt“,i,j,i*j); printf(“n“); ,外循环,内循环,int main() jiujiubiao(); ,数组的定义,引例 读入某班全体50位同学某科学习成绩,然后求平均成绩、最高分。 问题中要处理的数据是50个成绩,读入(从键盘输入)这5
16、0个成绩的值,就需要50个变量来存放。虽然程序本身的算法很简单,但这么多的变量从定义到使用却非常繁琐。,数组的定义,数组是一组或多组连续的类型相同的变量,这些变量有一个共同的名字:数组名。例如:这50个连续存放的变量构成一个数组,变量们共有一个名字:a。为了将这些变量相互区分,对变量按存放顺序从0开始统一编号,这些编号称为数组下标。数组中的变量称为数组元素,数组元素可以是前面所述除void之外的所有类型,甚至是数组类型,但必须是同一类型。,数组的声明,int a10;char name8;float x8*2+1;,是数组类型说明符,数组元素的类型,a是数组名,int a10;声明了10个连续
17、的整型变量,这些变量有 一个共同的名字:a。,数组的声明,数组声明的一般格式:,数据类型 数组名数组长度,数组长度是数组元素的最大个数,必须是常量表达式,数组元素的类型,数组类型说明符,错误: int n=5; int an;,数组元素,数组元素采用“数组名编号”的形式表示。例如:a0 、a1、 a5分别表示数组的第1个、第2个和第6个元素。 数组元素的本质就是变量。通过数组声明语句只是定义了一组 “空”变量,必须赋值后才能使用。 数组元素的赋值,可以在声明数组的同时初始化,也可以定义数组之后再赋值。,数组元素,声明数组时,为数组元素设定初始值。例如:int a5=1,2,3,4,5; cha
18、r b=1,2,3; int c5=1; 字符数组的初始化 可以用字符串常量对字符数组元素初始化,例如: char ch6= “ Hello “;,省略数组长度,长度由初始值的个数可知,字符串常量以0作结束符,所以实际长度是字符数+1,初始值少于数组长度时,对前面元素依次赋初值,其他元素初值为0,数组元素,数组元素也可在定义数组后,通过赋值、输入等形式对数组元素赋值或改值。例如:int a6; a0=10;a1=20;scanf(“%d“,任何可以用单个变量的地方都可用数组元素。,在声明语句中,是类型说明符,在执行语句中,是下标运算符,法一 int i,a100; for(i=0;i100;i+)ai=i;,法二 int i,a100; for(i=0;i=99;i+)ai=i;,数组元素,数组元素排列的连续性,决定我们可以通过循环结构,用循环变量的变化控制数组元素的变化,以实现对数组元素的处理,从而简化程序。,小于数组长度,小于等于最大下标,如何使两个数组的值相等,/*错误编程*/ main() int a4=1,2,3,4,b4;b=a; ,解决方法 法1:逐个元素赋值b0=a0;b1=a1;b2=a2;b3=a3; 法2:通过循环赋值int i;for (i=0;i4;i+)bi=ai;,循环简化编程,