c语言输入为无符号的变量,C语言无符号数据读取|Leon Dong’s Blog

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

背景

像C语言这种语言对输入输出的要求极其严格,你必须要制定你读取的数据类型以及格式。现在的问题是如果你读取的时候指定了错误的数据类型,会发生什么?

案例分析

加入说你要读取64位无符号整数类型数据,所以你的程序可能大概是这样子的。1

2unsigned long val=0;

scanf("%lu",&val);

在这里面有两点需要注意,其一是%lu,这说明了我要读取的数据类型是long类型且无符号。另一点是变量val类型的声明一点要一致,否则读取出来的值会被截断。当然你如果读取short,用int来存储是不发生任何精度损失的。不过即使如此,这种类型不匹配的方式也是不推荐的。

现在的问题是,如果把程序写成这样会发生什么?1

2unsigned long val=0;

scanf("%ld",&val);

我们知道%ld也是读取long类型的数据,只不过数据是包含符号的。由于无符号类型的数据的取值范围是$[0,2^{64}-1]$,如果把这个范围分为两份,一部分对于有符号数的正数部分$[0,2^{63}-1]$,另一部分对于与负数部分$[2^{63}-1,2^{64}-1] rightarrow [-2^{63},-1]$。

对于位于$[0,2^{63}-1]$的数据,在这个例子里面用%ld%和%lu%都可以得到相同的结果。但是对于输入位于$[2^{63}-1,2^{64}-1]$的数据,%ld能正确读取么,它能自动的将这份数据转为负数读取进来么?如果是的话,那么%ld%读取的值也会是正确的。因为一个负的long型正数传给unsinged long 类型的变量时,会自动发生强转。

事实上,scanf("%ld",&val) 并不能正确的读取数据。对于$[2^{63}-1,2^{64}-1]$的数字,他将最高的二进制位自动当0处理,读取出来的数值永远在分$[0,2^{63}-1]$之间。

从这个例子里面,我们可以看到C语言对输入输出的要求,在平时写程序的时候一定要注意这些细节。事实上,我们也是因为代码改来改去的,忘记去改输入了才发现的这个问题。

Please Indicate the Source When Reproduce

转载请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值