版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C/C++程序设计
(第三版)第2章分支和循环
主要内容2.1分支结构2.2循环结构
语句(statement)分类语句(statement)分类
从功能上分直接完成计算的语句表达式语句、赋值语句等用于控制程序流程的语句完成分析、判断、循环、转移等功能
从语句结构形式上分简单语句(一句就是一句)表达式语句、赋值语句、函数调用结构型语句(一句中含有多个子句)复合语句条件语句循环语句开关语句简单的控制语句无条件转移语句goto中止语句break继续语句continue函数调用语句返回语句return最简单的语句——空语句(仅含一个分号)不含任何其他符号,既不做任何操作,不起控制作用作用是为了在程序某特殊部位设置“转移点”或空循环体,空函数体为满足语法规定的需要(能自圆其说)
2.1分支结构
2.1.1if语句
一般格式形式一
if(E)S;形式二if(E)S;
elseS1;E是判别表达式——除结构类型、联合类型的任意表达式(括起来),如:关系表达式、逻辑表达式,算术表达式等S(if子句)、S1(else子句):是任一条语句(注意:一条)形式一的执行步骤1)计算E的值2)若E的值为真(等于1,或非0),则执行语句S,结束本语句的执行,转而执行该语句的后继语句3)否则(E的值为假,或等于0),什么也不做(相当于空语句)形式二的执行步骤1)~2)同上3)否则,执行语句S1,结束本语句的执行,转而执行该语句的后继语句若语句S(S1)中不含控制语句本语句的后继语句就是下一条语句
表达式E
语句S为1(真)
为0(假)
为1(真)
为0(假)
表达式E
语句S
语句S1
流程图示例1)使a获得a和b两个数中的较大值:
if(a<b)a=b;对应的条件表达式a=a<b?b:a2)使max获得a和b两个数的较大值:
if(a<b)max=b;elsemax=a;
对应的条件表达式max=a<b?b:a3)使max获得a和b两个数的较大值,而min获得a和b两个数的较小值:
if(a<b)max=b,min=a;elsemax=a,min=b;//用逗号表达式对应的条件表达式a<b?(max=b,min=a):(max=a,min=b)示例4)使a获得a和b两个数的较大值,而b获得a和b两个数的较小值:
if(a<b)temp=a,a=b,b=temp;//若a不大于b交换a和b的值对应的条件表达式a<b?(temp=a,a=b,b=temp):1注意换值操作:temp=a,a=b,b=temp“1”没有具体含义
temp是中间变量2.1.2复合语句和if语句的嵌套
1.复合语句(compoundstatement)凡语法规定只能用一条语句的地方(主要是结构型语句的内嵌语句)一条语句又“不够用”(达不到程序功能)就要使用复合语句一般格式
{S1;
S2;
…;
Sn;}“{}”——语句括号
S1,S2,…Sn是任意语句不管括起来多少条语句,语法上只算一条复合语句又叫块(block)语句if(a>b){max=a;min=b;}//这是一条复合语句
else{max=b;min=a;}//这是一条复合语句示例
if(a<b){temp=a;a=b;b=temp;}//这是一条复合语句2.if语句的嵌套if的内嵌语句(或else的内嵌语句)中又包含if语句——嵌套if嵌套的形式多种多样if(E1)if(E2)S1;//if内嵌if
elseS2;elseif(E3)S3;
elseS4;//else内嵌if2.if语句的嵌套算法设计思想(假定a、b、c不等)先比较a和b:情况1(a<b)和情况2(b<a)例2-1将a、b、c三个数按从小到大的次序输出情况1(a排在b前)比较a和c:情况1-1(a<c)和情况1-2(c<a)在情况1-1(a最小,a排在b、c前)比较b和c,可确定b排在c之前还是排在c之后情况1-2(a排在b之前,c排在a之前)输出次序(由小到大)c,a,b情况2(b<a)处理步骤与情况1对称算法的流程图
abc
a<b
a<c
b<c
a<c
b<c
1
1
0
1
0
1
0
1
0
0
bac
cba
bca
acb
cab
if(a<b)//第一大分支,对应流程图左侧
if(a<c)if(b<c)printf("%d,%d,%d\n",a,b,c);elseprintf("%d,%d,%d\n",a,c,b);elseprintf("%d,%d,%d\n",c,a,b);else//第二大分支b≤a
,对应流程图右侧
if(a<c)printf("%d,%d,%d\n",b,a,c);elseif(b<c)printf("%d,%d,%d\n",b,c,a);elseprintf("%d,%d,%d\n",c,b,a);}算法的实现程序段例2-2按考试成绩score输出三类信息:90~100输出优秀60~89输出合格,0~59输出不合格
算法设计思想和流程图可有多种方法:例2-2按考试成绩score输出三类信息:90~100输出优秀60~89输出合格,0~59输出不合格
if(score>=90)printf("score=%d,优秀\n",score);elseif(score>=60)printf("score=%d,合格\n",score);elseprintf("score=%d,不合格\n",score);例2-2按考试成绩score输出三类信息:90~100输出优秀60~89输出合格,0~59输出不合格
if(score>=60)if(score>=90)printf("score=%d,优秀\n",score);elseprintf("score=%d,合格\n",score);elseprintf("score=%d,不合格\n",score);关于if语句的一般说明:1)if后面的表达式用括号括起来,不能写成
ifx<y…2)在嵌套的if结构中:
else总是与其前面最近的未配过对的if相配对3)if内嵌语句和else内嵌语句,尾部都加分号4)若内嵌语句不止一条,用“{}”括起来,构成复合语句复合语句尾部的“}”后面不加分号5)第一种if形式是第二种的特例相当于else内嵌一条空语句6)不要让else与其对应的if相距太远比如配对关系
if(E1)if(E2)S1;
elseif(E3)S2;
elseS3;实际配对原想配对关于if语句的再说明:1)if(E)等价于if(E!=0)if(!E)等价于if(E==0)2)嵌套的if结构使用缩排格式,增强程序的易读性3)Ⅱ型if语句的if子句中嵌套Ⅰ型if语句时会出现二义性
例如:
if(x>0)//第一个ifif(y<5)a=a+1;//第二个ifelsea=a+2;if(x>0)//第一个ifif(y<5)a=a+1;//第二个ifelsea=a+2;错!错!例如:
if(x>0)//第一个if{if(y<5)a=a+1;}//第二个ifelsea=a+2;
if(x<=0)a=a+2;//将第一个if的条件反过来
elseif(y<5)a=a+1;//第二个if加{}改变语句性质if(E){…//此处很长很长,有几十行
}else{…}//此处较短,只有几行
不如改为:if(!E)//条件反过来
{…}//较短的行
else{…//较长的几十行
}4)对下面的程序段:
两段都很长将改成子函数调用
2.1.3*switch语句Ⅰ型
switch(E){caseC1:S1;
caseC2:S2;
……caseCn:Sn;
default
:Sk;
}Ⅱ型
switch(E){caseC1:S1;
caseC2:S2;
……caseCn:Sn;
}E是判别表达式关键字
常量表达式
语句序列
2.1.3*switch语句Ⅰ型、Ⅱ型
switch(E){caseC1:S1;
caseC2:S2;
……caseCn:Sn;
default:Sk;
}执行流程:计算判别表达式E的值依次将此值与各case后面的常量表达式逐一比较1)如果E的值与某个常量表达式的值相等,则从该case后面的语句开始执行,直至本switch所辖的最后一条语句2)如果E的值与所有常量表达式的值都不相等,对于Ⅰ型,则执行default后的语句Sk对于Ⅱ型,则什么也不执行
例switch(a){case3:b=30;case1:b=10;case2:b=20;default:b=50;}如果a=3
执行
b=30;b=10;b=20;b=50;
如果a=1
执行
b=10;b=20;b=50;
这种控制,无意义
例switch(a){case3:b=30;break;case1:b=10;break;case2:b=20;break;default:b=50;}如果a=3
执行
b=30;
如果a=1
执行
b=10;
真正实现“多选一”例2-3设今天是星期三(Wednesday),求t(t>0)天以后是星期几?要求输出星期几的英文名称switch((t+3)%7){case0:printf("Sunday\n");break;case1:printf("Monday\n");break;case2:printf("Tuesday\n");break;case3:printf("Wednsday\n");break;case4:printf("Thursday\n");break;case5:printf("Friday\n");break;
case6:printf("Saturday\n");}用整数0~6对应一周的七天:0对应星期天,1对应星期一,…,6对应星期六只要计算出(3+t)%7的值,便可得出是星期几几点说明
1)各case后面只能是常量表达式不能写成casex<0:s1;case(0<x)&&(x<1.2):s2;case(1.2<x)&&(x<10.4):s3;case(x>11)&&(!y):s4;default: s5;
switch不能用来复杂条件的多选一控制几点说明
2)switch语句的判别表达式和常量表达式通常为整型、字符型或枚举类型3)多个case可以共用一组执行语句
switch(x){case1:case2:case3:y=123;break;……}4)各case后面的常量表达式的值必须互不相同例2-4将学生考试分数x(0~100的整数)转换为优、良、中、下四个等级,其中,90~100分为优,70~89分为良,60~69分为中,不足60分为下。switch(x/10){case0:case1:case2:case3:case4:case5:cout<<"下";break;case6:cout<<"中";break;case7:case8:cout<<"良";break;case9:case10:cout<<"优";}不能写成:switch(1){case(x<60):cout<<"下";break;case(x>59&&x<70):cout<<"中";break;case(x>69&&x<90):cout<<"良";break;case(x>89):cout<<"优";}2.1.4程序设计示例
例2-5判断一个三位数x是否是一个“水仙花数”——各位数字立方之和等于这个三位数本身。例如:153=13+53+33
算法设计思想设x=c×100+b×10+a,个位数a,十位数b,百位数c从x中分离出a、b、c方法(x是三位数)x的个位数为:a=x%10x的十位数为:b=x/10%10x的百位数为:c=x/100判断a3+b3+c3是否等于x,可以写成:if(x==a*a*a+b*b*b+c*c*c)例2-5判断一个三位数x是否是一个“水仙花数”——各位数字立方之和等于这个三位数本身。例如:153=13+53+33
#include<iostream.h>voidmain(){inta,b,c,x;cout<<"请输入x的值:";cin>>x;a=x%10;b=x/10%10;c=x/100;if(x==a*a*a+b*b*b+c*c*c)cout<<x<<"是水仙花数"<<endl;elsecout<<x<<"不是水仙花数"<<endl;}例2-6将大小不等的四个数a、b、c、d排列成有序形式:
a<b<c<d(小型排序问题)算法设计思想:分两个阶段描述第二阶段排成a<b<c<d形式第一阶段排成a<b<c形式例2-6将大小不等的四个数a、b、c、d排列成有序形式:
a<b<c<d(小型排序问题)实现第一阶段的程序段为:if(a>b)temp=a,a=b,b=temp;if(b>c)if(c>a)temp=b,b=c,c=tempelsetemp=a,a=c,c=b,b=temp;交换a和b至此,a<b至此,a<b<c至此,a<b、b>c、a<c交换b和c,即成a<b<c至此,a<b、b>c、a>cc最小,b最大,循环换位成a<b<c至此,a<b<c例2-6将大小不等的四个数a、b、c、d排列成有序形式:
a<b<c<d(小型排序问题)实现第二阶段的程序段为:if(b>d)if(d>a)temp=d,d=c,c=b,b=temp;elsetemp=a,a=d,d=c,c=b,b=temp;elseif(c>d)temp=c,c=d,d=temp; 现在a<b<c至此可知d排在b之前至此可知d排在b之前a之后至此d最小至此可知d排在b之后至此d最大至此可知d排在b之后c之前例2-6将大小不等的四个数a、b、c、d排列成有序形式:
a<b<c<d(小型排序问题)#include<stdio.h>voidmain(){inta,b,c,d,temp;printf("请输入四个整数:");scanf("%d%d%d%d",&a,&b,&c,&d);
//第一阶段
if(a>b)temp=a,a=b,b=temp;
if(b>c)if(c>a)temp=b,b=c,c=temp;//当a<c<b时,换位
elsetemp=a,a=c,c=b,b=temp;//当c<a<b时,换位
例2-6将大小不等的四个数a、b、c、d排列成有序形式:
a<b<c<d(小型排序问题)
//第二阶段
if(b>d)if(d>a)temp=d,d=c,c=b,b=temp; //处理a<d<b<c的换位操作
elsetemp=a,a=d,d=c,c=b,b=temp;//处理d<a<b<c的换位操作
elseif(c>d)temp=c,c=d,d=temp;//处理a<b<d<c的换位
printf("排序结果:%4d%4d%4d%4d\n",a,b,c,d);}例T2-1外观相同的12枚金币中混入一枚伪币,用天平称三次找出伪币,并指出它比真币轻,还是重(智力游戏)算法设计思想和描述采用分组编号称量法,将12枚金币分成A、B、C三组A组:a1,a2,a3,a4B组:b1,b2,b3,b4C组:c1,c2,c3,c4第一次,A组4个与B组各4个称量A组有一轻,或B组有一重A组有一重,或B组有一轻A、B好的,伪币在C组二者对称例T2-1外观相同的12枚金币中混入一枚伪币,用天平称三次找出伪币,并指出它比真币轻,还是重(智力游戏)已知A=B:第二、第三次的称量左有疑问,右好的
c1,c2,c3之一轻了
c1,c2,c3之一重了
c4是坏的
例T2-1外观相同的12枚金币中混入一枚伪币,用天平称三次找出伪币,并指出它比真币轻,还是重(智力游戏)已知A<B:第二、第三次的称量a1轻了,或b3重了
a2轻了,或b1、b2之一重了
例T2-1外观相同的12枚金币中混入一枚伪币,用天平称三次找出伪币,并指出它比真币轻,还是重(智力游戏)已知A<B:第二、第三次的称量a3、a4之一轻了,或b4重了
例T2-1外观相同的12枚金币中混入一枚伪币,用天平称三次找出伪币,并指出它比真币轻,还是重(智力游戏)if(a1+a2+a3+a4==b1+b2+b3+b4) //情况2(A=B){if(c1+c2+c3<b1+b2+b3) //情况2-1if(c1<c2)printf("c1:L\n");elseif(c1==c2)printf("c3:L\n");elseprintf("c2:L\n");elseif(c1+c2+c3==b1+b2+b3)//情况2-2if(c4<b1)printf("c4:L\n");elseprintf("c4:H\n");else//情况2-3与情况2-1对称
if(c1<c2)printf("c2:H\n");elseif(c1==c2)printf("c3:H\n");elseprintf("c1:H\n");}//情况2处理完毕else//进入下一屏例T2-1外观相同的12枚金币中混入一枚伪币,用天平称三次找出伪币,并指出它比真币轻,还是重(智力游戏)if(a1+a2+a3+a4<b1+b2+b3+b4) //情况1(A<B)
{if(b1+b2+a1<b3+a2+c1)//情况1-1if(a1<c1)printf("a1:L\n");elseprintf("b3:H\n");elseif(b1+b2+a1==b3+a2+c1)//情况1-2if(a3<a4)printf("a3:L\n");elseif(a3==a4)printf("b4:H\n");elseprintf("a4:L\n");else //情况1-3与情况1-1对称
if(b1<b2)printf("b2:H\n");elseif(b1==b2)printf("a2:L\n");elseprintf("b1:H\n");}else//进入情况3的处理(与情况1对称)第2章分支和循环
主要内容2.1分支结构2.2循环结构
2.2循环结构
三种循环语句while(最简单,好用)for语句(最灵活多变,功能最强大)do-while语句(不常用)2.2.1while语句
一般格式while(E)S;E:判别表达式S:“一条”语句(循环体)通常是复合语句执行步骤:计算判别表达式E的值若为0,则退出while语句(结束循环)若不为0,则执行循环体一次再次计算判别表达式E的值(重复)
0
非0
表达式E
语句S
例2-7编程求1到100之间所有整数倒数的和算法设计思想和描述采用累加法使用变量n做计数器,变量sum做“累加器”第1步,定初值n=1,sum=0。第2步,如果n<=100,继续下一步;否则转第4步第2-1步,作一次累加:sum=sum+1/n
第2-2步,计数器增1:n=n+1第3步,返回第2步(循环处理)第4步,输出sum的值,结束例2-7
编程求1到100之间所有整数倒数的和#include<stdio.h>voidmain(){doublen=1,sum=0;//sum=0,准备循环累加
while(n<=100){sum=sum+1/n; //累加
n=n+1; //计数器增1}printf("1/1+1/2+1/3+…+1/100=%-12.6f\n",sum);}累加模式——先清0,再循环累加例2-7
编程求1到100之间所有整数倒数的和#include<stdio.h>voidmain(){doublen=1,sum=0;//sum=0,准备循环累加
while(n<=100){sum=sum+1/n; //累加
n=n+1; //计数器增1}printf("1/1+1/2+1/3+…+1/100=%-12.6f\n",sum);}可改为:while(n<100)sum+=1/++n;
例2-7
编程求1到100之间所有整数倒数的和#include<stdio.h>voidmain(){intn=1;doublesum=0;//sum=0,准备循环累加
while(n<=100){sum=sum+1.0/n; //累加
n=n+1; //计数器增1}printf("1/1+1/2+1/3+…+1/100=%-12.6f\n",sum);}请注意这里的改动
例2-8输入一批学生某门功课的考试成绩(0~100分)
当输入不在0~100范围内,则表示输入结束
统计总人数、不及格的人数、平均成绩算法的自然语言描述使用总人数计数器n、不及格人数计数器m分数总和累加器sum第1步,定初值n=0,m=0,sum=0第2步,读入第一个分数x第3步,当0≤x≤100时执行第3-1~3-4步的循环体(否则转第4步)第3-1步,总分累加,sum+=x
第3-2步,总人数累加,n++
第3-3步,若x<60,则不及格人数累加,m++
第3-4步,读后续分数第4步,输出计算结果,结束例2-8输入一批学生某门功课的考试成绩(0~100分)
当输入不在0~100范围内,则表示输入结束
统计总人数、不及格的人数、平均成绩#include<stdio.h>voidmain(){floatsum=0; //总分累加器清零
intx,n=0,m=0; //计数器清零
printf("请输入学生成绩,以负数或大于100结束!\n");scanf("%d",&x); //读第一个分数
while(x>=0&&x<=100)//若分数不是0~100终止循环
{sum+=x; //总分累加
n++; //总人数计数
if(x<60)m++; //累计不及格人数
scanf(“%d”,&x); //读第二、第三、…个分数
}例2-8输入一批学生某门功课的考试成绩(0~100分)
当输入不在0~100范围内,则表示输入结束
统计总人数、不及格的人数、平均成绩//以下是输出数据程序段
if(!n)printf("输入数据有误!\n");else{printf("总人数为:%d,
平均成绩为:%-6.2f\n",n,sum/n); if(!m)printf("没有不及格的。\n");elseprintf("共有%d人不及格。\n",m);}}
若n=0,则不能相除
使用while要注意几点:1)E中涉及到的变量在进入循环前必先赋值(因为,先计算E,再判断)2)体内必须有修改E值的语句,且最终要使E的值为0;否则死循环3)若进入循环前E的值为0,则循环体一次也不执行
while语句的循环体执行次数:0到多次2.2.2for语句
一般格式:for(E1;E2;E3)S;E1,E2,E3是用分号隔开的表达式S是一条语句(循环体),通常是复合语句for(E1;E2;E3)S;E1:初始表达式主要作用:为E2设置循环初始条件E2:判别表达式E3:后置表达式
E2与E3配合控制循环的执行执行流程:1)计算初始表达式E1的值2)计算判别表达式E2的值3)若E2的值为非0,则执行一次循环体,接着计算后置表达式E3的值4)转步骤2
直到判别表达式E2的值为0,终止循环
0
循环体非0
计算表达式E2
计算初始表达式E1
计算后置表达式E3
for(E1;E2;E3)S;
“翻译”成while语句E1;while(E2){S;
//for的循环体
E3;
}while(E)S;
“翻译”成for语句for(;E;)S;E1和E3皆为空但分号不能少用for语句求1到100之间所有整数倒数和(多种灵活用法)doublen,sum=0;for(n=1;n<=100;n++)sum+=1/n;//规矩用法1)doublen,sum;for(n=1,sum=0;n<=100;)sum+=1/n++;
//初始表达式设置多项初始值2)doublen=1,sum=0;for(;n<=100;n++)sum+=1/n;
//初始表达式为空(前面已经设置了初始条件)3)doublen=1,sum=0;for(;n<=100;)sum+=1/n++;
//后置表达式为空(其功能放在循环体内)用for语句求1到100之间所有整数倒数和(多种灵活用法)4)doublen,sum;for(n=1,sum=0;;)if(n>100)break;elsesum+=1/n++;//判别表达式为空(其功能放在循环体内)5)doublen,sum;for(n=1,sum=0;n<=100;sum+=1/n++);//循环体是空语句(其功能放在后置表达式中)6)doublen=1,sum=0;for(;;)if(n>100)break;elsesum+=1/n++;//三个表达式都空(控制功能分别放在for之前和循环体中)for语句更为特殊的用法
for(;getchar()!='\n';); //E1,E3和循环体都为空功能:反复读字符,直到读入换行符为止(甩掉换行符)例2-9用for循环计算下面公式s的值算法设计思想在循环累加时,根据n的奇偶性,确定加“1/n”还是减“1/n”#include<stdio.h>voidmain(){intn=1,m;doubles=0;printf("请输入m的值m=");scanf("%d",&m); //输入m的值
while(n<=m){if(n%2)s=s+1.0/n;elses=s-1.0/n;n=n+1;}printf("s=%-12.6f\n",s);}2.2.3do-while语句一般格式:
doS;while(E);E:判别表达式S:循环体(一句)执行流程:先执行一次循环体,再计算E的值若E的值为非0,则再执行一次循环体如此往复,直到表达式E的值为0,结束循环
用do-while语句求1到100之间所有整数倒数和
doublen=1,sum=0;do//循环体是复合语句
{sum+=1/n;n++;}while(n<=100);
doublen=1,sum=0;do//循环体是简单语句
sum+=1.0/n++;while(n<=100);while与do-while的主要差别:1)先判断,后执行;与先执行,后判断2)要不要先定判别表达式E的初值3)执行次数(0到多次与1到多次)共同点:体内必修改E的值并且最终使E的值变为0凡do-while能实现的功能,while也一定能够实现;反之却未必do-while主要用于初始条件不好确定,并保证循环体至少执行一次的场合例2-10输入一串字符(以“&”结束),统计其中
有多少个字母,多少个数字#include<stdio.h>#include<ctype.h>//isdigit和isalpha所在头文件voidmain(){intletters=0,digits=0;//用于记录字母个数和数字个数
charch;do{ch=getchar();//读字符
if(isdigit(ch))digits++;//是数字
elseif(isalpha(ch))letters++;//是字母
}while(ch!='&');//判断是否是结束符
printf("字母个数=%d数字个数=%d\n",letters,digits);}例2-10输入一串字符(以“&”结束),统计其中
有多少个字母,多少个数字do{ch=getchar();//读字符
if(isdigit(ch))digits++;//是数字
elseif(isalpha(ch))letters++;//是字母
}while(ch!='&');//判断是否是结束符
程序的主体部分
ch=getchar(); //读第一个字符
while(ch!='&'){if(isdigit(ch))digits++;elseif(isalpha(ch))letters++;ch=getchar(); //读下一个字符
}
改用while语句2.2.4多重循环
1×1=1
1×2=2
1×3=3
1×4=4
…
1×9=
9
2×1=2
2×2=4
2×3=6
2×4=8
…
2×9=18
…
…
…
…
…
…
9×1=9
9×2=18
9×3=279×4=36
…
9×9=81
例2-11
生成乘法表1×1=1
1×2=2
1×3=3
1×4=4
…
1×9=
9
2×1=2
2×2=4
2×3=6
2×4=8
…
2×9=18
…
…
…
…
…
…
9×1=9
9×2=18
9×3=279×4=36
…
9×9=81
算法设计思想使i和j各自从1变到9i=1时,j从1变到9,输出第一行的9个等式i=2时,j从1变到9,输出第二行的9个等式……i=9时,j从1变到9,输出第九行的9个等式#include<stdio.h>voidmain(){inti,j;for(i=1;i<=9;++i){for(j=1;j<=9;++j)printf("%2d*%d=%2d",i,j,i*j);printf("\n");}}请考虑如何生成这样两个乘法表
2.2.5break语句和continue语句
1.break语句最简单的控制语句用于从switch语句或循环体跳出(提前终止)增强循环的控制能力,使程序流程灵活多变break语句用法示例例如,测试变量n是不是素数的程序段
for(i=2,p=1;i*i<=n;i++)if(n%i==0){p=0;break;}if(p)printf("%d是素数。\n",n);elseprintf("%d不是素数。\n",n);break语句用法示例再如,反复读字符直到读入换行符的程序段:
for(;;) //无控制循环
{ch=getchar(); //循环读字符
if(ch=='\n')break; //若读到换行符,跳出循环
elseputchar(ch); //不是换行符,则输出它
}break语句跳出循环的图示不能指望用一条break一下子跳出多重循环2.continue语句
只能用在循环体中结束循环体的本次执行,提前进入下一轮循环循环体的尾部,并不终止循环语句
例2-12连续为整数n输入不同的数值,直到n是素数,但是若输入的n≤1,则给出输入错误信息,并要求重新输入数据。采用双重循环结构,外循环负责输入数据n,并根据n是否大于1作出相应的处理。内循环负责测试并检测n是不是素数第1步,读入n第2步,如果n<=1,报错,并跳到第6步;否则执行下一步第3步,用循环结构测试n是不是素数第4步,若测试结果n是素数,则输出n是素数的信息,算法结束;否则执行下一步第5步,输出n不是素数的信息第6步,转第1步例2-12连续为整数n输入不同的数值,直到n是素数,但是若输入的n≤1,则给出输入错误信息,并要求重新输入数据。#include<stdio.h>voidmain(){inti,n,p;while(1) //外循环,终止条件设在循环内
{printf("请输入整数n的值,n=");scanf("%d",&n);if(n<=1) //n是否合乎要求
{printf("n=%d输入错误,请重新输入\n",n);
continue;//跳到while(1)循环体尾部
}
for(i=2,p=1;i*i<=n;i++)//内循环,检测n是不是素数
if(n%i==0){p=0;break;}//作n不是素数标记,终止内循环例2-12连续为整数n输入不同的数值,直到n是素数,但是若输入的n≤1,则给出输入错误信息,并要求重新输入数据。
if(!p) //用标记p控制外循环是否终止
printf("%d不是素数。\n",n);//继续执行外循环
else{printf("%d是素数。\n",n);break; //第二个break,终止外循环
}
//while(1)循环体尾部
}printf("程序结束。\n");}例2-12连续为整数n输入不同的数值,直到n是素数,但是若输入的n≤1,则给出输入错误信息,并要求重新输入数据。
本示例程序特点:程序结构比较复杂,既有while循环,又有for循环既有Ⅰ型if结构,也有Ⅱ型if结构既有continue语句,也有break语句带有容错功能(若输入的n不大于1,提示重新输入)使用了一些特殊的设计技巧
本示例使用的特殊设计技巧:while(1)无限循环结构,靠循环体内的break语句终止标记p的用法既控制内循环环(n是不是素数)又控制外循环(当前是否找到素数,是否继续外循环)例2-12连续为整数n输入不同的数值,直到n是素数,但是若输入的n≤1,则给出输入错误信息,并要求重新输入数据。注意程序中,检测n是不是素数的程序段的写法for(i=2;i*i<=n;i++)if(n%i==0)…//n不是素数的处理步骤
else…//n是素数的处理步骤for(i=2;i*i<=n;i++)if(n%i==0)p=0;//作n不是素数标记
elsep=1;//作n是素数标记
if(p==0)… //n不是素数的处理步骤
else… //n是素数的处理步骤正确错误错误for(i=2,p=1;i*i<=n;i++)if(n%i==0){p=0;break;例2-12连续为整数n输入不同的数值,直到n是素数,但是若输入的n≤1,则给出输入错误信息,并要求重新输入数据。程序中可以不用continue语句
if(n<=1){printf("n=%d输入错误,请重新输入\n",n);continue; //跳到while(1)循环体尾部
}… //判断n是不是素数的那大段程序
if(n>1){… //判断n是不是素数的那大段程序
}elseprintf("n=%d输入错误,请重新输入\n",n);原来的程序段
可以改为2.2.6*goto语句无条件转移语句,控制能力最强一般格式:
goto
语句标号;语句标号:语句S;例如:
gotoL;…L:语句S;2.2.6*goto语句goto的功与过:过:破坏程序结构,难以阅读、维护功:可以轻松地从多层循环中跳出(break没有这样的能力)做法:有限制地使用,而不能滥用goto
例2-13用goto语句构成循环,统计学生总人数、不及格的人数、平均成绩要求:每输入一个数据换一行,若输入分数超过100分提示输入错误信息(本次输入无效),继续输入数据若输入成绩为负数,输入结束第1步,定初值n=0,m=0,sum=0。第2步,请求输入数据第3步,读入分数x,并要求输入一个换行符第4步,若x>100,则报错并转到第2步第5步,若x<0,则转到第10步;否则,继续下一步第6步,总分累加,sum+=x第7步,总人数累加,n++第8步,若x<60,则不及格人数累加,m++第9步,转第2步第10步,输出计算结果,结束例2-13用goto语句构成循环,统计学生总人数、不及格的人数、平均成绩#include<stdio.h>voidmain(){floatsum=0;intx,n=0,m=0;L1:printf("请输入学生成绩,以负数结束!\n");scanf("%d",&x);for(;getchar()!='\n';);//甩掉换行符前的输入内容
printf("你本次输入的数据为:%d请核对。\n",x);if(x>100){printf("输入错误,请重新输入\n");gotoL1;}if(x<0)gotoL2;例2-13用goto语句构成循环,统计学生总人数、不及格的人数、平均成绩sum+=x;n++;if(x<60)m++;
gotoL1;L2:if(!n)printf("输入数据有误!\n");else{printf(“总人数为:%d,平均成绩为:
%-6.2f\n",n,sum/n);//输出统计结果
if(!m)printf("没有不及格的。\n");elseprintf("共有%d人不及格。\n",m);}}2.2.7程序设计示例
例2-14输出26个英文字母的大小写及其ASCII码值,每4个字母占一行A:65a:97B:66b:98C:67c:99D:68d:100E:69e:101F:70f:102G:71g:103H:72h:104I:73i:105J:74j:106K:75k:107L:76l:108M:77m:109N:78n:110O:79o:111P:80p:112Q:81q:113R:82r:114S:83s:115T:84t:116U:85u:117V:86v:118W:87w:119X:88x:120Y:89y:121Z:90z:122#include<stdio.h>voidmain(){charletter;intaline;for(letter='A',aline=1;letter<='Z';letter++,aline++){printf("%6c:%3d%4c:%3d",letter,letter,letter+'a'-'A',letter+'a'-'A');if(!(aline%4))printf("\n");//够4个,则输出换行符
}printf("\n");//最后输出一个换行符}例2-14输出26个英文字母的大小写
及其ASCII码值,每4个字母占一行
例2-15输入N个整数,输出其中最大数和最小数
用变量max和min分别记录最大数和最小数先读入第一个数,并将其作为max和min的初值循环读入其余整数,每读入一个数x
就考查x是否更大、更小:若x>max,则将x赋给max若x<min,则将x赋给minmax、min始终保持当前最大数和最小数循环结束后,max、min则为所求最大数和最小数例2-15输入N个整数,输出其中最大数和最小数
#include<stdio.h>#defineN10//假定N=10voidmain(){inti,x,max,min;printf("请输入%d个整数:\n",N);scanf("%d",&max); //输入第一个数
min=max; //为max和min定初始值
for(i=2;i<=N;++i){scanf("%d",&x); //输入后续各数
if(x>max)max=x; //找最大数
elseif(x<min)min=x; //找最小数
}printf("最大数=%d最小数=%d\n",max,min);}【例2-16】[斐波那契(Fibonacci)]问题假设小兔子出生一个月后就变为成年兔,并具有繁殖能力假定每对成年兔每个月生一对小兔子,新生的小兔子一个月后又可以每个月生一对小兔子假设兔子都不死,现在有一对幼兔,问多少个月后兔子数目超过100对?这时共有多少对兔子算法设计思想把兔子分成有繁殖能力的成年兔和刚出生的幼兔如果本月有m对成年兔和n对幼兔(共m+n对兔子)那么到下个月幼兔就长成了大兔子所以下个月成年兔子就有m+n对而原先m对成年兔子又生出m对小兔子故下个月共有m+n对成年兔和m对幼兔【例2-16】[斐波那契(Fibonacci)]问题用f3、f2、f1分别表示本月、前一个月、前两个月的免子数目因为前个月的兔子到本月都还存在(没死)前两个月的f1对兔子到本月各生一对幼兔故本月共有f2对成年兔和f1对幼兔即本月共有f3=f2+f1对兔子算法设计思想(续)斐波那契序列:1,1,2,3,5,8,13,……【例2-16】[斐波那契(Fibonacci)]问题得出求第i个月兔子数目的递推公式:斐波那契序列:1,1,2,3,5,8,13,……#include<stdio.h>voidmain(){intf1=1,f2=1,f3=0,i=2; //i表示月数
while(f3<=100)f3=f1+f2,f1=f2,f2=f3,i++;printf(“第%d个月后,兔子数目超过100对,达
%d对。\n",i,f3);}【例2-16】[斐波那契(Fibonacci)]问题例T2-2计算多项式
p(x)=anxn+an-1xn
1+…+a1x+a0在x=b点的值
Hanoi算法
p(x)=1.3x3
6x2+2.1
x+5.03=((1.3x
6)x+2.1)x+5.03
p(x)=(…((anx+an
1)x+an
2)x+…+a1)x+a0
#include<stdio.h>voidmain(){inti,n;doublex,a,p;printf("请输入多项式的次数n和自变量x的值:");scanf("%d%lf",&n,&x); printf(“请从最高项起,输入%d次多项式的%d个系数:\n",n,n+1);for(i=0,p=0;i<=n;i++){scanf("%lf",&a);//输入一个系数
p=p*x+a; //乘x并累加
}printf("多项式的值=%-20.6lf\n",p);}例T2-2计算多项式值的Hanoi算法例2-17求正整数a和b的最大公约数gcd(a,b)
欧几里德“辗转相除”算法原理:gcd(a,b)=gcd(b,a%b)若a是b的倍数a%b=0,gcd(a,b)=b否则,gcd(a,b)=gcd(b,r)
其中r=a%b直到余数为0止例2-17求正整数a和b的最大公约数gcd(a,b)
gcd(124,46)=gcd(46,32) 余数:14=gcd(32,14) 余数:4=gcd(14,4) 余数:2=gcd(4,2) 余数:0=2 计算出结果值2while(b)r=a%b,a=b,b=r; //a的最终值为计算结果
#include<stdio.h>voidmain(){inta,b,r;while(1) //反复输入数据,直到a和b均为正整数
{printf("请输入a和b的值:");scanf("%d%d",&a,&b);if(a<1||b<1)printf("你输入的数据不正确,a=%d,b=%d\n",a,b);elsebreak;}printf("gcd(%d,%d)=",a,b);while(b)r=a%b,a=b,b=r; //算法的主体部分
printf("%d\n",a);}例2-17求正整数a和b的最大公约数gcd(a,b)
例T2-3判断尼罗河、密西西比河、亚马逊河、长江的长短张、王、李、赵四个人争论尼罗河、密西西比河、亚马逊河、长江的长短排列(从长到短)如下:张的排列:尼罗河,亚马逊河,密西西比河,长江王的排列:亚马逊河,尼罗河,长江,密西西比河李的排列:尼罗河,长江,亚马逊河,密西西比河赵的排列:密西西比河,亚马逊河,长江,尼罗河已知他们每人都说对其中的2条河,另2条河不对根据他们的说法,编程判断四条大河的长短排列推理智力游戏
例T2-3判断尼罗河、密西西比河、亚马逊河、长江的长短算法设计思想:用1、2、3、4表示四条河的长短次序编号(1最长,4最短)用标识符(变量名)代表四条河流ni:尼罗河mi:密西西比河ya:亚马逊河ch:长江比如,表达式ni==1表示A说的尼罗河最长
如果尼罗河的确最长,则表达式ni==1的值为1,否则为0根据A的排列写成表达式:(ni==1)+(ya==2)+(mi==3)+(ch==4)应等于2(因为他说对2个)例T2-3判断尼罗河、密西西比河、亚马逊河、长江的长短用a,b,c,d分别代表张王李赵四人的排列结果,则有:
a=((ni==1)+(ya==2)+(mi==3)+(ch==4)==2)b=((ya==1)+(ni==2)+(ch==3)+(mi==4)==2)c=((ni==1)+(ch==2)+(ya==3)+(mi==4)==2)d=((mi==1)+(ya==2)+(ch==3)+(ni==4)==2)其中,a,b,c,d的值只能是1或0
用穷举法让ni,mi,ya,ch分别从1到4变化(循环)找出a,b,c,d的值均为“1”的一组解(a+b+c+d=4)便是问题的答案例T2-3判断尼罗河、密西西比河、亚马逊河、长江的长短#include<stdio.h>voidmain(){inta,b,c,d,ni,mi,ya,ch
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 一轮筑基 2027届新高考II卷政治高考二轮专题卷(含答案+解析)
- 2027年四川省历史高考限时特训卷(含答案+解析)
- 2027年湖北省语文高三查漏补缺卷(含答案+解析)
- 2026综合类-专业综合第十二章其他-专业综合第八章精神、神经系统历年真题摘选带答案详解
- 2026精算师资格-精算师-精算师历年参考题库含答案详解
- 2026福建省机关事业单位工勤人员技能等级考试(计量检定工)历年参考题库含答案详解
- 2026福建省医疗卫生系统招聘考试(医学检验)历年参考题库含答案详解
- 2026福建机关事业单位工勤人员技能等级考试(客房服务员·初级)历年参考题库含答案详解
- 2026监理工程师-建设工程合同管理(官方)-第七章建设工程总承包合同管理参考试题库历年考点答案详解
- 2026电工特种作业-低压电工(官方)-电气防火与防爆参考试题库历年考点答案详解
- 城市轨道交通工程常见质量问题控制指南(征求意见)
- T-GDCKCJH 090-2024 微生物电化学法水质生物毒性在线自动监测技术规范
- 仓储公司 仓储合同范例
- 徐州至淮北至阜阳高速公路淮北段特许经营实施方案
- 血糖监测与胰岛素注射
- 护理正高答辩常见问题
- 三年级语文 《赠刘景文》课件-“江南联赛”一等奖
- 第10章-液相烧结
- 电工作业安全培训
- 全过程工程咨询工作总结报告(全过程咨询)
- 株洲冶炼集团股份有限公司株洲市天元区工业五区房地产估价报告
评论
0/150
提交评论