第六部分 循环控制

52
1 第第第第 第第第第

description

第六部分 循环控制. 第六章 循环控制. 0x1C. 0x18. 0x14. 0x10. 0x0C. 0x08. 0x04. 0x00. 提纲. goto. 1. while. 2. 3. do while. FIQ. IRQ. 4. (Reserved). for. Data Abort. Prefetch Abort. 5. 循环嵌套. Software Interrupt. Undefined Instruction. Reset. 概述 C 语言可实现循环的语句: - PowerPoint PPT Presentation

Transcript of 第六部分 循环控制

Page 1: 第六部分      循环控制

1

第六部分 循环控制

Page 2: 第六部分      循环控制

2

提纲

4444

5555

do while

第六章 循环控制

FIQ

IRQ

(Reserved)

Data Abort

Prefetch Abort

Software Interrupt

Undefined Instruction

Reset

0x1C

0x18

0x14

0x10

0x0C

0x08

0x04

0x00

1111

3333

2222 while

goto

for

循环嵌套

Page 3: 第六部分      循环控制

3

概述C 语言可实现循环的语句:

– 用 goto 和 if 构成循环– while 语句– do ~ while 语句– for 语句

goto 语句及用 goto 构成循环goto 语句一般格式:

标号:语句; …….. goto 语句标号; ….…..

6.1 概述

Page 4: 第六部分      循环控制

4

功能:无条件转移语句说明:

不能用整数作标号只能出现在 goto 所在函数内 , 且唯一只能加在可执行语句前面限制使用 goto 语句

Page 5: 第六部分      循环控制

5

例用 if 和 goto 语句构成循环,求

100

1n

n

/*ch5_1.c*/#include <stdio.h>main(){ int i,sum=0; i=1;loop: if(i<=100) { sum+=i;

i++; goto loop;

} printf("%d",sum);}

sum=0+1sum=1+2=3sum=3+3=6sum=6+4……sum=4950+100=5050

循环初值

循环终值循环变量增值

循环条件

循环体

Page 6: 第六部分      循环控制

6

例 从键盘输入一组数据,以 0 结束输入,求数据和

/*ch5_11.c*/#include <stdio.h>main(){ int number,sum=0;read_loop: scanf("%d",&number);

if(!number) goto print_sum; sum+=number; goto read_loop;

print_sum: printf("The total sum is %d\n",sum);}

Page 7: 第六部分      循环控制

7

一般形式:

while( 表达式 ) 循环体语句;

执行流程:

expr

循环体

假 (0)

真 ( 非0)

while

while 语句

Page 8: 第六部分      循环控制

8

特点:先判断表达式,后执行循环体说明:

循环体有可能一次也不执行循环体可为任意类型语句下列情况,退出 while 循环

条件表达式不成立(为零)循环体内遇 break,return,goto

无限循环 : while(1) 循环体 ;

Page 9: 第六部分      循环控制

9

例 用 while循环求

100

1n

n

/*ch5_2.c*/#include <stdio.h>main(){ int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum);}

循环初值

循环终值循环变量增值

循环条件

循环体

Page 10: 第六部分      循环控制

10

例 显示 1~10 的平方

/*ch5_21.c*/#include <stdio.h>main(){ int i=1; while(i<=10) { printf("%d*%d=%d\n",i,i,i*i); i++; }}

运行结果:1*1=12*2=43*3=94*4=165*5=256*6=367*7=498*8=649*9=8110*10=100

Page 11: 第六部分      循环控制

11

do~while 语句一般形式:

do 循环体语句; while( 表达式 );执行流程

do

循环体

expr

假 (0)

真 ( 非 0)while

Page 12: 第六部分      循环控制

12

特点:先执行循环体,后判断表达式说明:

至少执行一次循环体do~while 可转化成 while 结构

expr

循环体

假 (0)

真 ( 非0)

循环体While 循环

Page 13: 第六部分      循环控制

13

例 用 do~while 循环求

100

1n

n

/*ch5_3.c*/#include <stdio.h>main(){ int i,sum=0; i=1; do { sum+=i;

i++; }while(i<=100); printf("%d",sum);}

Page 14: 第六部分      循环控制

