大端模式:
字数据的高字节存储在低地址中,而字数据的低字节存储在高地址中。
小端模式:
字数据的低字节存储在低地址中,而字数据的高字节存储在高地址中。
如图:
用C写一个函数判断当前系统的存储模式
#include <stdio.h>
#include <windows.h>
int endian()
{
int i = 1;
char *p = (char *)&i;
return *p;
}
int main()
{
if (1==endian())
printf("小端存储\n");
else
{
printf("大端存储\n");
}
system("pause");
return 0;
}
对上面代码进行解释,如图:
从图片可以看到,整型变量 i 在两种模式下的存储。
指针p指向了整型变量 i 的地址,并且指针p是char类型指针,代表p指向的内容为char类型变量,所以当返回 *p 的时候,会按照char类型返回,即只读取一个字节,那么我们只需要看 *p返回的值来判断系统是大端存储还是小端存储。
返回1,说明是小端模式;返回0,说明是大端模式。
那么,这个函数就是最好的判断方式了吗?
答案当然是否定的!
我们可以利用联合体(共用体)union型数据来写这个函数。
首先,先简单介绍一下union型
union关键字的用法与struct的用法非常类似。
union维护足够的空间来放置多个数据成员中的“一种”,而不是为每一个数据成员配置空间。在union中所有的数据成员共用一个空间,同一时间只能存储其中一个数据成员,所有的数据成员具有相同的起始地址。例如:
union StateMachine
{
char character;
int number;
char * str;
double exp;
};
一个union只配置一个足够大的空间来容纳最大长度的数据成员,以本例而言,最大长度是double类型,所以StateMachine的空间大小就是double数据类型的大小。
在C++里,union的成员默认属性页为public。union主要用来压缩空间。如果一些数据不可能在同一时间同时被用到,则可以使用union。
–摘自 陈正冲《C语言深度剖析》 1.17章节
如果上面的内容看懂了,则我们就可以用union来写这个函数。
代码如下:
#include <stdio.h>
#include <windows.h>
int endian()
{
union
{
int i;
char c;
}u = {1};
return u.c;
}
int main()
{
if (endian() == 1)
printf("小端存储\n");
else if (endian()==0)
{
printf("大端存储\n");
}
system("pause");
return 0;
}
因为union型数据中的数据成员共用一个空间,具有相同的起始地址, 一个union只配置一个足够大的空间来容纳最大长度的数据成员。
所以,当我们把整型数据 1 存储在union内时,返回 u.c 便是把这块空间的第一个字节的内容返回,因此,同第一个代码的原理,可用其返回值判断大小端。
返回1,说明是小端模式;返回0,说明是大端模式。