c语言入门---循环语句

前言

亲爱的小伙伴们大家好啊,之前我们说过c语言是一个结构化的程序设计语言,有顺序结构,选择结构,循环结构,那么这一章我们就要学习最后一个结构,叫循环结构废话不多说我们开始学习吧。


一.为什么有循环结构

  我们先来想象一下我们生活中的现代化工厂里面的流水线,在没有机器人之前,都是我们人类来干这些重复枯燥的工作,但是我们人类也是生物,我们的注意力,耐力都会随着工作时间的增加而一点一点的减少,这也就导致生产的效率低下,但是随着我们人类科技的发展,我们发明出来了机器人,这些各种各样的机器人就可以替代我们干这些枯燥乏味还很耗体力的事情,又因为机器人拥有许多我们人类没有的能力,所以机器人在干这些事情的时候,拥有更高的效率而且成本还更低,那么这是我们在生活中,在c语言当中循环结构就扮演者机器人的工作,比如说我们要打印1000个hello world这句话,如果使用循环结构,几行代码就写完了,但是使用顺序结构我们就得写1000行 printf语句才能完成这个目的,那么我们再回过头来看为什么会有循环结构,就是因为他可以使那些重复性的工作,需要很多时间的工作,要很多行一模一样的代码的工作得到极大的简化,那我们接下来就来看有哪些循环语句。


二.while循环

  在学习while循环之前我们先来看看之前学的if语句:
请添加图片描述
这是我们if语句的基本形式,当条件满足之后,就会执行下面的语句,如果条件不满足,就不会执行下面的语句,而且这个语句它只会执行一次,但是在外面的生活中其实有很多实际的例子,他在满足情况下是要重复做很多次的,并且每做一次有些变量还要发生改变,从而影响了判断的结果,那我们的if语句显然很难满足这一要求,那么我们c语言就引入了while语句。

1.while循环的基本形式

请添加图片描述
  while语句的基本形式如图所示,while语句首先检验一个条件,也就是括号中的表达式。当条件为真时,就执行紧跟其后的循环语句或者语句块。每执行一遍循环,程序都将回到while语句处,重新检验条件是否满足。如果一开始条件就不满足,则跳过循环体中的语句,直接执行后面的程序代码。如果第一次检验时条件满足,那么在第一次或其后的循环过程中,必须得有使条件为假的操作,否则循环就无法终止,我们把无法终止的循环通常称为死循环或者无限循环。

2.while循环的例子

第一个例子:
计算n~100的累加,用户输入一个值,从这个值开始,依次与之后的连续若干个自然数相加,当该自然数大于100时结束,并输出这若干个自然数的和。
第一步:
我们首先可以看到我们首先得提示使用者一些基本的信息,于是就得使用printf函数,使用者要输入一个值,那么我们就得使用scanf函数,并且得创建一个变量来储存这个值,那么我们的代码如下:

#include<stdio.h>
int main()
{
	int n = 0;
	printf("请输入一个小于100整数\n");
	scanf("%d", &n);
	return 0;
}

第二步:
我们使用者输入了一个值但是这个值可能大于100,那么我们这时就得提醒一下使用者您输入的值不符合要求,那么首先我们得进行一次判断,判断是否大于100,那么这里就有两种可能一种是小于等于100,一种就是大于100,那么我们这里就可以使用if…else语句在第一个if后面的括号中填入n<=100,下面的语句块中实现计算的功能,在else下面的语句块里面用printf语句告诉使用者您输入的数据错误,那么代码如下:

#include<stdio.h>
int main()
{
	int n = 0;
	printf("请输入一个小于100整数\n");
	scanf("%d", &n);
	if (n <= 100)//判断输入的数小于等于100
	{
		语句块
	}
	else//判断输入的数大于100
	{
		printf("您输入的数据错误\n");
	}
	return 0;
}