14

例 while 和 do~while 比较

/*ch5_4.c*/#include <stdio.h>main(){ int i,sum=0; scanf("%d",&i); do { sum+=i;

i++; }while(i<=10); printf("%d",sum);}

main(){ int i,sum=0; scanf("%d",&i); while(i<=10) { sum+=i;

i++; } printf("%d",sum);}

Page 15: 第六部分      循环控制

15

for 语句 一般形式:

for([expr1] ;[ expr2] ;[ expr3]) 循环体语句;

执行流程:

expr2

循环体

假 (0)

真 ( 非0)

for

expr1

expr3

Page 16: 第六部分      循环控制

16

for 语句一般应用形式:for( 循环变量赋初值;循环条件;循环变量增值 ){

循环体语句;}

说明:for 语句中 expr1, expr2 ,expr3 类型任意,都可省略,但分号;不可省无限循环 : for(;;)for 语句可以转换成 while 结构

expr1;while(expr2){

循环体语句;expr3;

}

例 用 for 循环求

#include <stdio.h>main(){ int i,sum=0; for(i=1;i<=100;i++) sum+=i; printf("%d",sum);}

Page 17: 第六部分      循环控制

17

例: #include<stdio.h> main( ) { int i=0; for(i=0;i<10;i++) putchar(‘a’+i); }

运行结果: abcdefghij

例: #include<stdio.h> main( ) { int i=0; for(;i<10;i++) putchar(‘a’+i); }

例: #include<stdio.h> main( ) { int i=0; for(;i<10;) putchar(‘a’+(i++)); }

例: #include<stdio.h> main( ) { int i=0; for(;i<10;putchar(‘a’+i),i++) ; }

Page 18: 第六部分      循环控制

18

main(){ int i,j,k; for(i=0,j=100;i<=j;i++,j--) { k=i+j;

printf("%d+%d=%d\n",i,j,k); }}

#include<stdio.h>main(){ char c; for(;(c=getchar())!='\n';) printf("%c ",c);}

#include <stdio.h>main(){ int i,c; for(i=0;(c=getchar())!='\n';i+=3)

printf("%c ",i+c);}

Page 19: 第六部分      循环控制

19

例 ( for) 梯形法求数值积分

0

y

xa a+h a+ih a+(i+1)h b

f(x)

Page 20: 第六部分      循环控制

20

三种循环可互相嵌套 ,层数不限外层循环可包含两个以上内循环 ,但不能相互交叉嵌套循环的执行流程

(1) while() { …… while() { …… } …... }

(2) do { …… do { …… }while( ); …... }while( );

(3) while() { …… do { …… }while( ); ……. }

(4) for( ; ;) { …… do { …… }while(); …… while() { …… } …...}

内循环

外循环

内循环

嵌套循环的跳转禁止:

从外层跳入内层跳入同层的另一循环向上跳转

循环的嵌套

Page 21: 第六部分      循环控制

21

例 循环嵌套,输出九九表

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

2 4 6 8 10 12 14 16 18

3 6 9 12 15 18 21 24 27

9 18 27 36 45 54 63 72 81

……………..

i

j

/*ch5_5.c*/#include <stdio.h>main(){ int i,j; for(i=1;i<10;i++) printf("%4d",i); printf("\n---------------------------------------\n"); for(i=1;i<10;i++) for(j=1;j<10;j++)

printf((j==9)?"%4d\n":"%4d",i*j);}

Page 22: 第六部分      循环控制

22

i<10

printf

假 (0)

真 ( 非0)

i=1

j++

j=1

j<10真 ( 非

0)

假 (0)

i++

for(i=1;i<10;i++) for(j=1;j<10;j++) printf((j==9)?"%4d\n":"%4d",i*j);

外循环

内循环

Page 23: 第六部分      循环控制

23

break 语句

功能:在循环语句和 switch 语句中 , 终止并跳出循环体或开关体

说明:–break 只能终止并跳出最近一层

的结构–break 不能用于循环语句和 switc

h 语句之外的任何其它语句之中

break 和 continue

Page 24: 第六部分      循环控制

24

expr

……

break;

……

假 (0)

真 ( 非0)

while do

