数据的存储(中)整型

26 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

上一章节讲解了进制,为下面的两章做了一个简单的铺垫,下面对整型的存储模式进行详解。

二、整型

1、存储形式

计算机中的有符号整数有三种表示方法:原码、反码、补码(无符号数和正数的原码、反码、补码均相同); 三种表示方法均有符号位和数值位两部分,符号位中0为正,1为负,而数值位三种表示方法各不相同; 原码: 直接将整型按照正负数的形式翻译成二进制就可以了; 反码: 将原码的符号位不变,其他位依次按位取反; 补码: 反码+1得到补码;

例如: 将int a=20翻译成二进制: 00000000000000000000000000010100---原码 00000000000000000000000000010100---反码 00000000000000000000000000010100---补码 翻译成十六进制(补码的每四个二进制位为1个16进制位): 0x00000014 (其中0x表明它是一个十六进制数)

将int b=-10翻译成二进制: 10000000000000000000000000001010---原码 11111111111111111111111111110101---反码 11111111111111111111111111110110---补码 翻译成十六进制: 0xFFFFFFF6

对于整形来说,存放在内存中的是补码,原因在于:可以将符号位和数值位统一处理,同时,加法和减法也可以统一处理(CPU只有加法器),此外,补码和原码相互转换,其运算过程是相同的,不需要额外的硬件电路;

如:1-1会被计算机转化为1+(-1),即1和-1的补码相加,过程如下: 00000000000000000000000000000001 +111111111111111111111111111111111 得到100000000000000000000000000000000,由于1位于第33位,而int类型只能存放32bit,所以1被丢弃; 从而得到00000000000000000000000000000000,转化为整型后得到0;

二、大小端存储模式

数据的存储往往涉及大小端存储模式的问题(PC机器中多为小端存储模式)

大端(字节序)存储模式:数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中;

小端(字节序)存储模式:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中;

注解:内存的地址从左到右是由低地址到高地址; 数据的位数从左到右是由高位到低位;

对于机器中大小端存储模式的判断,可以采用以下的代码形式:

int check_sys()
{
	int a = 1;//在大端存储模式中1在内存中的十六进制为0x00000001,
              //小端中为0x01000000
	char* p = &a;//通过char类型的指针访问a的第一个字节
	return *p;//返回第一个字节的值
}
int main()
{
	int x = check_sys();
	if (x == 1)//如果第一个字节为01,则返回值为1,为小端存储模式
		printf("小端");
	else//如果第一个字节为00,则返回值为0,为大端存储模式
		printf("大端");
	return 0;
}

三、例题分析

int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

输出结果是什么呢? 不妨先自己算一下,然后看后面的详解; 、 、 、 、 、 、 、 、 详解: -1的补码为11111111 11111111 11111111 11111111 char类型只读取内存中的第一个字节,也就是11111111,而a和b都是有符号char类型,且要以%d的形式输出,所以对11111111进行整型提升(在高位处补符号位,补到32位为止)得到11111111 11111111 11111111 11111111,输出后得到-1; 而c是无符号整型,对11111111进行整型提升(无符号整型在高位处补0)得到00000000 00000000 00000000 11111111,由于无符号数原反补相同,所以输出结果为255;

所以最终的答案为::a=-1,b=-1,c=255

详解数据存储(上)——进制 详解数据存储(下)——浮点型