第三步:
这一步我们就来实现计算的功能,因为我们这里的过程复杂,我们要把大于等于n小于等于100的数全部加起来,如果我们一项一项来加的话要处理的数据是不是很多啊,而且我们还不知道那位脑回路奇特的使用者会输入什么样的数据,那我们这里显然是不能用顺序结构一个一个加的,所以我们这里就得考虑循环结构,我们假设这里的n等于90,这时候可能就有小伙伴很感到非常的疑惑了,这里哪有循环啊!他不是要我们从n加到100吗?没看到循环啊!大家可以这么看我每次都只加一个数,然后再循环100-n次,每次循环加的那个数的值都会加一,那么这是不是就是循环了,这是不是就是n加到100了,那我们这里如何来实现呢?首先这里的每次加的值都加1就很容易实现,我们可以每次循环都执行一次n++就可以,而且我们可以直接将n写到while后面的表达式里面,这样我们就可以来实现循环100-n次,那我们怎么来实现每次都加上这个值呢?而且我们不仅得加这个值,还得把之前加的值储存起来,其实这里我们可以创建一个变量y,一开始将其赋值为0,每次执行循环的时候我们就可以将y的值加上n的值再赋值给y,这样的话我们就可以实现上面的功能,大家可能有点无法理解我们来详细说一下:一开始y等于0然后我们让y=y+n这里的n=90,那么我们这里是先运算等于号右边的值,然后再赋值给左边,那么这里右边计算的值是90,所以我们的y就变成了90,第二次循环我们的n就变成了91,我们右边的y这时候就是上一次循环得到的y值90,那么第二次循环右边的值就变成了90+91再赋值给左边的y,第三次循环n等于92而右边的y就等于90+91,那么这里右边的值就变成了92+91+90再赋值给左边的y,所以依次类推我们就可以得到n到100的累计的值,那我们的代码如下:

#include<stdio.h>
int main()
{
	int n = 0;
	int y = 0;
	printf("请输入一个小于100整数\n");
	scanf("%d", &n);
	if (n <= 100)//判断输入的数小于等于100
	{
		while (n <= 100)
		{
			y = y + n;
			n++;
		}
		printf("结果为:%d\n", y);
	}
	else//判断输入的数大于100
	{
		printf("您输入的数据错误\n");
	}
	return 0;
}

第二个例子:
模拟细菌分裂。生物实验室做单细胞细菌繁衍实验,一代菌落中只有一个细菌,二代菌落中分裂成两个细菌,三代菌落分裂成4个细菌,以此类推,每代细菌数量都会成倍的增长。计算第十二代菌落中的细菌数量。
第一步:
我们首先得创建一个变量用来储存细菌的数目,然后再创建一个变量用来储存细菌的数目。代码如下:

#include<stdio.h>
int main()
{
	int number = 1;//初始化细菌的数目
	int x = 1;//初始化代数
	return 0;
}

第二步:
因为我们这里要求第12代细菌的数目,是不是重复的次数很多啊,又因为我们这里的细菌繁衍之后的数目是具有规律性,我们发现相同两代之间的数目是两倍的关系,下一代的数目是上一代的两倍,那么我们这里就可以考虑循环结构,因为题目要求的是第12代细菌的个数,所以我们后面的表达式就可以填入x<=12,意思为代数只要小于等于12就继续执行循环语句,又因为每经过一次繁衍,细菌的数目就直接翻倍,所以我们下面循环语句就可以写成number=number * 2;x++;表示每经历一次繁衍细菌的数目翻倍,代数加一,这里的计算过程是这样的:先让number的值乘以2,这里的number是上一次循环得到的number的值,然后再让相乘之后的结果赋值给number,比如说第一次循环中number的值为1,那么这里的顺序是先将number * 2然后再赋值给number,赋值完后number就等于2,第二次循环也是先让number * 2,这个number的值是上一次循环得到的number值为2,然后将4赋值给number,以此类推所以我们的代码如下:

#include<stdio.h>
int main()
{
	int number = 1;//初始化细菌的数目
	int x = 1;//初始化代数
	while (x <= 12)//代数小于12就执行循环
	{
		number = number * 2;//计算细菌的额数目
		x++;//使得代数+1
	}
	printf("第十二代细菌的数目为:%d\n", number);
	return 0;
}

三.while循环中的break

1.break在while循环中的作用

  在while循环中遇到break,就停止后期的所有的循环,直接终止循环,所以while中的break是用于永久终止循环的。

2 .break在while循环的例子

我们来看一端段代码:

#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
		{
			break;
		}
		printf("%d", i);
		i = i + 1;
	}
	return 0;
}

  大家来看看这段代码的结果是多少,我来给大家列出几个结果大家觉得答案是哪个第一个:1 2 3 4.第二个:1 2 3 4 5.第三个:1 2 3 4 5 6 7 8 9 10.第四个:1 2 3 4 6 7 8 9 10。这里的答案是第一个1 2 3 4 为什么呢?我们来看:首先在循环到 i 等于4的时候都是正常的打印,所以我们的1 2 3 4 就会顺利的打印出来,但是当 i 等于5的时候就会执行if语句,if语句的内容是break,break的作用就是直接终止循环,并且跳出循环,所以一旦break被执行break后面的所有代码都不会执行,循环也直接跳出,所以我们这里打印的结果就是1 2 3 4 ,如果这里我们把代码改一下将printf语句改到if语句之前,我们会发现运行的结果为1 2 3 4 5这是因为虽然break会终止循环,并且跳出循环但是在break之前的语句还是会正常执行,这里大家不要误认为第五次循环中执行了break,就导致了第五次循环直接报废,啥都不执行。这里还是会执行第五次循环中break之前的语句的。大家多理解一下。

