大端模式和小端模式
1.大端模式(Big_endian): 字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
2.小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
函数判断
函数实现小端返回0,大端返回1;
int FunCheckLittle()
{
union check_system
{
int i;
char ch;
}c;
c.i = 1;
return c.ch==1? 0:1;
}
图解
应用
1、下面在x86 Linux系统下输出什么?
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1); //line 104
printf("%#x,%#x",ptr1[-1],*ptr2);
编译提示:
hello.c:104:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
hello.c:104:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
运行结果:
Segmentation fault (core dumped)
分析:打印出a的地址0x9de27a30,直接通过*(int *)0x9de27a30读写也报段错误,不应该啊?待解决。。。
可以明确的是ptr1[-1]打印5,如果能编译不报错的话*ptr2应该打印0x2000000,是这样吗?
2、p->i输出什么?
union
{
int i;
char a[2];
}*p, u;
p =&u;
p->a[0] = 0x39;
p->a[1] = 0x38;
printf("i=%#x\n", p->i);
如果是小端模式,打印出0x3839,大端应该是打出0x39380000,待验证。。。
变体1:
union
{
int i;
unsigned char a[2];
}*p, u;
p =&u;
p->a[0] = -1;
p->a[1] = -2;
printf("i=%#x,%#x,%#x,%#x,%#x\n", p->i,p->a[0],p->a[1],p->a[2],p->a[3]);
打印:i=0xfeff,0xff,0xfe,0,0
变体2:
union
{
int i;
unsigned char a[2];
}*p, u;
p =&u;
p->i = -2;
printf("i=%#x,%#x,%#x,%#x,%#x\n", p->i,p->a[0],p->a[1],p->a[2],p->a[3]);
打印:i=0xfffffffe,0xfe,0xff,0xff,0xff