第三章C语言的基本控制结构_第1页
第三章C语言的基本控制结构_第2页
第三章C语言的基本控制结构_第3页
第三章C语言的基本控制结构_第4页
第三章C语言的基本控制结构_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

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

文档简介

第三章C语言的基本控制结构Chapter3ControlFlow问题#include<stdio.h>#include<math.h>voidmain(void){floata,b,c,x1,x2;scanf(“%f,%f,%f”,&a,&b,&c);x1=(-b+sqrt(b*b-4.*a*c))/(2.0*a);x2=(-b-sqrt(b*b-4.*a*c))/(2.0*a);printf(“x1=%7.2f\nx2=%7.2f”,x1,x2);}b*b-4ac<0?一元二次方程根求解算法描述b2-4ac=0?yes求等根nob2-4ac>0?yes求实根no求复根问题:如何构造条件?如何根据条件实现不同算法?3.1程序的三种控制结构

结构化程序设计是软件设计的第三次革命。结构化程序设计的基础是采用三种程序的控制结构。1966年BÖHM&Jacopini证明:只要三种控制结构就能表达用一个入口和一个出口框图所能表达的任何程序逻辑。三种控制结构如下:⒈顺序结构Sequence算法描述:f;g;框图:f;g;⒉选择结构Selection(分支结构)算法描述:if(e)f;elseg;框图:e?yesf;nog;⒊循环结构Repetition⑴当型循环whilecistruedofc?fYESNO⑵直到循环dofuntilcisfalsefc?YESNO三种控制结构有如下共同的特点:一个入口和一个出口;无死语句;无死循环。如何构造条件?⒋复合语句Compound Statement

概念:C语言可以用{}包括一系列的语句。一对{}所包含的内容称为一个复合语句。其中可以含有0到多条C语言语句。#include<stdio.h>voidmain(void)

{inta,b;scanf(“%d,%d”,&a,&b);

{inttemp;

temp=a;a=b;b=temp;

}printf(“%d,%d”,a,b);}复合语句复合语句复合语句可以嵌套凡是可以出现单一语句的地方都可以使用复合语句。复合语句的作用:⒈作为分支和循环的块。⒉作为标识符的作用域。交换算法演示3.2关系运算和逻辑运算⒈关系运算(RelationalOperator)关系运算是比较两个表达式的数值相互关系的运算。运算符比较的关系实例>大于a>b>=大于等于a>=b<小于2<1<=小于等于c<=d==等于1==c!=不等于1!=3

关系运算规则:参加运算的表达式的从左到右按关系运算符提供的关系进行比较,满足关系得到整型值1,不满足关系得到整型值0。inta=1,b=3,c,d;c=a>b;d=a+2<=b+3;⒉逻辑运算(LogicalOperator)逻辑运算运算时判断对象真、假的运算。C语言没有提供逻辑类型。任何类型的值都可以表示逻辑状态,如下表:表达式的值所对应的逻辑值表达式的值表示的逻辑关系非0真true0假false运算对象非0代表逻辑真,是0代表逻辑假。也就是说任何类型的量都有逻辑值。逻辑运算的结果用整型值表示。运算结果为真时,得到整型值1;运算结果为假时,得到整型值0。inta=2,b=0;aba+bC语言的逻辑运算运算符逻辑关系举例&&逻辑与a>2&&a<3||逻辑或s<2||s>6!逻辑非!a其中,!运算是单目运算。逻辑运算演示⒊复杂逻辑关系的表示在实际应用中,经常会遇到描述复杂的关系。如:判断x是否大于等于5或小于3。此类关系的描述在程序设计中会大量使用。035x<3||x>=50-23-2<x<3?x=4-2<x&&x<3表示数值关系的原则:开放区间用或;闭合区间用与。思考题⒈判断是否在一、三象限的表达式。⒉判断是否在如图圆环内的表达式。sqrt(x),代表对x开平方。⒊ch为字符变量,判断ch是否为字母的表达式。(ch>=’a’&&ch<=‘z’)||(ch>=’A’&&ch<=‘Z’)不是字母的表达式?⒋运算的优先级C语言允许所有基本类型的量参加同一表达式的运算,也允许所有类型的运算符出现在一个表达式中。因此,表达式值的类型如何确定,运算的先后顺序如何确定,必须通过一套规则解决。为了便于调整优先级,设置()为最高优先级。相同优先级存在一个顺序称为结合顺序,结合顺序有从右向左或从左向右。⑴运算优先级第一原则:单目运算的优先级高于双目运算。第二原则:算术运算关系运算逻辑运算赋值运算表达式优先级举例说明:++a-b>c+d&&a>=b*34①②③④⑤⑥⑦注意:在无法确定优先级时,加()区分。简化表达式。c=b*=a+2c=(b*=(a+2))级别运算符结合顺序1()[]->.从左向右2!-++--(type)sizeof*&~从右向左3*/%从左向右4+-从左向右5<<>>(移位运算)从左向右6<<=>>=从左向右7==!=从左向右8&(位与运算)从左向右9^(位异或运算)从左向右10|(位或运算)从左向右11&&从左向右12||从左向右13?:从右向左14=op=从右向左15,从左向右优先级总表优先级特例