四.while循环中的continue

1.continue在while循环中的作用

  这里continue的作用是用于终止本次循环的,也就是本次循环中continue后边的代码不再执行,然后直接跳转到while语句的判断的部分。进行下一次循环的判断入口。

2.continue在while循环中的例子

我们来一段代码:

#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		i = i + 1;
		if (i == 5)
		{
			continue;
		}
		printf("%d ", i);
	}
	return 0;
}

  首先i的值初始化为1,所以会进入while循环,因为一开始会执行i=i+1这个语句,所以我们这里i的值就变成了2,然后正常打印出来,这里的if因为不满足条件就不会执行下面的continue,以此类推 3 4 都可以正常打印,但是等我们循环到i=5的时候,我们就会执行continue语句,因为continue的作用是终止本次循环,continue后面的代码都不会执行,所以下面的printf语句就不会执行,所以5就不会打印出来,然后直接跳转到while的判断部分,因为i=5,又满足循环条件,所以while的循环语句又会执行,但是循环语句中第一个是i=i+1,所以i就变成了6,if后面的表达式不成立,所以里面的continue就不再执行,那么这段代码的结果就是 2 3 4 6 7 8 9 10 11 。大家可以再体会体会下一段代码:

#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (i == 5)
		{
			continue;
		}
		i = i + 1;
		printf("%d ", i);
	}
	return 0;
}

这段代码跟上面的代码很像,但是结果却完全不同,同样的将i初始化为1 ,然后进入while循环,因为i不等于5所以就不会执行continue语句,于是就接着执行i=i+1,那么这里的i就变成了2 ,所以我们第一个打印出来的值就是2 ,依次类推2 3 4 5都会被正常打印,当打印出5 后就会接着进入while的判断部分,因为判断为真所以就继续执行循环语句,这时候i是等于5 的,我们if后面就会判断为真,就会执行if下面的语句块,但是语句块的内容是continue啊,他一旦执行就会跳过下面的i=i+1和printf语句,就直接跳转到判断部分,但是这一跳转i的值就没有发生改变,所以我们这里的i还是等于5,继续进入if后面的语句块,然后执行continue语句,然后i=i+1和printf语句就又不会执行,又跳转到while后面的判断部分,所以我们这里就进入了死循环,大家在运行的时候可以看到5后面有一个点一直在闪这就是死循环的表现所以我们这里的答案就是2 3 4 5 。看了这两个例子大家应该能够发现while循环中的continue语句在不同的地方可能会照成不同的结果,大家在写代码的时候一定要注意continue的位置,大家可以自行体会一下。

五. while语句的易错点

第一点:
  初学者很容易在while语句后添加英文分号(;),从而导致编译错误。大家一定要注意if,if…else,else if ,while后面是没有分号的。
第二点:
  使用while语句恒容易出现多执行一次,少执行一次循环,这类错误被称为差一错误。把number<=20,写成number<20,就会少执行一次循环,因此一定要给出正确的循环条件。


六.do…while循环

  在有些情况下,不论条件是否满足循环必须执行至少一次,那么这里我们就可以采用do…while语句。do…while语句的特点就是先执行循环语句块的内容,然后再判断循环条件是否成立。

1.do…while语句的基本形式

请添加图片描述
  do…while语句的是这样执行的,首先执行一次循环体语句中的内容,然后判断表达式,当表达式的值为真时,返回重新执行循环体语句,然后再次判断表达式,直到表达式的值为假,此时循环结束。

2.do…while语句和while语句的区别

  while语句和do…while语句的区别在于:while语句在每次循环之前检验条件,do…while语句在每次循环之后检验条件。这也可以从两种循环结构的代码上看出来,while结构中的while语句出现在循环体之前,do…while结构中的while语句出现在循环体的后面。我们来看一下下面的例子:

#include<stdio.h>
int main()
{
	int a = 100;
	while (a < 100)
	{
		a++;
	}
	printf("%d", a);
	return 0;
}
#include<stdio.h>
int main()
{
	int a = 100;
	do
	{
		a++;
	} while (a < 100);
	printf("%d", a);
	return 0;
}

