如何判断一个机器的大小端
- 一:什么是机器的大小端
- 二:为什么会有大小端
- 三:设计一个小程序来判断当前机器的大小端
- 方法一:指针类型强转
- 方法二:联合体
一:什么是机器的大小端
机器的大小端是指在内存中存储多字节数据时的字节顺序。在一个多字节数据(如整数、浮点数)被存储在内存中时,会按照一定的字节顺序将它们存储。主要有两种类型的大小端:
- 大端序:数据的
高位字节
存储在低地址位置
,低位字节
存储在高地址位置
。 - 小端序:数据的
低位字节
存储在低地址位置
,高位字节
存储在高地址位置
。
例子:
这两种大小端序的命名来自于《格列佛游记》(Gulliver’sTravels)中的一个故事:主人公吉列佛来到了两个相互战争的王国,其中一个王国的人们从蛋的大端开始吃,而另一个王国的人则从蛋的小端开始吃。这个故事被引用来描述字节顺序不同的机器。
不同的计算机体系结构(如x86、ARM)有不同的大小端表示方式,而在网络传输中,通常使用大端序(网络字节序)来保证数据的一致性。在实际编程中,需要注意数据在不同大小端机器上的转换和处理。
二:为什么会有大小端
为什么会有⼤⼩端模式之分呢?
- 这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为
8bit
位,但是在C语⾔中除了8 bit
的char
之外,还有16 bit
的short
型,32 bit
的long
型(要看具体的编译器)。 - 另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了⼤端存储模式和⼩端存储模式。
例如:⼀个 16bit
的 short
型 x
,在内存中的地址为 0x0010
,x
的值为 0x1122
,那么0x11
为⾼字节, 0x22
为低字节。对于⼤端模式,就将 0x11
放在低地址中,即 0x0010
中,0x22
放在⾼地址中,即 0x0011
中。⼩端模式,刚好相反。我们常⽤的 X86
结构是⼩端模式,⽽KEIL C51
则为⼤端模式。很多的ARM,DSP都为⼩端模式。有些ARM处理器还可以由硬件来选择是
⼤端模式还是⼩端模式。
三:设计一个小程序来判断当前机器的大小端
方法一:指针类型强转
存储一个int
类型变量赋值为1
,把它的地址强转为char*
类型。
因为1
在内存中的存储为0x00000001
如果是小端存储,char
类型中存储的应该为0x01
如果是大端存储,char
类型中存储的应该为0x00
#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;
}
方法二:联合体
使用联合体可以判断大小端的原理是通过联合体的成员共享同一块内存空间。在这段代码中,union
定义了一个联合体 un
,包含一个整型变量 i
和一个字符型变量 c
。
-
通过将
un.i
赋值为1
,将1
存储在联合体un
的整型变量i
中。 -
un.c
表示将联合体un
的整型变量i
强制转换为字符型变量c
,这样就可以访问联合体un
内存中的字节。 -
在小端存储方式中,联合体
un
的字节从低地址到高地址分别是1 00 00 00
,其中的1
是最低有效字节。 -
在大端存储方式中,联合体
un
的字节从低地址到高地址分别是00 00 00 1
,其中的1
是最高有效字节。
int check_sys()
{
union
{
int i;
char c;
}un;
un.i = 1;
return un.c;
}
int main()
{
int ret = check_sys();
if(ret == 1)
{
printf("⼩端\n");
}
else
{
printf("⼤端\n");
}
return 0;
}
※ 如果文章对你有帮助的话,可以点赞收藏!!谢谢支持