C语言——循环结构详解(while、for、do while循环)

目录

while循环

for循环

do  whlie循环


while循环

首先我们先来看看while循环的语法结构:

while(表达式)
    循环体;

它的意思是,如果表达式为真,循环体就一直执行。

来看一个简单的实例:使用while循环打印一下变量1-10

是不是很简单呢?

但是在以后的代码中,我们还会遇到像break、continue这样的语句。让我们一起来看看。

break和continue

break:在while循环中,break用于永久终止本次循环。

continue:在while循环中,continue用于跳过本次循环中continue后面的代码,直接去判断部分,看是否进行下一次循环。

听起来是否有点费力?没关系,我们用代码实现一下。

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

思考一下,运行结果会是怎样的?会不会打印出5呢?答案是否定的。

为什么会产生这种结果?

i=4之前,循环都是正常进行的。当i的值为5时,满足if里面的表达式“i==5”,执行continue语句,跳过本次循环中剩下的“printf("%d ", i);与 i++;”,跳过“printf("%d ", i)”时,自然不会打印5,同时,也跳过了“i++”,无法实现变量的递增,因此结果只打印到4。

getchar和putchar

明白了break和continue的原理后,我们接着来分析一个代码:

#include<stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)
		putchar(ch);
	return 0;
}

这段代码中出现了两个陌生的东西:getchar和putchar,一起来认识一下。

getchar():从键盘获取一个字符不是真的直接从键盘读,getchar和键盘中有一个缓冲区,当键盘没有输入时,缓冲区里什么都没有,当我们从键盘上输入a并按enter时,其实相当于给缓冲区放入了“a”和“\n”。

getchar()的工作原理:从一个stream上读取一个字符,或从一个stdin上得到一个字符(注意是一个)

那么什么是stream呢?

stream:标准输入,也就是从键盘输入

它的返回类型是int类型,为什么?

int ch = getchar();

因为当正确读取的时候,返回的是字符的ASCII码值,错误读取的时候,返回的是EOF(end of file文件结束标志),EOF的本质是-1。

小tips:运行程序时,按快捷键crtl+z读取就会结束

putchar():输出一个字符

示例:

putchar(ch);

我们来分析下这段代码:

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//为什么没有取地址?password是个数组数组的数组名本来就是个地址
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
		printf("确认成功!\n");
	else
	{
		printf("确认失败~\n");
	}
	return 0;
}

它的思路是这样的:电脑让我们输入密码,我们输入一串字符,然后按Y或N来确认。

但是我们运行的时候发现,还没有输入Y或N,直接就确认失败了,

 问题到底出在哪里?

不管是getchar还是scanf,这些输入函数都要去中间的缓冲区拿东西。而当我们输入完密码后,还会按一下enter,enter会触发scanf去读内容,当读取的时候,只把输入的密码拿走,不会拿enter导致的“\n”,程序继续执行,getchar直接就把缓冲器里面的“\n”拿走放在“ch”里面,“\n”不等于“Y”,执行else后面的语句,所以直接就输出了确认失败。

显然,这和我们的预期是不符的,那要怎么解决呢?

让缓冲区里没东西,清除掉\n,清理缓冲区

怎么清理?见下方代码:

//清理缓冲区
	getchar();//处理\n
	int ch = getchar();
	if (ch == 'Y')
		printf("确认成功!\n");
	else
	{
		printf("确认失败~\n");
	}

运行结果如下,可见,我们成功的清除掉了缓冲区里面的“\n”。

但是我们又会发现,当密码含空格时,也会直接输出“确定失败”,这又是为什么?

