数据的存储(unsigned 以及char的截断和提升(原码,反码,补码))

今天说的东西有点杂,咱们先讲最基础的原码,反码,补码。可以说这篇文章都要用到它。

粗略的讲一下,就比如1的原码就是00000000000000000000000000000001;正数反码补码都是跟原码是一样的。而-1的原码就是10000000000000000000000000000001;反码是111111111111111111111111111111110;补码是:111111111111111111111111111111111;

可以观察到1和-1的原码首个数字是不一样的,其实首个数字是符号位,0代表正数,1代表负数。负数的反码是除了符号位其他按位取反,补码是反码加1。内存中显示的是补码。这个是因为方便进行运算,因为内存中是进行加法运算的1-1其实算起来是用1+(-1)的,这个时候就是俩个补码之间进行加。(这是个题外话,可能描述的不太精确)我就不展开讲了,可以自行看图理解。

 

大致讲到这里,接下来我们讲char的截断和提升。

我们知道int类型的大小是4个字节,也就是32bit。而char类型的大小是1个字节,也就是8bit。那么当int数据存入char类型变量会发生什么呢。

就比如上面提到的1存入char类型变量,它的原码是00000001,这个就是截断,把32bit变成8bit,这个时候首个数字依旧是符号位,当他进行打印或使用的时候会还原成32bit,这个时候还原就是按照你的符号位去进行补充,这里是0,也就是补充为00000000000000000000000000000001。这就是所谓的提升。

那么问题来了,这样截断和提升是有限制的。就比如说这个时候如果你存入了一个正数它的大小刚好为11111111, 它的首数字成为了符号位它进行提升的时候全按1来补充,补码就成了11111111111111111111111010000000从一个正数变成了一个负数,这就是它的局限性。

左图就是代表八个bit位从00000000到11111111所存储的大小,有图是左图最下面几个数的补码。总结来说char存储的整形大小就是-128到127。

那么是不是无论如何char类型存储的就不会变化。其实不然,我们还有unsigned这个表达无符号的。

这个改变的原理就是首数字的不在表示符号,因为已经没有符号了,这个时候提升就是补0;

总结一下

 

 那么触类旁通short类型就是:

 这个时候讲的差不多了,再讲个题贯通一下。

 可以看到这里很奇怪,用了unsigned修饰,打印出来的还是-10。

注意这里有两个问题,1.你既然用了unsigned,还要赋值-10。

                                    2.打印的时候还用%d,我们打印unsigned修饰的东西的时候是要用%u的。

我们来加点东西。

 来看这里-10不变,我们加一个printf语句用%u来打印出来,发现也不是10。这是为什么。

其实这里的原理跟unsigned char差不多,你原本的-10是有符号位的。如图,我们按负数变成补码,这个时候这个补码就被当做了num的原码,num是无符号的,所以补码也是这个,所以最终打印出来的结果不是10。

总结一下,当你赋值一个数给一个变量的时候,它的过程其实是你要赋值的数先变成补码,然后存进去给你,你要如何使用是你的事情了。我这个数的补码就在那里。

也就是说其实不管怎么存,它的二进制值是不变的吧,只是解释的方式不同,那么打印出来的数值就不同了。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值