我们每一次写代码的时候,都会创建变量。那么所创建的整形变量是如何在内存中存储的呢?
目录
1.数据类型介绍
本文重点介绍内置类型中的整形家族。
(1)内置类型(C语言本身具有的类型)
整形家族:字符型char,整形int,短整型short,长整形long,更长整形long long。
浮点型家族:单精度浮点型float,双精度浮点型double。
(2)自定义类型
数组类型
结构体类型
枚举类型
联合类型
(3)指针类型
(4)空类型void
在整形家族中,每个类型又可分为两种类型,有符号signed类型和无符号unsigned类型。如何理解有符号类型和无符号类型?
在我们日常生活中,如人的体重,身高等都只有正数,不存在负数,这种数据就是无符号类型。
像温度,有正有负,就属于有符号类型。
signed有符号类型:既有正数,又有负数。
unsigned无符号类型:只有正数,没有负数。
创建和初始化变量的时候,编译器默认的是有符号signed类型。
如,创建一个int类型的变量int i=-10,编译器会默认变量i是signed int i =-10。
创建一个 int类型的变量 unsigned int j =5,这里创建的才是无符号整形变量 j。
下表是整形家族的所有类型、存储容量及取值范围。
整形数据类型 | 存储容量 | 取值范围 |
char | 8bit(1字节) | -128 ~ 127(-2^7 ~ 2^7-1) |
unsigned char | 8bit(1字节) | 0 ~ 255(0 ~ 2^8 – 1) |
int | 32bit(4字节) | -2147483648 ~ +2147483647(-2^31 ~ 2^31-1) |
unsigned int | 32bit(4字节) | 0 ~ 4294967295(0 ~ 2^32-1) |
short | 16bit(2字节) | -32767 ~ 32768(-2^15 ~ 2^15-1) |
unsigned short | 16bit(2字节) | 0 ~ 65536(0 ~ 2^18-1) |
long | 32/64bit(4/8字节) | -2147483648 ~ +2147483647(-2^31 ~ 2^31-1) |
unsigned long | 32/64bit(4/8字节) | 0 ~ 4294967295(0 ~ 2^32-1) |
long long | 64bit(8字节) | -9223372036854775808 ~9223372036854775807(-2^63 ~ 2^63-1) |
unsigned long long | 64bit(8字节) | 0 ~ 18446744073709551615(0 ~ 2^64-1) |
从表中可以观察到,无符号类型的取值范围都是正数,有符号类型的取值范围有正有负。
那么有符号和无符号类型有什么意义呢?这就要说到整形数据在内存中的存储方式了。
2.整形数据在内存中的存储形式
一个数值的表示形式有多种:2进制,8进制,10进制,16进制等等。
一个整形数据在内存中是以二进制的方式存储的。
整形数据的二进制数又有三种表示形式:原码、反码、补码。
signed类型二进制序列最高位是符号位,其他位是有效位。
unsigned类型没有负数,二进制序列所有位都是有效位。
正数的原码、反码、补码相同。
负数的原码、反码、补码需要计算。
原码:整形数据的二进制序列。
反码:原码的符号位不变,其他位按位取反。
补码:反码+1。
那么一个整形变量在内存中是以二进制的哪种形式存储的呢?前往编译器,创建一个整形变量,调试并查看内存。
-10的二进制序列: 10000000000000000000000000001010--原码
111111111111111111111111111111110101--反码111111111111111111111111111111110110--补码
在内存中可以看到,-10在内存中存放的是f6 ff ff ff,这是以16进制呈现出来的,把ff ff ff f6转化为二进制序列:111111111111111111111111111111110110,与-10的二进制数中的补码相同,由此可知整形数据在内存中是以补码的二进制序列形式存放的。对于在内存中为什么看到的是16进制形式,是因为编译器为了方便表示出来,以16进制数的形式表示的,内存中实际存放的还是二进制数。
-10的补码的二进制序列转化为16进制是0x ff ff ff f6,而在内存中看到的是却是 f6 ff ff ff,存放的顺序是相反的,这与大小端字节序相关。
3.大小端字节序的介绍
大端字节序:把数据的高位字节序内容存放在低地址处,把数据的低位字节序内容存放在高地址处。
小端字节序: 把数据的高位字节序内容存放在高地址处,把数据的低位字节序内容存放在低地址处。
由此可见,-10在内存中存放的方式就是小端字节序存储,大部分编译器在内存中存放数据的方式都是小端字节序存储。