(假如我们输入的密码为“123 abc")因为空格前的(123)被scanf拿走给password,而剩下的字符(abc)仍在缓存器中,而getchar只能读取一个字符,用刚刚的方法就不能把剩下的东西清理干净,怎么清理掉剩下的东西?这时候就要用到while循环了。

在if else语句前加入这个while循环:

//清理缓冲区中的多个字符
	int tmp = 0;
	while ((tmp = getchar()) != '\n');
	{
		;
	}
	int ch = getchar();

好了,现在我们来小小的总结一下while循环,它分为三个部分:初始化部分、判断部分和调整部分。

int i = 1;//初始化

	while (i <= 10)//判断部分
	{
		printf("%d ", i);
		i++;//调整部分
	}

但是当代码比较长的时候,区分这三个部分就会麻烦,而for循环结构就很一目了然。

for循环

先来看看for循环的基本语法

for(表达式1;表达式2;表达式3)
    循环语句

for循环中的表达式1、表达式2、表达式3分别对应while循环的三个部分:初始化部分、判断部分和调整部分。

三个部分放一起,从形式上讲优于while循环。

我们来用for循环打印1-10

int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

是不是更简洁了呢?

来看看for循环的操作流程:

在for循环中,同样会遇到break语句和continue语句。

for循环里的break也是用于终止整个循环。

continue跳过本次循环,会执行下一次循环。

那么while循环和for循环里面的continue语句有什么区别呢?

while循环可能会跳过调整部分,而for循环不会。

一些建议:

  1. 不要在循环体内修改循环变量,防止for循环失去控制
  2. 建议for语句的循环变量采取“前闭后开”的写法

如果判断部分省略的话,会判断部分恒为真,循环就可能会出现一些问题,所以不建议大家随便省略。

我们来看一个例子:

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

会输出几个“apple”呢?

显然,是9个。 

如果省略for循环的初始化条件(i=0;j=0),我们再来看一下。

int main()
{
	int i = 0;
	int j = 0;
	for (; i <3; i++)
	{
		for (; j < 3; j++)
		{
		printf("apple\n");
		}
	}
	return 0;
}

思考思考,这次会输出几个“apple”?

 答案是3个。为什么不是9个呢?这就是省略带来的锅。当i=0时,进入第一次循环,此时j=0,开始执行内层循环,直到 j=3 ,跳出内层循环,此时打印了三个“apple”,i++后,i=1,将进入内层循环,因为初始化条件 j=0 被省略,此时 j 的值为3,这就不符合内层循环中打印“apple”的条件了,所以最终只打印了i=0时的三个“apple”。

所以在没有熟练把握for循环前,不要随便省略,这会带来很多不便。

另外,for循环的循环变量控制可以由两个循环变量来控制。例如下面这行代码:

for(x=0,y=0;x<2&&y<5;++x,y++);

我们再来分析一个代码,请问这段代码要循环多少次?

#include<stdio.h>
int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 0; i++, k++)
		k++;
	return 0;
}

零次。因为判断部分是k=0,注意,"="是赋值,意味着把0赋值给了k,表达式的值为假,所以一次循环都没进行。

do  whlie循环

最后我们看看do  whlie循环。

do  while循环的语法结构:

do
    循环语句;
while(表达式);

注意while()后面有“;”

先do,在进入while,判断表达式是否为真,若为真,继续循环,反之,退出循环。

和while不同的是,do  while是先执行循环语句,再判断表达式是否为真。

简言之,while循环先判断,再执行;do while循环先执行,再判断。

同样的,我们用do while循环来打印1-10:

int main()
{
	int i = 1;
	do
	{
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

应该没什么问题。

在使用do while循环的过程中,也可能会遇到continue和break,我们来用一两个简单的实例来分析一下。

遇到break语句时:

int i=1;
do
	{
		if (i == 5)
			break;
		printf("%d ", i);
		i++;
	} while (i <= 10);

打印出1-4,跳出循环。

遇到continue语句时:

int i = 1;
	do
	{
		if (i == 5)
			continue;
		printf("%d ", i);
		i++;
	} while (i <= 10);

打印1-4,进入死循环。

可以看出,在break语句和continue语句的使用这块,还是和for循环还是比较像的。我们就不在赘述。

好啦,今天的分享就到这里,希望对你有帮助!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

采代码的小蘑菇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值