大小端

大小端
一般人的书写习惯:数据左边的为高位,右边的为低位,地址则相反:地址左边的为低位,右边的为高位例如数据16位数据:0x12345678,12为数据的高位,78位数据的低位

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
例如四字节的数据:0x12345678,地址低->高,低地址存放高位,高地址存放位,存储为:

12
34
56
78

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
例如四字节的数据0x12345678,地址:低->高,高地址存放高位,低地址存放低位,存储为:

78
56
34
12

只需记住与我们阅读习惯一致的为大端模式。
判断方法

union方法

union的特殊性会申请内部最大的长度为union的长度,取值会从地址的开始往后读取
#include <stdio.h>
union check_point{
int a;
char b;
} check_point;
int main()
{
check_point.a=1;
if(check_point.b == 1)
printf(“LITTLE ENDIAN!\n”);
else
printf(“BIG ENDIAN !\n”);
return 0;
}
我的测试机为mac,为小端模式,所以执行结果是
LITTLE ENDIAN!
linux内核也是用了类似的方法:
tatic union { char c[4]; unsigned long mylong; } endian_test = {{ ‘l’, ‘?’, ‘?’, ‘b’ } };
#define ENDIANNESS ((char)endian_test.mylong)
测试用例如下:
#include <stdio.h>
static union { char c[4]; unsigned long mylong; } endian_test = {{ ‘l’, ‘?’, ‘?’, ‘b’ } };
#define ENDIANNESS ((char)endian_test.mylong)
int main()
{
printf(“%c \n”,ENDIANNESS);
return 0;
}
测试结果:
l
linux内核可直接使用ENDIANNESS宏的返回结果判断大小端

int 1的特殊性

int 1的大端存储方式为地址:低->高,高地址存放低位,低地址存放高位

00
00
00
01

小端存储方式为地址:低->高,高地址存放高位,低地址存放低位

01
00
00
00

#include <stdio.h>
int main()
{
int a = 1;
char pc = *(char*)(&a);
if (pc == 1)
printf(“LITTLE\n”);
else
printf(“BIG\n”);

return 0;
}
输出结果为:
LITTLE

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理