……

break;

…...

expr

假 (0)

真 ( 非 0)while

Page 25: 第六部分      循环控制

25

expr2

……

break;

…...

假 (0)

真 ( 非0)

for

expr1

expr3

switch

expr

语句组 1

break;

语句组 2

break;

语句组n

break;

语句组

break;

…...

const 1 const 2 const n default

case

Page 26: 第六部分      循环控制

26

例 break 举例:输出圆面积,面积大于 100 时停止。

#define PI 3.14159main(){ int r; float area; for(r=1;r<=10;r++) { area=PI*r*r; if(area>100)

break; printf("r=%d,area=%.2f\n",r,area); }}

Page 27: 第六部分      循环控制

27

例 break 举例:小写字母转换成大写字母 , 直至输入非字母字符

#include <stdio.h>main(){ int i,j; char c; while(1) { c=getchar();

if(c>='a' && c<='z') putchar(c-'a'+'A');

else break;

}}

Page 28: 第六部分      循环控制

28

功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断

仅用于循环语句中

expr

……

continue;

……

假 (0)

真 ( 非0)

while

真 ( 非 0)

do

……

continue;

…...

expr假(0)

while

expr2

……

continue;

…...

假 (0)

真 ( 非0)

for

expr1

expr3

continue 语句

Page 29: 第六部分      循环控制

29

例 求输入的十个整数中正数的个数及其平均值/*ch5_12.c*/#include <stdio.h>main(){ int i,num=0,a; float sum=0; for(i=0;i<10;i++) { scanf("%d",&a);

if(a<=0) continue;num++;sum+=a;

} printf("%d plus integer's sum :%6.0f\n",num,sum); printf("Mean value:%6.2f\n",sum/num);}

Page 30: 第六部分      循环控制

30

t=1,pi=0,n=1.0,s=1

当 |t|1e-6

pi=pi+t

n=n+2

s=-s

t=s/n

pi=pi*4

输出 pi

分子: 1 , -1 , 1 , -1…分母: 1 , 3 , 5 , 7 , ...

6

1 1 11

4 3 5 7

10

例用 公式求 的近似值,直到

最后一项的绝对值小于 为止

Page 31: 第六部分      循环控制

31

/*ch6_6.6.c*/#include <studio.h> #include <math.h>main() {float pi=0.0,n=1.0,s=1.0,t;

do {t=s/n; pi+=t; s*=-1.0; n+=2; } while (fabs(t)>=1e-6);

printf(“pi=%f\n”,4*pi);}

例 5:/4=1-1/3+1/4-1/5+…±1/n ( 精度要求为 1/n 的绝对值 <1e-6) 。

Page 32: 第六部分      循环控制

32

例 求 Fibonacci 数列: 1 , 1 , 2 , 3 , 5 , 8 ,……的前 40个数

f1=1,f2=1

for i=1 to 20

输出 f1,f2

f1=f1+f2f2=f2+f1

15

34233

15971094675025

5142293524578

24157817

18

55377

258417711

121393832040

570288739088169

21389

6104181

28657196418

13462699227465

63245986

321

144987

676546368

3178112178309

14930352102334155

1 2

1 1 ( 1)

2 1 ( 2)

( 3)n n n

F n

F n

F F F n

Page 33: 第六部分      循环控制

33

Ch5_12.c

/*ch6_6.7.c*/#include <stdio.h>main() {long int f1,f2; int i; f1=f2=1;printf(“\n”); for(i=1;i<=20;i++) {printf(“%12Ld%12Ld”,f1,f2); if(i%2==0) printf(“\n”); f1=f1+f2; f2=f2+f1; } }

例 2. 求 Fibonacci 数列前 40 个数。

Page 34: 第六部分      循环控制

34

例 判断 m 是否素数

读入 m

k=m

i=2

当 ik

m 被 i 整除真 假

用 break结束循环

i=i+1

ik+1真 假

输出 :m” 是素数”输出 :m” 不是素数”

Page 35: 第六部分      循环控制

35

