C的流程控制语句课件_第1页
C的流程控制语句课件_第2页
C的流程控制语句课件_第3页
C的流程控制语句课件_第4页
C的流程控制语句课件_第5页
已阅读5页,还剩123页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章C++的流程控制语句5.1C++语言的语句和程序结构5.2选择结构语句5.3循环结构语句5.4转向语句5.5程序举例5.6程序调试方法简介作业:4~7,9,10(1),19(2),20第5章C++的流程控制语句5.1C++语言的语句和程序结5.1C++语言的语句和程序结构一个C++源程序:由若干个源程序文件组成。一个源程序文件:由编译预处理命令、全局类型定义、全局变量定义、函数定义等组成。一个函数:包括函数首部和函数体。函数体包含局部类型定义、局部变量定义、函数原型声明、编译预处理命令、若干个语句等。5.1C++语言的语句和程序结构一个C++源程序:由若干个C++语句的分类说明语句:完成数据类型和变量的定义。控制语句:改变程序执行顺序的语句,包括:条件、循环、开关、转向、返回语句。函数调用语句:在函数调用后加分号构成。如:

sin(x);表达式语句:在表达式后加分号构成。如:i=i+1;空语句:仅由一个分号所构成,不执行任何动作。复合语句(也称块语句):用花括号{}把一个或多个语句括起来后构成的语句。作为一个语句处理。C++语句的分类说明语句:完成数据类型和变量的定义。5.2选择结构语句选择语句也称分支语句:根据给定条件,选择执行两个或两个以上分支程序段中的某一个。C++语言的选择语句:

条件语句:if。有三种形式。开关语句:switch。5.2选择结构语句选择语句也称分支语句:根据给定条件,选择条件语句格式1:if(<表达式>)S其中,<表达式>是任何C++表达式,通常为算术表达式、关系表达式、逻辑表达式或逗号表达式;S是一个单一语句,包括复合语句和空语句。作为判断条件的<表达式>必须用括号括起来。格式2:if(<表达式>)S1elseS2条件语句格式1:例5.1从键盘上输入三个整数,输出三个数中的最大数。分析:先读入三个数,求出前两个数中的大数,再求出该大数与第三个数之间的最大数。#include<iostream.h>voidmain(void){inta,b,c,t;cout<<"输入三个整数:";

cin>>a>>b>>c;if(a>b)t=a;elset=b;//Acout<<"\n最大数是";//Bif(t>c)cout<<t<<'\n';elsecout<<c<<'\n';//C}A、B、C三行可用下列语句替代:t=a;if(t<b)t=b;if(t<c)t=c;cout<<"\n最大数是"<<t<<endl;例5.1从键盘上输入三个整数,输出三个数中的最大数。A、例5.2求ax2+bx+c=0的根。a、b、c从键盘输入,a≠0。分析:当输入a、b、c的值后,若b2-4ac<0,则方程无实根;若b2-4ac>0,则方程有两个不同的实根;若b2-4ac=O,则方程有两个相等的实根。#include<iostream.h>#include<math.h>voidmain(void){floata,b,c,delta;cout<<"输入三个系数:";

cin>>a>>b>>c;delta=b*b-4*a*c;例5.2求ax2+bx+c=0的根。a、b、c从键盘输入,if(delta>=0)//使用复合语句{delta=sqrt(delta);if(delta){cout<<"方程有两个不同的实根:";

cout<<"\nx1="<<(-b+delta)/2/a;cout<<"\tx2="<<(-b-delta)/2/a<<'\n';}elsecout<<"方程有两个相等的实根:x1=x2="<<-b/2/a<<'\n';}elsecout<<"方程没有实根!\n";}if(delta>=0)//使用复合语句条件语句格式3:

if(<表达式1>)S1elseif(<表达式2>)S2elseif...elseSn注意,当出现如下形式的嵌套条件语句时:

if(e1)if(e2)S1elseS2C++规定:else与其前面最近的还没有配对的if进行配对。这样,上面的条件语句中else与第二个if配对。若希望else与第一个if配对,则可用{}改变:

if(e1){if(e2)S1}elseS2条件语句格式3:例5.3输入三角形的三边,判断其为何种三角形。#include<iostream.h>voidmain(void){inta,b,c;cout<<"输入三角形的三边?";

cin>>a>>b>>c;if(a+b<=c||b+c<=a||a+c<=b)cout<<"不能组成三角形!\n";elseif(a==b&&b==c)cout<<"等边三角形\n";elseif(a==b||b==c||c==a)cout<<"等腰三角形\n";elseif(a*a+b*b==c*c||b*b+c*c==a*a||a*a+c*c==b*b)cout<<"直角三角形\n";elsecout<<"普通三角形\n";}例5.3输入三角形的三边,判断其为何种三角形。开关语句:switch格式:switch(<表达式>){case<常量表达式1>:[<语句序列1>];[break;]case<常量表达式2>:[<语句序列2>];[break;]…case<常量表达式n>:[<语句序列n>];[break;][default:<语句序列>]}

