小端模式(Little-Endian):低字节存储在低地址(先存)
大端模式(Big-Endian):高字节存储在低地址(先存)
使用union联合体判断
union A
{
int i;
char c;
}a;
a.i=1;
printf("%d",a.c);
小端存储:
i 0x01 00 00 00
大端存储:
i 0x00 00 00 01
联合体union会给其中的成员分配同一个地址,长度为最大成员的长度,所以小端下c = 1,大端下c = 0。
写一个检测大小端的函数
// 大端返回1,小端返回0
int CheckDX()
{
union A
{
int i = 1;
char c;
}a;
a.i = 1;
return if(i==c);
}
大小端很容易记忆混乱,我自己想了一个理解的方法:常用的X86如Windows、GCC中都是小端模式,小端也比较好理解,例如上面int类型i的储存,四个字节,从左往右地址依次增高,字节也依次增高(从低字节0x01到高字节0x00),就是写出来视觉上
看着是反的。一句话,小端模式是先存低字节。
KEIL C51为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。大端模式等下次用的时候测试一下。
采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。
笔试题
#include <stdio.h>
void main()
{
char str[20] = "Hello world!";
int *p = (int *)str;
p[0] = 0x61626364;
p[1] = 0x41424344;
p[2] = 0x31323334;
printf("%s", str);
}
结果:
dcbaDCBA4321
#include <stdio.h>
void main()
{
union Test
{
char a[4];
short b;
};
union Test test;
test.a[0]=256;
test.a[1]=255;
test.a[2]=254;
test.a[3]=253;
printf("%d\n",test.b);
}
结果:
-256
char a[0]=256;
val=-128+(256-128)%256=0 ====>a[0]:00000000
char a[1]=255;
val=-128+(255-128)%256=-1 ====>a[1]:11111111
10000001(-1源码)
11111110(-1反码)
11111111(-1补码)
80X86-->小端模式 数据低位--->内存低地址
test共4字节
test XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
低地址 a[0] 00000000
a[1] 11111111
a[2] ........
a[3] ........
====>short 11111111 00000000(补码)
10000000 11111111(反码)
10000001 00000000(源码-256)
参考资料:
1. https://blog.csdn.net/vevenlcf/article/details/46924267
2. https://blog.csdn.net/qq_18815817/article/details/70196100