第5章循环结构程序设计
结构化程序设计的3种基本结构:
循环结构 顺序结构 选择结构
5.2用while语句实现循环
while循环和for循环的区别_FutureForXHF的博客-CSDN博客_while循环和for循环的区别
do-while和while的区别
Do可以简单的使用英语翻译进行理解,就是做
Do{ 做
Printf(“2 “); 输出2 (这个行为)
}while(i<=5) 当i<=5时
而while则是
While(i<=5) 当i<=5时
{
Printf(“2 “); 输出2
}
从这两个例子就可以看到,do- while循环比while多了一个“做”的命令,而这就可以理解为:不管怎么样,你先给我运行一次再说。
求1-1/4+1/7-1/10+1/13-1/16+……
输入一个正整数repeat (0<repeat<10),做repeat次下列运算:
读入1个正实数 eps,计算并输出下式的值,精确到最后一项的绝对值小于 eps(保留6位小数)。请使用 while 语句实现循环。
计算:1-1/4+1/7-1/10+1/13-1/16+……
输入输出示例:括号内是说明
输入
2 (repeat=2)
2E-4 (eps=2E-4)
0.02 (eps=0.02)
输出
sum = 0.835549
sum = 0.826310
#include <stdio.h>
#include <math.h>
int main(void)
{
int denominator, flag;
int repeat, ri;
double eps, item, sum;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%le", &eps);
sum=0;
denominator=1;
flag=1;
item=1.0;
while(fabs(item)>=eps){
item=flag*1.0/denominator;
sum=sum+item;
flag=-flag;
denominator=denominator+3;
}
printf("sum = %.6f\n", sum);
}
return 0;
}
40013 求奇数和
输入一个正整数repeat (0<repeat<10),做repeat次下列运算:
读入一批正整数(以零或负数为结束标志),求其中的奇数和。请使用while语句实现循环。
输入输出示例:括号内是说明
输入
2 (repeat=2)
1 3 90 7 0
8 7 4 3 70 5 6 101 -1
输出
The sum of the odd numbers is 11.
The sum of the odd numbers is 116.
#include <stdio.h>
int main(void)
{
int x, sum;
int repeat, ri;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++) {
scanf("%d", &x);
sum=0;
while(x>0) {
if(x%2!=0)
sum+=x;
scanf("%d", &x);
}
printf("The sum of the odd numbers is %d.\n", sum);
}
}
40014 求整数的位数
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
输入一个整数 in,求它的位数。例如123的位数是3。请使用do-while语句实现循环。
输入输出示例:括号内是说明
输入
4 (repeat=4)
12345 (in=12345)
-100 (in=-100)
-1 (in=-1)
1290 (in=1290)
输出
count = 5 (12345的位数是5)
count = 3 (-100的位数是3)
count = 1 (-1的位数是1)
count = 4 (99的位数是2)
#include <stdio.h>
int main(void)
{
int count, in;
int repeat, ri;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%d", &in);
count=0;
if(in<0) in=-in;
do{
count++;
in=in/10;
} while (in!=0);
printf("count = %d\n", count);
}
return 0;
}
求整数的位数以及各位数字之和
程序填空,不要改变与输入输出有关的语句。
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
输入一个整数 in,求它的位数以及各位数字之和。例如 123 的各位数字之和是 6,位数是 3。
输入输出示例:括号内是说明
输入
4 (repeat=4)
0 (in=0)
23456 (in=23456)
-100 (in=-100)
-1 (in=-1)
输出
count = 1, sum = 0 (0的位数是1, 各位数字之和是0)
count = 5, sum = 20 (23456的位数是5, 各位数字之和是20)
count = 3, sum = 1 (-100的位数是3, 各位数字之和是1)
count = 1, sum = 1 (-1的位数是1, 各位数字之和是1)
#include <stdio.h>
int main(void)
{
int count, in, sum;
int repeat, ri;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%d", &in);
count=0; sum=0;
if(in<0) in=-in;
do{
count++;
sum+=in%10;
in=in/10;
} while (in!=0);
printf("count = %d, sum = %d\n", count, sum);
}
return 0;
}
5.4用for语句实现循环
for(表达式1;表达式2;表达式3;)
for(循环变量赋初值;循环条件;循环变量增值)
小tips:for语句会比while语句功能强,除了可以给出循环条件外,还可以赋初值,使循环变量自动增值。
求2/1+3/2+5/3+8/5+...
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
输入一个正整数 n,输出 2/1+3/2+5/3+8/5+……前n项之和,保留2位小数。(该序列从第2项起,每一项的分子是前一项分子与分母的和,分母是前一项的分子)
输入输出示例:括号内是说明
输入
3 (repeat=3)
1 (n=1)
5 (n=5)
20 (n=20)
输出
sum = 2.00 (第1项是2.00)
sum = 8.39 (前5项的和是8.39)
sum = 32.66 (前20项的和是32.66)
#include <stdio.h>
int main(void)
{
int i, n;
int repeat, ri;
double denominator, numerator, sum, temp;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%d", &n);
sum=0;
denominator=1;
numerator=2;
for(i=1;i<=n;i++){
sum += numerator/denominator;
temp = denominator; /* 为求下一项分子,保留当前项分母 */
denominator=numerator;
numerator=numerator+temp;
}
printf("sum = %.2f\n",sum);
}
}
高空坠球 (循环语句)
程序填空,不要改变与输入输出有关的语句。
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
皮球从 height(米)高度自由落下,触地后反弹到原高度的一半,再落下,再反弹,……,如此反复。问皮球在第 n 次落地时,在空中一共经过多少距离?第 n 次反弹的高度是多少?(输出保留1位小数)
输入输出示例:括号内是说明
输入
3 (repeat=3)
10 2 (height=10m, n=2)
4 1 (height=2m, n=1)
100 8 (height=100m, n=8)
输出
distance=20.0, height=2.5 (第2次落地时,空中经过距离为20米, 第2次反弹高度为2.5米)
distance=4.0, height=2.0 (第1次落地时,空中经过距离为4米,第1次反弹高度为2米)
distance=298.4, height=0.4 (第8次落地时,空中经过距离为298.4米,第8次反弹高度为0.4米)
#include <stdio.h>
int main(void)
{
int i, n;
int repeat, ri;
double distance, height, bh;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%lf%d", &height, &n);
/*---------*/
distance = height;
bh = height/2.0;
if ( n>1 )
for (i = 2; i<=n; i++) {
distance += bh*2;
bh = bh/2;
}
printf("distance = %.1f, height = %.1f\n", distance, bh);
}
}
5.5循环的嵌套
使用嵌套循环求e = 1+1/1!+1/2!+....+1/n!
程序填空,不要改变与输入输出有关的语句。
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
输入1个正整数n,计算下式的前n+1项之和(保留4位小数)。要求使用嵌套循环。
e = 1+1/1!+1/2!+....+1/n!
输入输出示例:括号内为说明
输入:
2 (repeat=2)
2 (n=2)
10 (n=10)
输出:
e = 2.5000
e = 2.7183
#include "stdio.h"
int main(void)
{
int i, j, n;
int repeat, ri;
double e, product;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%d", &n);
e = 1.0;
for (i = 1; i<= n; i++) {
product = 1;
for (j = 1; j<=i ; j++) {
product *= j;
}
e += 1.0/product;
}
/*---------*/
printf("e = %0.4f\n", e);
}
}
40023 换硬币 (多重循环语句)
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
将一笔零钱(大于8分,小于1元, 精确到分)换成5分、2分和1分的硬币。
输入金额,问有几种换法?针对每一种换法,每种硬币至少有一枚,请输出各种面额硬币的数量和硬币的总数量。
要求:硬币面值按5分、2分、1分顺序,各类硬币数量依次从大到小的顺序,输出各种换法。
输出使用语句:printf("fen5:%d,fen2:%d,fen1:%d,total:%d\n",fen5, fen2, fen1, fen5+fen2+fen1);
输入输出示例:括号内为说明
输入:
2 (repeat=2)
10 (money=10分)
13 (money=13分)
输出:
fen5:1,fen2:2,fen1:1,total:4
fen5:1,fen2:1,fen1:3,total:5
count = 2 (10分有2种换法)
fen5:2,fen2:1,fen1:1,total:4
fen5:1,fen2:3,fen1:2,total:6
fen5:1,fen2:2,fen1:4,total:7
fen5:1,fen2:1,fen1:6,total:8
count = 4 (13分有4种换法)
#include "stdio.h"
int main(void)
{
int count, fen1, fen2, fen5, money;
int repeat, ri;
scanf("%d", &repeat);
for(ri = 1; ri <= repeat; ri++){
scanf("%d", &money);
count=0;
for(fen5=money/5;fen5>=1;fen5--)
for(fen2=money/2;fen2>=1;fen2--)
for(fen1=money/1;fen1>=1;fen1--)
if(fen5*5+fen2*2+fen1*1==money){
printf("fen5:%d,fen2:%d,fen1:%d,total:%d\n",fen5, fen2, fen1, fen5+fen2+fen1);
count++;}
printf("count = %d\n", count);
}
return 0;
}
5.6几种循环的比较
5.7改变循环执行的状态
用break语句提前终止循环
验证歌德巴赫猜想(选作)
程序填空,不要改变与输入输出有关的语句。
验证哥德巴赫猜想:任何一个大于6的偶数均可表示为两个素数之和。例如6=3+3,8=3+5,…,18=7+11。
输入两个正整数 m 和 n(6<=m, n<=100),将 m 到 n 之间的偶数表示成两个素数之和,打印时一行打印5组。
输出使用语句:printf("%d=%d+%d ", number, i, number - i);
输入输出示例:括号内为说明
输入:
89 100 (m=90, n=100)
输出:
90=7+83 92=3+89 94=5+89 96=7+89 98=19+79
100=3+97
#include "stdio.h"
#include "math.h"
int main(void)
{
int count, i, j, k, m, n, number;
scanf("%d%d", &m, &n);
if(m % 2 != 0) m = m + 1;
if(m >= 6){
/*---------*/
}
}
#include <stdio.h>
int prime(int m)
{
int i, ifPrime=0;
if(m==1) return 0;
for(i=2;i<=m/2;i++) {
if(m%i==0)
break;
}
if(i>m/2)
ifPrime=1;
return ifPrime;
}
int main(void)
{
int count, i, m, n, number;
scanf("%d%d", &m, &n);
if(m % 2 != 0) m = m + 1;
if(m >= 6) {
count=0;
for(number=m;number<=n;number=number+2) {
for(i=1;i<=number/2;i++) {
if( prime(i) && prime(number-i) ) {
printf("%d=%d+%d ", number, i, number-i);
count++;
if(count%5==0)
printf("\n");
break;
}
}
}
}
}
注:此题标准答案是输出每个数的第一对满足条件的素数之和,但是:
90=7+83 90=11+79 90=17+73 90=19+71 90=23+67 ...90=83+7
也都是满足条件的, 而机器只对输出第一种为正确解
用continue语句提前结束本次循环
一定要记住当执行continue时只是结束本次循环而不是终止整个循环的执行。而break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。
continue语句应该这样理解:当执行continue语句时,流程跳转到表示循环体结束的右花括号的前面(注意不是右花括号的后面) 也可以理解为continue后的不执行,然后重新进入下一次新的循环当中
# include <stdio.h>
int main(void)
{
int val; //variable的缩写, “变量”的意思
printf("请输入您想去的楼层:");
while (1)
{
scanf("%d", &val);
switch (val)
{
case 1:
printf("1层开!\n");
break; //跳出switch
case 2:
printf("2层开!\n");
break; //跳出switch
case 3:
printf("3层开!\n");
break; //跳出switch
default:
printf("该层不存在, 请重新输入:");
continue; //结束本次while循环
}
break; //跳出while
}
return 0;
}
区别:
continue和break的区别
continue 语句和 break 语句的区别是,continue 语句只结束本次循环,而不是终止整个循环。break 语句则是结束整个循环过程,不再判断执行循环的条件是否成立。而且,continue 只能在循环语句中使用,即只能在 for、while 和 do…while 中使用,除此之外 continue 不能在任何语句中使用。
所以,再次强调:continue 不能在 switch 中使用,除非 switch 在循环体中。此时 continue 表示的也是结束循环体的本次循环,跟 switch 也没有关系。
第五章典型题(循环):
斐波那契数列
【C语言】斐波那契数列_EurekaO-O的博客-CSDN博客_斐波那契数列c语言
斐波那契数列_详解(C语言)_小-黯的博客-CSDN博客_斐波那契数列c语言
斐波那契数列的四种实现方式(C语言)_cherrydreamsover的博客-CSDN博客_斐波那契数列c语言
第五章习题答案:
C语言程序设计第五版谭浩强课后答案 第五章习题答案_月已满西楼的博客-CSDN博客_统计出当fabs(t) >= pow(10, -6)和fabs(t) >= pow(10, -8)时
3.输人两个正整数m和n,求其最大公约数和最小公倍数
答案解析:
该题题目直接使用“辗转相除法”来求解最大公约数,以除数和余数反复做除法运算,当余数为 0 时,就取得当前算式除数为最大公约数。
最大公约数和最小公倍数之间的性质:两个自然数的乘积等于这两个自然数的最大公约数和最小公倍数的乘积。所以,当我们求出最大公约数,就可以很轻松的求出最小公倍数。
代码示例:
#include <stdio.h>
int main()
{
int p, r, n, m, temp;
printf("请输入两个正整数n,m:");
scanf("%d%d,", &n, &m);
//调整n保存较大的值
if (n < m)
{
temp = n;
n = m;
m = temp;
}
p = n * m;
while (m != 0)
{
r = n % m;
n = m;
m = r;
}
printf("它们的最大公约数为:%d\n", n);
printf("它们的最小公倍数为:%d\n", p / n);
return 0;
}
6.求∑ n = 1 20 n ! \sum\limits_{n=1}^{20}n!
n=1
∑
20
n! (即求1!+2!+3!+4!+…+20!)。
答案解析:
该题需要从1循环到20,依次求出每一个数字阶乘的结果。所以在代码当中需要有两个循环,大循环从1到20,保证1到20个数字都被循环到,小循环里计算N阶乘,累加求和。注意:对于20的阶乘已经超出了int类型能过表示的数字范围,所以在代码当中使用double类型
代码示例:
#include<stdio.h>
int main()
{
double total_sum = 0;
for(int i = 1; i <= 20; i++)
{
double single_sum = 1;
for (int j = i; j > 0; j--)
{
single_sum *= j;
}
total_sum += single_sum;
}
printf("1~20每个数字阶乘总和为:%lf\n",total_sum);
return 0;
}
8.输出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。例如,153是水仙花数,因为153=1*+5*+3。
答案解析:
从题目当中得到”水仙花数“为一个3位数,则范围确定为[100, 999]。另外需要获取该数字的百位数字,十位数字,个位数字相加起来等于该数本身,则我们需要使用到%除的方式,来获取每一个位权的数字。
代码示例:
#include <stdio.h>
int main()
{
//a表示百位数字,b表示十位数字,c表示各位数字
int a, b, c;
for (int i = 100; i <= 999; i++)
{
a = i / 100;
b = (i / 10) % 10;
c = i % 10;
if (a * a * a + b * b * b + c * c * c == i)
{
printf("%d\n", i);
}
}
return 0;
}
第五章目录回顾:
5.1为什么需要循环控制110
5.2用while语句实现循环111
5.3用do…while语句实现循环113
5.4用for语句实现循环116
5.5循环的嵌套120
5.6几种循环的比较121
5.7改变循环执行的状态121
5.7.1用break语句提前终止循环122
5.7.2用continue语句提前结束本次循环123
5.7.3break语句和continue语句的区别124
5.8循环程序举例127