前言:
之前我在不同数据类型的存储方式中有提到过,一个数据被存储在一个地址中,char类型大小是1个字节,需要一个地址去存储,int类型大小是4个字节,需要4个连续的地址存储,short类型的大小是2个字节,需要2个连续地址去存储。
在存储过程中存的都是二进制数据,这些二进制数据存进去时涉及到这些二进制0,1的数字如何存放的问题,这里涉及到两种存储方式:大端存储和小端存储。接下来就来探讨一下它们的区别。
大端存储:
定义:
什么是大端存储?
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址 中;这里通过画图来解释一下:
在计算机中假设左边是低地址,右边是高地址如图:
例子:
假设我现在要存一个int类型的数据,int a= 4;它的二进制是00000000000000000000000000000100,如果是把a存入内存,而且是大端存储:
小端存储:
定义:
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地 址中。
例子:
假设我现在要存一个int类型的数据,int a= 7;它的二进制是00000000000000000000000000000111,如果是把a存入内存,而且是大端存储:
注:这里的小端存储可不是把二进制数据倒着放进去就结束了!!!
在VS中调试:
在VS中我们可以看一看是大端存储还是小端存储:
还是用上述的例子,代码如下;
#include<stdio.h> int main() { int a = 4; int b = 7; return 0; }
按下F11,然后在调试窗口打开内存,然后输入&a:
如上图,内存中存是04000000,相当于0x04000000,这里内存中按8进制存储,我们知道,在64位机器中4的2进制是00000000000000000000000000000000000000000000000000000000000100
所对应的16进制是
00000004.
但是内存中存的是04000000,这里我们可以看出,VS中存储方式是小端存储。(低地址处存放低位,高地址处存放高位)。
在不进行调试的情况下,用代码验证大小端
当我们清楚大小端的定义以后,那么我们能不能在不进行调试的情况下,验证编译器的大小端的存储方式。
这里需要注意一点,编译器如何读取内存中的值,是从低地址开始,往高地址读取数据,而且每次是1个字节一个字节读取。
例如内存中如果存放的16进制是01201000。
那么读取方式是:
10
02
01
00
然后组合在一起是00102001,转换为10进制就是4 020 001。
如果我只将一个字节拿出来,然后去判断这一个字节是转换为整形是多少即可。
步骤:
例如:int a = 1;它的十六进制是00000001,如果是小端存储那么存储应该是01000000
方法一:
如果是大端存储应该是00000001,此时,此时我如果从低地址处拿出一个字节数据,
小端我拿出的是01,大端我拿出的是00。
那么如何做到4个字节中取出一个字节数据呢,也很简单。因为一个字节对应着一个地址,我可以4个地址拿出一个地址,然后把这一个地址的值打印出来。
代码如下:
#include <stdio.h> int check_sys() { int i = 1; return (*(char *)&i); }
然后如果解引用后的值是1,那么就是小端存储,如果是0,就是大端存储。
int main() { int ret = check_sys(); if(ret == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
完整代码与结果:
#include <stdio.h>
int check_sys()
{
int i = 1;
return (*(char*)&i);
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}