第五章 循环结构程序设计
例题
1、求和n(n=1+2+3+......100)
(1)用while实现
#include <stdio.h>
int main()
{
int i=1,sum=0; // i为循环体变量,sum需要赋初值
while(i<=100)
{
sum+=i;
i++;
}
printf("%d\n",sum);
return 0;
}
(2)用do...while实现
#include <stdio.h> int main() { int i=1,sum=0; // i为循环体变量,sum需要赋初值 do { sum+=i; i++; }while(i<=100); // 这里需要分号 printf("%d\n",sum); return 0; }
(3)用for循环实现
#include <stdio.h>
int main()
{
int i,sum=0; // i为循环体变量,sum需要赋初值
for(i=1;i<=100;i++)
{
sum+=i;
} // 这里需要分号
printf("%d\n",sum);
return 0;
}
2、募集基金10000元,有若干人捐款,每输入一个的捐款数后,计算机就输出当时的捐款总和。当某一次输入捐款数后,总和达到或超过10000元时,即宣告结束,输出最后的累加值。
#include <stdio.h>
int main()
{
float sum=0,amount;
printf("Please enter the number :\n");
do
{
scanf("%f",&amount);
sum+=amount;
printf("Current sum=%10.2f\n",sum);
}while(sum<10000); // 循环条件
printf("Total sum=%10.2f\n",sum);
return 0;
}
3、国王的麦子
#include <stdio.h>
#include <math.h>
int main()
{
int i;
double p=1,t=1,v;
for(i=1;i<64;i++) // 执行63次
{
p=p*2; // p是当前一个格子中的麦子粒数
t=t+p; // t是当前麦子总粒数
}
v=t/1.42e8;
printf("total=%e\n",t);
printf("volume=%e\n",v);
return 0;
}
4、人口增长预测。据2012年末统计,我国人口约13.54亿人,如果人口的年增长率为1%,请计算到哪一年中国总人口超过15亿。
#include <stdio.h>
int main()
{ int year;
double r,p;
r=0.01;
p=1.354e9;
year=2012;
for(year=2012;p<1.5e9;year++)
{
p=p*(1+r);
}
printf("year=%d,p=%e\n",year-1,p);
return 0;
}
5、统计各班级的学生的平均成绩。已知各班级人数不等,但都不超过30人。编一个程序能处理人数不等的各班学生的平均成绩。(break的应用)
#include <stdio.h>
int main()
{
double score,sum=0,average;
int i,n;
for(i=1;i<31;i++)
{
scanf("%l2f",&score);
if(score<0)
{
break; // 若输入一个负数,则跳出整个循环,即执行下面的n=i-1
}
sum=sum+score;
}
n=i-1;
average=sum/n;
printf("n=%d,average=%8.2f\n",n,average);
return 0;
}
6、输入一个班全体学生的成绩,把其中不及格的成绩输出,并求及格成绩学生的平均成绩。
#include <stdio.h>
int main()
{
double score,sum=0,average;
int i,n=0;
for(i=1;i<6;i++)
{
printf("Please enter score!\n");
scanf("%lf",&score);
if(score<60)
{
printf("Fail!%7.2lf\n",score);
continue; // 跳过本次循环,不执行本次for语句里面的内容,执行下一次
}
n=n+1;
sum+=score;
}
average=sum/n;
printf("n=%d,average=%8.2f\n",n,average);
return 0;
}
7、斐波那契数列(求前40项和)***
特点:第1、2两个数为1、1,从第3个数开始,该数是其前面两个数之和。
F1=1(n=1);
F2=1(n=2);
Fn=Fn-1+Fn-2(n>=3)
#include <stdio.h>
int main()
{
long int f1,f2;
int i;
f1=1;f2=1;
for(i=1;i<=20;i++) //为什么i是20?
{
printf("%12ld%12ld",f1,f2); // 输出f1,f2
if(i%2==0)
{
printf("\n"); // 每次显示输出2个数,i%2=0是每行输出4个数
}
f1=f1+f2; // 因为f1、f2前面已经赋值,集合前面分析
f2=f2+f1; // 即1、1、2、3
}
return 0;
}
8、求一个数是否为素数
素数又称质数。所谓素数是指除了 1 和它本身以外,不能被任何整数整除的数,例如17就是素数,因为它不能被 2~16 的任一整数整除。
思路1):因此判断一个整数m是否是素数,只需把 m 被 2 ~ m-1 之间的每一个整数去除,如果都不能被整除,那么 m 就是一个素数。
思路2):另外判断方法还可以简化。m 不必被 2 ~ m-1 之间的每一个整数去除,只需被 2 ~
之间的每一个整数去除就可以了。如果 m 不能被 2 ~
间任一整数整除,m 必定是素数。例如判别 17 是是否为素数,只需使 17 被 2~4 之间的每一个整数去除,由于都不能整除,可以判定 17 是素数。
原因:因为如果 m 能被 2 ~ m-1 之间任一整数整除,其二个因子必定有一个小于或等于
,另一个大于或等于
。例如 16 能被 2、4、8 整除,16=2*8,2 小于 4,8 大于 4,16=4*4,4=√16,因此只需判定在 2~4 之间有无因子即可。
思路1) 的代码:
#include <stdio.h>
int main()
{
int i,num=0,a=0;
printf("Please enter a integer number");
scanf("%d",&num);
for(i=2;i<num;i++)
{
if(num%i==0)
{
a++; // 不是素数a加1
}
}
if(a==0)
{
printf("%d is a prime number.\n",num); // 是素数
}else
{
printf("%d is a not prime number.\n",num); // 不是素数
}
return 0;
}
思路2) 的代码:
#include <stdio.h>
#include <math.h>
int main()
{
int m; // 输入的整数
int i; // 循环次数
int k; // m 的平方根
printf("输入一个整数:");
scanf("%d",&m);
// 求平方根,注意sqrt()的参数为 double 类型,这里要强制转换m的类型
k=(int)sqrt( (double)m );
for(i=2;i<=k;i++)
if(m%i==0) // m在k的范围内中找是否有被整除的数
break;
// 如果完成所有循环,那么m为素数
// 注意最后一次循环,会执行i++,此时 i=k+1,所以有i>k
if(i>k)
printf("%d是素数。\n",m);
else
printf("%d不是素数。\n",m);
return 0;
}
9、译密码
#include <stdio.h>
int 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是已经加了4,c<='Z'+4是预算了会输入'Z',则限制了字母的范围
{
c=c-26;
}
printf("%c",c);
}
}
printf("\n");
return 0;
}
提高部分
1、while和do...while的比较
(1)while实现1加到10的和;
#include <stdio.h>
int main()
{
int sum=0,i;
scanf("%d",&i);
while(i<=10)
{
sum=sum+i;
i++;
}
printf("sum=%d\n",sum);
return 0;
}
(2)用do...while实现1加到10的和:
#include <stdio.h>
int main()
{
int sum=0,i;
scanf("%d",&i);
do
{
sum=sum+i;
i++;
}
while(i<=10);
printf("sum=%d\n",sum);
return 0;
}
比较结果:当两个程序输入为1时结果的一样,,而当输入1时,while结果是0,do...while则是11,原因是do...while是先执行再判断,这里执行了一次,判断不符合,所以接下来就不执行了,只是11。
2、for语句的各种形式
(1)表达式1可以省略,但是表达式1后面的分号不能省略,并且for语句的循环变量必须提前声明和赋初值:
int i=o;
for(;i<=100;i++) sum=sum+i;
(2)表达式2不能省略,否则循环不会退出:
for(i=1; ;i++) sum=sum+i;
等价于下面(死循环)
i=1;
while(1)
{
sum=sum+i;
i++;
}
(3)表达式3省略,但是循环递增或者递减变量必须写在for执行语句中:
for(int=1;i<=100;)
{
sum=sum+i;
i++;
}
(4)总结:表达式1和表达式3都可以省略,但是有前提条件,上面已经讲到。
int=1
for(;i<=100;)
{
sum=sum+i;
i++;
}
int i;
while(i<=100)
{
sum=sum+i;
i++;
}
(6)表达式1赋值表达式或者与循环变量无关的其他表达式,表达式3可以是与控制无关的任意表达式,1和3可以是简单表达式和可以是逗号表达式
for(sum=0;i<=100;i++) sum=sum+i;
for(i=1;i<=100;i++,i++) sum=sum+i;
(7)表达式一般式关系表达式,但是也可以是逻辑表达式:
for(i=0;(c=getchar())!='\n';i+=c);
习题部分:
1、判断100-200的素数
#include <stdio.h>
int main()
{
int i,j;
for(i=100;i<=200;i++)
{
for(j=2;j<200;j++)
{
if(i%j==0)
{
break;
}
}
if(j>=i) //如果j>=i则为素数,并输出
{
printf("%d\t",i); //用表格的形式输出结果
}
}
return 0;
}
2、统计输入字符各类别字符的个数
#include <stdio.h>
int main()
{
char c;
int f=0,k=0,n=0,o=0;
for(;(c=getchar())!='\n';)
{
if(c>=65&&c<=90||c>=97&&c<=122)
{
f=f+1;
}else if(c>=48&&c<=57)
{
n=n+1;
}else if(c==32)
{
k=k+1;
}else
{
o=o+1;
}
}
printf("字母个数为:%d\n",f);
printf("数字个数为:%d\n",n);
printf("空格个数为%d\n",k);
printf("其他字符个数:%d\n",o);
}
3、水仙花数
#include <stdio.h>
int main()
{
int b,s,g,num;
printf("The water number is :\n");
for(num=100;num<1000;num++)
{
b=num/100; // 计算百位的数字
s=num/10%10; // 计算十位的数字
g=num%10; // 计算个位的数字
if(num==b*b*b+s*s*s+g*g*g)
{
printf("%-5d",num);
}
}
printf("\n");
return 0;
}
4、四叶玫瑰
#include <stdio.h>
int main()
{
int q,b,s,g,num;
printf("The water number is :\n");
for(num=1000;num<10000;num++)
{
q=num/1000; // 计算千为位的数字
b=(num/100)%10; // 计算百位的数字
s=(num/10)%10; // 计算十位的数字
g=num%10; // 计算个位的数字
if(num==q*q*q*q+b*b*b*b+s*s*s*s+g*g*g*g)
{
printf("%-5d",num);
}
}
printf("\n");
return 0;
}
5、小球反弹问题
题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
分析:本题要求的数有两个,共经过多少米则要求出每次弹跳的高度,注意字眼共经过多少米,必须要算上往返举例,由于第一次下落只算单程,所以第一次单独计算,后续弹跳都是下落反弹两个过程,所以算两次,故循环从2开始,一直算到第10次,第10次反弹多高则计算到第十次即可
#include <stdio.h>
int main() {
double h = 100; // 使用除法会出现小数,所以用浮点型
double s = 100;
h = h / 2; // 计算第一次反弹高度
for (int i = 2; i <= 10; i++) {
s = s + 2 * h; // 下落和反弹算两次,所以要乘2
h = h / 2;
}
printf("第10次落地时,共经过%f米\n第10次反弹高%f米\n", s, h);
return 0;
}
6、猴子吃桃问题
题目:
猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半, 又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
① 程序分析:采取逆向思维的方法,从后往前推断。
②程序源代码:
D10=1
D9/2-1=D10
D9=(D10+1)*2
#include <stdio.h>
int main()
{
/*这里采用逆向思维,假设x2为第十天,x1为第九天*/
int day=9,x1,x2=1; // 第十天剩余个数为一
while(day>0) // 天数如果大于0,则执行day--
{
x1=(x2+1)*2; // x1 为前一天,x2为后一天
x2=x1; // 将后一天的赋值给前一天的
day--;
}
printf("Total:%d\n",x1);
}
7、打印菱形

浙公网安备 33010602011771号