循环结构主要用于解决那些需要重复执行的操作;例如:求若干数之和、迭代求根、排序、查找等。
设计循环结构时,要从重复性的操作过程中寻找规律,包括重复执行的代码段和重复执行的条件。
常见的循环结构语句:while语句、do…while语句、for语句、goto语句(一般不提倡使用)
使用goto语句与if语句一起也可以构成循环结构;goto语句也称为无条件转移语句
goto语句一般格式如下:
goto 语句标号; . . . 标号:语句 . . .
goto语句的语义是改变程序流向,转去执行语句标号所标识的语句
例:用goto语句构造循环计算1到100的整数和
#include <stdio.h> void main() { int i=1,sum=0; loop:sum=sum+i; i++; if(i<=100) goto loop; printf("The sum of 1 to 100 is:%d\n",sum); }
由while语句构成的循环称为当型循环,当满足循环条件,执行循环体语句;
while语句的一般形式:
while(表达式) 循环语句; /*表达式为循环条件*/
while语句特点是先判断表达式,再执行循环体语句
例:统计从键盘输入一行字符的个数
#include <stdio.h> void main() { int n=0; printf("输入一个字符串:\n"); while(getchar()!='\n') /*只要从键盘输入的字符不是换行符就继续执行循环*/ n++; printf("%d",n); }
while语句中的表达式可以是任意合法的表达式,一般是关系表达式或逻辑表达式,只要表达式的值为真(非0)就继续执行循环
循环体如果包括一条以上的语句,就必须用花括号{}括起来,组成复合语句
选择循环条件必须避免死循环,循环条件必须要能从真变成假,循环体语句可以为空
do…while循环称为直到型循环;先执行循环体语句,再判断表达式,直到while中表达式为假,跳出循环
do…while循环一般形式为:
do 循环体语句; while(表达式); /*句末有分号!*/
do…while语句的执行过程为先执行一次循环体语句,再判别表达式的值,表达式值为真,则继续循环,直到表达式值为假,跳出循环
例:求整数i,它满足1+2+…+(i+1)<100且1+2+…+i>=100
#include <stdio.h> void main() { int i=0,sum=0; do { i++; sum=sum+i; }while(sum<100); printf("The integer is:%d\n",i); }
例:任意输入一个正整数,将该数各位颠倒顺序输出,如输入1234,输出4321
分析:可对输入的正整数取余来求没位的数字,第一次取余得到个位数字,然后除10,再对10取余得到原正整数的十位数字
#include <stdio.h> void main() { int a,b; printf("输入一个正整数:"); scanf("%d",&a); while(a!=0) { b=a%10; printf("%d",b); a=a/10; } }
#include <stdio.h> void main() { int a,b; printf("输入一个正整数:"); scanf("%d",&a); do { b=a%10; printf("%d",b); a=a/10; }while(a!=0); }
for循环不仅适用于已知循环次数的情况,也适用于未知循环次数的情况
for循环的一般形式为:
for(表达式1;表达式2;表达式3) 循环体语句;
for循环的执行流程:
整个for循环过程,表达式1只执行1次,表达式2和3则可能执行多次,循环体可能多次执行,可能一次都不执行
for循环中的三个表达式都可以省略,但分号不能省略
例:将所有可显示字符与其ASCII码对照表在屏幕上输出
ASCII码从32(空格)开始到126(’~’)都是可显示字符
#include <stdio.h> void main() { char c; for(c=32;c<=126;c++) printf("%c %d\n",c,c); }
break和continue语句都是控制程序的流程转向的跳转语句
例:计算r=1到r=10时的圆面积,当面积大于100时终止
#include <stdio.h> #define PI 3.1415926 void main() { int r; float area; for(r=1;r<=10;r++) { area=PI*r*r; if(area>100) break; printf("r=%d area is: %.2f\n",r,area); } }
continue语句只能用在循环体内,一般形式为:continue;
continue语句语义是结束本次循环,不再执行循环体中continue语句之后的语句,转入下次循环条件的判断和执行
continue语句一般也要与if语句配合使用,达到结束本次循环的目的
在while和do…while语句中,continue语句使得流程直接跳到循环控制条件的判断部分;在for语句中,遇到continue后,跳过循环体中余下的部分,而去对for语句中的表达式3求值
例:输出100以内能被7整除的数
#include <stdio.h> void main() { int a; for(a=1;a<=100;a++) { if(a%7!=0) continue; printf("%d ",a); } } 不适用continue语句也可以: #include <stdio.h> void main() { int a; for(a=1;a<=100;a++) { if(a%7==0) printf("%d ",a); } }
循环嵌套指在一个循环的循环体内完整的包含另一个或几个循环结构
例:演示嵌套循环的执行过程
#include <stdio.h> void main() { int i,j; for(i=0;i<3;i++) { printf("i=%d",i); for(j=0;j<4;j++) printf("j=%-4d",j); printf("\n"); } }
例:在8×8的棋盘64个格子里,第一个格子放一个豆子,第二个放两个豆子,第三个放4粒依次累计,放满64个格子,设计算法求共放多少豆子,合多少立方米?1立方米豆子约1.42e8粒。
分析:第一个格子放1个,第二个放2个,第三个放4个,以此类推第i个格子放2(i-1)个豆子,则豆子总数便是20+21+22+23+…263
#include <stdio.h> void main() { double sum,t; /*t为累乘器,初值通常为1;sum为累加器,初值有时为0、有时为累加的第一个数;i为计数器, 初值为1,即为2^1的指数*/ int i; for(t=1,sum=1,i=1;<=63;++) { t=t*2; sum=sum+t; } printf("豆子总数为:%e\n",sum); printf("折合体积为:%e立方米\n",sum/1.42e8); }
例:100块钱,公鸡5块钱,母鸡3块钱,三个鸡崽1块钱,若买100块买100只鸡,公鸡母鸡鸡崽各几只?
分析:公鸡i,母鸡j,鸡崽k,i+j+k=100;5i+3j+k/3=100;如果100块全买公鸡,能买20只,所以i的范围020;全买母鸡,最多能买33只,剩1块,所以j的范围是033;k的范围可以通过i和j来决定
#include <stdio.h> void main() { int i,j,k; int m=100/5,n=100/3; for(i=0;i<=m;i++) { for(j=0;j<=n;j++) { k=100-i-j; if(i*5+j*3+k/3 == 100&&k%3 == 0) printf("i=%d,j=%d,k=%d\n",i,j,k); } } }
例:输出斐波那契数列的前40项,每行输出4项,斐波那契数列为:1,1,2,3,5,8,13…,第一项第二项均为1,后面各项均为前两项之和
分析:通项表达式:f1=1 (n=1)
f2=1 (n=2)
fn=fn-1+fn-2 (n>=3)
#include <stdio.h> void main() { long f1,f2; int i; f1=f2=1; for(i=1;i<=20;i++) { printf("%12ld %12ld",f1,f2); if(i%2==0) printf("\n"); f1=f1+f2; f2=f1+f2; } } 运行情况: 初始f1=f2=1 ①:i=1,i=1<=20;进入循环输出右对齐左侧12空格f1=1、f2=1;i=1,1%2不等于0,不输出换行符;f1=2,f2=3 ②:此时i经过i++得到i=2<=20;进入循环输出右对齐左侧12空格f1=2、f2=3;i=2,2%2等于0,输出换行符;f1=5,f2=8 ③:此时i经过i++得到i=3<=20;进入循环输出右对齐左侧12空格f1=5、f2=8;i=3,3%2不等于0,不输出换行符;f1=13,f2=21 ④:此时i经过i++得到i=4<=20;进入循环输出右对齐左侧12空格f1=13、f2=21;i=4,4%2等于0,输出换行符;f1=34,f2=55 . . . ⑤:此时i经过i++得到i=19<=20;进入循环输出右对齐左侧12空格f1=24157817、f2=39088169;i=19,19%2不等于0,不输出换行符;f1=63245986,f2=102334155 ⑥:此时i经过i++得到i=20<=20;进入循环输出右对齐左侧12空格f1=63245986、f2=102334155;i=20,20%2等于0,输出换行符;f1=165580141,f2=267914296 ⑦:此时i经过i++得到i=21,i<=20为假,跳出循环,结束程序
y为整型变量,且y>=0
#include <stdio.h> void main() { float x,z; int y; printf("输入x和y:\n"); scanf("%f,%d",&x,&y); for(z=1;y>0;y--) z*=x; printf("z=%f",z); } 运行情况: 输入x=4,y=5; ①:z=1,y=5>0;进入循环得到z=z*x为z=1*4 ②:z=1*4,此时y经过y--得到y=4>0;进入循环得到z=z*x为z=1*4*4 ③:z=1*4*4,此时y经过y--得到y=3>0;进入循环得到z=z*x为z=1*4*4*4 ④:z=1*4*4*4,此时y经过y--得到y=2>0;进入循环得到z=z*x为z=1*4*4*4*4 ⑤:z=1*4*4*4*4,此时y经过y--得到y=1>0;进入循环得到z=z*x为z=1*4*4*4*4*4 ⑥:此时y经过y--得到y=0,跳出循环输出z=1*4*4*4*4*4=4^5
判断素数方法:判断一个整数m是否是素数,只需把m被 2 ~ m-1 之间的每一个整数去除,如果都不能被整除,那么m就是一个素数。
#include <stdio.h> void main() { int i,j; for(i=3;i<=100;i++) { for(j=2;j<=i-1;j++) if(i%j == 0) break; if(j == i) printf("%3d",i); } } 运行情况: ①:i=3<=100; 进入内层循环: 1.j=2<=2;此时i=3,j=2,3%2=1!=0;进入j++,此时j=3 2.j=3>2;结束内层循环 此时j=i=3,输出i=3;进入i++,此时i=4 ②:i=4<=100; 进入内层循环: 1.j=2<=3;此时i=4,j=2,4%2=0;进入break;结束内层循环 此时j=2,i=4;不输出i;进入i++,此时i=5 . . .
#include <stdio.h> void main() { long int n,i,k,j,sum; print("输入n="); scanf("%ld",&n); k=n*n*n; for(i=1;i<k/2;i+=2) { for(j=i,sum=0;sum<k;j+=2) sum+=j; if(sum==k) printf("%ld*%ld*%ld=%ld=form%ldto%ld\n",n,n,n,sum,i,j-2); } } 运行情况: 输入n=5,则k=125 ①:i=1<k/2=62 进入内层循环: 1.j=i=1,sum=0<125;则sum=sum+j=1;进入j+=2得j=3 2.sum=1<125;则sum=sum+j=1+3=4;进入j+=2得j=5 3.sum=4<125;则sum=sum+j=4+5=9;进入j+=2得j=7 4.sum=9<125;则sum=sum+j=9+7=16;进入j+=2得j=9 5.sum=16<125;则sum=sum+j=16+9=25;进入j+=2得j=11 6.sum=25<125;则sum=sum+j=25+11=36;进入j+=2得j=13 7.sum=36<125;则sum=sum+j=36+13=49;进入j+=2得j=15 8.sum=49<125;则sum=sum+j=49+15=64;进入j+=2得j=17 9.sum=64<125;则sum=sum+j=64+17=81;进入j+=2得j=19 10.sum=81<125;则sum=sum+j=81+19=100;进入j+=2得j=21 11.sum=100<125;则sum=sum+j=100+21=121;进入j+=2得j=23 12.sum=121<125;则sum=sum+j=121+23=144;进入j+=2得j=25 13.sum=144>125;则不进入内层循环,进入if语句,sum=144!=k=125;进入i+=2,i=3 ②:i=3<k/2=62 进入内层循环: 1.j=i=3,sum=0<125;则sum=sum+j=3;进入j+=2得j=5 2.sum=3<125;则sum=sum+j=3+5=8;进入j+=2得j=7 3.sum=8<125;则sum=sum+j=8+7=15;进入j+=2得j=9 4.sum=15<125;则sum=sum+j=15+9=24;进入j+=2得j=11 5.sum=24<125;则sum=sum+j=24+11=35;进入j+=2得j=13 6.sum=35<125;则sum=sum+j=35+13=48;进入j+=2得j=15 7.sum=48<125;则sum=sum+j=48+15=63;进入j+=2得j=17 8.sum=63<125;则sum=sum+j=63+17=80;进入j+=2得j=19 9.sum=80<125;则sum=sum+j=80+19=99;进入j+=2得j=21 10.sum=99<125;则sum=sum+j=99+21=120;进入j+=2得j=23 11.sum=120<125;则sum=sum+j=120+23=143;进入j+=2得j=25 12.sum=143>125;则不进入内层循环,进入if语句,sum=143!=k=125;进入i+=2,i=5 ③:i=5<k/2=62 进入内层循环: 1.j=i=5,sum=0<125;则sum=sum+j=5;进入j+=2得j=7 2.sum=5<125;则sum=sum+j=5+7=12;进入j+=2得j=9 3.sum=12<125;则sum=sum+j=12+9=21;进入j+=2得j=11 4.sum=21<125;则sum=sum+j=21+11=32;进入j+=2得j=13 5.sum=32<125;则sum=sum+j=32+13=45;进入j+=2得j=15 6.sum=45<125;则sum=sum+j=45+15=60;进入j+=2得j=17 7.sum=60<125;则sum=sum+j=60+17=77;进入j+=2得j=19 8.sum=77<125;则sum=sum+j=77+19=96;进入j+=2得j=21 9.sum=96<125;则sum=sum+j=96+21=117;进入j+=2得j=23 10.sum=117<125;则sum=sum+j=117+23=140;进入j+=2得j=25 11.sum=140>125;则不进入内层循环,进入if语句,sum=140!=k=125;进入i+=2,i=7 ④:i=7<k/2=62 进入内层循环: 1.j=i=7,sum=0<125;则sum=sum+j=7;进入j+=2得j=9 2.sum=7<125;则sum=sum+j=7+9=16;进入j+=2得j=11 3.sum=16<125;则sum=sum+j=16+11=27;进入j+=2得j=13 4.sum=27<125;则sum=sum+j=27+13=40;进入j+=2得j=15 5.sum=40<125;则sum=sum+j=40+15=55;进入j+=2得j=17 6.sum=55<125;则sum=sum+j=55+17=72;进入j+=2得j=19 7.sum=72<125;则sum=sum+j=72+19=91;进入j+=2得j=21 8.sum=91<125;则sum=sum+j=91+21=112;进入j+=2得j=23 9.sum=112<125;则sum=sum+j=112+23=135;进入j+=2得j=25 10.sum=135>125;则不进入内层循环,进入if语句,sum=135!=k=125;进入i+=2,i=9 ⑤:i=9<k/2=62 进入内层循环: 1.j=i=9,sum=0<125;则sum=sum+j=9;进入j+=2得j=11 2.sum=9<125;则sum=sum+j=9+11=20;进入j+=2得j=13 3.sum=20<125;则sum=sum+j=20+13=33;进入j+=2得j=15 4.sum=33<125;则sum=sum+j=33+15=48;进入j+=2得j=17 5.sum=48<125;则sum=sum+j=48+17=65;进入j+=2得j=19 6.sum=65<125;则sum=sum+j=65+19=84;进入j+=2得j=21 7.sum=84<125;则sum=sum+j=84+21=105;进入j+=2得j=23 8.sum=105<125;则sum=sum+j=105+23=128;进入j+=2得j=25 9.sum=128>125;则不进入内层循环,进入if语句,sum=128!=k=125;进入i+=2,i=11 ⑥:i=11<k/2=62 进入内层循环: 1.j=i=11,sum=0<125;则sum=sum+j=11;进入j+=2得j=13 2.sum=11<125;则sum=sum+j=11+13=24;进入j+=2得j=15 3.sum=24<125;则sum=sum+j=24+15=39;进入j+=2得j=17 4.sum=39<125;则sum=sum+j=39+17=56;进入j+=2得j=19 5.sum=56<125;则sum=sum+j=56+19=75;进入j+=2得j=21 6.sum=75<125;则sum=sum+j=75+21=96;进入j+=2得j=23 7.sum=96<125;则sum=sum+j=96+23=119;进入j+=2得j=25 8.sum=119<125;则sum=sum+j=119+25=144;进入j+=2得j=27 10.sum=144>125;则不进入内层循环,进入if语句,sum=144!=k=125;进入i+=2,i=13 . . .
#include <stdio.h> void main() { int n,k,score,sum; float ave; for(n=1;n<=10;n++) { sum=0; for(k=1;k<=4;k++) { scanf("%d",&score); sum+=score; } ave=sum/4.0; printf("NO.%d:%f\n",n,ave); } }
#include <stdio.h> void main() { int i,j,k,sum; for(i=1;i<=9;i++) for(j=0;j<=9;j++) for(k=0;k<=9;k++) { sum=100*i+10*j+k; if(sum==i*i*i+j*j*j+k*k*k) printf("%d ",sum); } }
#include <stdio.h> void main() { int sum=0,mix=1,n; scanf("%d",&n); while((n>=2)&&(mix<=10)) { if((n%11==0)||(n%19==0)) { sum=sum+n; mix++; } n--; } printf("%d\n",sum); }
例:10080,数字值为0的有3个,各位上数字最大的为8
#include <stdio.h> void main() { unsigned m; int n=0,max=0,t; scanf("%d",&m); do { t=m%10; if(t==0) n++; if(max<t) max=t; m=m/10; }while(m); printf("\n结果是:最大的数字是%d 0有%d个\n",max,n); }
求1-1/2+1/3-1/4+…+1/99-1/100
#include <math.h> void main() { int s; /*s为分子,且需要来决定各项正负*/ float n,t,sum; /*n为分母,需要累加;t为各项的具体数值;sum为总和*/ t=1; sum=0; n=1; s=1.0; while(n<=100) { sum=sum+t; n=n+1; s=-s; t=s/n; } printf("sum=%10.6f\n",sum); }
求1~10的阶乘,并分别显示在屏幕上
#include <stdio.h> void main() { int i; long int n=1; for(i=1;i<=10;i++) { n=n*i; printf("%d ",n); } }
#include <stdio.h> void main() { int n,i,j; scanf("%d",&n); for(i=0;i<=n;i++) { for(j=1;j<=n+i-1;j++) if(j<=n-i) printf(" "); else printf("*") printf("\n"); } } 运行情况: 输入7;则n=7 ①:i=0<=7; 进入内层循环: 1.j=1<=7+0-1=6;j=1<7-0=7,输出空格
一个数恰好等于它的因子之和,称为完数;完数6等于1+2+3,
#include <stdio.h> void main() { int m,s,i; /*s为因子和;m为验证是否为完数的数;i为因子*/ for(m=2;m<1000;m++) { s=0; for(i=1;i<m;i++) if((m%i)==0) s=s+i; if(s==m) { printf("%d its factors are ",m); for(i=1;i<m;i++) if((m%i)==0) printf("%d ",i); printf("\n"); } } }
8发打了53环,全部命中10环、7环、5环上,问各打中多少环
#include <stdio.h> void main() { int h10,h7,h5; for(h10=1;h10<=4;h10++) for(h7=1;h7<=6;h7++) for(h5=1;h5<=8;h5++) if(h10+h7+h5==8&h10*10+h7*7+h5*5==53) printf("h10=%d,h7=%d,h5=%d",h10,h7,h5); }
猴子第一天摘下一堆桃子,吃了一半,没吃带劲,又多吃了一个;第二天又把昨天剩下的桃子吃了一半,又没吃带劲,又多吃了一个;往后每天都吃了上一天剩下的多一个;到第10天再吃时,就剩一个了;问第一天摘了多少桃?
分析:第九天吃了第八天剩下的桃一半加1个,然后还剩下一个桃
逆向思维,倒推 #include <stdio.h> void main() { int day,x1,x2; /*day为第几天;x2初始为第九天吃完给第十天剩的桃;x1为第八天吃完给第九天剩的桃*/ day=9; x2=1; while(day>0) { x1=(x2+1)*2; x2=x1; day--; } printf("第一天摘得桃为%d个\n",x1); } 方法二 #include <stdio.h> void main() { }
利用辗转相除,直到b为0为止
#include <stdio.h> void main() { int p,r,n,m,temp; printf("输入两个正整数:"); scanf("%d,%d",&n,&m); if(n<m) { temp=n; n=m; m=temp; } p=n*m; while(m!=0) { r=n%m; n=m; m=r; } printf("最大公约数是:"); printf("最小公倍数是:"); }