⒈自加、自减运算优先级遵循原则:

前置:先运算后引用;

后置:先引用后运算。#include<stdio.h>voidmain(void){inta=3,b;b=a+++a++;printf(“b=%d”,b);b=++a+(++a);printf(“b=%d”,b);}CHAP3EX0⒉在逻辑运算中,如果逻辑值能够确定,则不再进行运算。inta=0,b=0++a||++b;printf(“a=%d\nb=%d”,a,b);a=0;a&&++b;/*b的值?*/++CHAP3EX13.3分支结构(选择结构Selection)

⒈if及if-else的三种结构。由标准的分支结构可以演化成单分支、多分支结构。C语言的分支语句有if、if–else、switch三种。

⑴if语句格式:

if(expression)statement;语句表达式,非0为yes,0为no。语句,可以是复合语句。流程图:e?statement;yesno举例:#include<stdio.h>voidmain(void){charch;ch=getchar();

if(ch>=‘a’&&ch<=‘z’)ch-=32;putchar(ch);}CHAP3EX2⑵if–else结构格式:

if(expression)

stat1;

else stat2;语句或复合语句。流程图:e?falsestat2;stat1;true入口出口举例:输出|x|。#include<stdio.h>voidmain(void){intx;scanf(“%d”,&x);

if(x>=0)

printf(“%d”,x);

else

printf(“%d”,-x);}⑶if–elseif结构(Muliline)格式:

if(e1)

stat1;

elseif(e2)

stat2;

elseif(e3)

stat3;…

elseif(en-1)

statn-1;

elsestatn;

框图:e1?tstat1;fe2?tstat2;出口fen-1?tstatn-1;fstatn;n-1个条件,满足某个条件,执行对应的语句,然后到出口。ifelseif结构举例:征税问题:1000以下税率为3%1000~2000税率为4%2000~3000税率为5% 3000以上税率6%输入收入,求应缴税款。#include<stdio.h>voidmain(void){floatx,rate;scanf(“%f”,&x);

if(x<1000)rate=.03;elseif(x<2000)rate=.04;elseif(x<3000)rate=.05;elserate=.06;printf(“%f”,x*rate);}3/100?⑷if语句的嵌套对于如下的结构:if(e1)stat1;elsestat2;在stat1或stat2中又含有if结构:if(e2)stat3;elsestat4;称为if结构的嵌套。各种if结构都可以嵌套。

如求符号函数:-1(x<0)y=0(x=0)1(x>0)#include<stdio.h>voidmain(void){intx,y;scanf(“%d”,&x);

if(x<0)y=-1;

else

if(x==0)y=0;

else

y=1;printf(“x=%d,y=%d\n”,x,y);}外层内层在外层else语句中,含有一个if结构。说明:①书写采取缩进形式,便于区分。内层缩进。②else与最近的if相匹配,从内到外。y=-1;if(x!=0)if(x>0)y=1;elsey=0;x==0结果?举例:求一元二次方程ax2+bx+c=0的根。#include<stdio.h>#include<math.h>voidmain(void){floata,b,c,d,x1,x2;scanf(“%f,%f,%f”,&a,&b,&c);d=b*b-4.0*a*c;

if(fabs(d)<1.0e-6)

{printf(“\nx1=x2=,%f”,-b/(2.0*a));

}

else

{

if(d>0)

{

printf(“\nx1=%f”,(-b+(float)sqrt(d))/(2.0*a));printf(“\nx2=%f”,(-b-(float)sqrt(d))/(2.0*a));

}

else

{

printf(“\nx1=%f+i%f”,-b/(2.0*a),(float)sqrt(-d)/(2.0*a));printf(“\nx2=%f-i%f”,-b/(2.0*a),(float)sqrt(-d)/(2.0*a));

}

}}外层内层求相等实根。求不等实根。求共扼复根。CHAP3EX4判断实型量相等或不等用误差的方法。flaota=1.0/*a=1.000001或0.999999*/a==1.0?⒉switch语句(多分支结构)格式:switch