值只能是字符型或整型可选项default分支可放在开关语句中的任何位置,通常为开关语句的最后一个分支。应加空格,否则被认为是语句标号,如case9,并不出现语法错,这类错误较难查找。<常量表达式>的值必须互不相同开关语句:switch格式:值只能是字符型或整型可选项de开关语句:switch执行过程:先求<表达式>的值,再依次与case后面的<常量表达式>比较,若与某一<常量表达式>的值相等,则转去执行该case后边的语句序列,一直执行下去,直至遇到break语句或开关语句的右花括号为止。否则,若有default分支,则执行该分支后边的语句序列,否则什么也不执行。与if语句相比:⑴任一开关语句均可用条件语句来实现,但反之不然。原因是开关语句限定表达式的取值类型,而条件语句中的条件表达式可取任意类型的值。⑵开关语句结构清晰,易理解。开关语句:switch执行过程:例5.4输入一个字符,判断它是元音字母还是空白符。#include<iostream.h>voidmain(void){charc;cin.get(c);switch(c){case'a':case'A':case'e':case'E':case'i':case'I':case'o':case'O':case'u':case'U':cout<<"这是元音字母\n";break;case'':case'\n':case'\t':cout<<"这是空白符\n";break;default:cout<<"这是其它字符\n";}}请画程序流程图用if语句改写本例若default分支及其语句前移到第一个分支,则如何修改程序而保持功能不变?当省略case后面的语句序列时,则可实现多个入口,执行同一语句序列。例5.4输入一个字符,判断它是元音字母还是空白符。请画程序5.3循环结构语句循环:某条件成立时,重复执行的操作。问题:计算1+2+3+…+100。分析:编程时不可能依次列出1~100个数。设变量sum--累计和值,初值为1;变量i--存放当前待累计的数,初值为2。算法:

s1.给变量sum赋初值1,i赋初值2;

s2.令sum=sum+i,i=i+1;s3.若i<=100,则转s2;s4.输出sum的值。s2和s3是重复执行的操作。while、do…while和for语句实现循环,并把这三个语句称为循环结构语句。5.3循环结构语句循环:某条件成立时,重复执行的操作。s2while语句格式:while(<表达式>)S其中,表达式是任何表达式;语句S是任一语句,称为循环体。执行过程:先计算表达式的值,若表达式的值不等于0,则执行语句S,再计算表达式的值,重复以上过程,直到表达式的值等于0为止。特点:先判断后执行,故循环体有可能一次也不执行。while语句格式:特点:先判断后执行,故循环体有可能一次也例5.6用while语句求1+2+3+…+100的值。#include<iostream.h>voidmain(void){inti=2,//待求和的当前项

s=1;//当前项前所有项的累加和

while(i<=100){s+=i;i++;}cout<<"1+2+3+…+100="<<s<<'\n';}必须明确所用变量的含义及初值或:while(i<=100)s+=i,i++;或:while(i<=100)s+=i++;此处无须使用复合语句此处必须使用复合语句在循环体或表达式内,应有改变表达式的值的成分,否则,会产生无休止的循环(称死循环)。例5.6用while语句求1+2+3+…+100的值。必第05章C的流程控制语句课件do…while语句格式:

do

语句

while(<表达式>);语句为任一语句,是循环体;表达式是任一表达式。执行过程:先执行语句,后判断表达式的值;若表达式的值不为0,则继续执行循环体,直到表达式的值为0时为止。特点:先执行后判断,故循环体至少执行一次。do…while语句格式:特点:先执行后判断,故循环体至少执例5.7用do…while语句求1+2+…+100。#include<iostream.h>voidmain(void){inti=2,//待求和的当前项

s=1;//当前项前所有项的累加和

dos+=i++;while(i<=100);cout<<"1+2+3+…+100="<<s<<'\n';}在循环体或表达式内,应有改变表达式的值的成分,否则,会产生无休止的循环(称死循环)。分号不能忘!例5.7用do…while语句求1+2+…+100。在循环第05章C的流程控制语句课件for语句格式:

for(<表达式1>;<表达式2>;<表达式3>)语句表达式1~3是任何表达式;语句是任一语句,为循环体。特点:先判断后执行,循环体有可能一次也不执行。执行过程:⑴计算表达式1;⑵若表达式2的值为0,则执行⑷,否则转⑶;⑶执行语句,计算表达式3,转⑵;⑷结束循环。for语句格式:特点:先判断后执行,循环体有可能一次也不执行例5.8用for语句求1+2+…+100。#include<iostream.h>voidmain(void){inti,//待求和的当前项

s;//当前项前所有项的累加和

for(i=2,s=1;i<=100;i++)s+=i;cout<<"1+2+3+…+100="<<s<<endl;}表达式1通常用于设置循环初值,多为赋值表达式和逗号表达式。表达式2通常用于循环结束条件的判断,多为关系表达式、逻辑表达式。表达式3通常用于改变循环的结束条件。表达式2也可省:i=2,s=1;for(;;){s+=i++;if(i>100)break;}三个表达式可分别省和同时省,但两个分号不可省,三个表达式的作用不能省:i=2,s=1;

for(;i<=100;)s+=i++;例5.8用for语句求1+2+…+100。表达式1通常用于第05章C的流程控制语句课件从循环的组成要素上讲,for语句的常用形式应为:

for(循环变量初始化;循环结束条件;循环变量更新)循环体语句例5.9输入一行字符,并按输入的顺序输出该行字符。#include<iostream.h>voidmain(void){charc;cout<<“输入一行字符串:\n";

for(cin.get(c);c!='\n';cin.get(c))cout<<c;//依次输出字符cout<<c;//输出最后一个字符,即结束条件'\n'}依次读取字符直到读取的是换行符为止从循环的组成要素上讲,for语句的常用形式应为:依次读取字符三种循环语句的比较for和while语句都是先判断循环条件,循环体可能一次也不执行。而do…while语句是先执行循环体,后判断循环条件,所以循环体至少要执行一次。因此对于至少要执行一次重复结构的程序段,建议使用do…while语句,而对于其他的重复结构的程序段,可使用for或while语句。由于for语句有三个表达式,可分别用于循环变量初始化、循环结束条件和循环控制变量的更新,所以用得最多的是for语句,其次是while语句,而do…while语句相对于前两种语句用得少一些。三种循环语句的比较for和while语句都是先判断循环条件,合理使用循环语句合理使用循环语句,可优化程序结构,精简程序。例如,例5.9再用while和do…while语句实现:#include<iostream.h>voidmain(void){charc;cout<<“输入字符串:\n";cin.get(c);while(c!='\n'){cout<<c;cin.get(c);}cout<<c;}#include<iostream.h>voidmain(void){charc;cout<<“输入字符串:\n";do{cin.get(c);cout<<c;}while(c!='\n');}从例5.9的三个程序可见,本例用do…while语句时,程序最简,其次为for语句,再次为while语句。合理使用循环语句合理使用循环语句,可优化程序结构,精简程序。循环的嵌套及其应用循环的嵌套:循环的内嵌语句也可以是循环语句。例5.10输出1000以内所有完数。“完数”是指与其因子之和相等的数。例如6=1+2+3,即6是完数。输出完数按如下形式,例如,对于完数6,应显示:6=1+2+3分析:⑴sum——保存一个数的因子和;⑵i——1000以内的一个数,初值为2,终值为1000;⑶j——i的试探因子,取值从1到i/2。因1是i的因子,故直接作为sum的初值,j的初值为2。若i%j为0,则说明j是i的因子,则sum+=j。循环的嵌套及其应用循环的嵌套:循环的内嵌语句也可以是循环语句#include<iostream.h>voidmain(void){inti,//1000以内的一个数

