程序基本结构_第1页
程序基本结构_第2页
程序基本结构_第3页
程序基本结构_第4页
程序基本结构_第5页
已阅读5页,还剩88页未读 继续免费阅读

下载本文档

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

文档简介

1、第二章 程序基本结构,引言,第一章中我们学习了顺序结构的C程序设计方法,但是实际应用中,很多问题仅有顺序结构的方法是无法解决的,算法,算法,问题1的算法,S1:输入3个整数,分别赋值给a,b,c S2: 如果ab, 则a b S3: 如果ac,则ac S4: 如果bc,则bc S5: 输出a,b,c的值,分支结构,输入a,b,c的值,a b,输出a,b,c的值,a c,bc,2.1关系运算和逻辑运算2.1.1 关系运算符和关系表达式,一、关系运算符 种: 、=、=、!= 说明: 1、优先级:前4种相同,后2种也相同,但前4种高于后两种;所有关系运算符的优先级都低于算术运算符而高于赋值运算符。

2、2、结合性:自左至右,ab-c,a(b-c,a=b=c,a=(b=c,a=b!=c,a=(b!=c,二、关系表达式 用关系运算符将两个表达式连接起来的式子。 其中被连接的表达式可以是算术表达式、关系表达式、逻辑表达式、赋值表达式或字符表达式。 如:a+bc+d、xy=c+d、aA,关系表达式的值只能是1或0,当表达式成立即为“真”时,值为整数1;否则为“假”,值为整数0。因此可看作整型表达式,假设a=3, b=2, c=1,求以下关系表达式的值: ab (ab)=c abc f=ab=c,1,1,0,1,2.1.2 逻辑运算符和逻辑表达式,一、逻辑运算符 种: (! + -)负类指针有地址,

3、(-, 类型转换, *, ( 从右至左)逗号不是停顿符, ( , )顺序求值得结果. (顺序求值运算符,C语言运算符的“优先级口决”2,括号成员第一; /括号运算符() 成员运算符.-全体单目第二; /所有的单目运算符比如+ - +(正) -(负) 指针运算* /注意顺序:优先级(|)底于 优先级( printf(Input a,b:); scanf(%d%d, /*按从小到大顺序输出 */,例2.1的C语言程序如下,复合语句:在同一个条件下作为一个整体执行的多条语句,例2.2输入三个数x1,x2,x3,按从小到大的顺序输出这三个数,include void main() int x1,x2,

4、x3,temp; scanf(“%d%d%d”,输入:3 5 1 输出:1,3,5,2.2.2 双分支结构,例2.3: 输入两个整数,输出其中较大的一个,算法: S1: 输入两个整数a,b S2: 如果ab,则输出a, 否则输出b,C语言单分支结构: if (表达式) 语句1; else 语句2,一般形式,if (表达式) 语句1 else 语句2,流程图,例2.3 输入两个整数,输出其中较大的一个,N-S流程图,include void main() int x1,x2; scanf(“%d%d”,判断某年是否闰年?若是,输出XXXX年是闰年,若不是,输出XXXX年不是闰年,提示:闰年的判断

5、,能被4整除不能被100整除,或者能被400整除的都是闰年,2.2.3 多分支结构一、if语句嵌套,一般形式,流程图,if (表达式1) 语句1 else if (表达式2) 语句2 else if (表达式3) 语句3 else if (表达式n) 语句n else 语句n+1,关于if语句的说明,1、表达式一般为关系表达式或逻辑表达式。但在C语言中它也可以是任意的数值表达式,if (3) n=1,if (a) printf(%d, a,if (n=3-3) x=1; else x=-1,2、表达式后面不能有任何标点符号,3、else只能与if配对使用。仅else本身不能单独作为一个语句使用

6、,if (x5); y=x; else y=2*x-1,if (x5) ; y=x; else y=2*x-1,将出现语法错误,4、每个语句序列可以是一个语句也可以是若干个语句,但要用花括号括起来构成复合语句,if (ab) t=a; a=b; b=t;,if (a+bc,复合语句的花括号后不能再写分号。复合语句在语法上是一个整体,相当于一个语句,5、if语句的嵌套,在if语句的原“语句”中又包含一个或多个if语句,1. if (表达式1) if (表达式2) 语句,2. if (表达式1) 语句1 else if (表达式2) 语句2,3. if (表达式件1) 语句1 else if (表

7、达式2) 语句2 else 语句3,4. if (表达式1) if (表达式2) 语句1 else 语句2,二义性,语言规定:else总是与它前面最近的且未曾配对的if配对,if (表达式1) if (表达式2) 语句1 else 语句2,if (表达式1) if (表达式2) 语句1 else 语句2,例2.4 输入3个数,判断组成什么类型三角形,if(a+b)c,例2.5 编程求解函数,程序1: if (x0) y=-1; else if (x=0) y=0; else y=1,程序2: if (x=0) if (x0) y=1; else y=0; else y=-1,eg502.c,程

8、序3: y=0; if (x!=0) if (x0) y=1; else y=-1,例: 求一元二次方程ax2+bx+c=0的根,a,b,c由键盘输入,分析:对于一元二次方程有以下几种可能: a=0,不是二次方程; b2-4ac=0,有两个相等的实根; b2-4ac0,有两个不等的实根; b2-4ac0,有两个共轭复数根,例2.6 求一元二次方程ax2+bx+c=0的根,a,b,c用键盘输入,include void main() float a,b,c,d,x1,x2,realpart,imagpart; scanf(“%f%f%f”,a,b,c); if(fabs(a)1e-6,x1=(-

9、b+sqrt(disc)/(2*a); x2=(-b-sqrt(disc)/(2*a); printf(“has distinct real roots:%f,%fn”,x1,x2); else realpart=-b/(2*a); imagepart=sqrt(-disc)/(2*a); printf(“%f+%fin”,realpart,imagpart); pritnf(“%f-%fin”,realpart,imagpart);,1、条件运算符: ? :(C中唯一的三目运算符) 优先级仅高于赋值类,右结合性,2、条件表达式的一般形式: 表达式1?表达式2:表达式3,运算过程:首先求表达式

10、1的值,若为真(非0),则求表达式2的值,且整个表达式的值为表达式2的值;若表达式1为假(0),则求表达式3的值,且整个表达式的值为表达式3的值,二、条件运算符,2)右结合性,3)“表达式1?表达式2:表达式”中,表达式2和表达式3不仅可以是数值表达式,还可以是赋值表达式或函数表达式 例如: ab?(a=100):(b=100) ab?printf(“”%dn”,a):printf(“%dn”,b,4)表达式1、表达式2和表达式3的类型都可以不同。表达式值的类型是表达式2、3中类型较高的类型。 例如:xy?1:1.5 表达式值是double类型,1)优先级高于赋值,低于关系运算符和算数运算符,

11、例:x= ab? a:b+1,x= (ab)? a:(b+1,ab? a : cd? c : d,ab? a : (cd? c : d,if (ab) x=a; else x=b+1,例2.7:输入一个字符,如果是大写字母,转换为小写,如果不是不转换。最后输出,include void main() char ch; scanf(“%c”,*/,三、 switch(多分支)语句,switch结构与else if结构是多分支选择的两种形式。 else if: 多条件并列测试,从中选一 switch: 单条件测试,从多种结果中选取一种执行,1、格式,switch(表达式) case 常量表达式1:

12、 语句组1;break; case 常量表达式2: 语句组2;break; case 常量表达式n: 语句组n;break; default: 语句 组n+1,2、功能: 先计算表达式的值,测试该值是否与某常量表达式的值相同 、若有相同者,流程转向其后面的语句执行 、若无,再看有没有default部分:若有default,则执行其后面的语句;若无default,则switch语句什么也不做,流程转向其后继语句,说明,1、switch后面括号内的表达式可以是整型,也可以是字符型 2、各个case后常量表达式的值必须互不相同; 3、各个case和default的出现次序不影响执行结果; 4、cas

13、e后的语句为复合语句时可省略花括号,例: #include void main ( ) int x, y ; scanf(“%d”,5、case后常量表达式只起语句标号的作用,每个case之后通常都有一个break,使流程跳出switch语句,否则流程转到下一个case(default)中继续执行,6、多个case可以共用一组执行语句,case 6 : case 7 : printf(Resetn); break,但不能写成:case 6,7: printf(Resetn); break,7、switch语句可以嵌套;但有多层switch语句时,break只能退出本层的switch语句体,举例

14、: 在学生成绩管理中,成绩经常要在百分制与等级制之间进行转换。90分以上为A等,80-89为B等,70-79为C等,60-69分为D等,其余为E等。编制程序,根据输入的百分制,输出对应的等级,void main() int score; printf(Input score of student:); scanf(%d,void main( ) int score,temp; printf(Input score of student:); scanf(%d,break,简单选择界面的编程。从键盘输入整数,输出不同的字符串: 输入1,输出Good morning; 输入2,输出Good aft

15、ernoon; 输入3,输出Good evening; 输入4,输出Good night; 输入其它数字,输出Bye-bye,算法,2.3 循环结构,2.3.1 循环结构的引出,问题2的算法,算法1:直接写出算式 S1: result=1+2+3+4+5+100,容易实现吗,算法2: 考虑到1+2+3+100可以改写为:(1+2)+3)+100) S1: p1=1+2 S2: p2=p1+3 S3: p3=p2+4 S99: p99=p98+100,结果在p99里,定义99个变量,容易实现吗,注意观察:每一步都类似,算法3: S0: p=0, i=1 S1: p=p+i, i=i+1 S2:

16、p=p+i, i=i+1 S3: p=p+i, i=i+1 S99: p=p+i, i=i+ 1 S100: p=p+i, i=i+ 1,完全一样的99步,算法4: S0: p=0, i=1(循环初值) S1: p=p+i, i=i+1(循环体) S2: i=100,则返回重新执行步骤S1及S2;否则,算法结束(循环控制,循环结构,循环控制结构一般由四部分组成: 、进入条件 、退出条件 、循环体:循环体需要完成的功能(需要重复执行的语句) 、循环变量的修正,根据进入条件和退出条件,循环控制结构可以分为三种形式: 、while结构:退出条件是进入条件的反条件。即满足 条件时进入,重复执行循环体直

17、到进入的条件不再满足为止。 、do-while结构:无条件进入,执行一次循环体后再判断是否满足再进入循环的条件。 、for结构:与while结构类似,但结构更紧凑。适用于循环之前循环次数就已经确定的情况,使用形式: while(表达式) 语句,特点: 先判断表达式, 后执行语句,2.3.2 while 语句,例:求1+2+3+100,i=1,sum=0,i=100,sum=sum+i i=i+1,假,真,void main(),int i, sum,i=1; sum=0,while (i=100) sum=sum+i; i+;,printf (“sum=%dn”, sum,注意:while起作

18、用的范围,注意:要有改变循环结束条件的语句,void main(),int i, n, sum,i=1; sum=0,while (i=n) sum=sum+i; i+;,printf (“sum=%dn”, sum,计算 1+2+3+n(n为任意正整数,scanf(%d,思考问题: 循环结束后循环变量的值是多少,void main(),int i , n, sum,i=1; sum=0,while (i=n) sum=sum+i; i=i+2;,printf (“sum=%dn”, sum,scanf(%d,计算 1+3+5+7+n(n为奇数,例:输入一个字符,如果是大写字母,转换为小写,如

19、果不是则不转换。输入“0”结束程序,include void main() char ch; while(ch=getchar()!=0) ch=(ch=A,2.3.3 do-while 语句,使用形式: do 循环体语句 while(表达式,特点: 先执行循环体语句, 后判断表达式,注意:、循环部分为多个语句时,必须用大括号构成复合语句;、循环体中应有使循环趋于结束的语句,例:求1+2+3+100,int i, sum,i=1; sum=0,do sum=sum+i; i+; while (i=100,printf (“%dn”, sum,void main(),while 和 do-whi

20、le 循环的比较(?不同之处,main() int sum=0, i; scanf (“%d”,main() int sum=0, i; scanf (“%d”,2.3.4 for 语句,一般形式: for(表达式1;表达式2;表达式3) 语句,一般使用格式: for(循环变量赋初值;循环条件表达式;循环变量修正值) 循环体,执行过程: (1)求解表达式1 (2)求解表达式2,若其值为真(值为非0),则执行for语句中指定的内嵌语句,然后执行(3)。若为假(值为0),则结束循环,转到(5)。 (3)求解表达式3 (4)转回执行(2) (5)循环结束,执行for语句下面的一个语句,for(表达式

21、1;表达式2;表达式3) 语句,例:求1+2+3+100,void main( ) int i,sum=0; for(i=1;i=100;i+) sum=sum+i; printf(“%d”,sum);,循环变量赋初值,循环条件,循环变量修正,循环体,例:计算某个班英语成绩的平均分, 学生人数和每个学生的成绩由键盘输入,void main() int i,n; float s,sum,ave; sum=0; for ( i=1; i=n ; i+ ) ave=sum/n; printf(“ave is %f”,ave);,scanf(%d,scanf(%d,想想这条语句是否能放到循环体内,fo

22、r语句的三个表达式都可以缺省,但两个分号不能缺省,如果在for语句之前已经给循环变量赋初值,则for语句的循环变量赋初值部分可以省略,但其后得分号不省略,也可以将循环变量修正值的工作纳入到循环体中去做,说明,i=1; for ( ; i=10; i+) m=m*i,如,for (i=1; i=10; ) m=m*i; i,如,也可以省略for语句的第一和第三部分,i=1; for( ; i=10; ) m=m*i ; i,如,for ( ; ;,但是注意不能两处同时修正值,通常不缺省表达式2;有时缺省表达式2,此时不判断循环条件,循环将无终止的执行,即认为表达式2始终为真;在循环体内用if和b

23、reak控制循环结束,for (i=1; ; i+) if (条件) break; sum=sum+i;,如果有多个循环变量赋初值,或多个循环变量值要修正,应在各变量之间用逗号隔开,for(i=1, j=10; i=j; i+, j- -) k=i+j,如,循环条件表达式一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,每次系统判断该表达式的结果不为0,就执行一遍循环体,for(m=0;( c=getchar( ) ) != !;) m=m+c,如,考虑问题:运行程序时如何停止循环,for、while、dowhile的互相转化,i=1;sum=0; do sum=sum+i; i

24、+; while(i=100,for (i=1; i=100; i+) sum=sum+i,i=1; sum=0; while(i=100) sum=sum+i; i+;,输出所有的水仙花数。 (水仙花数就是一个三位数,这个数正好等于该数的每一位的立方和。 例如: 153=1*1*1+5*5*5+3*3*3,void main() for() a=i/100; c=i%10;,补充:循环的嵌套,一个循环体内又包含另一个完整的循环结构,称为循环嵌套。内层的循环中还可以嵌套循环,构成多重循环,while ( ) while ( ),for ( ; ; ) for ( ; ; ),do do whi

25、le ( ); while (,while ( ) for ( ; ; ),for ( ; ; ) do while( );,while ( ) do while( );,例:输出如图所示的矩形,* * * * * * * * * * * * * * * * * *,void main( ) printf(*n); printf(*n); printf(*n); printf(*n);,void main( ) int i, j ; i=1; while (i=4),while ( j=5 ) printf(“*”); j+;,j=1,printf(“n”); i,include void m

26、ain( ) int i , j ; i=1; while (i=4) for (j=1; j=5;j+) putchar(*); putchar(n); i+;,include void main( ) int i , j ; for ( i=1; i=4; i+) for (j=1; j=5; j+) putchar(*); putchar(n);,例:输出如图所示的矩形,* * * * * * * * * * * * * * * * * *,内外层循环的循环控制变量不能重名,例:输出如图所示的三角形,* * * * * * * *,特点:第i行有i个星号,include void mai

27、n( ) int i , j ; for( i=1; i=4; i+) for (j=1; ; j+) putchar(*); putchar(n);,j=i,例:输出如图所示的等腰三角形,* * * * * * * * * * * * * *,特点:一共有4行,第i行有2i-1个星号;第i行的第1个星号前有4-i个空格,include main( ) int i , j ; for( i=1; i=4; i+) for (j=1; j=4-i; j+) putchar(32); for (j=1; j=2*i-1; j+) putchar(*); putchar(n);,例:输出如图所示的菱

28、形,* * * * * * * * * * * * * * * * * * * * * * *,分析: 将图形分为上下两部分分别输出,* * * * * * * * * * * * * * * * * * * * * * *,for ( i=1; i=4 ; i+) for ( j=1; j=4-i ; j+) putchar( ); for ( k=1; k=2*i-1 ; k+) putchar(*); putchar(n);,for ( i=3; i=1 ; i- -) for ( j=1; j=4-i ; j+) putchar( ); for ( k=1; k=2*i-1 ; k+)

29、 putchar(*); putchar(n);,几种循环的比较,C语言中的三种循环结构都由表达式控制执行一个循环体,一般情况下可以相互代替; 、用while和do-while循环时,循环变量初始化的操作应在while和do-while语句之前完成;而for语句一般在表达式1中实现循环变量的初始化; 、当循环次数及控制条件要在程序运行过程中确定时,选用while或do-while语句; 、在初值、增量及控制条件明显,或循环次数已经给定的情况下,选用for语句,在循环的执行过程中,应不断的改变循环控制表达式的值,以便逐步形成使它为0的条件,否则将可能出现死循环,三种循环可以相互嵌套,形成多重循环

30、,外循环可以包含多个或多重内循环,循环之间可以并列但不能相交,并列的循环控制变量可以同名,但嵌套的循环控制变量不能同名; 、不允许用其它的控制语句把程序流程从循环体外转入循环体内,但必要时可以用break、goto等语句把流程从循环体内转到循环体外,2.4 break和continue语句2.4.1 break语句,1、格式,break,2、功能: 中止当前循环语句或switch语句的执行,3、说明: 、若是多重循环,break只能使流程跳出离break最近的一层; 、break只用于switch语句和循环语句,case 6 : case 7 : printf(Resetn); break,例

31、2.14:计算 r=1到 r=10时的圆面积,直到面积大于100为止,include void main( ) float r, area; for (r =1; r 100) break; printf(%6.2fn, area);,输出结果: 3.14 12.56 28.26 50.24 78.50,2.4.2continue语句,1、格式,continue,2、功能: 提前结束本次循环体的执行(不再执行循环体中continue后面的语句),接着进行下一次是否执行循环的判定,3、说明: 、continue语句只能用于循环语句中,它是一种具有特殊功能的转移语句; 、continue与brea

32、k不同:continue语句只结束本次循环,而不是终止整个循环的执行;而break语句则结束整个循环,不再判断循环条件是否成立,例2.15:把10到20之间能被3整除的数输出,include void main( ) int n; for (n=10; n=20; n+) if (n%3!=0) continue; printf(%d , n); printf(“n%dn”,n),break,12 15 18 21,10,while ( ) break;,while ( ) continue;,经典问题:判断素数,素数是除了1和它自身不能被任一个数整除的数,算法提示:1、可以让除数从2n1逐个

33、去除该数n,判断是否被其中的任何一个整数整除,如果是,则说明不是素数。如果一直都没有出现过整除现象,则说明该数是素数,for(i=2;i=n) printf(“ %d is sushu!”,n,判断素数,算法改进1:可以定义一个标志变量,判断起来很方便,flag0; for(i=2;in;i+) if(n%i=0) flag=1; break; if(flag=0) printf(“ %d is sushu!”,n,判断素数,算法改进2:可以进一步减少循环次数。循环的终止条件可缩小为n/2,或,k=n/2; 或 k= for(i=2;i=k+1) printf(“ %d is sushu!”,

34、n,例:打印3100之间的全部素数,for (m=3; m=100; m+=2),k=sqrt(m); for (i=2; i=k; i+) if (m%i=0) break;,if (i= ) printf(%-5d,m,k+1,void main() int i,k,m;,判断n是否素数,补全程序,main() int i, n, flag=0; for(i=2; _; i+) if ( _ ) flag=1; if ( _ ) printf(“是素数n”);,in,n%i=0,flag=0,经典算法一(穷举法):百鸡百钱问题,一只公鸡值5元,一只母鸡值3元,三只小鸡值1元,总共有100元

35、钱要买一百只鸡,问有多少种方案,include void main( ) int x,y,z; printf(* 百鸡问题 *n); for (x=1;x20;x+) for (y=1;y33;y+) for (z=3;z100;z+=3) if (5*x+3*y+z/3=100,程序使用了三层循环来解决问题,程序结构简单明了。但是我们设计程序不仅要正确无误,还要注意程序的执行效率。 一般来说,在循环嵌套中,内层循环执行的次数等于该循环嵌套结构中每一层循环重复次数的乘积。 例如,上面的程序中,外层每循环一次,第二层要循环32次,而第三层要循环32*33=1056次。这样程序执行下来,最内层的i

36、f语句要执行19*32*33次。所以我们在编写程序时,需要考虑尽可能的减少循环执行的次数,特别是循环的嵌套,对于“百鸡问题”,由方程组:x+y+z=100,5x+3y+z/3=100可以导出: x=4z/3-100 y=100-x-z这样就只有z一个未知数,如果知道了z就可以求出x值,进而求出y值。因此我们只要将z作为循环变量就可以了,include void main() int x,y,z; printf(“* 百鸡问题 *n”); for (z=3;z100;z+=3) x=4*z/3-100; y=100-x-z; if (5*x+3*y+z/3=100,尽管每次循环执行的语句增多了,但是循环次数只有33次,运行效率大大提高,从上面的分析可以看到,一个好的算法可以提高程序的执行效率,但是要设计出一个好的算

温馨提示

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

评论

0/150

提交评论