/*ch6_6.8.c*/#include <stdio.h>main(){ int prime; unsigned int num; printf(“Input a positive integer:”); scanf(“%d”,&num); for(prime=2; prime<num; prime++) if(num%prime==0) break; if(prime==num) printf(“%5d is a prime.\n ”,num); else printf(“%5d is note a prime.\n ”,num);}

例 2. 输入一个正整数 num, 判断是否是素数。

Page 36: 第六部分      循环控制

36

/*ch6_6.9.c*/#include <stdio.h>#include<math.h>main() {int m,k,i,n=0; for(m=101;m<=200;m+=2) {k=sqrt(m); for(i=2;i<=k;i++) if(m%i==0)break; if(i>=k+1) {printf(“%5d ”,m);n++;} if(n%10==0)printf(“\n”); } printf(“\n”); }

例 2. 求 100 ~ 200 间的全部素数。

Page 37: 第六部分      循环控制

37

例 译密码

例如 Hello,world!译成密码: Lipps,asvph!

Page 38: 第六部分      循环控制

38

/*ch6_6.10.c*/#include <stdio.h>main() {char c; while((c=getchar())!=‘\n’) {if(c>=‘a’&&c<=‘z’)||(c>=‘A’&&c<=‘Z’)) {c=c+4; if(c>’Z’&&c>’Z’+4)||c>’z’)c=c-26; } printf(“%c”,c); } }

例 : 译密码。 (P119 页 )

Page 39: 第六部分      循环控制

39

#include <stdio.h>/* program to reverse the digits of a number.*/#include <studio.h> main() {int number,right_digit; printf(“Please enter your number:\n”); scanf(“%d”,&number); do {right_number=number%10; printf(“%d”, right_digit); number=number/10 ; } while (number!=0) printf(“\n”); }

例 : 求从终端输入一个数字串 , 然后以逆序在终端上显示出来。

Page 40: 第六部分      循环控制

40

#include <stdio.h>main(){char c;

do {c=getchar(); if(c>=‘a’&&c<=‘z’) c+=‘A’-’a’; putchar(c); } while (c!=EOF);

}

例 : 从终端输入一个字符 , 然后将小写字母转换成大写字母输出 ; 当读到文件结束标志 EOF( 在 studio.h 中定义 , 是 Ctrl_z 或 Ctrl_d 或 -1) 时 , 程序结束。

Page 41: 第六部分      循环控制

41

#include <stdio.h>main() {int x,max,min; scanf(“%d”,&x); max=min=x; for(;x!=0;) {if(x<min)min=x; if(x>max)max=x; scanf(“%d”,&x); } printf(“max=%d,min=%d\n”,max,min); }

例 : 从键盘输入若干整数 , 求其中的最大数和最小数。输入的数以 0 为中止标记。

Page 42: 第六部分      循环控制

42

scanf(“%d”,&x); i=1;for(;i<=x;) {if(x%i==0)printf(“%3d”,i); i++; }例 :鸡兔共有 30 只 ,脚共有 90 个 ,问鸡兔各多少的程序片段。 for(x=1;x<=29;x++) {y=30-x; if(2*x+4*y==90) printf(“%d,%d”,x,y); }

例 : 下面程序段是找出整数的所有因子。

Page 43: 第六部分      循环控制

43

#include <stdio.h>main(){ int int i,double e,new; e=1.0; new=1.0; for(i=1;new>=1e-6;i++) { new/=(double)i; e+=new; } printf(“e=%f\n”,e);}

例 :e=1+1/1!+1/2!+1/3!... 求 e 的近似值 , 精度要求为 1e-6 。

Page 44: 第六部分      循环控制

44

例如 :1^3=1;2^3=3+5;3^3=7+9+11 。要求程序对每个输入的自然数计算并输出相应的连续奇数 , 直到输入的自然数为 0 止。#include <studio.h>main(){ int i,n,k,k1,m; scanf(“%d”,&n); while(n!=0) {k1=1; do{ k=k1;m=0; for(i=1;i<=n;i++) {m=m+k;k=k+2;} if(m==n*n*n)break; else k1=k1+2; }while(1); for(i=1;i<=n;i++) {printf(“%d ”,k1);k1+=2;} printf(“\n”); scanf(“%d”,&n); }}