(expression)

{case常量表达式1:statement1;case常量表达式2:statement2;…case常量表达式n-1:statementn-1;default:statementn;

}只能是整型或字符型表达式。整型字符型常量表达式。表达式的值要互不能相等!

流程:①先求expression的值。②依次比较expression和各常量表达式的值。

③如果与第i个常量表达式相等,则执行第i条以后的语句。④如果都不相等,则执行default以后的语句。语句标号的概念:#include<stdio.h>voidmain(void){chargrade;grade=getchar();

switch(grade){

case‘A’:printf(“90—100\n”);

case‘B’:printf(“80—89\n’);

case‘C’:printf(“70—79\n”);

case‘D’:printf(“60—69\n”);

case‘E’:printf(“<60\n”);

default:printf(“error\n”);}}CHAP3EX5语句标号。break语句:格式:break;作用:中断switch流程。break;break;break;break;break;CHAP3EX6例:输出五分制对应的百分制范围。#include<stdio.h>voidmain(void){charchGrad;chGrad=getchar();

switch(chGrad){

case‘a’:case‘A’:

printf(“90—100\n”);break;case‘b’:case‘B’:printf(“80—89\n”);break;case‘c’:case‘C’:printf(“70—79\n”);break;case‘d’:case‘D’:printf(“60—69\n”);break;case‘e’:case‘E’:printf(“<60\n”);break;

default:printf(“DataError!\n”);

}}多个标号可以共用相同的语句。default语句可以省略。3.4

循环结构(Repetition)程序经常会重复执行某些相同的操作,如:求:s=1+2+3+4+…+100算法描述:①s=0;i=1;②s+=i;i++;③判断i是否小于等于100

如果i小于等于100,重复②;

否则,结束。此类根据“条件”重复执行相同算法的结构,称为循环。初始化部分。循环体。含有使条件趋假的语句。循环的条件。注意:循环应在有限次完成。

C语言提供了三类实现循环的语句:

while,dowhile,for

⒈while循环(当型循环)格式:

while(expression)

statement;表达式:值非0,表示满足条件;值为0代表不满足条件。语句(复合语句),重复执行部分(循环体)。流程:e?truestatement;false含有使条件趋假的语句。举例:求s=1+2+3+4+…+100#include<stdio.h>voidmain(void){ints=0,i=1;

while(i<=100)

{s=s+i;/*s+=i;*/i++;}

printf(“s=%d\n”,s);}初始化部分循环体条件测试使条件趋假语句CHAP3EX7⒉do–while循环(直到型循环)格式:

do{

statement;}

while

(expression);流程:statement;e?truefalse含有使条件趋假的语句。while循环与do-while循环的区别:while循环先判条件,后执行循环体;do–while循环先执行循环体,后判条件。举例:求:30!#include<stdio.h>voidmain(void){floats=1.0;inti=1;

do{s*=i;i++;}while(i<=30);

printf(“30!=%f”,s);}初始化。循环体。测试条件。使条件趋假。CHAP3EX8思考题:用do-while实现s=1+2+…+100。用while实现30!。⒊for循环格式:

for

(e1;

e2;e3)

statement;流程:e1e2?truestatement;e3false举例:求:s=1+2+3+…+100#include<stdio.h>voidmain(void){ints=0,i;

for(i=1;i<=100;i++

)

{s=s+i;

}

printf(“s=%d”,s);}使e2趋假。在for循环中,e1、e2、e3都可以省略!e1省略

i=1;e3省略

i++;初值表达式。测试表达式。增值表达式。for循环实例求100以内的偶数和。ints=0,i;for(i=2;i<100;i+=2){s+=i;}求500以内最大的5个能被50整除数的和。inti,j,s=0;for(j=500,i=0;i<5;i++,j-=50){s+=j;}从大到小输出100以内能被5整除的数。inti;for(i=100;i>=0;i-=5)printf(“%d\n”,i);inti,j,s=0;for(i=0,j=0;i+j<100;i++,++j){s+=i+j;}⒋循环应用的几个问题⑴循环的嵌套概念:在一个循环的循环体内又包含一个完整的循环称为循环的嵌套。i123456789 11112……19

j 22122……29 99192……99如打印一99的乘法表:i=1时,j从1变化到9,完i*j。多重循环打印99乘法表。#include<stdio.h>voidmain(void){inti,j;for(i=1;i<=9;i++){

printf(“\n“);}}外层循环内层循环说明:⒈内外层循环采用缩进形式。⒉while和do-while和for可以相互嵌套。