j,//i的试探因子

sum;//i的因子和

for(i=2;i<=1000;i++)//外层for语句{for(sum=1,j=2;j<=i/2;j++)//内层for语句

if(i%j==0)sum+=j;if(sum==i)//i是完数,按指定格式输出{cout<<i<<"=1”;for(j=2;j<=i/2;j++)//因未存i的因子,需再求

if(i%j==0)cout<<'+'<<j;cout<<endl;}}}#include<iostream.h>5.4转向语句goto语句是一条非常简单的无条件转向语句,它可以将程序的执行流程转到程序中的任何位置,通常是从它所在的地方转移到带有标号的语句处。goto语句与条件语句组合,可形成当型和直到型循环。滥用goto语句,会导致程序流程过于复杂,降低程序的可读性、可维护性等。软件危机爆发后,goto语句一度成为争论的焦点。结构化程序设计为了保持程序结构的"单入口、单出口"特性,严格限制直接使用goto语句,但考虑到有时不得不改变程序执行的流程,C++语言提供了功能受到限制的转向语句break和continue来替代goto语句。5.4转向语句goto语句是一条非常简单的无条件转向语句,break语句格式:

break;该语句只用在switch或循环语句中。用在开关语句switch中的某个分支语句中,其作用是结束开关语句的执行,并把控制转移到该开关语句之后的第一个语句执行。用在循环语句的循环体中,当执行到break语句时,直接结束该循环语句的执行,把控制转移到紧跟该循环语句之后的语句执行。break语句格式:例5.11判别所输入的一个大于1的正整数是否是素数。#include<iostream.h>#include<math.h>voidmain(void){intx,i,j;//x存放所输入的正整数

cout<<"输入两个大于1的正整数?";

cin>>x;for(i=2,j=(int)sqrt(x);i<=j;i++)if(x%i==0)break;if(i>j)cout<<x<<"是素数!\n";elsecout<<x<<"不是素数!\n";}若x%i为0,说明i是x的因子,即x不可能是素数,无需再做后续的循环。因此,用break语句提前结束循环。for有两个出口:i>j:说明x没有大于2和小于自身的因子,即x是素数。x%i==0:说明x不可能是素数,此时i肯定小于等于j。根据i与j的关系来确定是何种情况结束for循环的。例5.11判别所输入的一个大于1的正整数是否是素数。若x%特别关注:当循环语句存在多个结束出口时,通常会在该循环结束后,对不同结束出口作出不同的处理,因此,正确区分不同结束出口是非常重要的。问题:例5.11程序中的for语句能否不用break语句?若能,如何修改for语句?特别关注:当循环语句存在多个结束出口时,通常会在该循环结束后continue语句格式:

continue;只用在循环语句的循环体中,作用是结束本次循环的循环体,提前进入下一次循环。对于while和do…while循环来说,若遇到continue,则跳到循环<表达式>的位置;而对于for循环来说,则跳到for循环的<表达式3>处。与break语句的区别:break是结束循环;continue是结束本次循环,提前进入下一次循环。continue语句格式:例5.12输入两个大于1的正整数并输出。若输入有误,则给出提示并允许重新输入,直到输入正确为止。分析:⑴检查输入数据很重要。例如在例5.11中,若运行时输入整数1,程序输出也是"1是素数!"。程序运行时,难免输入出错,应允许用户重新输入,直到输入正确为止,除非特殊场合,如用户身份验证等。⑵为了便于输入出错时重新输入,程序使用do…while循环,并设置一个输入出错标志error,用作输出不同提示信息的依据和循环结束条件。例5.12输入两个大于1的正整数并输出。若输入有误,则给出#include<iostream.h>voidmain(void){intx,y,//x、y分别存放所输入的正整数

error=0;//输入出错标志。为1时出错,为0时正常

cout<<"输入两个大于1的正整数?";

do{if(error)cout<<"\n\n输入无效!\n重输两个大于1的正整数?";

error=0;cin>>x;if(x<2){error=1;continue;}cin>>y;if(y<2)error=1;}while(error);//error为1表示输入出错,需要重新输入

cout<<"\n\n输入的两个数为"<<x<<','<<y<<endl;}#include<iostream.h>goto语句简介*标号

label:S

S是任一语句,包括空语句;label为语句标号,简称为标号,采用标识符。标号无需定义,可直接使用。goto语句

gotolabel;其中,label是语句标号,当执行到该语句时,无条件地将控制转移到标有该标号的语句处执行。goto语句简介*标号*goto语句的主要用途从循环体内转移到循环体外:但可用break或continue替代。从多层循环的内层跳到外层循环外:但这种用法不符合结构化编程原则,不提倡使用。不允许从循环语句的外面转移到循环语句的里面。与if语句构成循环:如例5.13所示。但可由while、do…while和for取代,因此也不提倡这样使用。*goto语句的主要用途从循环体内转移到循环体外:但可用br例5.13用goto和if构成循环,求1+2+…+100的值。#include<iostream.h>voidmain(void){inti=2,//待求和的当前项

