数据在内存中的存储(一)

整数在内存中的存储

整数的二进制表示形式有三种,原码、反码、补码。而整数在内存中的存储形式为补码。

有符号整数

对于有符号整数,三种表示形式都由符号位和数值位两部分组成。最高的一位被当作符号位,正数符号位为“1”,负数符号位为“0”。

有符号整数的原码是将数值位以二进制形式表示,第一位为符号位。反码是符号位不变,数值位各按位取反。补码是反码加1。

无符号整数

对于无符号整数,每一位都是数值位。

其原码反码补码都相同,将整数直接由二进制形式表示即可。

补码的好处

补码的出现使得二进制数的加法与减法可以使用同一个运算器同一个电路进行,无需再为减法配置一个运算器。而且,从原码到补码的运算(符号位不变,数值位按位取反加1)与补码到原码的运算一致,也是符号位不变,数值位按位取反加1,读者可自行验证。

大小端字节序和字节序的判断

什么是大小端字节序

对于整型a=0x11223344,他在内存中占四个字节,这四个字节是怎么排序的呢,存放11的字节和存放22,33,44的字节的位置关系是什么样的呢?

我们进行调试,查找a的地址,可以看到,存放44的字节放在这块内存的低地址位置,存放11的字节放在高地址位置。而对于一个十六进制数,44代表4+4*16,11代表4*(16^6)+4*(16^7),显然,11的位数高于44,我们把4的位数称为较低位,把1的位数称为较高位。就如十进制数17,1的位数比7高。而如下图所示,a的最低位4存放到内存的较低地址,被称为小端存储。与之对应的是大端存储,低位存在内存的高地址处。大端存储和小端存储方式由编译器决定,在vs编译器中,由下图可知使用的是小端存储,其他编译器可能是大端存储。

如何确定字节序类型

对于a=0x11223344,我们可以发现,在小端字节序存储下,他的第一个字节存放的是0x11,那么在大端字节序存储下,就应该存放的是0x44。也就是说,我们可以通过第一个字节的值来确定字节序类型。取出a的第一个字节,对其进行解引用即可。由于a为整型,需要先将&a强制类型转换为char*类型才能访问一个字节的地址。

#include<stdio.h>
int main()
{
	int a = 0x11223344;
	int b = *(char*)(&a);
	if (b == 0x11)
		printf("大端");
	else
		printf("小端");
	return 0;
}

练习


一、

此题给出不同类型的a,b都赋值为-1,再将其以整型的形式打印,求打印结果。

#include<stdio.h>
int main()
{
	char a = -1;
	unsigned char b= -1;
    printf("a=%d,b=%d",a,b);
	return 0;
}

-1是一个有符号整型,它在内存空间中以补码形式存储。

-1的原码为10000000000000000000000000000001

       反码为    1111111111111111111111111111110 

       补码为     1111111111111111111111111111111

而要想将其放在a和b中,因为a是char类型,b为unsigned char类型,都只有一个字节长度,所以只能放进后八个二进制位,

即a=11111111,b=11111111。

打印时因为要将ab以整型形式打印,需要进行整型提升。

a是有符号数,有符号数进行整型提升时补符号位,提升后补码为11111111 11111111 11111111 11111111

b是无符号数,整型提升时补0,提升后补码为

00000000 00000000 00000000 11111111

对a,b求原码,有符号数原码为补码除符号位按位取反再加1,无符号数原码补码相等。

a的原码为10000000 00000000 00000000 00000001

b的原码为 00000000 00000000 00000000 11111111

则a为-1,b为2^8-1=255

二、

此题给出一个char类型的-128,要求以无符号整型形式打印,求打印结果。

#include<stdio.h>
int main()
{
	char a = -128;
	printf("%u", a);
	return 0;
}

-128的原码为10000000 00000000  00000000  10000000

           补码为11111111   11111111   11111111     10000000

则a中为11111110

因为a是char类型,整型提升时补1,提升后补码为

11111111 11111111 11111111 10000000

以unsigned int 形式打印时,最高位为数值位,则打印结果应该是一个很大的正数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值