⒊执行次数为内层循环次数和外层循环次数的乘积。CHAP3EX9如何打印乘法表的一半?for(j=1;j<=9;j++){printf(“%4d“,i*j);}⑵循环的中断(break)和继续(continue)①循环的中断:break语句概念:循环体中可以加分支,判断是否继续执行循环,break语句可以提前结束循环。举例:求:r=1—10的圆的面积,如圆面积大于100则中断。for(r=1;r<=10;r++){area=3.14159*r*r;

if(area>100)

break;

printf(“\n%f“,area);}满足条件,则退出循环。②继续循环:continue语句continue语句的作用是跳过本次循环剩余的循环体内容,执行下次循环。举例:求1—100内的偶数和。

s=0;for(n=1;n<=100;n++){

if(n%2!=0)

continue;

s+=n;}满足条件,跳过本次循环体剩余内容,继续下次循环。ints=0,i;for(i=2;i<100;i=i+2)s+=i;⑶无限循环和空循环①条件为恒真的循环——无限循环while(1){…}do{…}while(1);for(;;){…}通过条件控制的break语句退出循环。例:程序等待直到输入字母A。for(;;){ch=getchar();if(ch==’A’)break;}②循环体为空语句的循环——空循环for(i=1;i<=MAX;i++)

;作用:程序延时。空语句{;}⑷goto语句格式:gotoLabel/*Label:同一函数内语句前的标号。*/作用:转移到标号对应的语句上继续执行。loop:

if(i<=100){

sum=sum+i;i++;

gotoloop;

}循环和分支相互嵌套输入10个自然数统计其中偶数的个数及偶数值和。算法框图:start定义变量初始化循环?true输入偶数?true统计累加falsefalse输出结果end#include<stdio.h>voidmain(void){inti,ix,iCount=0,iSum=0;

for(i=1;i<=10;i++){

scanf(“%d\n”,&ix);

if(ix%2==0){iSum+=ix;iCount++;}

}printf(“Num=%d\nSum=%d”,iCount,iSum);}循环结构分支结构输入负数?do{

if(ix<=0)printf(“dateerror”);}while(ix<=0);

算法的健壮性注意:结构应完整的包含和被包含。程序设计的基本方法根据计算机的特点,结合循环与分支结构在程序设计时常使两种常用的基本方法。枚举法(穷举法)迭代法本专题将结合分支和循环介绍两种方法的基本思想和具体实现!枚举法Enumeration存在有限状态;其中某些状态满足特定条件。通过循环产生所有状态(枚举)。对每一状态,按条件进行状态测试,满足条件的状态,为所求的解。求100到200内的所有素数。通过循环使i从101变化到199(枚举所有状态)对每次循环的i进行是否是素数的测试,如果是素数,输出i。枚举法举例:⒈求100到200之间的所有素数(只能被1和自身整除的数)。对于自然数n,判断其是否为素数有以下三种方法:①判断n是否能被从2到n-1范围内的数整除;②判断n是否能被从2到(int)(n/2)范围的数整除;③判断n是否能被从2到(int)sqrt(n)范围的数整除;程序如下:#include<stdio.h>#include<math.h>voidmain(void){intn,j,s;

for(n=101;n<200;n+=2){

s=(int)sqrt((double)n);

for(j=2;j<=s;j++){if(n%j==0)break;}

if(j>s)

printf(“\n%d”,n);

}}枚举所有数构造,测试条件如果n能被2到s的任意数整除,退出循环。如果n是素数,输出n。CHAP3EXA

⒉求水仙花数(条件:三位数的个、十、百位的方和等于该数。153==13+53+33)。n为枚举变量,枚举初值100,枚举终值999。构造条件:取出n的个、十、百位数。测试是否满足条件,满足条件输出n。#include<stdio.h>voidmain(void){intn,a,b,c;

for(n=100;n<=999;n++){

a=n/100;b=n%100/10;c=n%10;

if(a*a*a+b*b*b+c*c*c==n) printf(“\n%d”,n);

}}枚举所有三位数构造条件测试条件取n的百位a、十位b、个位c。CHAP3EXB⒊爱因斯坦阶梯问题(不定范围的枚举)。设有一阶梯,每步跨2阶,最后剩1阶;每步跨3阶,最后剩2阶;每步跨5阶,最后剩4阶;每步跨6阶,最后剩5阶;每步跨7阶,正好到阶梯顶。问共有多少阶梯。根据条件可以得出:台阶数一定是奇数且为7的倍数。枚举初值:k=7;

枚举公式:k=k+14

