C语言%u、%d打印的规则、数据在内存中的存储及大小端存储模式

数据在内存中的存储

整形存储

一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同的类型而决定的。
像 int a = 20;
int b = -10;
这样的整形数据在内存中是如何存储的呢?
我们先来了解以下的概念:
原码、反码、补码
计算机中的有符号数有三种表示方法,即原码、反码和补码。

三种表示方法均有符号位和数值位两部分,符号位都是最高位用0表示“正”,用1表示“负”,而数值位三种表示方法各不相同。

原码:直接将二进制按照正负数的形式翻译成二进制就可以。
反码:将原码的符号位不变,其他位依次按位取反就可以得到了。
补码:反码+1就得到补码。

而正数的原码反码补码都是相同的
对于整形来说,数据在内存中存放的是补码。
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
如int a = 10;
原码为:00000000000000000000000000001010
因为它是正数,所以最高位为0表示正数,且原反补相同。
而像int b = -10;
原码为:10000000000000000000000000001010
最高位为1,表示负数
反码为:11111111111111111111111111110101
补码为:11111111111111111111111111110110
所以b在内存中的存放内容是11111111111111111111111111110110

无符号整型、无符号整型的打印

而像无符号整型,就没有符号位之分,所有的二进制位都为数值位。
如果把上述int b = -10改为unsigned int b = -10;
则-10的补码为11111111111111111111111111110110,又因为b是个无符号整型,所以b的值实际上是一个很大的值,而要想打印出来,必须用%u的形式打印,打印结果如下图。
在这里插入图片描述
如果我们用%d的形式来打印b会是什么结果呢?
在这里插入图片描述
我们看到,结果和a的一样,这是因为b在内存中实际上还是按照11111111111111111111111111110110来存储,用%d打印的话,打印的还是一个有符号的整形,所以会以原码的形式打印出来。
那要是a用%u的形式打印,又是什么结果呢?
看下图
在这里插入图片描述
这里我们看到结果和b的一样,又是为什么呢?
因为a的补码是11111111111111111111111111110110,而按照%u的形式打印,就不存在符号位之分,所有位都为数值位,故打印的结果和b的值相同。

char类型的打印

我们知道整型分为有符号和无符号两种,有符号的char类型大小范围是-128-127,无符号char的大小范围是0-255。
我们可能会好奇,-128怎么表示呢?
因为有符号的char最高位为符号位,而要表示128又是2^7,大小为1个字节(8个bit位)的char不够用啊,于是,c语言就规定了char类型中10000000的值为-128。
我们在打印char的时候,如果用%d,%u的形式打印,它们都表示有符号或无符号的32个bit位的整型,那char类型打印出的结果是怎么样的呢?
这里我们以char a = 128和char b = -128为例,因为这两个数字在char中存储的情况很特殊。
我们来看结果:
在这里插入图片描述
可以看到,a和b用%d的形式打印的结果相同,%u的形式也相同,这是因为128本身的补码就为10000000(char类型中),而规定10000000的值是-128,所以这里a的值实际上是-128。用%d的形式打印出来,结果就为-128.
而使用%u打印,却是这么一个庞大的数字,是因为10000000进行了整型提升,变成了11111111111111111111111110000000,而用%u的形式打印,就把它看作了一个无符号数,故打印结果为上图所示,我们可以用计算器来进行验证:
在这里插入图片描述
其实在用%d打印的时候,也进行了整型提升,只不过是个有符号的整型,所以要转换成原码进行打印,如下:
补码:11111111111111111111111110000000
反码:11111111111111111111111101111111
原码:10000000000000000000000010000000
这时转化为十进制数值就为-128了。

下面我们来看几道题:
1.

 char a= -1;

    signed char b=-1;

    unsigned char c=-1;

    printf
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WoLannnnn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值