s=1;//当前项前的所有项的累加和lp:if(i<=100)//goto语句和if语句构成while型循环{s+=i++;gotolp;}cout<<"1+2+3+…+100="<<s<<'\n';}lp:s+=i++;//do…while型循环

if(i<=100)gotolp;例5.13用goto和if构成循环,求1+2+…+100的exit()函数exit()函数是stdlib.h库中的函数,原型为:

voidexit(intstatus);执行该函数时,将终止当前程序的执行并将控制返还操作系统。但终止前,系统要做必要的收尾工作,如关闭该程序打开的文件,写完缓冲输出的内容,释放变量占用内存(不含堆内存)等。status为终止程序的原因,0表示正常退出,非0表示异常退出。exit()函数exit()函数是stdlib.h库中的函5.5程序举例例5.14编程计算1!+2!+…+10!。分析:每项都是计算阶乘,可用循环结构处理。#include<iostream.h>voidmain(void){inti,//取值从1~10,初值为2

p,//保存i!,初值为1

s;//前i个阶乘和,初值为1

for(i=2,p=1,s=1;i<=10;i++){p*=i;s+=p;}cout<<"1!+2!+3!+…+10!="<<s<<'\n';}程序运行结果:1!+2!+3!+…+10!=4037913循环程序设计要点:找出重复计算规律;合理安排计算,提高计算效率。如计算i!不是每次从头开始计算,而是利用(i-1)!(保存在p中)再乘i所得。5.5程序举例例5.14编程计算1!+2!+…+10!n!的溢出问题及处理用double或longdouble型变量存放阶乘值。对于某些C++系统,可用8字节整型,如VC++的_int64。自编大整数运算程序:例如使用字符型数组实现。近似方法:当阶乘值大于等于10时,就除以10,使指数加1。最后将尾数和指数分别输出。n!的溢出问题及处理用double或longdouble型#include<iostream.h>voidmain(void){inti,e;//e保存阶乘的指数,初值为0

doublep;//保存阶乘的尾数,初值为1

for(i=2,p=1,e=0;i<=1000000;i++){p*=i;

while(p>=10)//阶乘p反复除以10,分离指数

{p/=10.0;e++;}}cout<<"1000000!="<<p<<'e'<<e<<endl;}程序运行结果:1000000!=8.26393e5565708#include<iostream.h>程序运行结果:例5.15编写程序,利用以下公式计算π的近似值,直到最后一项的绝对值小于10-8为止。

分析:本题属于求和问题,可用循环语句解决。主要特点:⑴所算的项数是未知,循环的结束条件是最后一项的绝对值小于10-8。⑵每个计算项的符号正负相间,每一项的分母比前一项增加2。⑶要求计算到最后一项的绝对值小于10-8,即有效位数超过7位,已超出float型的精度范围,应使用double型。例5.15编写程序,利用以下公式计算π的近似值,直到最后#include<iostream.h>#include<math.h>#include<iomanip.h>voidmain(){doublepi=0,//π/4的前n项的和,初值为0t=1,//π/4的当前项的值,初值为1n=1;//n表示分母

ints=-1;//s表示符号

while(fabs(t)>=1E-8){pi+=t;n+=2;s=-s;t=-s/n;}cout<<"π≈"<<setiosflags(ios::fixed)<<setprecision(8)<<pi*4<<endl;}程序运行结果:π≈3.14159263#include<iostream.h>程序运行结果:例5.16用迭代法求的近似值。求平方根的迭代公式为:

直到|xn+1-xn|≤10-8为止。分析:迭代法是数值近似计算的重要方法之一。变量a—存放输入的正数变量x0—代表公式里的xn,初值为a/2变量x1—代表公式里的xn+1,其值由公式计算算法:若|x1-x0|≤10-8则x1就是所求平方根的近似值;否则将x1赋给x0,再计算新的x1,重复上述过程。例5.16用迭代法求的近似值。求平方根的迭#include<iostream.h>#include<iomanip.h>#include<math.h>voidmain(void){doublex0,x1,a;cout<<"输入一个正数:";cin>>a;while(a<0)//检查输入数据

{cout<<a<<"不能开方!\n请重输入一个正数:";cin>>a;}#include<iostream.h>x1=a/2;do{x0=x1;x1=(x0+a/x0)/2;}while(fabs(x1-x0)>1e-8);cout<<a<<"的平方根等于:"<<setiosflags(ios::fixed)<<setprecision(8)<<x1<<'\n';}程序运行结果:输入一个正数:3↙3的平方根等于:1.73205081x1=a/2;程序运行结果:例5.17输入一行字符,分别统计数字字符、字母字符和其它字符的个数。分析:输入任何字符使用cin.get()函数。源程序:#include<iostream.h>voidmain(void){intdigit=0,//统计数字字符的个数

letter=0,//统计字母字符的个数

other=0;//统计其他字符的个数

charc;例5.17输入一行字符,分别统计数字字符、字母字符和其它字cout<<“输入一行字符串:\n";do{cin.get(c);if(c>='0'&&c<='9')digit++;elseif(c>='a'&&c<='z'||c>='A'&&c<='Z')letter++;elseother++;}while(c!='\n');cout<<"\n数字字符的个数="<<digit++<<",字母字符的个数="<<letter++<<",其它字符的个数="<<other++<<endl;}cout<<“输入一行字符串:\n";例5.18用生成伪随机数的库函数rand(),设计一个自动出题程序,能实现两位正整数的四则运算。四则运算的具体类型也由随机数确定。共出10题,每题10分,最后给出总分。注意,减法计算题要保证被减数大于等于减数,除法的结果为商。分析:①伪随机数库函数rand()的介绍参见3.4.2节。②两位正整数的范围是10~99,共90个数,因此,用rand()函数生成的两位正整数可表示为:

rand()%90+10③其它说明参见程序中的注释。源程序如下。例5.18用生成伪随机数的库函数rand(),设计一个自动源程序:#include<iostream.h>#include<stdlib.h>voidmain(void){inti,//循环变量,用作出题序号

a,b,//随机生成的两个操作数

c,//计算机算出的参考答案

d,//答题者算出的答案

op,//随机生成的运算类型

sum=0;//答题者答题累计所得分数

srand(c);//初始化伪随机数发生器源程序:for(i=0;i<10;i++){a=rand()%90+10;b=rand()%90+10;op=rand()%4;switch(op){case0:cout<<a<<'+'<<b<<'=';c=a+b;break;case1:if(a<b){intt=a;a=b;b=t;}cout<<a<<'-'<<b<<'=';c=a-b;break;case2:cout<<a<<'*'<<b<<'=';c=a*b;break;case3:cout<<a<<'/'<<b<<'=';c=a/b;}for(i=0;i<10;i++)cin>>d;if(d==c){sum+=10;cout<<"正确,加10分!\n";}elsecout<<"错误,不得分!\n";}cout<<“10题中,答对:”<<sum/10<<“题,得分:"<<sum<<'\n';}cin>>d;例5.19在同一坐标中输出sinx和cosx两条曲线。应注意处理以下问题:⑴用's'代表sinx曲线,用'c'代表cosx曲线;⑵当x为某值时,若sinx=cosx,此时只要求输出's';⑶输出一条轴(x轴),由字符'l'或'!'或'|'构成。分析:⑴字符界面:每屏25行,每行80个字符。若显示内容超过25行,则前面显示的内容向前滚动并消失。⑵坐标系统:为了便于周期性显示正弦和余弦曲线,将显示器的水平方向作为y轴,垂直方向作为x轴。⑶正弦和余弦函数的取值范围为[-1,1],需将其展宽映射到[-38,38],再映射到[1,77],以便显示。⑷为了整屏显示正弦和余弦函数的一个周期,从一个周期上等间隔取了24点。例5.19在同一坐标中输出sinx和cosx两条曲线。应注第05章C的流程控制语句课件#include<iostream.h>#include<math.h>#definePI3.1415926voidmain(void){inti,sinx,cosx;for(floatx=0;x<2*PI;x+=PI/12){cosx=39+(int)(38*cos(x));sinx=39+(int)(38*sin(x));for(i=1;i<80;i++)//注意输出字符的顺序if(i==sinx)cout<<'s';elseif(i==cosx)cout<<'c';elseif(i==39)cout<<'l';elsecout<<'';cout<<'\n';}}#include<iostream.h>5.6程序调试方法简介用分支和循环语句编程,可处理的问题更加广泛。随着程序复杂性的增加,出错的机会增大。学会调试程序,是提高实际编程能力的重要保证。程序常见错误类型:编译错误(error和warning)、链接错误、运行错误和逻辑错误。5.6程序调试方法简介用分支和循环语句编程,可处理的问题更编译错编译错:编写的语句不符合C++语法规则。编译错分两类:⑴error—程序肯定有错;⑵warning—程序可能有错,希望用户确定。若用户置之不理,也可生成目标代码,但有运行风险,明智的做法是把warning当成error来严格处理。举例:⑴用了未定义的标识符(如变量名、函数名等);⑵语句后缺少分号或在不该有分号的地方加分号;⑶花括号、圆括号不配对;⑷用中文的分号、逗号、等号代替英文的分号、逗号、等号等。编译错编译错:编写的语句不符合C++语法规则。编译错解决办法:⑴根据编译器给出的出错信息(出错行号及出错提示),较易定位和解决。⑵有时所给行号并非真正的出错行,需细看出错行前后的程序,才能最终确定错误。调试策略:⑴先定位后解决;⑵先改error后改warning;⑶只改第一个错,改完即编译,直到没有编译错为止。编译错解决办法:链接错误链接错误:发生在将用户程序的目标代码与用户程序引用的库函数的目标代码链接生成可执行代码的过程中。举例:通常情况是找不到main函数或找不到某某库函数等,原因大多是用户录入错误引起,如main误写成mian。解决办法:按编译器给出的链接出错信息解决。链接错误链接错误:发生在将用户程序的目标代码与用户程序引用的运行错误运行错误:是在程序运行时发生的。举例:突然中止程序的运行;无法结束程序的运行。原因:要求机器去做不该做或做不到的事情。如:当执行表达式:a=a/b时,除数b的值为0;又如在进行数值运算时,运算结果超出机器允许的范围等。解决办法:断点+单步跟踪执行程序。运行错误运行错误:是在程序运行时发生的。逻辑错误逻辑错:程序可以运行并得出运行结果,但并不是用户预期的结果。由于这类错误无法用编程工具直接确定出错位置,因此,这类错误较难查找。原因:变量初始化不正确而造成的计算错误;编程所用的语句不正确;算法设计错误。解决办法:断点+单步跟踪执行程序。逻辑错误逻辑错:程序可以运行并得出运行结果,但并不是用户预期VC++的调试工具——定位和排除错误断点+单步跟踪执行程序⑴先在源程序的疑点位置设置断点(对小程序不一定需要),生成调试版的可执行程序。⑵用断点+单步执行方式,观察程序执行的流程和有关变量的瞬时值,以判断出错位置。使用监视窗口监测程序执行过程中某些变量或表达式值的变化,这时可利用监视窗口的功能。综合利用监视窗口和断点+单步执行逐行运行程序,观察变量的值是否正常,若正常,这一行就调试通过,否则也就找到了出错位置。VC++的调试工具——定位和排除错误断点+单步跟踪执行程演讲完毕,谢谢观看!演讲完毕,谢谢观看!第5章C++的流程控制语句5.1C++语言的语句和程序结构5.2选择结构语句5.3循环结构语句5.4转向语句5.5程序举例5.6程序调试方法简介作业:4~7,9,10(1),19(2),20第5章C++的流程控制语句5.1C++语言的语句和程序结5.1C++语言的语句和程序结构一个C++源程序:由若干个源程序文件组成。一个源程序文件:由编译预处理命令、全局类型定义、全局变量定义、函数定义等组成。一个函数:包括函数首部和函数体。函数体包含局部类型定义、局部变量定义、函数原型声明、编译预处理命令、若干个语句等。5.1C++语言的语句和程序结构一个C++源程序:由若干个C++语句的分类说明语句:完成数据类型和变量的定义。控制语句:改变程序执行顺序的语句,包括:条件、循环、开关、转向、返回语句。函数调用语句:在函数调用后加分号构成。如:

sin(x);表达式语句:在表达式后加分号构成。如:i=i+1;空语句:仅由一个分号所构成,不执行任何动作。复合语句(也称块语句):用花括号{}把一个或多个语句括起来后构成的语句。作为一个语句处理。C++语句的分类说明语句:完成数据类型和变量的定义。5.2选择结构语句选择语句也称分支语句:根据给定条件,选择执行两个或两个以上分支程序段中的某一个。C++语言的选择语句:

条件语句:if。有三种形式。开关语句:switch。5.2选择结构语句选择语句也称分支语句:根据给定条件,选择条件语句格式1:if(<表达式>)S其中,<表达式>是任何C++表达式,通常为算术表达式、关系表达式、逻辑表达式或逗号表达式;S是一个单一语句,包括复合语句和空语句。作为判断条件的<表达式>必须用括号括起来。格式2:if(<表达式>)S1elseS2条件语句格式1:例5.1从键盘上输入三个整数,输出三个数中的最大数。分析:先读入三个数,求出前两个数中的大数,再求出该大数与第三个数之间的最大数。#include<iostream.h>voidmain(void){inta,b,c,t;cout<<"输入三个整数:";

cin>>a>>b>>c;if(a>b)t=a;elset=b;//Acout<<"\n最大数是";//Bif(t>c)cout<<t<<'\n';elsecout<<c<<'\n';//C}A、B、C三行可用下列语句替代:t=a;if(t<b)t=b;if(t<c)t=c;cout<<"\n最大数是"<<t<<endl;例5.1从键盘上输入三个整数,输出三个数中的最大数。A、例5.2求ax2+bx+c=0的根。a、b、c从键盘输入,a≠0。分析:当输入a、b、c的值后,若b2-4ac<0,则方程无实根;若b2-4ac>0,则方程有两个不同的实根;若b2-4ac=O,则方程有两个相等的实根。#include<iostream.h>#include<math.h>voidmain(void){floata,b,c,delta;cout<<"输入三个系数:";

cin>>a>>b>>c;delta=b*b-4*a*c;例5.2求ax2+bx+c=0的根。a、b、c从键盘输入,if(delta>=0)//使用复合语句{delta=sqrt(delta);if(delta){cout<<"方程有两个不同的实根:";

cout<<"\nx1="<<(-b+delta)/2/a;cout<<"\tx2="<<(-b-delta)/2/a<<'\n';}elsecout<<"方程有两个相等的实根:x1=x2="<<-b/2/a<<'\n';}elsecout<<"方程没有实根!\n";}if(delta>=0)//使用复合语句条件语句格式3:

if(<表达式1>)S1elseif(<表达式2>)S2elseif...elseSn注意,当出现如下形式的嵌套条件语句时:

if(e1)if(e2)S1elseS2C++规定:else与其前面最近的还没有配对的if进行配对。这样,上面的条件语句中else与第二个if配对。若希望else与第一个if配对,则可用{}改变:

if(e1){if(e2)S1}elseS2条件语句格式3:例5.3输入三角形的三边,判断其为何种三角形。#include<iostream.h>voidmain(void){inta,b,c;cout<<"输入三角形的三边?";

cin>>a>>b>>c;if(a+b<=c||b+c<=a||a+c<=b)cout<<"不能组成三角形!\n";elseif(a==b&&b==c)cout<<"等边三角形\n";elseif(a==b||b==c||c==a)cout<<"等腰三角形\n";elseif(a*a+b*b==c*c||b*b+c*c==a*a||a*a+c*c==b*b)cout<<"直角三角形\n";elsecout<<"普通三角形\n";}例5.3输入三角形的三边,判断其为何种三角形。开关语句:switch格式:switch(<表达式>){case<常量表达式1>:[<语句序列1>];[break;]case<常量表达式2>:[<语句序列2>];[break;]…case<常量表达式n>:[<语句序列n>];[break;][default:<语句序列>]}

值只能是字符型或整型可选项default分支可放在开关语句中的任何位置,通常为开关语句的最后一个分支。应加空格,否则被认为是语句标号,如case9,并不出现语法错,这类错误较难查找。<常量表达式>的值必须互不相同开关语句:switch格式:值只能是字符型或整型可选项de开关语句:switch执行过程:先求<表达式>的值,再依次与case后面的<常量表达式>比较,若与某一<常量表达式>的值相等,则转去执行该case后边的语句序列,一直执行下去,直至遇到break语句或开关语句的右花括号为止。否则,若有default分支,则执行该分支后边的语句序列,否则什么也不执行。与if语句相比:⑴任一开关语句均可用条件语句来实现,但反之不然。原因是开关语句限定表达式的取值类型,而条件语句中的条件表达式可取任意类型的值。⑵开关语句结构清晰,易理解。开关语句:switch执行过程:例5.4输入一个字符,判断它是元音字母还是空白符。#include<iostream.h>voidmain(void){charc;cin.get(c);switch(c){case'a':case'A':case'e':case'E':case'i':case'I':case'o':case'O':case'u':case'U':cout<<"这是元音字母\n";break;case'':case'\n':case'\t':cout<<"这是空白符\n";break;default:cout<<"这是其它字符\n";}}请画程序流程图用if语句改写本例若default分支及其语句前移到第一个分支,则如何修改程序而保持功能不变?当省略case后面的语句序列时,则可实现多个入口,执行同一语句序列。例5.4输入一个字符,判断它是元音字母还是空白符。请画程序5.3循环结构语句循环:某条件成立时,重复执行的操作。问题:计算1+2+3+…+100。分析:编程时不可能依次列出1~100个数。设变量sum--累计和值,初值为1;变量i--存放当前待累计的数,初值为2。算法:

