模块2结构化程序设计.ppt
实用C语言程序设计教程李金祥 顾小晶 主编,Visual C+,模块2结构化程序设计,任务1 顺序结构程序设计和程序的基本结构学习目标 了解程序设计的三种基本结构,掌握流程图的绘制方法。,案例1 计算课程总评成绩1.问题描述 已知某学生课程A的平时成绩、实验成绩和期末考试成绩,求该课程的总评成绩。其中平时、实验和期末成绩分别占20、30和50。,2.1.1 案例讲解,2编写程序(1)定义整型变量score1、score2 和score3分别存放课程A的平时成绩、实验成绩和期末考试成绩;定义实型变量total存放总评成绩;(2)输入score1、score2 和score3的值;(3)根据比例计算总评成绩total=score1*0.2+score2*0.3+score*0.5;(4)输出总评成绩total。,3编写源程序/*EX2_1.C*/#include stdio.h void main()int score1,score2,score3;float total;printf(请输入成绩:);scanf(%d%d%d,printf(总评成绩是%.1fn,total);4运行结果图2-1 案例1运行结果,5归纳分析 案例1程序的执行过程是按照源程序中语句的书写顺序逐条执行的,这样的程序结构称为顺序结构。模块1中的程序均属于顺序结构。顺序结构在程序自上而下执行时,程序中的每一条语句都要执行一次,并且只执行一次,以这样固定的处理方式只能解决一些简单的任务。但实际应用中,往往会出现一些特别的要求,比如根据某个条件来决定下面该进行什么操作,或根据某个要求不断地重复执行若干动作,这就需要控制程序的执行顺序。,2.1.2 基础理论,1三种基本控制结构 程序中语句的执行顺序是由程序设计语言中的控制结构规定的。控制结构有顺序结构、选择结构及循环结构三种基本结构。顺序结构是最简单的结构。选择结构又称为分支结构,当程序执行时,计算机按一定的条件选择下一步要执行的操作。例如:输入三角形的三条边计算面积时,要判断三条边是否能构成三角形,若能则计算面积,否则要告诉用户输入错误。循环结构又称为重复结构,它是程序中需要,按某一条件反复执行一定的操作而采用的控制结构。例如,从键盘上输入20个整数,求其累加和。三种结构之间可以是平行关系,也可以相互嵌套,结构之间通过复合可以形成复杂的结构。已经证明,由以上三种基本结构顺序组成的程序结构,可以解决任何复杂的问题。由三种基本结构构成的程序称为结构化程序。2.程序流程图,在对一个复杂问题求解时,程序的结构比较复杂,所以在程序设计阶段为了表示程序的操作顺序往往先画出程序流程图,这样有助于最终写出完整正确的程序。下面介绍流程图的有关概念。流程图是用规定的图形、连线和文字说明表示问题求解步骤(算法)的一组图形,具有直观、形象、易于理解等优点。流程图使用的图形符号见表2-1。流程图中的每一个框表示一段程序(包括一个或多个语句)的功能,各框内必须写明,要做的操作,说明要简单明确,不能含糊不清。如在框内只写“计算”,但却不写出计算什么,就不容易让人明白。一般来说,用得最多的是矩形框和菱形框。矩形框表示处理,不进行比较和判断,只有一个入口和一个出口;菱形框表示进行检查判别,有一个入口,两个出口,即比较后形成两个分支,在两个出口处必须注明哪一个分支是对应满足条件的,哪个分支是对应不满足条件的。,表2-1 流程图图形符号,前面介绍的三种基本结构的流程图可分别用图2-2、图2-3和图2-4表示。其中循环结构有两种形式:当型(图2-4(a)和直到型(图2-4(b)。图2-4 循环结构,3.C语句 在模块1中,我们已经了解了C语言程序的基本构成。其中C语句是程序的主要部分。C语句一般可分为:表达式语句、控制语句、复合语句和空语句。(1)表达式语句 表达式语句由一个表达式加上分号构成,一般格式为:表达式;最常用的表达式语句是赋值表达式语句,例如:total=score1*0.2+score2*0.3+score*0.5;,在C语言中,任何一个合法的C语言表达式后面加上一个分号就成了一个语句,例如:m=a+b是表达式,不是语句 i+;是语句,作用是使i加1 x+y;也是语句,作用是完成x+y的操作,它是合法的,但并不把结果赋给变量,所以没有实际意义。案例1中出现的以下语句:printf(请输入成绩:);scanf(%d%d%d,称为函数调用语句,是由一次函数调用加上一个分号构成。函数调用语句也属于表达式语句。(2)控制语句 控制语句是用于控制程序执行流程的。C语言中有以下九种控制语句,它们是:(1)if()else条件语句(2)switch多分支选择语句(3)for()循环语句(4)while()循环语句,(5)dowhile()循环语句(6)continue 结束本次循环语句(7)break中止执行switch或循环语句(8)goto转向语句(9)return函数返回语句 其中语句(1)和(2)用于实现程序的选择结构,语句(3)(5)用于实现程序的循环结构。(3)复合语句,复合语句是用一对花括号括起来的一组语句,又称块语言。一般格式为:语句1 语句2 语句n 在以后的案例程序中将会经常使用到复合语句。(4)空语句,空语句是仅有一个分号的语句,格式为:;空语句被执行时实际上什么也不做。但在后面的案例程序中我们将会看到它的特殊用途。,2.1.3 技能训练,【实验2.1.1】编写程序,求一个三位正整数的各位数字之和。例如756的各位数字之和为7+5+6=18.【指导】(1)问题分析 首先要正确分离出三位正整数的个位数、十位数和百位数:百位数可用对100整除的方法求得,如756/100=7;十位数用对100求余的结果再对10整除求得,如756%100/10=5;个位数用对10求余求得,如756%10=6。(2)求解步骤,定义变量num存放三位正整数;变量n1、n2和n3分别存放个位数、十位数和百位数;变量sum 存放和;分离正整数num;求和;输出结果。(3)编写源程序/*EX2_2.c*/,#include stdio.h void main()int num,n1,n2,n3,sum;printf(请输入一个三位正整数:);scanf(%d,(4)运行结果图2-5实验2-1运行结果,【实验2.1.2】用流程图表示求解下述问题的程序流程。(1)问题描述 根据人体的身高和体重因素,可以按以下“体重指数”对人的肥胖程度进行划分:体重指数t=体重w/(身高h)2(w单位为kg,h单位为m)当t27时,为肥胖。,(2)问题分析 该问题需要采用选择结构来实现。具体步骤如下:输入体重w和身高h;计算体指数t;根据体指数t 判断体型。(3)流程图,图2-6 实验2-2流程图,【实验2.1.3】用流程图表示输入10个整数,输出其中最大数的求解步骤。(1)问题分析 该问题采用循环结构实现反复输入数据和比较数据,数据的比较则用选择结构完成。具体步骤如下:设变量a存放输入的数据,变量max存放最大数;输入第一数a,并将它设为最大值(默认为最大),即max=a;,依次读入数据,与max比较,若比max大,则用当前数代替max中的值,如此循环9次;输出最大数。(2)流程图,图2-7 实验2-3流程图,2.1.4 拓展与练习,【练习1】编写程序求解一元二次方程ax2+bx+c=0的根(假定方程有实根)。编程要求:(1)画出流程图;(2)从键盘输入系数a、b、c,输入前要有如下提示:“请输入系数”;(3)以“x1=”和“x2=”的格式输出方程的根。【练习2】用流程图表示判断一个数能否同时被3和5整除。,【练习3】从键盘输入20学生的成绩,统计合格和不合格学生的人数。成绩大于等于60为合格,否则为不合格。用流程图表示求解步骤。,2.1.5 编程规范与常见错误,1.编程规范(1)表达式比较复杂时,可以在运算符的两边各加一个空格,使源程序更加清晰。例如:total=score1*0.2+score2*0.3+score3*0.5;age=20,避免这样的书写习惯:int num;scanf(%d,。,2.常见错误(1)表达式漏括号。例如计算x=,写成x=-b/2*a。源程序能通过编译,但运行结果会出错。正确的写法是x=-b/(2*a),或x=-b/2/a。(2)语句漏分号。这是初学者上机时遇到的最多问题。例如程序中有以下语句:sum=num1+num2;ave=sum/2.0;编译时会出现出错提示:syntax error:missing;before identifier ave。表示由于前一语句漏分号引起语法错误。,2.1.6 贯通案例之一,1.问题描述 学生成绩管理系统可以分为八个主要的模块,包括加载文件模块、增加学生成绩模块、显示学生成绩模块、删除学生成绩模块、修改学生成绩模块、查询学生成绩模块、学生成绩排序模块和保存文件模块。2.系统模块结构,图2-8 功能模块结构图,3.编写程序实现系统主菜单的显示/*EX2_3.C*/#include stdio.h main()printf(#=#n);printf(“#学生成绩管理系统#n);printf(#-#n);printf(#copyright 2009-10-1#n);printf(#=#n);printf(“#1.加载文件#n);printf(“#2.增加学生成绩#n);,printf(“#3.显示学生成绩#n);printf(“#4.删除学生成绩#n);printf(“#5.修改学生成绩#n);printf(“#6.查询学生成绩#n);printf(“#7.学生成绩排序#n);printf(“#8.保存文件#n);printf(“#0.退出系统#n);printf(#=#n);,4运行结果图2-9 系统主菜单界面,任务2 选择结构程序设计,学习目标 掌握关系运算符、逻辑运算符,熟练掌握 if else 的三种用法,领会 switch 与 break 语句的作用。,2.2.1 案例讲解,案例1 出租车计费1问题描述 某市出租车3公里的起租价为10元,3公里以外,按1.8元/公里计费。现编程输入行车里程数,输出应付车费。2编程分析(1)用实型变量km存放行车里程数,实型变量fee存放车费;(2)输入行车里程数;(3)根据行车里程数作出判断,进行不同的处理;,(4)输出车费。3编写源程序/*EX2_4.C*/#include main()float km,fee;printf(输入行车里程数:);scanf(%f,if(km=3.0),fee=10.0;else fee=10.0+(km-3.0)*1.8;printf(%.2f公里,请付¥%.2fn,km,fee);,4运行结果图2-10 案例1运行结果,5归纳分析 案例1需要根据行车里程数作出选择进行不同的两种计算。处理此类两个分支问题时常使用if语句。if语句是用来判断给定的条件是否满足,根据判断的结果(真或假)决定执行某个分支的操作。(1)if语句的一般形式 if()else,(2)执行过程:计算的值,若结果为“真”(非0),则执行,否则,执行。if-else构成了一个两路分支结构。流程图见图2-11。(3)注意if后面的必须用圆括号括起来;if和else同属于一个if语句,else不能作为语句单独使用,必须与if配对使用。,案例2 计算三角形的面积1问题描述 输入三角形的三个边长,判断能否构成三角形,若能则计算并输出三角形的面积,否则输出出错信息。2编程分析(1)用实型变量a、b和c表示三角形的三条边,实型变量area表示三角形的面积;(2)构成三角形的条件是任意两边之和大于第三边;,(3)如满足构成三角形的条件,计算并输出三角形的面积;否则输出出错信息。计算三角形的面积使用海伦公式:其中:3编写源程序,/*EX2_5.C*/#include#include main()float a,b,c;float area,s;/*s为中间变量,存放三角形的半周长*/printf(Please input a b c:);scanf(%f%f%f,if(a+bc&a+cb&b+ca)/*判断输入的a,b,c能否构成三角形*/,s=(a+b+c)/2.0;area=sqrt(s*(s-a)*(s-b)*(s-c);printf(area is%fn,area);elseprintf(input errern);,4运行结果图2-12 案例2三边符合构成三角形的运行结果,图2-13案例2三边不符合构成三角形的运行结果,5归纳分析 当输入的三条边符合构成三角形条件时,进行计算并输出三角形的面积时需要三条语句完成,此时必须用一对花括号把它们括起来,即使用复合语句的形式。案例3 数制转换1问题描述,输入一个无符号整数,然后按用户输入的进制代号,分别以十进制(代号d)、八进制(代号o)和十六进制(代号x)数的形式输出。2编程分析(1)设变量ua存储无符号整数、变量code表示进制代号;(2)根据输入的进制代号输出相应的数据。流程图如图2-14所示。,图2-14 案例3的流程图,3编写源程序/*EX2_6.C*/#include main()int ua;char code;printf(请输入无符号整数和进制代号:);scanf(%d%c,switch(code)case d:printf(十进制数:%d n,ua);break;case o:printf(八进制数:%o n,ua);break;case x:printf(十六进制数:%x n,ua);break;default:printf(进制代号错误!);,4运行结果 图2-15 案例3运行结果1,图2-16 案例3运行结果2,5归纳分析 案例3是一个多路分支问题,程序中使用了C语言提供的实现多路选择的语句switch语句。(1)switch语句根据一个供进行判断的表达式的结果来执行多个分支中的一个,其一般形式如下:switch()case:case::,case:default:其中,每个“case:”称为case子句,代表一个case分支的入口。因此每个case后面的值必须互不相等。(2)switch语句的执行过程 先计算的值,然后依次与每个case子句后面的的值进行比较,如果,匹配成功,则执行该case子句后面的,在执行过程中,若遇到break语句,就跳出switch语句,否则就继续执行后面的,直到遇到break语句或执行到switch语句的末尾();若表达式的值不能与任何一个匹配,则执行default子句所对应的语句。default子句是可选项,如果没有该子句,则表示在所有匹配都失败时,switch语句什么也不执行。,案例4 字符类型判断。1问题描述 从键盘输入一个字符,判断是英文字母、数字字符还是其他字符。2编程分析(1)输入字符存放在变量ch中;(2)如果是英文字母,输出“是英文字母”,转(4);否则转(3);(3)如果是数字字符,输出“是数字字符”,否则输出“是其他字符”;,(4)结束运行。其中英文字母可以用表达式“ch=A&ch=a&ch=0&ch=9。流程图见图2-16所示。,图2-17案例4流程图,3编写源程序/*EX2_7.C*/#include main()char ch;printf(请输入一个字符:);scanf(%c,else if(ch=0,4运行结果 图2-18 案例4运行结果1,图2-19 案例4运行结果2,5归纳分析 本案例中,对给定问题要分三种情况进行判断。这就需要使用嵌套形式的if语句来实现。if语句的嵌套就是在一个if语句中又包含另一个if语句。(1)if语句的一般嵌套形式 if()if()内嵌if-else语句 else else 外层if-else语句 if()内嵌if-else语句 else,上面的一般形式中是在if和else 中各自内嵌一个if-else语句。(2)嵌套形式不具有固定的语句格式。本案例中使 用的在外层if语句中的else的后面内嵌一个if-else语句的形式。自上而下看流程图2-16可知,当ch是英文字母时,执行路径为;当ch是数字文字符时,执行路径为,ch是其他字符时,执行路径为。,2.2.2 基础理论,1if语句的缺省形式 如果if-else语句中else后面的是空语句时,则if语句可简化为:if()其执行过程是:计算的值,如果的值“真”(非0),执行,否则什么也不做,转去执行if语句的后继语句。流程图见图2-20。,图2-20流程图,用缺省形式的if语句重写【案例1】。#include main()float km,fee;printf(输入行车里程数:);scanf(%f,程序中在if语句前加了一条语句fee=10.0;,当输入的行车里程数小于3公里时,不再需要计算车费,所以可以采用缺省的if语句。2if和else的配对规则 使用if语句的嵌套形式时,如果if的数目和else的数目相同,它们的配对关系比较清楚。但由于存在if语句的缺省形式,会出现if与else的数目不一样的情况,初学者往往会弄错它们的配对关系。因此,必须正确理解C语言中if与else的配对规则。C语言规定:else与前面最接近它而又没有和其它else配对的if配对。,下面的程序是试图判断x是大于0的偶数还是小于等于零。现分析一下程序在x分别取值为8、-5和5时的输出结果。#include main()int x;printf(Enter x:);scanf(%d,if(x0),if(x%2=0)printf(x0 and x is even.n);else printf(x=0.n);,程序运行情况1:Enter x:8 x0 and x is even.,程序运行情况2:Enter x:-5,程序运行情况3:Enter x:5 x=0.,从程序运行的三种情况来看:情况2、3的结果显然是错误的。为什么呢?从书写格式上看,编程者是试图使else与第一个if组成if-else结构,即当x=0时执行else后面的printf(x=0.n);语句。但是,根据if-else的配对原则,编译系统实际上是把else与第二个if作为配对关系处理,程序运行情况3的结果就说明了这种配对关系。所以书写格式并不能代替程序逻辑。为实现编者的意图,必须加“”,来强制确定配对关系,即将第二个if语句用“”括起来,即:,if(x0)if(x%2=0)printf(x0 and x is even.n);else printf(x=0.n);3正确使用switch语句,在案例3中我们已经使用了switch语句,但还应注意以下问题:(1)switch后面表达式的类型,一般为整型、字符型和枚举类型(枚举类型将在后面模块中介绍)。(2)case子句中的类型应该与switch后面的类型相容,每个case子句中的值必须互不相等,case和之间要有空格,case后面的之后有“:”,且所有case包含在“”里。(3)一种情况处理完后,一般应使程序的执行流程跳出switch语句,则由break语句完成。如果没有,break语句,将会在继续执行后面的语句,直到switch语句结尾。重写【案例3】,观察case子句中没有break语句时程序的运行结果。#include main()int ua;char code;printf(请输入无符号整数和进制代号:),scanf(%d%c,运行情况如图2-21所示。由此可见,case子句,只是起一个标号的作用,确定匹配的入口,然后从此处开始一直执行下去,对后面的case子句的值不再进行比较。所以,当仅需执行一个分支情况时,则在case子句后面的语句序列中必须包含一个break语句。图2-21运行结果,(4)当多种常量表达式代表同一种情况时,出现在前面的case子句可以无处理语句,即多个case子句共用一组处理语句。例如【案例3】中,如果用户希望输入进制代号时对字母无大小写要求,则可对【案例3】的源程序作如下修改。运行结果如图2-22所示。,图2-22运行结果,2.2.3 技能训练,【实验2.2.1】输入一个整数n,判断n是否是一个能被23整除的三位奇数。【指导】(1)问题分析 要对n作出正确的判断,关键在于利用C语言的关系运算符和逻辑运算符,设计出正确、合理的表达式。根据题意,n应满足:取值范围:-999-100或者100999;n能被23整除:用n%23=0判断;n是奇数:用n%2!=0判断;,把这些条件组合起来,可用一个复杂的逻辑表达式来表示:(-999 main()int n;,printf(Enter n:);scanf(%d,(3)上机运行程序并分析结果。,(4)问题思考 在上例中,如果将条件表达式设计为:(-999=n&n=-100|100=n&n=999&n%23=0&n%2=1)能不能对三位负数作出正确的判断?为什么?【实验2.2.2】下列程序EX2_9.c的功能是计算并输出下面分段函数值。但程序上机发现运行结果错误,见图2-23。,/*EX2_9.c*/#include main()double x,y;,printf(input x=);scanf(%f,请理解程序执行流程,通过调试修改程序中的错误。具体要求如下:(1)不允许改变计算精度;(2)不允许改变原程序的结构,只能在语句和表达式内部进行修改;(3)设计x的值,测试程序的正确性。,图2-23 程序EX2_9.c运行结果出错,【指导】程序EX2_9.c使用的是一种阶梯形的嵌套结构,通过不断在else子句中嵌套if语句来实现。这种结构可以进行多个条件(互相排斥的条件)的判断,用来实现多路分支问题的处理:依次对各个条件进行判断,一旦某个条件满足,就执行该条件下的有关语句,其他部分将被跳过;若各个条件均不满足,就执行最后一个if-else语句中else后面的语句。如果没有最后的else子句,就表示什么也不执行。,【实验2.2.3】某商场在节日期间举办促销活动,顾客可按购买商品的款数多少分别给予以下不同的优惠折扣:购物不足250元的,没有折扣,赠送小礼品;购物满250元,不足500元的,折扣5%;购物满500元,不足1000元的,折扣8%;购物满1000元,不足2000元的,折扣10%;购物满2000元及2000元以上,折扣15%。试用switch语句编写程序,计算顾客的实际付款数。,【指导】(1)问题分析 由于switch后面的表达式不具有对某个区间内的值进行判断的作用,它的取值必须对应于每个case子句的一个单值,所以如何设计表达式是关键。对于本题,假设购物款为payment,由于折扣点是以250的倍数变化的,所以可以把表达式设计为payment/250,即:payment250元时,对应折扣点payment/250为0;250payment500元时,对应折扣点payment/250取值1;,500payment,main()float payment,discount,amount;/*discount:折扣点,amount:付款数*/int temp;/*中间变量*/printf(请输入你的购物款:);scanf(%f,/*计算折扣点*/switch(temp),case 0:discount=0;printf(你可获得一件小礼品。n);break;case 1:discount=5.0;break;case 2:case 3:discount=7.0;break;case 4:case 5:case 6:case 7:discount=10.0;break;,default:discount=15.0;break;amount=payment*(1-discount/100);printf(请付款¥%.2fn,amount);(3)上机运行程序并验证程序的正确性。(4)完善程序如果输入的购物款不合法(如负数),程序应输出出错信息;输出结果包含以下信息:购物款、获得的折扣和应付款。,2.2.4 拓展与练习,【练习1】编写程序,输入两个学生的成绩,按从高到低的次序输出。编程要求:(1)输入两个成绩放入变量score1和变量score2中(2)将高分存入变量score1中,低分存入变量score2中;(3)依次输出变量score1和score2的值。【练习2】根据任务1中【实验2-2】的题目要求、解题步骤和流程图,编写程序。要求设计四,组不同的体重和身高的测试数据,程序运行后能输出正确的结果。【练习3】输入一个学生的百分制成绩,然后按此输出等级:90100为优秀,7089为良好,6069为及格,60为不及格。编程要求:(1)用switch语句编写程序;(2)要判断百分制成绩的合理性,对于不合理的成绩应输出出错信息;(3)输出结果中应包括百分制成绩和对应的等级。,【练习4】编写程序求解一元二次方程ax2+bx+c=0的根。编程要求:(1)画出流程图;(2)从键盘输入系数a、b、c,输入前要有如下提示:“请输入系数”;(3)如果方程没有实根,输出信息“此方程无实数根”;如果有重根,以“x1=x2=”的格式输出方程的根;如果有两个不同的根,以“x1=”和“x2=”的格式输出方程的根。,【练习5】根据表2-2的工资、薪金所得适用税率表计算月交税金和月实际收入。表2-2 工资、薪金所得适用税率表,计算方法:月应纳税额=月应纳税所得额适用税率-速算扣除数。其中,月应纳税所得额=月工资收入-个税起征数;个税起征数为1600元。编程要求:输入月工资收入,计算并输出月应纳税额和月实际收入。,编程规范与常见错误,1.编程规范(1)if 和switch关键词与之后的表达式之间应加1个空格。(2)在if-else语句中,if与else不应在同一行,并上下对齐;后面的语句应采用缩进形式,如是复合语句,则一对花括号应上下对齐。缩进格式能增加程序的可读性。例如:if(a+bc,printf(area is%fn,area);else printf(input errern);2.常见错误(1)在关键词if 后面的表达式中将把赋值运算符“=”误作比较运算符“=”使用。例如下面的程序段中,输入的b无论为何值,均输出OK。因为这里的表达式是一个赋值表达式 b=a,并不是判断b是否等于a。由于b的值为-1(非0),代表逻辑真,所以语句printf(”NO”);是不可能被执行到的。,int a=-1,b;scanf(“%d”,总之,关键词if 后面的表达式只要是合法的C语言表达式,当它的值为“非0”,即代表“真”,否则为假。,(2)复合语句忘了用花括号括起来。例如在【案例2】的源程序中如漏了花括号如下示:if(a+bc,程序在编译时显示出错信息:“illegal else without matching if”。因为编译系统将if语句理解为是缺省形式,这时else就没有与之配对的if了。,2.2.6 贯通案例之二,1.问题描述 根据2.1.6 贯通案例之一中的菜单,对菜单进行编号,用switch语句实现菜单的选择:(1)当用户输入2 时模拟实现增加学生成绩的功能。(2)当用户输入18中的其他数字时,显示“本模块正在建设中.”(3)当用户输入18以外的数字时,显示适当的错误提示。,2.编写程序/*EX2_11.c*/#include stdio.h main()charch;long num;int score;printf(#=#n);printf(“#学生成绩管理系统#n);printf(#-#n);printf(#copyright 2009-10-1#n);printf(#=#n);,printf(“#1.加载文件#n);printf(“#2.增加学生成绩#n);printf(“#3.显示学生成绩#n);printf(“#4.删除学生成绩#n);printf(“#5.修改学生成绩#n);printf(“#6.查询学生成绩#n);printf(“#7.学生成绩排序#n);printf(“#8.保存文件#n);printf(“#0.退出系统#n);printf(#=#n);printf(请按0-8选择菜单项:);scanf(%c,switch(ch)case 1:printf(进入加载文件模块.本模块正在建设中.n);break;case 2:printf(进入增加学生成绩模块.n);printf(请输入学号和成绩:);scanf(%ld%d,break;case 4:printf(进入删除学生成绩模块.本模块正在建设中.n);break;case 5:printf(进入修改学生成绩模块.本模块正在建设中.n);break;case 6:printf(进入查询学生成绩模块.本模块正在建设中.n);break;case 7:printf(进入学生成绩排序模块.本模块正在建设中.n);break;,case 8:printf(进入保存文件模块.本模块正在建设中.n);break;case 0:printf(退出系统.n);exit(0);default:printf(输入错误!);break;3运行结果,图2-24 贯通案例运行结果1,图2-25 贯通案例运行结果2,任务3 循环结构程序设计,学习目标 领会程序设计中构成循环的方法,掌握 for、while 和do-while 语句的用法,了解 break 和continue 语句在循环语句中的作用。,2.3.1 案例讲解,案例1 累加问题1问题描述 计算100以内的奇数之和,即求1+3+5+97+99。2编程分析(1)设变量sum存放累加和,初值置0;变量i存放需累加的当前项,初值置1;(2)当i100时,反复执行当前项i加到累加和sum中当前项i+2,(3)输出累加和(4)结束 流程图见2-26。,3编写源程序/*EX2_12.c*/#include main()int i,sum;sum=0;/*累加器清0*/for(i=1;i100;i+=2)sum+=i;printf(“1+3+5+97+99=%dn”,sum);,4运行结果图2-27 案例1运行结果,5归纳分析 案例使用的是c语言提供的循环语句for语句。(1)for 语句的语法形式 for(;)其中,for是关键字。注意,三个表达式之间必须用分号(;)隔开。(2)for 语句的执行流程 首先计算;,求的值,若其值为非零,执行,然后转执行,若的值为零,则结束for语句。求解,转执行。流程图如图2-28。,(3)在程序EX2_12.c中,for循环的执行过程是:先赋值i=1,然后判断“i=100”为止。在此,变量i既是当前项,也起到了控制循环次数的作用,所以i也称为循环控制变量,它的值由表达式3来改变;sum起累加器的作用,共累加了50次。表2-3展示了i和sum在循环中的值的变化。,表2-3 循环中i和sum的变化案例2 求平均分问题1问题描述 输入若干个学生的C语言课程考试成绩,计算这门课程的平均分,输入负数时结束。,2编程分析 在程序中需要设置以下变量:score存放输入成绩;累加器sum存放总成绩;count统计人数;ave存放平均分(1)输入成绩score(2)当输入成绩不为负数时,反复执行人数加1成绩score累加到sum中输入下一个成绩score(3)计算平均分(4)输出平均分,(5)结束 流程图见图2-29。,3编写源程序/*EX2_13.c*/#include main()int score,sum=0,count=0;float ave;printf(请输入学生的C语言考试成绩,直到输入负数为止:n);scanf(%d,while(score0)count+;sum+=score;scanf(%d,4运行结果图2-30 案例2运行结果,5归纳分析 本案例使用了c语言的另一个循环控制语句while 语句。(1)while 语句的语法形式 while()其中,while为关键字。(2)while 语句的执行过程 首先计算的值,当的值为真(非零)时,执行,然后再判断的值,只要它不为假(零),继续执行,如此重复,直到的值为假(零)为止。其中,称为循环条件。流程图见图2-31。,(3)程序EX2_13.c是这样运行的:先输入成绩score,然后判断“score0”是否成立,如果为真,执行循环体:“count+;sum+=score;scanf(%d,”,再根据新成绩判断“score0”是否成立,如此反复,直到“score 0”为止。在本程序中控制循环变量是score,在进入循环前要有确定的值,在循环体中要有改变score值的语句;循环体由三条语句组成,一定要用花括号括起来,组成复合语句。,案例3 统计大写字母1问题描述 从键盘输入一串字符(输入换行符时结束),统计其中大写英文字母的个数。2编程分析(1)设置变量ch存放输入的字符;计数器变量num存放大写英文字母的个数(2)输入字符ch 若ch是大写英文字母,计数器num+1 重复上述操作,直到输入换行符为止,(3)输出大写英文字母个数 流程图见图2-32。,图2-32 案例3流程图,3编写源程序/*EX2_14.c*/#include main()char ch;int num=0;printf(输入字符串:);do ch=getchar();if(ch=A&ch=Z),num+;while(ch!=n);printf(字符串中有%d个大写字母。n,num);4运行结果图2-33 案例3运行结果,5归纳分析 本案例使用的是do-while 语句,用于构成“直到型”循环结构。(1)do-while 语句其语法形式 do while();其中do和while是关键字。值得注意的是:while后面的分号(;)不能少。,(2)do-while 语句执行过程 先执行,再判别,若的值为非零,则重复执行,直到的值为零为止。(3)do-while 语句是“先执行,后判断”。因此,无论是否成立,循环体至少要被执行一次。流程图见图2-34。本案例由于至少要输入一次,因此程序用do-while循环实现。,案例4 输出乘法“九九表”1问题描述 编写程序输出以下形式的乘法“九九表”。,2编程分析(1)乘法表第1行的变化规律:被乘数为1不变,乘数从1变化到9,每次增量为1,因此,第一行的输出可用如下的循环语句实现:for(j=1;j=9;j+)printf(“%d*%d=%4d”,1,j,1*j);,1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81,(2)乘法表第2行的变化规律:与第1行唯一不同的是被乘数为2,而处理过程完全一样,因此只需将被乘数改为2,再执行一次上面的循环语句即可;第39行与第2行同理。(3)在上述循环语句外面再加上一个循环(即构成双重循环),就可输出所要求的“九九表”。流程图见图2-35。,3编写源程序/*EX2_15.c*/#include main()int i,j;for(i=1;i=9;i+)/*外循环控制变量i,控制被乘数变化*/for(j=1;j=9;j+)/*内循环控制变量j 控制乘数变化*/printf(%d*%d=%-4d,i,j,i*j);printf(n);/*换行*/,4运行结果图2-36 案例4运行结果,5归纳分析 案例4在一个循环内又包含另一个完整的循环结构,这称为循环的嵌套。内嵌的循环又可以嵌套循环,这就形成多重循环。三种循环语句之间都可以相互嵌套,如在for循环中包含另一个for循环,在for循环中包含一个while循环或者dowhile循环等等。程序EX2_15.c中双重循环的执行过程是:先执行外循环,当外循环控制变量i取初值1后,执行内循环(j从1变化到9),