这里两段代码都是循环结构初始化的变量的值一样并且结束的条件一模一样,循环体也一模一样,我们将a的值初始化为100,但是我们将其代码跑起来就会发现第一段代码打印出a的值为100,而第二段代码打印出a的值就为101,这就两个不同的循环语句照成的差异,while语句会先判断a<100是否成立,然后再执行下面的循环体,由于我们的a=100不小于100,所以这里不成立,就不会执行下面的循环体,所以a的值就是100 。而我们第二段代码中的do…while他是先不管你成不成立我先执行循环语句,所以我们这里的a就变成了101,然和再进行判断,不成立就直接跳出循环,所以打印出来a的值101 。这就是两个循环语句的区别大家可以体会一下。

3.do …while语句的例子

  这里我们就举一个例子吧叫猴子摘桃。猴子第一天摘下若干个桃子,当即吃了一般,还不过瘾,又多吃了一个。第二天早上又将第一天剩下的桃子吃了一般,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第十天早上再想吃的时候,发现就只剩一个桃子了。编写程序,求解第一天猴子吃了多少个桃子。
第一步:
我们来看这个故事,猴子第一天吃了一半多一个,第二题吃了第一天剩下的一半多一个,这样不断的循环到第10天的时候发现就只剩下一个桃子了,那么我们这里可以明显的发现这里是个循环的问题,每次执行一次循环桃子的数目都会减少一半然后再减一,那么这里我们假设桃子的数目为x每经历一次循环桃子的数目就变成了x=x/2-1,循环的内容解决了,但是我们这里就有一个问题循环了多少次,猴子第十天起来准备吃的时候发现只有一个桃子了,那他第十天吃了没?肯定没吃啊,说明这泼猴只吃了九天就产生了这样的结果,那我们这里先初始化一个变量day使其赋值为1,然后while后面的表达式为day<10。这样就可以循环九次。
第二步:
其实按照我们上面的想法我们依然很难实现,因为我们要求的是一开始桃子的数目,如果按照吃桃子的思想来看的话,这个好像很难实现吧,因为我一开始就不知道你有多少个桃,那我来计算下面的值的时候结果还是一个未知数,所以我们这里就反过来,我们把吃桃子改成摘桃子,第一天只有一个桃子,每天上午摘一个桃子下午再摘桃子,下午摘完后桃子的数目是上午的两倍,依次循环摘九天问第十天有多少个桃子,大家这么想的话,是不是就清楚了很多,我们这里循环体的内容就是计算桃子的数目,我们先让x+1这是上午摘完所有桃子的数目,然后再让x+1的值乘以2这就是下午摘完所有桃子的数目,这就是每次循环计算桃子数目的算式,然后重复摘九天,就可以得到一开始桃子的数目,x一开始将他初始化为1 ,这样我们的代码就可以实现

#include<stdio.h>
int main()
{
	int x = 1;//一开始永远的桃子
	int day = 1;//摘桃子的天数
	int y = 0;//循环的次数
	do
	{
		x = (x + 1) * 2;//摘桃子的算式
		day++;
		y++;
	} while (day < 10);
	printf("%d", x);
	printf("%d", y);
	return 0;
}

七.do…while语句中的break

1.do…while循环中break的作用

  在do…while循环中遇到break,就停止后面的所有的循环,直接终止循环,然后跳出循环,所以do…while中的break是用于永久终止循环的。其实功能跟while语句中的break一模一样。

2.do…while循环中break的例子

我们首先来看这段代码

#include<stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
		{
			break;
		}
		printf("%d\n", i);
		i++;

	} while (i < 10);
	return 0;
}

  这段代码运行的结果为1 2 3 4 ,这其中的原因也很简单,因为我们一开始是可以正常打印的因为我们的break语句是在if语句里面的,而if语句成立的条件是i==5,所以当我们循环到第五次的时候,我们的i就等于了5,这时if后面的判断结果就为真就会执行break语句,又因为printf语句在break语句的后面所以break语句执行之后就会立刻停止该循环,然后直接跳出循环所以后面的printf语句就不会执行所以5也就不会打印出来,这就是我们的break的例子其实作用都一样,立刻停止,然后跳出循环。

八.do…while循环中的continue

1.do…while循环中continue的作用

  看了上面的break发现功能在while和do…while一模一样,有小伙伴这时候就想,这个continue是不是在两个循环语句里面的作用也一样啊?先说明一些还是有点区别的哈。我们来看这里continue的作用是用于终止本次循环的,也就是本次循环中continue后边的代码不再执行,然后直接跳转到do…while语句的循环体的开头部分,从头执行循环体。

2.do…while循环中continue的例子

我们来看个例子:

#include<stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
		{
			continue;
		}
		printf("%d ", i);
		i++;
	} while (i < 10);
	
	return 0;
}

  这里我们的1 2 3 4 的打印都很正常,但是当我们的i变成5的时候我们会发现if后面的语句块判定为真,所以就会执行下面的continue语句,而continue语句一旦被执行,他下面的代码就不会执行,所以我们的printf语句就不会执行,我们的i的值也就不会改变,编译器这时候就会从这个循环体的开头继续来执行代码,但是开头他还是if语句啊,if里面装的还是continue啊,你i的值还是5啊,所以这里就造成了死循环,这就是为什么只答应1 2 3 4 的原因,那么我们可以将其改一下我们可以将i++,放到if语句前面这样我们就不会出现死循环的现象,但是当i=5 的时候他还是会跳过他下面的代码,也就是说当i=5 的时候printf语句还是不会执行,我们这里的代码如下,运行的结果为2 3 4 6 7 8 9 10

#include<stdio.h>
int main()
{
	int i = 1;
	do
	{
		i++;
		if (5 == i)
		{
			continue;
		}
		printf("%d ", i);

	} while (i < 10);
	
	return 0;
}

所以do…while里面的continue和while里面的continue还是有一点区别的,while里面是跳到判断部分,而do…while是跳到循环体的开头。

九.do…while语句的易错点

  在使用do…while语句的时候,表达式要放到while关键字后面的括号中,而且后面还得加上一个分号(;),这里与while语句不同。

十. for循环

1.for循环的基本形式

我们先来看看for循环的基本形式:
请添加图片描述
我们再来看看这表达式1 2 3 分别代表什么意思
请添加图片描述
我们可以来看流程图请添加图片描述
  大家看到流程图的时候应该能够明白for循环的大致逻辑,那么这里我再简述一下,每条for语句包含3个用分号隔开的表达式,这三个表达式用一对圆括号括起来,其后紧跟着循环语句或语句块。当执行到for语句时,程序首先计算第一个表达式的值,接着计算第二个表达式的值。如果第二表达式的值为真,程序就执行循环体的内容,循环体的内容执行完后,就会计算第三个表达式,然后接着检验第二个表达式,执行循环,如此反复直到第二个表达式为假,就退出循环。大家是不是感觉这个跟while循环有点相似啊,那我们来看看for循环和while循环的区别。

2.for循环和while循环的对比

首先我们来看两段代码,这两段代码的功能都是用循环来打印出10个hehe首先 用while循环实现

#include<stdio.h>
int main()
{
	int i = 0;
	i = 0;//初始化
	while (i <= 10)//判断部分
	{
		printf("hehe\n");
		i++;//调整部分
	}
	return 0;
}

我们再来用for循环实现

#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1/*初始化*/; i <= 10/*判断部分*/; i++/*调整部分*/)
	{
		printf("hehe\n");
	}
	return 0;
}

其实对比两段代码我们可以发现在while循环中依然存在循环的三个必要的条件,但是由于风格问题使得三个部分可能相距很远,这样就导致我们在查找,修改的时候不够方便不够集中,而我们的for循环就不一样了,我们的for循环这三个条件都集中到了一起,一下子就找到了,所以我们的for循环的风格更胜一筹,for循环的使用频率也就更高。

3.for循环的例子

我们就来计算小球反弹高度的问题。一个球从80米的高度自由落下,每次落地后反弹的高度为原高度的一半,计算小球第六次反弹的高度。
第一步:
首先我们看到每次反弹的高度都为原高度的一半,所以我们这里每次反弹高度的计算公式都是一样的,又因为我们这里要求的是第六次的反弹高度,而且这都是重复的代码,用顺序结构的话,就很浪费时间和精力,所以我们这里就采用for循环,我们可以将大致的结构写出来,因为要反弹六次,所以我们创建一个整型变量i来记录反弹的次数,然后创建一个整型变量height来记录反弹后的高度,在for循环后面的括号里面将i初始化为1 ,判断部分就可以写成i<=6,这个就可以表示反弹到六次就可以跳出循环,然后i++用于调整反弹的次数,那我们的代码如下:

#include<stdio.h>
int main()
{
	int i = 0;//初始化
	int height = 80;//初始化
	for (i = 1; i <= 6; i++)
	{
		循环语句
	}
	return 0;
}

第二步:
有了上面那道累计题的经验,那我们做这道题的时候就很简单了,因为反弹的高度是有规律的,每次的反弹的高度都为下降的高度的一半,那么我们这里就要先得到下降的高度,因为题目告诉我们一开始的下降的高度为80,那我们直接除以2不就得到反弹的高度了嘛,然后我们把这个值赋值给height这个变量,不就表示下一次下降的高度,也可以表示这次反弹的高度,那我们将其放到循环体里面不就可以得到任意反弹多少次对应的高度。最后再打印出来那我们的代码实现如下:

#include<stdio.h>
int main()
{
	int i = 0;//初始化
	int height = 80;//初始化
	for (i = 1; i <= 6; i++)
	{
		height = height / 2;//循环计算反弹高度
	}
	printf("第六次反弹的高度为%d", height);
	return 0;
}

十一.for循环中的break

1. for循环中的break的作用

  其实for循环的break的作用和while循环中的是一样的,在for循环中遇到break,就停止后期的所有的循环,直接终止循环,所以for循环中的break是用于永久终止循环的,然后跳出for循环。

2.for循环中break的例子

我们来看一段代码

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (5 == i)
		{
			break;
		}
		printf("%d", i);
	}
	return 0;
}

这段代码的运行结果结果跟上面的那几个例子一模一样,因为当运行到i=5的时候if后面的表达式就会判断为真,为真的话就会执行下面的语句块,而语句块的内容就是break,又因为break一旦执行就会直接结束终止这个for循环,然后跳出for循环执行for循环下面的代码。所以这段代码的运行结果1 2 3 4

十二.for循环中的continue

1.for循环中的continue的作用

  小伙伴们看到这个可能就要说了,这个不会跟前面几个循环中的continue的作用一样吧,首先说明一点就是大致相同,在一些细节方面还是有些许不同的,如果相同的话,我为啥不把这个放到一起讲呢?干嘛跟自己过不去分开讲呢?这就是因为有细节上的不同嘛,好我们来看for循环中continue的作用:这里continue的作用是用于终止本次循环的,也就是本次循环中continue后边的代码不再执行,然后直接跳转到for循环的调整部分,再进行判断部分,再来看是否执行下面的循环语句。而我们while循环中的continue是跳转到判断的部分,do…while循环中的continue是直接跳转到循环体的开头,大家注意区分哈。

2.for循环中continue的例子

还是看段代码:

#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (5 == i)
		{
			continue;
		}
		printf("%d ", i);
	}
	return 0;
}

大家在看这道题的时候可以先去看一下前面的流程图,这道题的答案是1 2 3 4 6 7 8 9 10,其实大家看了前面的例子应该能发现其实都差不多,这里i等于5 的时候if后面的表达式就会判断为真,然后就会执行下面的语句块也就是continue,而它一执行就会跳过下面的printf语句,所以5就打印不出来,而这时编译的顺序就会跳转到调整部分,也就是i++所以i就变成了6,这也就导致了if后面的表达式判断为假,也就不再执行continue语句,所以我们这里就不会造成死循环,而且下面的printf语句会正常的执行,所以答案为1 2 3 4 6 7 8 9 10 。

十三.循环的嵌套

1.循环嵌套的基本形式

一个循环体内还可以包含一个或者多个其他的循环的结构,这称之为循环的嵌套。如果嵌套的循环有多层,这就是多层循环。我们来看一下其基本的形式,这里我们就列出几个例子大致相同大家可以自行尝试一下。
第一种:while循环中嵌套while循环
请添加图片描述
第二种:do…while循环中嵌套do…while循环
请添加图片描述
第三种:for循环中嵌套for循环
请添加图片描述
可能大家看的话没啥感觉我们来看两个例子就可以明白

2.循环嵌套的例子

因为上面的循环没有跟大家讲这个是如何使用的哈那我们第一个例子就来给大家讲讲循环的嵌套是如何运行的那么我们第一个例子就来看一段代码来讲解讲解

#include<stdio.h>
int main()
{
	int i = 0;
	int n = 0;
	for (i = 1; i <= 10; i++)
	{
		printf("i的值为%d\n", i);
		for (n = 1; n <= 10; n++)
		{
			printf(" n为%d ", n);
			if (10 == n)//大家可以不用管这个if语句,这是我为了运行结果方便看而写上去的。
			{
				printf("\n");
			}
		}
	}
	return 0;
}

