C语言入门笔记 第五讲【循环语句之while】

零、引言

我们已经掌握了,if语句。

当条件满足的情况下,if语句后的语句执行,否则不执行。但是这个语句只会执行一次。

但是我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。

那我们怎么做呢? C语言中给我们引入了:

while,

for,

do while

三种语句,

可以实现循环。

一、while

1、基本语法结构

//while 语法结构
while(表达式)
 循环语句;

表达式为真,执行循环语句;

直到表达式为假,不再执行。 

比如我们实现:

在屏幕上打印1-10的数字。

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

 2、while语句中的break和continue

break

看如下一段代码:

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

 这里代码输出结果为:

1 2 3 4

总结:

break在while循环中的作用:

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

 

continue

看如下一段代码:

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

这里的代码输出结果为:

1 2 3 4 并且程序并没有结束。

原因在于,当i===5时,if判断通过,从而执行continue;

那么continue后面的语句全部不执行,直接继续执行下一次while循环。

下一次while循环时,由于i还是等于5,所以继续执行下一个if语句,再判断,再continue,

从而成为了一个死循环,

一直在

while(i<=10)
 {
 if(i == 5)
     continue;

这三条语句中循环。 

再看如下一段代码:

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

这里的代码输出结果为:

1 2 3 4 6 7 8 9 10 11

总结:

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

 再看两个代码实例:

代码1

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

 番外--getchar()函数和putchar()函数的作用

int ch = getchar();
putchar(ch);
printf("%c\n",ch);

putchar(ch);
printf("%c\n",ch);

这两个语句等价。

getchar()函数让计算机读取一个字符,这个字符由我们来输入;

而putchar()函数让计算机将这个字符输出。

至于为什么它的类型是int,

因为getchar函数的返回值是用户输入的字符的ASCII码。

而再用printf函数,将打印类型改为“%c”,即可将这个ASCII码转换成对应的字符。

putchar()函数则简化了上述步骤。

注意,getchar()函数只能读一个字符,scanf可以读一个字符串。

那么为什么这段程序【代码1】能读一个串呢?

如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取。

也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完后,才等待用户按键。

用户按完键以后,putchar会把栈/队列里的字符一个一个输出,这就导致了用可以读一个字符串,而不是只读字符串的第一个字符。

番外二--EOF是什么

EOF是一个计算机术语,为End Of File的缩写,是文件结束标志

在操作系统中表示资料源无更多的资料可读取。

资料源通常称为档案或串流。

通常在文本的最后存在此字符表示资料结束。

它的值是-1。

那么如何获取一个EOF呢?

当我们输入crtl+z时,

会发现程序停止了运行。

Windows中,Ctrl+Z表示EOF。

我们看一个番外代码

int main() 
{
	char password[20] = { 0 };
	printf("请输入密码:");
	scanf("%s", password);//输入密码,并存放在password数组中
	printf("请确认(Y/N)");
	int ret = 0;
	ret = getchar();//Y/N
	if (ret == 'Y')
	{
		printf("确认成功");
	}
	else
	{
		printf("放弃确认");
	}
	return 0;
}

按照我们的想法,我们会输一遍密码,然后输入Y or N来确认;

然而,程序运行的结果是:

还没有到确认的那一步,程序就停止运行了。

原因是: 

我们先来看一看ret里面存放的是什么:

先按F10进行逐句运行

再 调试--窗口--监视

发现ret里存放的值是10。

10对应的ASCII码是\n

也就是回车!

破案了:我们在输入第一遍密码的时候,为了执行下一语句,按了回车

而这个回车被ret悄悄地拿走了,并存放了进去。

输入函数【scanf和getchar】的执行过程:

有一个区域叫做输入缓冲区,输入函数会去缓冲区中找,等待缓冲区中出现东西。

当我们输入了东西,被存到了输入缓冲区中;

一旦输入缓冲区中出现了数据,

输入函数就把它读走。

我们输入123456\n,

由于\n是一个转义字符,所以scanf函数会先把123456给读走

这时候缓冲区中还留了一个\n

到了getchar(),

它来缓冲区一看,发现有个\n,于是把它读走。

而这时候ret的ASCII码值并不是Y的ASCII码值,

所以不执行if,执行else。

所以会直接打印放弃确认。

这就是整个程序的执行过程。

【题外话:以下程序可以执行:

	int ret = 'Y';
	cout << ret;

执行结果为89。

如果令int 变量等于一个字符,那么其实他存放的其实是这个字符的ASCII码值。】

那么如何让这段代码1正确执行?

我们想让ret在打完回车后,缓冲区是空的,等待我们输入一个新的数据。

我们可以在输入完密码后,再执行一个getchar()函数,把缓冲区里的‘\n’读走。

代码如下:

int main() 
{
	char password[20] = { 0 };
	printf("请输入密码:");
	scanf("%s", password);//输入密码,并存放在password数组中
	//缓冲区还剩余一个‘\n’
	//读取一下‘\n’
	getchar();
	//不关心这个‘\n’读到哪了。
	printf("请确认(Y/N)");
	int ret = 0;
	ret = getchar();//Y/N
	if (ret == 'Y')
	{
		printf("确认成功");
	}
	else if(ret == 'N')
	{
		printf("放弃确认");
	}
	else
	{
		printf("请输入Y/N");
	}
	return 0;
}

这样代码暂时可正常跑完。

又出现了新的问题:

假如输入一串字符:123456 ABCD

因为scanf函数只会读取空格前的字符,

所以读完123456就会停止;

这时候,getchar读下一个字符,

把\n读走了。

还剩ABCD;

然后ret把A都走了,然而A并不是Y N中的一个,

所以会出现“请输入YN”。

那么怎么解决?

我们可以写一个循环:

while(ch=getchar()!='\n')

{

    ;

}

让这个循环不断地读,直到读到一个回车。

让回车被ch接受,然后跳出循环,

从而执行后面的代码。

代码2

#include <stdio.h>
int main()
{
 while ((ch = getchar()) != EOF)
 {
     if (ch < ‘0’ || ch > ‘9’)
        continue;
     putchar(ch);
 }
 return 0;
}

 代码意思是,只打印0~9的数,不然就跳走,继续下一次循环,直到遇到一个EOF(即ctrl+z)

这段代码可指定接收某些字符。

 

 

 

 

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值