例 :编一个程序验证下列结论 : 任何一个自然数 n 的立方等于 n个连续奇数之和。

Page 45: 第六部分      循环控制

45

#include <stdio.h>main() {int i,j,k,count=0; for(i=1;i<=9;i++) for(j=0;j<=9;j++) if(i==j)continue; else for(k=0;k<=9;k++) if(k!=i&&k!=j) count++; printf(“count:%5d\n ”,count);}

应用举例 : 若用 0 至 9之间不同的三个数构成一个三位数 , 下面程序将统计出共有多少种方法。

Page 46: 第六部分      循环控制

46

#include <stdio.h>/*解一 : ▲需 50 分钟 */main() {int x,y,z; printf(“\n%14s%14s%14s\n”,”公鸡” ,” 母鸡” ,”小鸡” ) for(x=1;x<=100;x++) for(y=0;y<=100;y++) for(z=0;z<=100;z++) if(x+y+z==100&&5*x+3*y+z/3==100) printf(“%15d%15d%15d\n ”,x,y,z);} 公鸡 母鸡 小鸡 0 25 75 4 18 78 8 11 81 12 4 84

例 :百钱买百鸡问题。“鸡翁一值钱五 ;鸡母一 , 值钱三 ;鸡雏三 , 值钱一。百钱买百鸡 ,问鸡翁、母、雏各几何 ?“设 x 为公鸡数 ,y 为母鸡数 ,z 为小鸡数。根据题意 :( 不定方程求解问题 ,找出所有解 ) 。 x+y+z=100 5x+3y+z/3=100

Page 47: 第六部分      循环控制

47

/*ch6_12.c*/#include <stdio.h>main(){ int x,y,z; printf(“\n%14s%14s%14s\n”,”公鸡” ,” 母鸡” ,”小鸡” ) for(x=1; x<=20; x++) for(y=0; y<=33; y++) for(z=0; z<=100-x-y; z++) if(x+y+z==100&&5*x+3*y+z/3==100) printf(“%15d%15d%15d\n ”,x,y,z);}公鸡 母鸡 小鸡 0 25 75 4 18 78 8 11 81 12 4 84

例 :百鸡百钱问题解二 : ▲需 4 分钟。

Page 48: 第六部分      循环控制

48

/*ch6_12.c*/#include <stdio.h>main() {int x,y,z; printf(“\n%14s%14s%14s\n”,”公鸡” ,” 母鸡” ,” 小鸡” ) for(x=1; x<=20; x++) for(y=0; y<=33; y++) { z=100-x-y; if(5*x+3*y+z/3==100) printf(“%15d%15d%15d\n ”,x,y,z); } }公鸡 母鸡 小鸡 0 25 75 4 18 78 8 11 81 12 4 84

例 :百鸡百钱问题解三 : ▲需 4秒钟。

Page 49: 第六部分      循环控制

49

/*ch6_12.c*/#include <stdio.h> main() {int i,j; for(i=4;i>=1;i--) {for(j=1;j<=i;j++) putchar(‘C’); for(j=1;j<=4-i;j++) putchar(‘D’); putchar(‘\n’); } }

例 : 输出如下图形。CCCC CCCD CCDD CDDD

Page 50: 第六部分      循环控制

50

/*ch6_12.c*/#include <stdio.h>main() {int i,j; for(i=0;i<=3;i++) {for(j=0;j<=5;j++) {if(i==0||j==0||i==3||j==5) printf(“*”); else printf(“ ”); } printf(“\n”); } }

例 : 输出如下图形。******* ** *******

Page 51: 第六部分      循环控制

51

/*ch6_12.c*/#include <stdio.h>void main(){int i,j,k; for(i=0;i<=3;i++) { for(j=0;j<=40-i;j++) printf(" "); for(k=0;k<=2*i;k++) printf("*"); printf("\n"); } for(i=0;i<=2;i++) { for(j=0;j<=38+i;j++) printf(" "); for(k=0;k<=4-2*i;k++) printf("*"); printf("\n"); } }

例 : 输出如下图形。 * *** ***** ******* ***** *** *

Page 52: 第六部分      循环控制

52

作业 :(P120 页 ) 6.1,6.2,6.4,6.7,6.11