1、设有两个正整数m和n,如何求其最大公约数?,有多种方法,例如:令k等于m和n中较小的数,用k去除m和n,若不能整除,则令k的值减去1,直到某个值能同时将m和n整除。,求最大公约数,k = mn?m:n;while (m%k!=0 | n%k!=0) k-;,求最大公约数(笨办法),#include int main( ) int m, n, k;scanf(“%d%d“, ,设有两个正整数m和n,如何求其最大公约数?,有多种方法,例如:令k等于m和n中的较小者,用k去除m和n,若不能整除,则令k的值减去1,直到某个值能同时将m和n整除。 求解速度最快的方法是辗转相除法。,辗转相除法(欧几里得算
2、法): 给定两个正整数m和n,求它们的最大公约数(公因子)。 步骤1:【求余数】以n除m并令r为所得余数(0rn) 步骤2:【余数为0?】若r=0,则算法结束;n即为答案 步骤3:【置换】置mn, nr,转向步骤1。,求最大公约数,辗转相除法求最大公约数,求最大公约数流程图,求最大公约数程序,#include int main( ) return 0; ,Y,N,r不等于0?,输出n的值,输入正整数m和n,开始,结束,m n; n r r m % n,r m % n,while (r != 0) m = n; n = r;r = m % n; ,printf(“input two intege
3、rs:“); scanf(“%d%d“,r = m % n;,int m, n, r;,printf(“ngcd = %dn “,n);,C的循环语句,C语言提供了描述循环计算的语句:while语句for语句do.while语句,学习循环结构程序设计就是掌握以上语句的使用方法 还要掌握break、continue语句,分析问题,在求解过程中: 存在一个(些)运算(动作)需要重复进行(循环)若干次。 重复的次数是事先确定的,或者是根据条件确定的。 处理循环计算需要明确的三个问题: 循环体:哪些运算(动作)是需要重复进行的; 循环条件:重复这些运算的条件是什么,即在什么情况下终止/继续这个重复的过
4、程。 循环准备:在进行重复的运算处理之前,需要进行的准备工作是什么;,循环结构程序的编写要点,for语句,for语句的格式和含义,for语句的基本格式:,for(表达式1;表达式2;表达式3)循环体语句A,for语句的含义: 1) 计算表达式1; 2) 计算表达式2,若表达式2的值为“假”,则结束for语句的执行,转4);否则,执行循环体语句A; 3) 计算表达式3, 然后转2); 4) 执行for语句之后的第一条语句;,for语句:1+2+.+100,#include main( ) int i, s; printf(“ %dn “,s); ,B,Y,N,I 1 S 0,I=100?,S S
5、+I,输出S的值,开始,结束,I I+1,A,C,for(i = 1,s = 0; i = 100;i+) s += i; ,#include int main( ) int i, s; i = 1; s = 0; while (i = 100) s += i;i+;printf(“ %dn “,s);return 0; ,for语句中的表达式,for语句的基本格式:,for(表达式1;表达式2;表达式3)循环体语句A,一般情况下 表达式1进行循环计算的初始化处理 表达式2是循环的条件 表达式3进行的计算能够对表达式2的值产生影响,求最大公约数程序(for),#include main( )
6、int m, n, r; printf(“input two integers:“);scanf(“%d%d“, ,Y,N,r不等于0?,输出n的值,输入正整数m和n,开始,结束,m n; n r rm被n除的余数,rm被n除的余数,for(r = m % n; r != 0; r = m % n) m = n; n = r; ,for语句与while语句的等价关系,for语句的基本格式:,for(表达式1;表达式2;表达式3)循环体语句A,表达式1; while (表达式2) 循环体语句A;表达式3; ,Y,N,K 2,K不能整除n?,K K+1,输出n是素数,输入n的值,开始,结束,Y,N
7、,K等于n?,输出n不是素数,判断素数算法及程序,#include int main ( ) int k, n;printf(“input an integer:“);scanf(“%d“, ,#include main ( ) int k, n;printf(“input an integer:“);scanf(“%d“, ,for(k = 2; n % k !=0; k+);,for语句小结,表达式1可放置在for语句之前,for(表达式1;表达式2;表达式3)循环体语句A,表达式1; for(;表达式2;表达式3)循环体语句A,表达式3可放置在for语句的循环体中,for(表达式1;表达
8、式2;)循环体语句A;表达式3; ,for语句中的表达式可以是C语言允许的任何表达式,for语句小结(续),进一步,表达式2可以没有,表示无休止地循环,for(表达式1;表达式3)循环体语句A,三个表达式都省略,for(;)循环体语句A,break语句,break语句的作用,在switch语句中使用,grade = score / 10; /*百分制成绩score转换为等级分制*/switch (grade) case 10:case 9: printf(“ grade = An “); break;case 8: printf(“ grade = Bn “); break;case 7: p
9、rintf(“ grade = Cn “); break;case 6: printf(“ grade = Dn “); break; case 5: case 4: case 3: case 2:case 1:case 0: printf(“ grade = En “); break;default: printf(“ Invalid data!n “);,break语句的作用(续),在循环语句中使用,强行中止循环,break语句的作用(续),在循环语句中使用,强行中止循环,/*计算正整数m和n的最大公约数*/for(k = m; k=1; k-)if ( n % k = 0 ,contin
10、ue语句,continue语句的作用,执行流程到达continue语句时,结束本轮循环,开始下一轮循环,continue语句的应用举例,输出100200之间所有不能被3整除的整数。,#include main( ) int n; for(n = 100; n = 200; n+) if (n % 3 = 0) continue;printf(“%dt“, n); /*end of for*/ ,循环语句应用举例,已知鸡兔共笼,头共45个,脚共120只,问鸡、兔各几何?,#include int main( ) int chicken, rabbits; for (chicken = 0; ch
11、icken = 45; chicken+) rabbits = 45 chicken;if (chicken * 2 + rabbits * 4 = 120) break; /*end of for*/printf(“chicken: %dt rabbits: %dn “, chicken, rabbits);return 0; ,a = 0; b = 45; while (2*a+4*b != 120) a+;b-; ,单重循环和多重循环,for语句和while语句,for语句的基本格式:,for(表达式1;表达式2;表达式3)循环体语句A,while语句的格式:,while (表达式p)循
12、环体语句A,循环语句应用举例,已知鸡兔共笼,头共45个,脚共120只,问鸡、兔各几何?,#include int main( ) int chicken, rabbits; for (chicken = 0; chicken = 45; chicken+) rabbits = 45 chicken;if (chicken * 2 + rabbits * 4 = 120) break; /*end of for*/printf(“chicken: %dt rabbits: %dn “, chicken, rabbits);return 0; ,循环体语句可以是语言允许的任何语句,多于一条语句时必
13、须用括起来,百钱百鸡问题,中国古代数学家张丘建在他的算经中曾提出著名的“百钱百鸡问题”,其题目如下: 鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,翁、母、雏各几何?,百钱百鸡问题,解:设i、j、k分别代表公鸡、母鸡、小鸡的数量,根据题意列方程:,根据题意可知,i、j、k的范围一定是0到100的正整数,那么,最简单的解题方法是:穷举i、j、k每一种可能的取值组合,直接代入方程组,若满足该方程组则是一组解。这样即可得到问题的全部解。,百钱百鸡问题,i 0,i 20?,买母鸡和 小鸡,开始,结束,i i + 1,i = 0; while (i 20 ) i+; , int i, j,
14、 k; /*i、j、k分别表示公鸡、母鸡和小鸡的数目*/ ,j = 0; while (j 34) j+; ,k = 0; while ( k 100) if ( i + j + k = 100 ,百钱百鸡问题(while),输出: 0 25 75 3 20 77 4 18 78 7 13 80 8 11 81 11 6 83 12 4 84,for(i = 0; i 20; i+ ) /*设定公鸡的数目*/ ,int main( ) int i, j, k; /*i、j、k分别表示公鸡、母鸡和小鸡的数目*/ return 0; ,for(j = 0; j 34; j+) /*设定母鸡的数目*
15、/ ,for(k = 0; k 100; k+) /*设定小鸡的数目*/ if ( i + j + k = 100 ,百钱百鸡问题(for),输出: 0 25 75 4 18 78 8 11 81 12 4 84,for(i = 0; i 20; i+ ) /*设定公鸡的数目*/ ,int main( ) int i, j, k; /*i、j、k分别表示公鸡、母鸡和小鸡的数目*/ return 0; ,for(j = 0; j 34; j+) /*设定母鸡的数目*/ ,k = 100 i j ; if (i*15 + j*9 + k = 300)printf(“%d %d %dn“,i,j,k
16、);,百钱百鸡问题(for续),直到型循环结构和do-while语句,p,A,a,b,循环结构2(until),p,A,成立,不成立,a,b,循环结构1(while),until循环结构,循环结构 当型循环结构(while型循环) 重复地判断条件p,若成立,则执行计算A;条件p不成立时,终止该重复过程,如图循环结构1所示 直到型循环结构(Until型循环) 先执行计算A,然后判断条件p是否成立,如图循环结构2所示,do-while语句的格式和含义,do-while语句的使用格式:,do循环体语句A while (表达式p);,do-while语句的含义: 1) 执行循环体语句A; 2) 计算表
17、达式p,若表达式的值为“假”,则结束do-while语句的执行;否则,执行循环体语句A,然后转1);,Y,N,K 2,K不能整除n?,K K+1,输出n是素数,输入n的值,开始,结束,Y,N,K等于n?,BEGINinput n; /*输入正整数n*/k2; while (n mod k 0) dok k+1;if (k=n) then print “n是素数” else print “n不是素数” END,输出n不是素数,判断素数算法及程序,#include main ( ) int k, n;printf(“input an integer:“);scanf(“%d“, ,Y,N,K 2,
18、K不能整除n?,K K+1,输出n是素数,输入n的值,开始,结束,Y,N,K等于n?,输出n不是素数,判断素数程序,#include main ( ) int k, n;printf(“input an integer:“);scanf(“%d“, ,#include main ( ) int k, n;printf(“input an integer:“);scanf(“%d“, ,while语句和do-while语句,while语句的循环体执行0次或多次 do-while语句的循环体执行1次或多次,while(表达式p) 循环体语句A;,do-while语句可看作是while语句的变体 用
19、do-while语句表达的计算过程都可以用while语句表示,do 循环体语句A; while(表达式p);,do-while语句的使用,do-while语句常用于:为确保输入的数据满足要求而进行循环输入 例如,确保是输入了一个大于1的正整数,doprintf(“input a positive integer(1):“);scanf(“%d“,do-while语句的使用(续),printf(“input a positive integer(1):“); scanf(“%d“, ,doprintf(“input a positive integer(1):“);scanf(“%d“,与以上do-while语句等价的while语句:,练习,编写程序,输入10个整数,输出它们的和。,记事本,练习,编写程序,输入10个整数,找出其中最大的数并打印输出。,记事本,作 业,第 84 页:习题二 第 2、3 小题 第 85 页:习题二 第 6、7、9 小题,