文章转载自:嵌入式linux公众号,写代码的篮球痴
1. 什么是大端和小端
大端
高位字节存放在内存的低地址端,低位字节存放在内存的高地址端(CPU对操作数的存放方式是从高字节到低字节)
小端
低位字节存放在内存的低地址端,高位字节存放在内存的高地址端(CPU对操作数的存放方式是从低字节到高字节)
假设内存如下:
我们要存一个数据0x44332211到这块内存去,如果系统是大端模式的话,存储方式如下图:
如果系统是小端模式的话,存储方式如下图:
2. 如何通过代码来判断当前系统的存储模式
方式一
#include<stdio.h>
int main()
{
int i = 1;
(*(char*)&i == 1) ? printf("Little-endian\n") : printf("Big-endian\n");
return 0;
}
输出如下:
指针类型转换,最后取 char * 指针的值,也就是判断 int 低地址的数据是否为1。
方式二
#include<stdio.h>
union System
{
char a;
int b;
} ;
int main()
{
union System s;
s.b = 1;
printf("0x%x\n",&s.a);
printf("0x%x\n",&s.b);
(s.a == 1) ? printf("Little-endian\n") : printf("Big-endian\n");
return 0;
}
输出如下:
共用体的特点是,使用类型最大的那个类型作为共用体的大小,所以,char a 使用的是 int b的空间大小,判断 a的值,也就是判断低地址的数据值
方式三
#include<stdio.h>
static union
{
char a[4];
int ul;
}endian = {'L', '?', '?', 'B'};
#define ENDIAN ((char)endian.ul)
int main()
{
printf("%cENDIAN\n", ENDIAN);
return 0;
}
输出如下:
宏定义和字符数组
方法四
#include<stdio.h>
int main()
{
int a = 0x44332211;
char* b = (char*)&a;
(*b == 0x11) ? printf("Little-endian\n") : printf("Big-endian\n");
return 0;
}
输出如下:
直接指针操作,取出int
低地址数据进行判断