s1.给变量sum赋初值1,i赋初值2;

s2.令sum=sum+i,i=i+1;s3.若i<=100,则转s2;s4.输出sum的值。s2和s3是重复执行的操作。while、do…while和for语句实现循环,并把这三个语句称为循环结构语句。5.3循环结构语句循环:某条件成立时,重复执行的操作。s2while语句格式:while(<表达式>)S其中,表达式是任何表达式;语句S是任一语句,称为循环体。执行过程:先计算表达式的值,若表达式的值不等于0,则执行语句S,再计算表达式的值,重复以上过程,直到表达式的值等于0为止。特点:先判断后执行,故循环体有可能一次也不执行。while语句格式:特点:先判断后执行,故循环体有可能一次也例5.6用while语句求1+2+3+…+100的值。#include<iostream.h>voidmain(void){inti=2,//待求和的当前项

s=1;//当前项前所有项的累加和

while(i<=100){s+=i;i++;}cout<<"1+2+3+…+100="<<s<<'\n';}必须明确所用变量的含义及初值或:while(i<=100)s+=i,i++;或:while(i<=100)s+=i++;此处无须使用复合语句此处必须使用复合语句在循环体或表达式内,应有改变表达式的值的成分,否则,会产生无休止的循环(称死循环)。例5.6用while语句求1+2+3+…+100的值。必第05章C的流程控制语句课件do…while语句格式:

do

语句

while(<表达式>);语句为任一语句,是循环体;表达式是任一表达式。执行过程:先执行语句,后判断表达式的值;若表达式的值不为0,则继续执行循环体,直到表达式的值为0时为止。特点:先执行后判断,故循环体至少执行一次。do…while语句格式:特点:先执行后判断,故循环体至少执例5.7用do…while语句求1+2+…+100。#include<iostream.h>voidmain(void){inti=2,//待求和的当前项

s=1;//当前项前所有项的累加和

dos+=i++;while(i<=100);cout<<"1+2+3+…+100="<<s<<'\n';}在循环体或表达式内,应有改变表达式的值的成分,否则,会产生无休止的循环(称死循环)。分号不能忘!例5.7用do…while语句求1+2+…+100。在循环第05章C的流程控制语句课件for语句格式:

for(<表达式1>;<表达式2>;<表达式3>)语句表达式1~3是任何表达式;语句是任一语句,为循环体。特点:先判断后执行,循环体有可能一次也不执行。执行过程:⑴计算表达式1;⑵若表达式2的值为0,则执行⑷,否则转⑶;⑶执行语句,计算表达式3,转⑵;⑷结束循环。for语句格式:特点:先判断后执行,循环体有可能一次也不执行例5.8用for语句求1+2+…+100。#include<iostream.h>voidmain(void){inti,//待求和的当前项

s;//当前项前所有项的累加和

for(i=2,s=1;i<=100;i++)s+=i;cout<<"1+2+3+…+100="<<s<<endl;}表达式1通常用于设置循环初值,多为赋值表达式和逗号表达式。表达式2通常用于循环结束条件的判断,多为关系表达式、逻辑表达式。表达式3通常用于改变循环的结束条件。表达式2也可省:i=2,s=1;for(;;){s+=i++;if(i>100)break;}三个表达式可分别省和同时省,但两个分号不可省,三个表达式的作用不能省:i=2,s=1;

for(;i<=100;)s+=i++;例5.8用for语句求1+2+…+100。表达式1通常用于第05章C的流程控制语句课件从循环的组成要素上讲,for语句的常用形式应为:

for(循环变量初始化;循环结束条件;循环变量更新)循环体语句例5.9输入一行字符,并按输入的顺序输出该行字符。#include<iostream.h>voidmain(void){charc;cout<<“输入一行字符串:\n";

for(cin.get(c);c!='\n';cin.get(c))cout<<c;//依次输出字符cout<<c;//输出最后一个字符,即结束条件'\n'}依次读取字符直到读取的是换行符为止从循环的组成要素上讲,for语句的常用形式应为:依次读取字符三种循环语句的比较for和while语句都是先判断循环条件,循环体可能一次也不执行。而do…while语句是先执行循环体,后判断循环条件,所以循环体至少要执行一次。因此对于至少要执行一次重复结构的程序段,建议使用do…while语句,而对于其他的重复结构的程序段,可使用for或while语句。由于for语句有三个表达式,可分别用于循环变量初始化、循环结束条件和循环控制变量的更新,所以用得最多的是for语句,其次是while语句,而do…while语句相对于前两种语句用得少一些。三种循环语句的比较for和while语句都是先判断循环条件,合理使用循环语句合理使用循环语句,可优化程序结构,精简程序。例如,例5.9再用while和do…while语句实现:#include<iostream.h>voidmain(void){charc;cout<<“输入字符串:\n";cin.get(c);while(c!='\n'){cout<<c;cin.get(c);}cout<<c;}#include<iostream.h>voidmain(void){charc;cout<<“输入字符串:\n";do{cin.get(c);cout<<c;}while(c!='\n');}从例5.9的三个程序可见,本例用do…while语句时,程序最简,其次为for语句,再次为while语句。合理使用循环语句合理使用循环语句,可优化程序结构,精简程序。循环的嵌套及其应用循环的嵌套:循环的内嵌语句也可以是循环语句。例5.10输出1000以内所有完数。“完数”是指与其因子之和相等的数。例如6=1+2+3,即6是完数。输出完数按如下形式,例如,对于完数6,应显示:6=1+2+3分析:⑴sum——保存一个数的因子和;⑵i——1000以内的一个数,初值为2,终值为1000;⑶j——i的试探因子,取值从1到i/2。因1是i的因子,故直接作为sum的初值,j的初值为2。若i%j为0,则说明j是i的因子,则sum+=j。循环的嵌套及其应用循环的嵌套:循环的内嵌语句也可以是循环语句#include<iostream.h>voidmain(void){inti,//1000以内的一个数