我们首先来看这里是一个for循环嵌套一个for循环,我们外层的for循环里面结束的条件是i<=10,而我们内部的for循环结束的条件是n<=10,我们一开始将i和n初始化为0,然后就进入了外层的for循环,进入for循环的第一步就是将i初始化为1,然后表达式2判断为真,于是就进入了循环体里面,好!一开始执行了一次printf语句,然后我们就到了里面嵌套的for循环,我们来看遇到了里面的for循环我们的第一步就是将n初始化为1,然后进入判断部分,判断为真就进入内部for循环的循环体里面,由于循环体里面的内容简单,所以我们执行完printf语句这次循环就结束了,然后就来到调整部分,这里的调整部分是使得n的值加上1,调整完再经过判断部分发现结果依然为真,那么就继续执行循环体的内容,依次类推当我们的内部for循环执行10次之后n的值就变成了11,就会跳出内部的for循环,但是随着内部循环的跳出,我们外部的循环体也执行完了一次,(大家记住了这里是内部循环全部执行完,跳出内部循环才结束了外部循环的第一次)外部的循环体就来到了调整的部分,调整完之后i变成了2,就来到了判断部分,判断为真就第二次执行内部的循环体首先执行printf语句,好这时问大家一个问题这时候n的值等于多少,是1吗?是0吗?答案都不是是11,因为在上一次内部循环结束的时候,我们并没有将n赋值其他的数字,所以我们的n还是11,但是这里的内部for循环因为表达式1的存在,它会将n初始化为1再来进入判断执行循环体和调整部分,以此类推内部的循环结束一次又一次直到外部循环结束这段代码才结束,那么我们这里的执行结果就图所示:
请添加图片描述
看了这个例子大家应该有点体会那我们再来一个有趣的例子叫百钱百鸡
中国古典《算经》中有一道著名的百钱买鸡的问题:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。问买多少个鸡翁多少个鸡母多少个鸡雏能够正好用完这100元,并且恰好买了100只。列出所用情况。这里我就不用给大家解释这个题目是啥意思了吧,应该都能够看懂,那么我们这里来谈谈解题思路。
首先我们创建三个变量来记录不同鸡的数量,x来表示鸡翁,y表示母鸡,z表示为鸡雏,这里我来给大家讲一个思路吧,首先我们算出最多能买多少只鸡翁,和鸡母,然后把他当作限制条件,这里算出来最多买20只鸡翁,最多买33只鸡母,那我们可以这么想先买0只鸡翁0只鸡母剩下的鸡位置用来买鸡雏,然后算要用的钱是否等于100,如果不等于则鸡母数目加一,那么就变成了鸡翁0只鸡母1只鸡雏99只,然后算钱是否等于100,如果不等于则鸡母再加1,就变成了鸡翁0只鸡母2只鸡雏98只算是否有100元如果不等于就一只加直到鸡母的数目超过33,就将鸡母的数目变成0,鸡翁的数目变成1 ,那么购买的情况就变成了鸡翁1 只鸡母0只鸡雏1只,如果钱不等于100就还是鸡母加1,就变成鸡翁1只鸡母1只急雏98只,如果还是不等于则鸡母加一,依次类推又到鸡母超过33只时则鸡母变成0,鸡翁加一则购买变成鸡翁2只鸡母0只鸡雏98只依次类推则到鸡翁的数目超过20的时候则所有情况都验证完了,如果遇到了刚好钱等于100时就答应出该情况,根据我们上面所述我们这里就相当于两个循环的嵌套那么我们的代码如下:

#include<stdio.h>
int main()
{
	int x = 0;//初始化
	int y = 0;//初始化
	int z = 0;//初始化
	for (x = 0; x < 20; x++)//for循环,最多可以买20只鸡翁
	{
		for (y = 0; y < 33; y++)//嵌套循环,最多可以买33只母鸡
		{
			z = 100 - x - y;//计算鸡雏的数目
			if (5 * x + 3 * y + z / 3.0 == 100)//判断所有鸡的钱是否等于100
			{
				printf("鸡翁=%d,鸡母=%d,鸡雏=%d\n", x, y, z);
			}
		}	
		
	}
	return 0;
}

大家可以再体会体会。

十四.for循环的变种

我们来看看for循环的其他形式。

1.for循环的省略

  其实我们的for循环他是可以省略表达式1 2 3 的但是这些省略往往会造成一些不好的结果我们来分别看看。

①.表达式2的省略

  表达式2 是循环的判断部分,它的作用是判断循环是否继续进行,那如果我们将他省略则无法进行判断,那么我们这里是默认表达式2始终为真,所以循环将无终止的进行下去,我们来看个例子:

#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1;; i++)//这里我们将判断部分省略
	{
		printf("hello");
	}
	return 0;
}

我们来看看这段代码的运行结果:
请添加图片描述
跟我所说的一样这里表达式2 要是省略的话,就会始终判断为真,所以循环就会不断的执行下去,可见表达式2是不能省略的。

②.表达式3的省略

  表达式3用于改变循环变量,可以省略,但是此时程序的设计人员应该在循环体内增加类似的功能的语句以保证,以保证循环能正常的结束,否则程序也会无终止的循环下去。例如:

#include<stdio.h>
int main()
{
	int i = 0;
	int sum = 0;
	for (i = 1; i <= 50;)
	{
		sum = sum + i;
		i++;//可以替代表达式3的功能
	}
	printf("%d",&sum);
	return 0;
}

