C语言总结(第5章循环结构程序设计)

简介: 第5章循环结构程序设计结构化程序设计的3种基本结构:循环结构 顺序结构 选择结构

第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


目录
相关文章
|
3月前
|
算法 C语言
C语言------循环结构II
这篇文章是C语言循环结构II的实训教程,通过多个实例程序,教授如何综合运用选择结构和循环语句解决问题,体会算法在程序设计中的作用,并复习程序调试功能和技巧。
C语言------循环结构II
|
2月前
|
C语言
C语言程序设计核心详解 第四章&&第五章 选择结构程序设计&&循环结构程序设计
本章节介绍了C语言中的选择结构,包括关系表达式、逻辑表达式及其运算符的优先级,并通过示例详细解释了 `if` 语句的不同形式和 `switch` 语句的使用方法。此外,还概述了循环结构,包括 `while`、`do-while` 和 `for` 循环,并解释了 `break` 和 `continue` 控制语句的功能。最后,提供了两道例题以加深理解。
|
2月前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。
|
2月前
|
存储 C语言
C语言程序设计核心详解 第七章 函数和预编译命令
本章介绍C语言中的函数定义与使用,以及预编译命令。主要内容包括函数的定义格式、调用方式和示例分析。C程序结构分为`main()`单框架或多子函数框架。函数不能嵌套定义但可互相调用。变量具有类型、作用范围和存储类别三种属性,其中作用范围分为局部和全局。预编译命令包括文件包含和宏定义,宏定义分为无参和带参两种形式。此外,还介绍了变量的存储类别及其特点。通过实例详细解析了函数调用过程及宏定义的应用。
|
2月前
|
C语言
C语言程序设计核心详解 第三章:顺序结构,printf(),scanf()详解
本章介绍顺序结构的基本框架及C语言的标准输入输出。程序从`main()`开始依次执行,框架包括输入、计算和输出三部分。重点讲解了`printf()`与`scanf()`函数:`printf()`用于格式化输出,支持多种占位符;`scanf()`用于格式化输入,需注意普通字符与占位符的区别。此外还介绍了`putchar()`和`getchar()`函数,分别用于输出和接收单个字符。
|
2月前
|
存储 算法 C语言
C语言程序设计核心详解 第一章:数制及转换与ASCII码
本专栏旨在夯实C语言基础,涵盖基础知识与进阶内容,助力解决自命题考试和考研问题,为数据结构与算法设计奠定坚实基础。内容包括数制及其转换、ASCII码、内存管理、机器码等,重点讲解二进制、八进制、十六进制的概念与转换方法,并介绍C语言的结构、数据类型和标识符规范。
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。
|
2月前
|
存储 C语言
C语言程序设计核心详解 第九章 结构体与链表概要详解
本文档详细介绍了C语言中的结构体与链表。首先,讲解了结构体的定义、初始化及使用方法,并演示了如何通过不同方式定义结构体变量。接着,介绍了指向结构体的指针及其应用,包括结构体变量和结构体数组的指针操作。随后,概述了链表的概念与定义,解释了链表的基本操作如动态分配、插入和删除。最后,简述了共用体类型及其变量定义与引用方法。通过本文档,读者可以全面了解结构体与链表的基础知识及实际应用技巧。
|
2月前
|
C语言
C语言程序设计核心详解 第二章:数据与数据类型 4种常量详解 常见表达式详解
本文详细介绍了C语言中的数据与数据类型,包括常量、变量、表达式和函数等内容。常量分为整型、实型、字符型和字符串常量,其中整型常量有十进制、八进制和十六进制三种形式;实型常量包括小数和指数形式;字符型常量涵盖常规字符、转义字符及八进制、十六进制形式;字符串常量由双引号括起。变量遵循先定义后使用的规则,并需遵守命名规范。函数分为标准函数和自定义函数,如`sqrt()`和`abs()`。表达式涉及算术、赋值、自增自减和逗号运算符等,需注意运算符的优先级和结合性。文章还介绍了强制类型转换及隐式转换的概念。