scanf语句的使用和执行原理

本文详细解析了C语言中scanf函数的使用方法和执行原理。通过实例展示了如何正确使用scanf读取整数,并解释了输入格式的重要性。同时,深入探讨了scanf的工作机制,包括它如何从输入缓冲区读取数据,以及如何处理空格和回车符。在调试过程中,证实了scanf在读取数字后会处理后续的空格。最后,通过示例代码说明了不同情况下scanf的读取行为差异。
摘要由CSDN通过智能技术生成

scanf语句的使用和执行原理

1、如何使用scanf:

%d说明我们现在要读入一个整数了,scanf这个函数会读入一个整数,读到的结果赋值给指定变量,要注意指定变量前面的&

scanf("%d",&price);

如果要读入输入的数据,就必须严格按照""中的格式输入,如:

scanf("%d,%d",&a,&b);

输入应为1,2,此时可以正常读取,正常输出,如图所示:

在这里插入图片描述

但是如果我们不严格按照""中的格式输入,读取就会出现问题,如图所示:

在这里插入图片描述
输入缓冲区是行缓冲区,当你按下回车之前,除非特意对缓冲区进行刷新,否则你的程序不会读到任何东西,回车符会使行缓冲区进行刷新,即回车符是输入结束的标志。虽然说输入的结束标志是回车键,但是回车键并不一定代表输入结束,如果你输入的并没有满足scanf语句读取的格式化的内容,scanf会把回车键视作一个空格。

scanf("%d %d",&a,&b);

输入格式1 2或者 1(回车)2都是对的,输入回车时还没有满足scanf语句读取的格式化的内容,因此会把回车键视作一个空格。
在这里插入图片描述

我们要注意下面这段代码,输入应为1 2(2的后面还应该有个任意符号来满足那个空格,唯独不能用回车符来满足这个空格,回车符作为空格被读入,但是后面输入的作为行结束标志的回车符就不会被读到程序中。

scanf("%d %d ",&a,&b);

在这里插入图片描述

不过我们依然可以用回车符来满足中间的那个空格,如下图所示:

在这里插入图片描述

同上述代码一样,2的后面随便再输入什么东西来满足这个回车号,唯独不能用回车符来满足这个最后的回车号,回车符作为空格被读入,但是后面输入的作为行结束标志的回车符不会被读到程序中。

scanf("%d %d/n",&a,&b);//输入1 2

在这里插入图片描述

2、scanf语句的原理

scanf并不会直接从我们的键盘输入中读取数据,我们从键盘输入的数据先存储在输入缓冲区中,当按下回车键后,即输入缓冲区遇到回车符时,会对输入缓冲区进行一个刷新,程序才会在输入缓冲区中读取数据,scanf读取到空格、tab或者回车符的时候停止读取。

例子:

int main()
{
	int arr[10] = { 0 };
	int i = 0;

	for (i = 0; i < 10; i++)
	{
		scanf("%d", &arr[i]);
	}

	return 0;
}

上面这段代码它是如何给数组赋值的呢?

在第一次进入for循环执行到scanf语句的时候,会跳出命令行窗口,输入我们想要给数组赋的值,注意这里是一次性输入所有的值:
在这里插入图片描述
这些输入的值并不是直接被scanf语句读取,而是存储到输入缓冲区,当按下回车键(即输入回车符)的时候,输入缓冲区中便有了回车符,此时scanf语句开始读取输入缓冲区中的值,此时i的值为0,读取到1赋值给arr[0],读取完后scanf语句会继续读取,读取完空格后scanf语句就会停止读取,进入下一轮循环,此时i的值为1,scanf语句接着后面继续读取,就会把读取的2赋值给arr[1],然后继续读取空格,停止读取,进入下一轮循环,直到读取到回车符,停止读取,此时i的值为10,循环结束。

这个时候会有小伙伴们疑惑了,scanf每次读取完数字后,真的继续把后面的空格也读取掉了?

这里我们直接上代码调试证明一下即可。

如图所示,我们在scanf语句中的%d后面添加一个%c,看看会不会读取空格赋值给变量c1:

在这里插入图片描述

我们先在135行也就是for循环处设置断点,然后开始调试,监视c1,i和arr[i]的值,往下走到136行,也就是scanf语句处,此时scanf语句未执行,所以没有任何变化,再往下走,走到137行,此时scanf语句已经执行,我们在命令行窗口一次性输入需要给数组赋的值,1 2 3 4,然后按下回车键:

在这里插入图片描述

观察此时的arr[i]和c1:

在这里插入图片描述

如图所示此时arr[0]的值为1,说明scanf语句读取了数字1赋值给了arr[0],此时c1的值为32(‘ ’)说明scanf语句读取了数字1赋值给arr[0]后确实读取了后面的空格并且将其赋值给了变量c1。

这说明scanf语句读取完数字后,会把后面的空格也读取掉。如果后面有变量来接收,读取后就会把空格赋值给对应的变量,如果没有变量来接收,那么仅仅是读取,不会进行赋值操作。值得注意的是,scanf只有在读取完数字后会继续把后面的空格读取掉

我们仔细看看下面这段代码:

char word[8];
scanf("%s",word);//Hello world
printf("%s##\n",word);//Hello##

这说明读取完字符o后,并没有将后面的空格读取出来,遇到空格就直接停止读取了。

那么后面的流程大家应该都知道了,每一轮for循环,scanf语句都会读取数字赋值给数组单元,然后把后面的空格读取掉,停止读取,进入下一轮循环,但是在最后一轮循环中有些许不同,scanf读取掉4后,后面不是空格了,而是回车符,因此scanf会把后面的回车符读掉,然后停止读取,后面i自增1,i的值为4跳出循环。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

子非鱼Swx

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

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

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

打赏作者

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

抵扣说明:

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

余额充值