首先请看定义:
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
举例说明:假设变量x类型为int,位于地址0x100处,x的十六进制表示形式为0x01234567。地址范围0x100~0x103。则该变量在不同机器内存中的分布如下图所示:
若需用程序验证系统是大端模式还是小端模式,有两种方法
1.利用联合体的性质
因为联合体中的成员是共享内存的,并且数据是从低地址存放的,可以利用这一性质判断。
typedef union
{
char a;
short c;
}U;
int checkCPU1() //若是小端则返回1,否则返回0
{
U u;
u.c=1;
//printf("%d\n",u.a);
return u.a==1;
}
由于short占2字节,而char占1字节,当对c赋值为1时,若系统为小端模式,则在系统中存放方式为:
000000001
000000000
那么当取a的值时,a的整型值必定为1;否则为0.
2.强制取低地址单元的数据
int checkCPU2()
{
short a=0x1234;
char *p=(char *)&a;
//printf("%d\n",*p);
return *p==0x34;
}
很显然,若是小端模式,指针p指向的单元里面的数据整型值必为0x34,否则为0x12。
测试程序:
#include <iostream>
using namespace std;
typedef union
{
char a;
short c;
}U;
int checkCPU1() //若是小端则返回1,否则返回0
{
U u;
u.c=1;
//printf("%d\n",u.a);
return u.a==1;
}
int checkCPU2()
{
short a=0x1234;
char *p=(char *)&a;
return *p==0x34;
}
int main(int argc, char *argv[])
{
if(checkCPU1==1)
cout<<"your machine is littek endian"<<endl;
else
cout<<"your machine is littek endian"<<endl;
return 0;
}
考察一下大家掌握的怎么样?出一题,如下(问程序的输出是什么):
typedef struct {
int a:8;
int b:8;
}type;
int main()
{
type t;
t.a=0x01;
t.b=0x02;
printf("0x%04x\n",*(short*)(&t));
return 0;
}