j,//i的试探因子

sum;//i的因子和

for(i=2;i<=1000;i++)//外层for语句{for(sum=1,j=2;j<=i/2;j++)//内层for语句

if(i%j==0)sum+=j;if(sum==i)//i是完数,按指定格式输出{cout<<i<<"=1”;for(j=2;j<=i/2;j++)//因未存i的因子,需再求

if(i%j==0)cout<<'+'<<j;cout<<endl;}}}#include<iostream.h>5.4转向语句goto语句是一条非常简单的无条件转向语句,它可以将程序的执行流程转到程序中的任何位置,通常是从它所在的地方转移到带有标号的语句处。goto语句与条件语句组合,可形成当型和直到型循环。滥用goto语句,会导致程序流程过于复杂,降低程序的可读性、可维护性等。软件危机爆发后,goto语句一度成为争论的焦点。结构化程序设计为了保持程序结构的"单入口、单出口"特性,严格限制直接使用goto语句,但考虑到有时不得不改变程序执行的流程,C++语言提供了功能受到限制的转向语句break和continue来替代goto语句。5.4转向语句goto语句是一条非常简单的无条件转向语句,break语句格式:

break;该语句只用在switch或循环语句中。用在开关语句switch中的某个分支语句中,其作用是结束开关语句的执行,并把控制转移到该开关语句之后的第一个语句执行。用在循环语句的循环体中,当执行到break语句时,直接结束该循环语句的执行,把控制转移到紧跟该循环语句之后的语句执行。break语句格式:例5.11判别所输入的一个大于1的正整数是否是素数。#include<iostream.h>#include<math.h>voidmain(void){intx,i,j;//x存放所输入的正整数

cout<<"输入两个大于1的正整数?";

cin>>x;for(i=2,j=(int)sqrt(x);i<=j;i++)if(x%i==0)break;if(i>j)cout<<x<<"是素数!\n";elsecout<<x<<"不是素数!\n";}若x%i为0,说明i是x的因子,即x不可能是素数,无需再做后续的循环。因此,用break语句提前结束循环。for有两个出口:i>j:说明x没有大于2和小于自身的因子,即x是素数。x%i==0:说明x不可能是素数,此时i肯定小于等于j。根据i与j的关系来确定是何种情况结束for循环的。例5.11判别所输入的一个大于1的正整数是否是素数。若x%特别关注:当循环语句存在多个结束出口时,通常会在该循环结束后,对不同结束出口作出不同的处理,因此,正确区分不同结束出口是非常重要的。问题:例5.11程序中的for语句能否不用break语句?若能,如何修改for语句?特别关注:当循环语句存在多个结束出口时,通常会在该循环结束后continue语句格式:

continue;只用在循环语句的循环体中,作用是结束本次循环的循环体,提前进入下一次循环。对于while和do…while循环来说,若遇到continue,则跳到循环<表达式>的位置;而对于for循环来说,则跳到for循环的<表达式3>处。与break语句的区别:break是结束循环;continue是结束本次循环,提前进入下一次循环。continue语句格式:例5.12输入两个大于1的正整数并输出。若输入有误,则给出提示并允许重新输入,直到输入正确为止。分析:⑴检查输入数据很重要。例如在例5.11中,若运行时输入整数1,程序输出也是"1是素数!"。程序运行时,难免输入出错,应允许用户重新输入,直到输入正确为止,除非特殊场合,如用户身份验证等。⑵为了便于输入出错时重新输入,程序使用do…while循环,并设置一个输入出错标志error,用作输出不同提示信息的依据和循环结束条件。例5.12输入两个大于1的正整数并输出。若输入有误,则给出#include<iostream.h>voidmain(void){intx,y,//x、y分别存放所输入的正整数

error=0;//输入出错标志。为1时出错,为0时正常

cout<<"输入两个大于1的正整数?";

do{if(error)cout<<"\n\n输入无效!\n重输两个大于1的正整数?";

error=0;cin>>x;if(x<2){error=1;continue;}cin>>y;if(y<2)error=1;}while(error);//error为1表示输入出错,需要重新输入

cout<<"\n\n输入的两个数为"<<x<<','<<y<<endl;}#include<iostream.h>goto语句简介*标号

label:S

S是任一语句,包括空语句;label为语句标号,简称为标号,采用标识符。标号无需定义,可直接使用。goto语句

gotolabel;其中,label是语句标号,当执行到该语句时,无条件地将控制转移到标有该标号的语句处执行。goto语句简介*标号*goto语句的主要用途从循环体内转移到循环体外:但可用break或continue替代。从多层循环的内层跳到外层循环外:但这种用法不符合结构化编程原则,不提倡使用。不允许从循环语句的外面转移到循环语句的里面。与if语句构成循环:如例5.13所示。但可由while、do…while和for取代,因此也不提倡这样使用。*goto语句的主要用途从循环体内转移到循环体外:但可用br例5.13用goto和if构成循环,求1+2+…+100的值。#include<iostream.h>voidmain(void){inti=2,//待求和的当前项

s=1;//当前项前的所有项的累加和lp:if(i<=100)//goto语句和if语句构成while型循环{s+=i++;gotolp;}cout<<"1+2+3+…+100="<<s<<'\n';}lp:s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论