这里我们的循环语句里面有个i++,这里的功能与表达式3的调整部分的功能相同,所以我们这里可以省略表达式3 ,但是大家注意千万不要搞成死循环了哈,你能省略表达式3的前提是,你的循环语句里面得有类似于表达式3功能的语句。不然就会出现死循环。

③.表达式1的省略

  我为什么要把表达的省略放到最后啊?因为我觉得表达式1的省略是一个很隐蔽的,也就是说我们表达式 2 3的省略很容易就可以发现问题,并且问题还非常明显,而且我们同学自己在写代码的时候就会有个以为,为什么我一开始在创建变量的时候初始化了一次(int a =0;)为什么在for循环里面又要初始化一次,而且有些小伙伴们在写代码时候发现就算省略了表达式1也不会报错,而且结果还是对的,那么这里我们就得来看看我们新手在写表达式1 的时候该不该省略,首先来看第一段代码:

#include<stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	for (i = 0; i<=3; i++)
	{
		for (j = 0; j<= 3; j++)
		{
			printf("hehe\n");
		}
	}
	return 0;
}

我们上面讲了循环语句的嵌套我们这里可以轻松的得到这里会打印16个hehe但是我们要是把这个内部的for循环里面的表达式1去掉呢?我们再来看看运训的结果是什么?

#include<stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	for (i = 0; i<=3; i++)
	{
		for (; j<= 3; j++)
		{
			printf("hehe\n");
		}
	}
	return 0;
}

请添加图片描述
我们发现这里就只打印了四个hehe这是为什么呢?因为我们在第一次执行内部循环的时候,for循环循环了4次,我们的j就变成了4,但是我们的外部循环还没有结束,他就会再执行一次内部的循环体,那么这时候我们就又会执行一次内部的for循环,但是这时候我们的表达式1是去掉的,他也就不会对j进行初始化,也就是说我们这时候的j还是4,所以后面的判断部分就会判断为假,所以内部for循环直接跳过,所以等外部for循环结束的时候我们这里才打印了4次hehe,这也是为什么不建议新手省略表达式1 。

2.for循环中的逗号表达式

  在for语句中,表达式1和表达式3除了可以使用简单的表达式,还可以使用逗号表达式,即包含一个以上的简单表达式,中间用逗号间隔。
例如我们for循环可以一下子初始化两个变量

for (i = 0, j = 0; i < 100; i++)
{
	语句块
}

我们的for循环也可以一下子调整两个变量例如:

#include<stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	for (i = 0, j = 0; i < 10; i++, j++)
	{
		printf("i的值为%d\n", i);
		printf("j的值为%d\n", j);
	}
	return 0;
}

这里大家了解一下就可以不是很重要。

十五.for循环的易错点

第一点:
for循环后面括号里面的表达式中间隔开的是分号不是逗号
第二点:
省略表达式的时候,后面的分号不能省略。
第三点:
浮点值的误差是不可避免的。如果在for循环的条件表达式中使用浮点值,那么将导致数值错误。因此不建议开发者使用浮点类型定义for语句的循环变量。
第四点:
for循环不要在循环体内修改循环变量,这样会导致for循环失去控制,举个例子:

#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i < 10; i++)
	{
		i = 2;
		printf("hehe\n");
	}
	return 0;
}

因为这个我们在循环体内修改了变量,那么我们这里就会出现死循环这样的例子还有很多哈,这里就不一一列举了。

十六.三种循环语句的比较

我们前面介绍完了3种可以执行循环操作的语句。一般情况下,这三种循环之间是可以相互替换的。下面是对这3种循环语句在不同情况下的比较。
第一个:
while和do…while循环只在while后面指定循环条件,在循环体中应包含是循环区域结束的语句(比如i++或者i=i+1等),for循环可以在表达式3中包含使得循环趋于结束的操作。因此for循环的功能更加的强大,凡用while循环完成的功能,用for循环都能完成。
第二个:
用while和do…while循环时,循环便改良初始化的操作应在while和do…while语句之前完成,而for语句可以在表达式1中实现循环变量的初始化。
第三个:
while循环,do…while循环和for循环都可以用break跳出循环,用continue语句结束本次循环。

总结

这里我们的循环语句就结束了,大家看了之后是不是感觉循环语句也就这样嘛,都是差不多的东西,那么我们这里就结束了,我们这里还有刷题的文章带着大家写几道循环的编程题,带着大家更好的理解循环语句。其实本来还有goto语句的,但是这个太多了,怕大家看不过来我就把goto语句放到有趣的c语言游戏里面讲解,到时候来教大家编一个关机的程序。

本文章的所有代码都在这个链接里面方便大家学习

点击此处查看本文章所以代码

  • 37
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 28
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶超凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值