%lld,%d,%hd,%hhd在打印时的“潜规则”

先由一道经典例题引入,想必很多学习者都遇到过,

第2114行的打印结果毫无疑问是1 2 3;     

第2115行的打印结果为1 0 2;因为一般的编译器都是小端存储模式,即数据的低位存储于内存的

低地址中,数据的高位存储于内存的高地址中。前两个%d分别访问a的低32位和高32位,故打印

1,0;第三个%d访问b的低32位,结果打印2。

程序运行结果:

现在进入正题,讨论%hd和%hhd的打印情况;

 按照前面的思路,这里%hd打印2个字节的内容(访问16位),结果应该为:1 0 0;

程序运行结果:

 结果还是1 0 2,和%d打印结果一样,似乎访问的仍然是四个字节的空间,现做如下实验来验证这

一假设;

赋值a,让其第1和第33位为1,其余位上全部为0,如果猜想正确,则输出应该为 :1  1 2;

 继续换%hhd试验:

        由上可知,%d,%hd和%hhd在打印long long类型时,将其内存中的补码分成了连续的“4个字节(32位)的单元”,每次访问四个字节(32)

但是下面的这个情况可能会让你感到迷惑:

               

按照前面的结论 ,%hd和%hhd每次访问四个字节,那下面的两个结果也应该是:65536 65536 2才对;于是猜想:将打印的数据类型在内存中的补码分成“连续的四个字节(32位)的单元”后,不同之处在于%d 和(%hd和%hhd)读取数据的有效位不同;由上面结果我们猜测,%hd和%hhd只读取两个字节(低16位)的内容。

再次验证:

       将两个32位的低16位的最高位赋值1,如果%hd和%hhd读取的有效位为16位,则第16位为符号位,打印出来的数应该位负数;上述程序运行结果的确为负数,所以猜想成立。(实际上补码1000000000000000为short短整型数据的最小值-2^15=-32768在内存中的存储数据)

总结:%d,%hd,%hhd在打印long long类型数据时,将其划分为连续的“四个字节的单元(32位)”,且%d读取整个32位,%hd和%hhd读取低16位;

下面继续讨论打印int,short,char类型数据;

2,3均被打印出来了,证明,此情况下 %hd和%hhd仍是遵循访问“四个字节的单元(32位)”这一结论,且两个-32768说明%hd和%hhd打印时,读取的仍是低16位(最高位为符号位),至此前面的结论没有问题。

下面为打印short和char型数据的情况

        打印结果均为1 2 3;那连续访问“四个字节的单元(32位)”还是否成立呢,显然是成立的,实际上此时short类型数据会整型提升为int型数据,高位补符号位。严格一点,现在还需要讨论%hhd打印时读取的有效位问题;

       第一个输出结果均为负值,说明%hhd打印short数据时读取的最高位也是16位,因为整型提升补符号位;因此前面的结论仍然成立。

同理,打印char

 此情况下时,每次打印都发生整体提升,高位补符号位,结论还是成立。

总结:%d,%hd和%hhd在打印时,将其对应的数据在内存中的补码分成了连续的“4个字节的单元”,大于四个字节的类型进化“切割”,小于四个字节的类型发生整体提升,每次访问四个字节,但是%d读取全部32位,%hd和%hhd读取32位的低16位数据。

浮点数不在本次讨论范围。

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值