news 2026/8/13 13:35:59

第二章 循环结构程序设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第二章 循环结构程序设计

2.1 for循环

for循环的格式为:for(初始化;条件;调整) 循环体;

#include<stdio.h> int main(){ int i; for(i = 1;i<8;i++) printf("%d",i); printf("%d",i); //说是有这一行会报错 return 0; }

建议尽量缩短变量的定义范围。例如,在for循环的初始化部分定义循环变量。

#include<stdio.h> int main(){ int i; for(i=1;i<6;i++) printf("%d\n",i); printf("%d\n",i); for(i=1;i<6;i++) return 0; }

Visual C++6.0等早期编译器允许在循环体之后访问i,但这样,如果再写一个“for(int i = 0;i<n;i++)"则会出现i定义的错误。

但是

#include<stdio.h> int main(){ int i; for(i=1;i<6;i++) printf("%d\n",i); printf("%d\n",i); for(int i=0;i<6;i++) return 0; }

没有出现什么报错嘞?

#include<stdio.h> int main(){ for(int i=1;i<6;i++) printf("%d\n",i); printf("%d\n",i); for(int i=0;i<6;i++) return 0; }

是我错了这样就会像书本上说的报错了.(还是讲究作用范围)

不拘一格的使用伪代码来思考问题和描述算法是一种值得推荐的做法。

判断是否为平方数:

我的代码:

#include<stdio.h> #include<math.h> int main(){ int a,b,c,e; float d; scanf("%d%d",&a,&b); c = 1100*a+11*b; d = sqrt(c); e = d; if(e==d) printf("%d是平方数",c); return 0; }

具体的题目是找出满足AABB形式的完全平方数,我完成以上的代码后AI告诉我,浮点数的运算会有误差因此这个开方的办法行不通,下面是另一种办法是用平方根去推完成平方数。

#include<stdio.h> int main(){ int a; int m = 0; for(m;m*m<10000;m++){ if(m*m > 1000){ a = m*m; int qian = a / 1000; // 千位 int bai = a / 100 % 10; // 百位 int shi = a / 10 % 10; // 十位 int ge = a % 10; // 个位 if(qian == bai && shi == ge) printf("%d是完全平方数",a); } } return 0; } //能正常运行出结果7744

以下是课本上的代码

#include<stdio.h> int mian(){ for(int x = 1; ;x++) { int n = x * x; if(n<1000) continue; if(n>9999) break; int hi = b/100; int lo = n%100; if(hi/10 == hi%10 && lo/10 == lo%10) printf("%d\n",n); } return 0; }

在C语言中,continuebreak是控制循环语句执行流程的关键字,主要用于forwhiledo-while循环中。

break用于立即终止当前所在的循环或switch语句,程序会继续执行循环或switch之后的代码。

  • 在循环中使用break会直接跳出整个循环,不再执行循环内剩余的语句。
  • switch中使用break会跳出当前的case分支,防止“穿透”到下一个case

continue 的用法

continue用于跳过当前循环的剩余部分,直接进入下一次循环的条件判断或迭代。

  • for循环中,continue会跳到迭代部分(如i++)后再判断条件。
  • whiledo-while循环中,continue会直接跳到条件判断部分。

两者区别:

continue 的用法

continue用于跳过当前循环的剩余部分,直接进入下一次循环的条件判断或迭代。

  • for循环中,continue会跳到迭代部分(如i++)后再判断条件。
  • whiledo-while循环中,continue会直接跳到条件判断部分。

2.2while循环和do-while循环

猜想,输入一个大于1的自然数,若n为奇数则把n变为3n+1否则变为n的一半,经过若干次这样的变换结果一定等于1,但是问输入一个数求变换次数。

#include<stdio.h> int n; int s = 0; scanf("%d",&n); while(n!=1){ s++; if(n%2==0) n = n/2; else n=3*n+1; } printf("%d",s); return 0; } //通过实例输入3 输出7.正确。

欧,不不不对,疏忽了,这是算法书上的:

#include<stdio.h> int main() { int n,count = 0; scanf("%d",&n); while(n>1) //这点我疏忽了, 题目有说须有体现 { if(n%2==1) n = n*3+1; //开始我写成了3n+1,注意乘法之间须有乘法符号 else n/=2; count++; } printf("%d/n",count); return 0; }

书上说,当输入为987654321时,结果为1(但是我的电脑上就没显示结果,像是算不出来一样),这明显是错误的。错就错在乘法那里可能数据溢出了,好我们在来回顾一下第一章里,int整数的大小很可能是-2147483648~2147483647,很可能就很讲究了因为C99中只规定了int至少是16位没有规定具体值,但是目前的比赛平台上int都是32位整数。

while循环的格式为“while(条件)循环体;”。

例题2-3 计算4分之派=1-1/3+1/5-1/7+······,知道最后一项小于10的负六次方。

这是课本上的代码,我花了较长时间没能想出来是因为我不知道派怎么打出来,当我看到解答时就疑惑了,直接没有管这个四分之派。那么就是以小于10的负六次方为终止条件。

#include<stdio.h> int main(){ double sum = 0; for(int i = 0; ;i++) { double term = 1.0/ (i*2+1); if(i%2 == 0) sum += term; else sum -=term; if (term < 1e-6) break; } printf("%.6f\n",sum); return 0; }

我有do-while 写的解题代码:

double n, sum = 1.0; int i=1;//不能写在do里面 do { n = 1.0/(i*2+1);//注意要用1.0来除以 if(i%2==0) sum += n;//判断好该加还是改减 else sum -= n; i++;//do-while 本身就是个循环,不要在里面再写一个for循环(我开始就犯了这样的错误) } while(n>(1e-6));//注意加分号 printf("%.6f\n",sum); return 0;//0.785399

do-while 循环的格式为“do{循环体}while(条件);其中循环体至少执行一次,每次执行完循环后判断 条件,满足时再继续循环。

阶乘之和的题目

阶乘之和是一个经典的编程练习题,通常要求计算 1! + 2! + 3! + ... + n! 的末六位。下面是我的代码:

#include<stdio.h> int main(){ const int mod = 1000000; int n,m=1,s=0; scanf("%d",&n); for(int i=1;i<=n;i++) { m=1; for(int j = 1;j<=i;j++) { m = (m * j) % mod; } s=(s+m)%mod; } printf("%d",s); return 0; }

提示:要计算只包含加法、减法和乘法的整数表达式除以正整数 n 的余数,可以在每步计算之后对 n 取余,结果不变。

这句话的意思是:在计算一个只包含加、减、乘运算的整数表达式时,如果我们最终需要的是这个表达式的结果除以一个正整数 n 的余数(即结果对 n 取模),那么我们可以不必等到计算出整个表达式的最终结果后再取余,而是在每一步计算(每次加法、减法或乘法)之后,立即将中间结果对 n 取余,用这个余数继续参与后续计算,最终得到的余数与先算出完整结果再取余的结果是相同的。

为什么这样做?

  • 防止溢出:在编程中,直接计算阶乘等大数可能会超出整数类型的表示范围(溢出)。每步取余可以保证中间结果始终在 0 到 n-1 之间,避免溢出。
  • 提高效率:对于非常大的数,每步取余可以保持数字较小,计算更快。

这样太慢了,加上一个计时器,看看究竟有多慢。

#include<stdio.h> #include<time.h> int main(){ const int mod = 1000000; int n,m=1,s=0; scanf("%d",&n); for(int i=1;i<=n;i++) { m=1; for(int j = 1;j<=i;j++) { m = (m * j) % mod; } s=(s+m)%mod; } printf("%d",s); printf("Time used = %.2f\n",(double)clock() / CLOCKS_PER_SEC); return 0; }

键盘输入的时间也会被计算在内,为了避免输入数据的时间影响测试结果,可以使用一种称为“管道”的小技巧:在Windows命令行下执行echo 20| abc,操作系统会自动把20输入,其中abc是程序名。

2.4 算法竞赛中的输入输出框架

例题2-5 数据统计

输入一些数,求出他们的最大值、最小值和平均值(保留三位小数)。输入保证这些数都是不超过1000的整数。

