c语言 error 2,C语言笔记2 --新手常常犯的错误之scanf()

本文详细介绍了C语言中的输入函数scanf,包括其使用格式、取地址符的作用以及如何处理空白字符。强调了在使用scanf时应注意的细节,如避免在格式控制字符串中添加不必要的字符,以及scanf在处理字符串数据时的局限性和解决方案。通过实例说明了如何正确使用scanf避免数据丢失问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接着上次的输出函数,这次我们来细细的讲一下输入函数:

scnaf();

同学们在第一节C语言课上,老师还没要求我们从键盘输入数据,只是单纯的声明变量,用一些基本运算符输出结果。而在C语言中,有着输出,必然有着输入,就像英语中有 you,那么肯定也有 I.

在用这个函数的时候同学们常常会出一些小毛病,而这些毛病,对于刚刚进入编程大门的同学来说,是很难发现的。

这里我稍微详细的介绍下这个与输出对应的函数,输入。

写一个简单的输入函数的格式:

scanf(" 格式化字符串 ", 地址列表);

有观察到这里与printf函数极其相似嘛,双引号,逗号,分号。

格式化字符串与printf函数一样,也是由 % + x 构成:

%d %c %s %e %u

与printf不同的是,这里逗号右边是地址列表,同学们在写代码的时候,有没有好奇为啥要用到 & 这个符号?

这个符号在C语言中,在这个函数里面叫做 “取地址符”。

同学们记得第一节课老师讲的关于计算机中地址的概念嘛?

在我们声明变量的时候,编译器就会帮助我们为这个变量开辟一定大小的地址空间,用来存放数据,例如:

int num1, num2; //开辟两个大小为4个字节的整形变量

double num3, num4; //开辟了两个大小为8个字节的双精度变量

这里的地址是一个标识,让我们知道这个数据存放的位置。相当于你点外卖的时候,告诉商家你的地址是在XXXXX学校XX宿舍501号 这样的。外卖相当于是数据,当外卖小哥把外卖送你宿舍的时候,也就相当于把数据存进了地址。

这里的 & 作用就是告诉scanf函数这个我输入的数据是要存进这个地址的,也可以说是写进这个地址。

知道了这些之后,我们再来看下这个函数怎么用:

比如我想求两个整形变量相加减,那么首先我肯定是要先有这两个整形变量存在,不存在我数据放哪去?外卖小哥的外卖送去哪?

所以

int n1, n2; //声明两个整形变量

接下来输入,往这两个变量里面写入数据,这时候,我们的scanf函数就派上用场啦:

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

这里要解释一点 : 在格式控制字符串里面,一般都不需要添加任何字符的,有些同学喜欢在里面加上逗号:

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

这就导致你在输入数据的时候,也要把逗号输入进去。

可是这是为什么呢?

因为,在我们把数据从键盘敲进显示屏的时候,这些数据会以ASCII码的形式存在 ”缓冲区", 例如我输入12 74. 那么此时存在缓冲区的数据就是3132 3734 (ASCII码),然后scanf会从缓冲区扫描过去,从缓冲区读走一个字符,相当于清空缓冲区,直到结束。

也许会有同学有疑问,这个中间有空格咋办?

这个不用担心,scanf会自动忽略这样的空白字符,如大段空格,tab,回车。

也许还会问这个读走的是ASCII码呀,可是我要的是十进制的啊?

这个也不用担心,scanf会帮我们转换成对应的的数据类型。

然后我们在回头看一下,为啥要输入逗号呢?因为在输入数据的时候,若是没有空格,scanf在扫描数据的时候,本来要写入变量b地址的数据,写进了逗号,故变量b也就没写入数据。

用运行结果来看:

51be5963be0bd5fd97dccb2c821570fc.png

变量b的值还是系统随机分配的垃圾值(此值为上一个程序用过该地址后,未清空留下的值。比如有个程序利用了这块地址,假设地址为0x93fb78, 里面的数据为 -1234567. 用完之后里面的值没有清空,那么在我这个代码中,变量b恰好分配到了这个地址,而我还未对该变量进行赋值操作,由系统分配,那么该值就是上一次遗留的数据,也就是-1234567)。

若我b 赋初始值为 0 呢?

ae75c2a7c0b99e39d55b0fe1a6b56dd1.png

这就很直观的反映了我输入的数据74 并没有写入进b的地址,造成了数据丢失。

所以,在我们不是特别要求的情况下,最好还是不要在scanf函数里面加东西,直接写成:

scanf("%d %d",&n1, &n2);

scanf("%d%d",&n1, &n2); //%d%d之间可以空格,也可以不用空格隔开

上面的对scanf忽略空白符的描述也可以作为理解输入数据的时候,为什么可以用回车隔开,也可以空格很多次,而不影响数据的写入的理论基础。

如果说printf是拼图的时候一块块拼图,那么scanf函数就是拼图的建造者(数据写入)

它告诉printf函数这块拼图该往哪儿拼(数据输出)

这里我要对 取地址 & 讲下我在学习C语言时候的理解:

取地址,我把地址理解为计算机中一个个小盒子,这个盒子叫做地址,

取地址的时候就是把这个盒子给拿出来,scanf函数从键盘获取数据的时候,

把数据放进这个小盒子,在把盒子放到它原来的位置。

不同的数据类型对应着不同大小的盒子,double最大,int相对较小,而且double这个盒子能装水(浮点,浮这个词我想像成水 这样去看待的话是不是很好理解呢?

scnaf函数作为数据的写入,有一个缺陷,在写入字符数组数据的时候,只会读取第一个空格前的字符数据:

0dab73542abd2a6b571359bc17c532d4.png

同学们看到空格是不是联想到了前面的 scanf会忽略空白符 呢?它在读取到第一个空格的时候就误认为数据已经完毕了,所以把空格前的 Today 写进了字符变量 str 在的地址。

后面的数据就存在了缓冲区。这也是scanf函数的一个缺陷。

ps: 在用scanf函数对字符串进行操作的时候,不需要取地址符, 因为数组名就是这个变量的首地址。

为了解决这个缺陷,我们需要用到gets()函数来输入字符串数据:

7b14ae98e2223d1fdc9d9cbeef914760.png

关于scanf函数的问题就先讲到这里了,最后再次总结下关于scanf函数涉及到的几个方面:

0:取地址符

1:scanf会忽略空白符

2:输入数据的时候,格式要跟 ”格式控制字符串“ 一样。有逗号输入逗号,无逗号用空白符隔开数据即可。

3:数据在缓冲区,scanf读取数据,转换成我们需要的,清空缓冲区。

(如有错误欢迎指出)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值