大端存储模式 : 是指数据的低位字节序保存在内存的高地址中, 而数据的高位字节序, 保存在内存的低地址中;
小端存储模式 : 是指数据的低位字节序保存在内存的低地址中, 而数据的高位字节序, 保存在内存的高地址中;
通过上图可以看出 a 和 b 分别以补码的形式存储在内存当中 , 但是存储的顺序确是反过来的 , 这是因为在 VS2013 编译器上数据存储模式是小端字节序存储 , 是由低地址向高低址进行存储
为什什么有⼤大端和⼩小端 :
- 为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语⾔中除了8bit的char之外,还有16bit的short型, 32bit的long型( 要看具体的编译器器 ),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽⼤于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型 x,在内存中的地址为0x0010,x 的值为0x1122,那么0x11为⾼字节,0x22为低字节 . 对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在⾼地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEILC51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式
如何用一个小程序判断当前机器的字节序 ?
方法一 :通过强转的方式, 判断返回值
代码如下 :
#include <stdio.h>
int Check_key()
{
int i=1;
//将int型的i强转为char型
return *(char *)&i;
}
int main()
{
int ret=Check_key();
if(ret==1)
printf("小断\n");
else
printf("大端\n");
return 0;
方式二 : 通过使用联合( 共用体 )的方式判断
- 在使用联合时 , 联合里边的成员会公用一块空间 , 彼此之间是相互影响的
- 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的
- 联合是一种复合类型,其中,定义了一组不同类型的成员,并且所有成员对象都占用同一存储区域。因此,根据联合的指定方式,联合是一个变体类型的对象,在任何给定时间内仅有一个成员有效。通常,使用其他变量或状态部分来指示当前处于有效状态的联合成员。联合的大小为其最大成员的大小,用于联合的内存对齐为联合成员所需的最大对齐值。
当给un.i 赋值为 1 时 , 由于 i 和 j 公用一块空间 , 所以 j 的值也相应的被改变
代码如下 :
#include <stdio.h>
int Check_key()
{
union
{
int i;
char j;
}un;
nu.i=1;
return un.j;
}
int main()
{
int ret=Check_key();
if(ret==1)
printf("小断\n");
else
printf("大端\n");
return 0;
}
注:
字节序分为大端字节序和小端字节序
- 大端字节序是指一个整数的高位字节(32-31bit)存储在内存的低地址处,低位字节(0-7bit)存储在内存的高地址处。
- 小端字节序是指一个整数的高位字节(32-31bit)存储在内存的高地址处,低位字节(0-7bit)存储在内存的低地址处。
现代PC大多采用小端字节序,所以小端字节序又被称为主机字节序。
大端字节序也称为网络字节序。
即使是同一台机器上的两个进程(比如一个由C语言,另一个由Java编写)通信,也要考虑字节序的问题(JVM采用大端字节序)。