一,整数
整数在内存中的存储方式主要取决于整数的数据类型和计算机的体系结构,通常它们储存在内存中的基本单位是字节(byte)。
1,常见的整型数据类型(32位系统)
- int ——整形
int 占 4 个字节,范围在 -2,147,483,648 到 2,147,483,647 之间。
- short ——短整型
short 占 2 个字节,范围在 -32,768 到 32,767 之间。
- long——长整型
long 占 4 个字节,范围在 -2,147,483,648 到 2,147,483,647 之间
- long long ——长长整形
long long 占 8 个字节,范围在 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 之间。
- char ——字符型
char 是一种字符型,但它也具有整数的属性,char 类型的值是一个只有8位的整数,通常在0到255的范围内,可以表示各种字符,如字母、数字和符号。char 类型在内存中使用整数值来表示字符,每个字符都有一个相应的整数编码,通常使用ASCII编码或其他字符编码方案。因此可以看出char 型实际上就是整型的一种,只是它通常用于表示字符。
有一点需要注意,char 类型在声明时,有符号(signed char)还是无符号(unsigned char)这一点是不确定的,是取决于编译器的,在VS上,char == signed char。
那么,整数在内存中是如何存放的呢?
2,整数在内存中的存储
我们知道,一个整数的二进制表示方式有三种,即 原码 , 反码 和 补码 。这三种表示方式均由符号位和数值位两部分组成,其中 数值位 的 最高位就是 符号位。
而对于整形而言,数据在内存中存放的其实是 补码。其中:
正整数的原码,反码,补码,都相同。
而负整数的三种表示方式不相同。
原码 | 负数取绝对值再转换成二进制得到原码 |
反码 | 原码的符号位不变,其余数值位按位取反得到反码 |
补码 | 反码加 1 得到补码 |
当符号位为 0 时,表示正数,为 1 时表示负数。
例如数字 11 和 -11 :
11: 0000 0000 0000 0000 0000 0000 0000 1011
-11:1000 0000 0000 0000 0000 0000 0000 1011
3,大小端字节序
整数在内存中的存储遵循机器的字节序(endianness),而字节序分为两种 —— 大端字节序和小端字节序。那么什么是大端和小端呢?
在了解这个之前,我们需要知道字节的高位和低位是什么。下面给出一个整数:
123
这里 1 是整数123 的百位,也就是高位,3 是个位,也就是低位。
所谓大端字节序,就是说这个数存放在内存中的时候,高位字节在前,低位字节在后,也就是说,低位字节序的内容存放到高地址中,高位字节序的地址存放到低地址中。
而小端字节序则跟大端字节序刚好相反,高位字节在后,低位字节在后。
比如下面一行代码
int n = 0x11223344; // 16进制
大端的存储方式如图所示:
小端:
不同的环境下,存储方式可能会有不同。在VS2022中,采用的就是小段字节序存储,如图:
二,浮点数
1,基本概念
浮点数在内存中的存储方式通常遵循IEEE 754标准,该标准定义了浮点数的二进制表示方法,这是一种用于表示浮点数的二进制编码方式。IEEE 754标准定义了两种主要类型的浮点数:
单精度(32位)和双精度(64位)
浮点数在内存中通常由 符号位 ,指数位 和 尾数位 所组成:
- 符号位:和整数的符号位一样,浮点数的第一个位通常用于表示符号,表示数值的正负。0表示正数,1表示负数。
- 指数位:接下来的一组位用于表示指数。这些位用来表示浮点数的指数部分,通常是以二进制形式表示的,而且通常包括偏移值,以允许表示正指数和负指数。
- 尾数位:最后的一组位用于表示尾数或尾数部分。这些位存储了浮点数的小数部分。通常,这些位被标准化为小数点前面的值为1,因此在存储时,通常不需要存储整数部分的1。
而这三组位的大小,则取决于数据类型(即精度):
单精度浮点数(float)通常使用 32 位,其中 1 位用于符号,8 位用于指数,23 位用于尾数。
双精度浮点数(double)通常使用 64 位,其中 1 位用于符号,11 位用于指数,52 位用于尾数。
需要注意的是,浮点数表示是二进制的,因此可能存在精度问题,尤其是在进行浮点数运算时。对于一些特定的数值,如无理数,表示可能不精确。