结束条件:满足(k%3==2)&&(k%5==4)&&(k%6==5)结束。#include<stdio.h>voidmain(void){

intk=7;

while(

!((k%3==2)&&(k%5==4)&&(k%6==5)))

k+=14;

printf(“\nl=%d”,k);}CHAP3EXC思考题:

⒈36人一次搬36块砖,男搬4,女搬2,两个小孩抬一块。要一次搬完。问:男、女、小孩要多少?⒉

找出1000以内的完数,所谓完数是指该数的各因子之和等于该数,如6=1+2+3。⒊证明6到200以内的数,符合哥德巴赫猜想(一个大于6的偶数,可以分解成两个质数之和)。⒋奇妙的算式:用字母代替十进制数字写出如下算式: EGAL

LLGAE请找出这些字母代表的数字。迭代法Iteration迭代是通过循环不断由旧值推导新值,并最后求解的过程。迭代法有三个要点:

如人口每年按2%增长,现在人口有12亿,10年后人口有多少?⒈迭代公式。m=m*(1+2%)⒉迭代初值(边界条件)。m=12⒊迭代次数(或条件)。n=10迭代法举例⒈求ex=1+x+x2/2!+…+xn/n!前n+1项之和。迭代次数i012…n迭代公式t=t*x/i迭代初值exp=1,t=1,(i=1~n)#include<stdio.h>voidmain(void){floatexp,x,t;inti,n;

scanf(“%f,%d”,&x,&n);t=1.0;

exp=1.0;

for(i=1;i<=n;i++){

t*=x/i;exp+=t;

}

printf(“e^%d=%15.6f”,(int)x,exp);}迭代初值。迭代公式。迭代过程附加条件:当|t|<10-5,结束运算。if(fabs(t)<1e-5)break;CHAP3EXD⒉用梯形法求定积分(0,0)yxf(x)ab面积hx①将[a,b]分为n等份,h=(b-a)/n;②求n个梯形面积之和,第i小面积x=x+hf1=f(x)下底s=s+(f0+f1)*h/2f0=f1迭代x初值为as初值为0f0初值为f(a)

次数为n迭代求积分的方法程序如下:#include<stdio.h>voidmain(void){floata,b,f0,f1,h,x,s=0.0;intn,i;scanf(“%f,%f,%d”,&a,&b,&n);h=(b-a)/n;

x=a;f0=x*x+12.0*x+4.0;

for(i=0;i<n;i++){

x=x+h;f1=x*x+12.0*x+4.0;s=s+(f0+f1)*h/2.0;f0=f1;

}

printf(“S=%f”,s);}CHAP3EXE迭代初值。迭代循环⒊求s=a+aa+aaa+…+aaa…a。0<a<10共n项,最后一项有n个a。如求s=2+22+222+2222+…+222…222n、a从键盘输入。迭代次数:i=1~n迭代初值:s=0.0,t=a迭代公式:t=t*10+a程序如下:#include<stdio.h>voidmain(void){floats,t;inti,a,n;

do{

scanf(“%d,%d”,&a,&n);if(a<1||a>9)printf(“\nDataInputError!\nInputagain:”);

}while(a<1||a>9);

s=0.0;t=a;

for(i=1;i<=n;i++)

{s+=t;t=t*10+a;}

printf(“\ns=%f”,s);}xyf(x)x1f1=f(x1)x2f2=f(x2)算法分析:①输入x1、x2,并求出f1、f2。②迭代:将区间二分 x=(x1+x2)/2计算出f=f(x)xf③判断f与f1是否同号如果同号:x1=x,f1=f否则:x2=x,f2=fx1f1f1f2④判断fabs(x1-x2)是否小于某个规定的精度(如10-6)

: 如果小于精度:求出根,退出到⑤。 否则:继续②。⑤输出根,根的值是(x1+x2)/2。⒋二分法求方程f(x)=x3-6x-1=0,在[0,5]区间的根。二分法求方程根程序#include<stdio.h>#include<math.h>voidmain(void){floatx1,x2,x,f1,f2,f;scanf(“%f,%f”,&x1,&x2);

f1=x1*x1*x1-6.0*x1-1;f2=x2*x2*x2-6.0*x2-1;

do{

x=(x1+x2)/2;f=x*x*x-6.0*x-1;if(f*f1>=0){f1=f;x1=x;}else{f2=f;x2=x;}

}while(fabs(x1-x2)>=1e-6);

printf(“Rootis:%f”,(x1+x2)/2);}CHAP3EXF迭代初值。二分迭代循环迭代条

温馨提示

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

评论

0/150

提交评论