c语言 long long %d,定义一个long long类型,用%d打印的结果

这几天复习了一下整形提升,正好发现一个令我非常困惑的问题:

#include

int main()

{

long long a = 1, b = 2, c = 3;

printf("%lld %lld %lld\n", a, b, c);

printf("%d %d %d\n", a, b, c);

return 0;

}

输出结果:

a041e53bc4494f5983dcb77ce9893b7c.png

那么问题来了,%lld输出没问题,就是long long int类型,但是为什么%d输出就成了1 0 2了呢?

我们先来看如下代码:

#include

int main()

{

long long a = 1, b = 2, c = 3;

printf("%lld %lld %lld\n", a, b, c);

printf("%d %d %d %d %d %d\n", a, b, c);

return 0;

}

输出结果:

ad2ca384c61e499883469ab914800664.png

我们好像发现了什么,我对上面的现象解释如下:

因为a、b、c是long long类型,所以为64位数,在打印的时候,分割成6个32位数,%d每次只能读取其中的32位,第一个%d读第一个32位数,也就是1的低32位(1),第二个%d读第二个32位数,也就是1的高32位(0),第三个%d读第三个32位数,也就是2的低32位(2),所以结果就是1 0 2。

因为是小端存储,低位放在低地址处,高位放在高地址处,而指针是从低地址增加,所以先读到低32位,后读到高32位。

这里需要注意的是分割的时候针对的是补码,但是正数原反补相同。

请看如下代码:

#include

int main()

{

long long a = -2;

printf("%lld\n", a);

printf("%d %d\n", a);

return 0;

}

因为-2是负数,所以在a中存储补码为:

11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111110。

分割为两个32位数,最后输出结果如下:

def7c4fb290c45b7b1935919396b9808.jpg

正好低32位11111111 11111111 11111111 11111110对应int为-2,高32位11111111 11111111 11111111 11111111对应int为-1。

再看一个例子:

#include

int main()

{

int a = 1, b = 2;

printf("%d\n", a, b);

printf("%hd %hd\n", a, b);

return 0;

}

按照上面的推理,short int对应两个字节,int对应4个字节,那打印的时候应该把a和b分割成两个双字节的数,然后结果应该是1 0。也就是a的低16位和a的高16位,但是请看结果:

a19746f70c324e68a95b0326a3233dea.png

为什么和预想的不一样呢?

我给出的解释是:不管是什么类型,最后分割的时候都分割成32位,如果原来不够32位(比如说char类型),那么就进行整形提升变成32位,然后在读取并且打印的时候,%lld是读取两个32位,也就是读取了long long类型,%d、%hd、%c读取的则是32位,也就是不管是百分号什么,读取的都是32的整数倍。假若说是%d,则先读取一个32位数,然后取这个32位数的低8位,下一次读取的时候则接着读取下一个32位数。

上面的现象是在vs2013中发生的,在linux的gcc编译器可以正确打印,我认为linux的gcc编译器对于long long类型直接每次读64位了,不管格式控制符是不是%d,最后再将低32位打印。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值