这里得注意一下,我们的要求是直接输入一系列整数,开始不知道会输入多少个整数。那么这该怎么办呢?这个我想了一下,我不会,只有跟着教材来进行学习。(以下代码有BUG)

#include<stdio.h> //有BUG int main(){ int x,n = 0, min,max,s = 0; while (scanf("%d",&x) == 1) { s+=x; if(x<min) min = x; if(x>max) max = x; n++; } printf("%d %d %.3f\n",min,max,(double)s/n); return 0; }

我输入了一大串按了enter没有反应,回顾一下(scanf的输入格式是,空格,TAB和回车都是无关紧要的,那么我们应该怎么告诉他输入结束了呢?)

提示:在windows下,输入完毕后先按Rnter键,再按Ctrl+Z,最后再按Enter键即可结束。在Linux下,输入完毕后按Ctrl+D即可结束。

结果可得,但是你应该发现最大值是一个与输入无关的值,为什么?,因为变量max一开始就等于那个数,自然不能更新为更小的。

提示:变量在未赋值之前的值是不确定的。特别的,他不一定是0。

解决方法:把max的初始值定义成一个比较小的数,把min的初始值定义为一个比较大的数就行,或者先读取第一个数x,把max=min=x。

还有就是说,每次都要输入许多数,这样会很不方便,那么好,一个好的方法就是用文件————

把输入的数据保存在文件中,就不必每次输入了;也避免了输出太多一卷屏前面看不到的尴尬。使用文件最简单的方法是使用输入输出重定向,只需在main函数的入口处加入以下两条语句:

freopen("input.txt","r",stdin);

freopen("output.txt","w",stdout):

上述语句将使得scanf从文件input.txt读入 ,printf写入文件output.txt.事实上,不只是scanf和printf,所有读键盘、写屏幕输出的函数都将改用文件。尽管这样做很方便,但是不是所有的算法竞赛都允许用程序读写文件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/13 13:35:24

揭秘绵阳网站建设费用背后的真实逻辑,为什么你的报价总是差这么多

在绵阳这座充满生活气息的城市里,做生意的朋友们越来越多,大家也越来越意识到,拥有一个专业的网站不仅仅是为了在网络上“挂个号”,更是企业形象的延伸,是客户了解你的第一扇窗口。但是,每当有人问起:“绵阳网站建设费用大概是多少?”这个问题就像是一道坎,挡在很多老…

作者头像 李华
网站建设 2026/8/13 13:34:55

开源AI视频工具ZJT智剧通:从文本到分镜与口型同步实战指南

你有没有遇到过这样的场景&#xff1a;手里有一段视频素材&#xff0c;或者一个故事脚本&#xff0c;想要快速把它变成分镜图&#xff0c;或者直接修改视频里人物的口型、动作&#xff0c;让它更贴合你的新台词&#xff1f;过去&#xff0c;这可能意味着你要打开专业的视频编辑…

作者头像 李华
网站建设 2026/8/13 13:34:23

The Empowerment of Science of Science by Large Language Models: New Tools and Methods

文章主要内容与创新点总结 一、主要内容 本文系统围绕大型语言模型(LLMs)赋能科学学(SciSci)展开研究,核心内容分为三大模块: 1. 大型语言模型(LLMs)基础解析 定义与核心特征:LLMs是具备海量参数和复杂计算结构的基础模型,具有可扩展性、涌现性和通用性,是自然语…

作者头像 李华
网站建设 2026/8/13 13:33:52

TranslucentTB:让你的Windows任务栏焕然一新的透明美化神器

TranslucentTB&#xff1a;让你的Windows任务栏焕然一新的透明美化神器 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 你是否厌倦了Wind…

作者头像 李华
网站建设 2026/8/13 13:33:25

零基础快速制作专业泳道图的实用指南

1. 项目概述&#xff1a;零基础制作专业泳道图 在业务流程梳理和系统设计领域&#xff0c;泳道图&#xff08;Swimlane Diagram&#xff09;一直是最直观的表现形式之一。传统上这类专业图表需要依赖Visio等付费工具或者复杂的设计软件&#xff0c;操作门槛让很多业务人员望而却…

作者头像 李华