引言
今天想给大家分享一下几个简单数据类型在内存中的存储方式以及规则,附有一些例题,都很有趣,那么咱们开始吧!
整数在内存中的存储
整数二进制有三种表示方式,分别是:原码,反码,补码
对于整型来说:计算机中存储的形式是补码
原码是十进制的直接二进制表示形式
就整型来说,还可分为有符号整型(+/-,0表示正数,1表示负数)和无符号整型,下面先来讨论有符号整型的转换。
- 正数的原码,反码,和补码相同
- 负数的反码是其符号位不变(第一个比特位),其他位按位取反(0变1,1变0)
- 负数的补码是其反码加1
为了便于大家的理解这里举个例子:
(这里为了方便采用八个比特位模拟展示)
十进制整数 6
二进制原码:00000101
二进制反码:00000101
二进制补码:00000101
十进制整数 -6
二进制原码:10000101
二进制反码:11111010
二进制补码:11111011
为什么能用原码存储数据,还要引入反码和补码呢?
这是因为,再计算机数字计算的过程中,实现二进制减法的时候是一个相对加法复杂很多的过程。引入补码便可以通过简单的加法运算来实现有符号整数的加减法,而不再需要单独处理符号位了。这里有两点性质:补码加上其原码等于零,补码的补码等于其原码。
一些类型数据在内存中的存储
在刚刚讲解过整数的存储后,其他类型数据的存储也就好理解了。
- char类型(8个比特位)可表示-128~127之间的整数(有符号),也可表示0~255之间的整数(无符号)
- short(16个比特位)可表示-32768~32767之间的整数(有符号),也可表示0~65535之间的整数(无符号)
- int(32个比特位)可表示-2147483648~2147483647之间的整数(有符号),也可表示0~4294967295之间的整数(无符号)
- longlong(64个比特位)表示的范围更大,如果想了解详细范围可以了解#include头文件中存放的函数
了解了整数在内存中存储的形式,其实还有必要了解一下内存存储数据的不同字节顺序,这里分为大端序字节存储和小端序字节存储
大小端字节序存储及判断
大端字节序存储:高位字节存储在低地址
小端字节序存储:高位字节存储在高地址
我们可以先存储一个数据,来在编译器中观察一下其存储顺序
#include <stdio.h> int main() { int a = 0x11223344; return 0; }
在初始化a过后,我们打开存储a的地址内存,可以发现,11 22 33 44似乎是从右向左存储的,这代表着11这样的高位字节存储在了高位地址,是典型的小端字节序存储。下图在再进行进一步解释,大小端序。
总的来说,大小端是存储数据的不同方式,它们之间也没有什么优劣之分,只要能达到存储和拿取数据的目的,哪一种方式都可以。
说了这么多,其实让我联想到了一个大厂的笔试题,考的是通过写一份代码,来判断运行机器是大端序还是小端序。 我把这道题的答案放到下面供大家来参考
#include <stdio.h> int main() { int n = 1; if (*(char*)&n == 1) printf("小端\n"); else printf("大端\n"); return 0; }
这道题的原理其实很好理解
当为小端序时,指向的是0x01,表示的数字也就是1;当为大端序时 ,指向的是0x00,表示的数字是0。这样,就能很好的把大小端区分开了。