hello,大家好,我是霜淮子,阅读我的文章学习c语言,作者水平有限,如果发现错误的地方,欢迎大家在评论区留言,万分感谢!
欢迎订阅专栏《c语言程序设计》
目录
前言
在程序设计中,如果需要重复执行某些操作,就要用到循环结构,循环结构有两种形式:当型循环和直型循环。
4.1、循环
4.1.1、有些事情就得用循环才能解决
举个简单的例子,判断一个整数数是几位数,给出你一个数456,让你去判断这个数字是几位数,你可以一眼看出来这是一个三位数,但是你把这个数字给计算机的话,你就需要给他描述一个如何判断的步骤,比如说这个数字在100-999之间,是三位数,在1000-9999之间呢是四位数 ,可以用到之前说的if级联去判断,随着位数的不断增多,我们所写的if也就要多一层,你根本不知道什么时候才是一个头。
在夸张一点,判断45245343123454121678421这串数字,人为都要去数一大半天,所以我们要想办法让计算机来帮助我们。
4.1.2、while循环
就像if一样,条件满足就不断地做后面大括号里面的句子。
if(x>0){
x/=10;
n++;
}
while(x>0){
x/=10;
n++;
}
我们可以来看一下他的设计框图,方便更好的理解
- if和while最大的区别就是做一次还是反复的多次做,当然,最重要的一点就是我们的循环体内要有改变条件的机会,否则就会进入死循环,出不来, 如果在比赛时需要判断时间的时候,就很容易被认定为超时。
- 如果我们把while翻译做”当“,那么一个while循环的意思就是:当条件满足的时候,不断地重复循环体内的语句。
- 循环执行之前判断是否继续循环,所以有可能循环一次都没有被执行。
- 条件成立是循环继续的条件。
4.1.3、do-while循环
不管三七二十一,先做循环内的句子在判断条件
在进入循环的时候不做检查,而是在执行完一轮循环体的代码之后,再来检查循环的条件是否满足,如果满足则进行下一轮循环,不满足则结束循环。
do-while循环长下面这个样子
do
{
<循环体语句>
}while(<循环条件>);
注意结束循环条件的括号是分号,不然相当于循环没有结束。
4.2、第三种循环
4.2.1、for循环
for循环像一个计数循环:设定一个计数器,初始化它,然后在计数器达到某值之前,重复执行循环体,而每执行一轮循环体,计数器以一定步进进行调整,比如加1或者减1,
for(i=0;i<5;i=i+1){
printf("%d",i);
看for后面括号里的表达式,用分号隔开的,他们的意思分别是:
”i=0;"----初始动作
"i<5;"---- 循环继续的条件
"i++"----循环每一轮要做的动作
4.2.2、循环的选择
a、如何计算循环的次数
循环次数:for(i=0;i<n;i++)
则循环次数是n,而循环结束以后,i的值是n。循环控制变量i,是选择从0开始的还是从1开始,是判断i<n还是i=n,对循环的次数,循环结束后变量的值都有影响。
大家可以借助下面这个代码去理解
#include<bits/stdc++.h>
using namespace std;
int main(){
int i;
for(i=0;i<5;i=i+1){
printf("i=%d",i);
}
printf("\n最后的i=%d\n",i);
}
tips:for循环里面的每一个语句都能省略,但是;得留着,不然你可以试试,
b、如何选择不同的循环
选择tips:
- 如果有固定次数,用for
- 如果必须执行一次,用do-while
- 其他情况用while
4.3、循环控制
4.3.1、如何让用break和continue来控制循环
break VS continue
- break:跳出循环
- continue:跳过循环这一轮剩下的语句进入下一轮(放弃了执行那一轮的东西)
看流程图大家能更好的分析
4.3.2、嵌套的循环
嵌套的循环就是在循环里还是循环。
那如何从嵌套的循环中跳出呢?
一个break只能跳出一层循环;我们可以使用接力break跳出整个循环;
#include<bits/stdc++.h>
using namespace std;
int main(){
int x;
int one,two,five;
scanf("%d",&x);
for(one=1;one<x*10;one++){
for(two=1;two<x*10/2;two++){
for(five=1;five<x*10/5;five++){
if(one+two*2+five*5==x*10){
printf("可以用%d个1角加%d个2角加%d个五角得到%d元 \n",one,two,five,x);
}
}
}
}
return 0;
}
这是一个枚举问题,大家可以通过调试来查看,每一层循环之后下一步会跳到哪里,当我们在加上break之后,程序又会如何跳转。
除此之外还可以使用“goto"语句
现在我们来看卡goto 语句的用法,我们只需要在整个程序需要离开的地方放一个goto语句,goto语句后面还需要一个标号,这个标号是我们在程序里面自己设的,自己写的,
意思就是我们的goto就可以直接跳到这个地方。
所以当我们在编写程序的时候,需要从最内层跳到最外层的时候就可以使用这个goto语句。
4.4、循环应用
4.4.1、循环计算
作为语言本身不难,那编程难在想问题,如何去把这些问题变成程序,难在如何把一些细微的问题转化为程序,
例如我们现在计算
#include<stdio.h>
int main(){
int x;
int ret=0;
scanf("%d",&x);
while(x>1){
x/=2;
ret ++;
}
printf("log2 of %d is %d.",x,ret);
}
代码分析:
大家输入不同的数字,比如64或者128,他的运行结果都是log2 of 1 is多少,为什么最后输出的X都是1呢,那是因为在整个循环算完之后这个X就肯定是1,在计算的时候X的值在不断的变化,所以我们在输出的时候输出的就是留下的那个X的值,
tips:当我们在后面有可能用到原始大热X值的时候,我们在计算之前应该保留原始值。
把int x;换成int t=x;最后输出或者使用的时候,我们输成t就欧克了。
大家可以思考一下下面两个问题:
1、我们的ret值为什么是从0开始的?
2、while后面的判断条件为什么是“>1”的?
4.4.2、猜数游戏
现在让我们来做一个猜数游戏
让计算机来想一个数,然后让用户来猜,用户每输入一个数,就告诉它是大了还是小了,直到用户猜中为止,最后还要告诉用户猜了多少次。
注意:
因为需要不断需要用户去猜,所以需要用到循环
在实际写出程序之前,我们可以先用文字描述程序的思路,
核心重点是循环的条件,
接下来我们用自然语言来描述一下这个题的解题思路:
1、计算机随机想一个数,记在变量number里;
2、一个负责计次数的变量count初始化为0;
3、让用户输入一个数字a;
4、count递增(加一);
5、判断a和number的大小关系,如果a大,就输出“大”;如果a小就输出“小”;
6、如果a和number是不相等的,无论大还是小,程序转回第3步;
7、否则、程序输出“猜中”和次数,然后结束。
代码如下
#include<bits/stdc++.h>
using namespace std;
int main()
{
srand(time(0));
int number = rand()%100+1;
int count =0;
int a=0;
printf("我已经想好一个1到100之间的数字:");
do{
scanf("%d",&a);
count ++;
if(a>number){
printf("你猜的数大了!");
} else if(a<number){
printf("你猜的数字小了!");}
}while(a!=number);
printf("太好了,你用了%d次就猜对了答案,\n",count);
}
运行结果:
代码分析:#include<bits/stdc++.h>这个是一个万能头文件,暂时先别管,
随机数:每次召唤rand()就得到一个随机的整数,
取余:x%n的结果是[0,n-1]的一个整数,
4.4.3、算平均数
过程就不给大家分析了,直接看算法吧
1、初始化变量sum和count为0;
2、读入number;
3、如果number不是-1,则将number加入su,,并将count加1,回到2;
4、如果number是-1,则将计算和打印出sum/count(注意转换成浮点数来计算);
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main (){
int number;
int sum=0;
int count=0;
do{
scanf("%d",&number);
if(number!=-1){
sum+=number;
count++;}
}while(number!=-1);
printf("%d",sum/count);
//printf("%f",1.0*sum/count);
return 0;
}
4.4.4、整数求逆
整数的分解
- 一个整数是由1至多位数子组成的,如何分解出整数的各位上的数字,然后加以计算。
- 对一个整数做%10的操作,就是得到他的个位数;
- 对一个整数做/10的操作,就是去掉他的个位数;
- 然后再对2的结果做%10,就得到原来的十位数;
- .......
- 一次类推
大家可以通过一些简单的代码去验证
#include<bits/stdc++.h>
using namespace std;
int main (){
int number;
int x;
scanf("%d",&number);
x=number/10;
printf("%d\n",x);
return 0;
}
#include<stdio.h>
int main(){
int x;
scanf("%d",&x);
int digit;
int t=0;
while(x>0){
digit=x%10;
x/=10;
t=t*10+digit;
}
printf("%d",t);
return 0;
}
4.4.5、求1/n的前n项和F(n)
#include<bits/stdc++.h>
using namespace std;
int main (){
int n;
int i;
double sum=0.0;
scanf("%d",&n);
for (i=1;i<=n;i++){
sum+=1.0/i;
}
printf("F(n)=%f\n",sum);
return 0;
}
4.4.6、求最大公约数
#include <stdio.h>
int main()
{
int a,b,c; //先定义变量
printf("请输入:\n");
scanf("%d%d",&a,&b); //输入两个整型数字
if(a<b)
{
c=a;
a=b;
b=c; //保证a≥b
}
int i = 0;
for(i = b;i>0;i--)
{
if(a%i == 0 && b%i == 0)
{
printf("gcd(%d,%d) = %d\n",a,b,i);
break;
}
}
return 0;
}
-END-