Big-endian and Little-endian
概念
大端模式(Big-endian): 高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。即正序排列,高尾端;
小端模式(Little-endian):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。即逆序排列,低尾端;
描述
1)大端模式
int a = 0x12345678;
低地址 ------------------>高地址
0x12 | 0x34 | 0x56 | 0x78
2) 小端模式
int a = 0x12345678;
低地址 -------------------->高地址
0x78 | 0x56 | 0x34 | 0x12
#include <stdio.h>
int main (void)
{
union{
short i;
char a[2];
}u;//联合体u
u.a[0] = 0x11;
u.a[1] = 0x22;
printf ("0x%x\n", u.i); //0x2211 为小端 0x1122 为大端
return 0;
}
数组在大端小端模式下的存储:
比如 int a = 0x12345678为例,然后呢,在用一个char buf[4]来存储。
大端模式存储,低地址存放高位数据
低地址
|
| buf[0] = 0x12 ---->高位数据
|
| buf[1] = 0x34
|
| buf[2] = 0x56
|
| buf[3] = 0x78 ----->低位数据
高地址
小端模式存储,低地址存放低位数据
低地址
|
| buf[0] = 0x78 ---->低位数据
|
| buf[1] = 0x56
|
| buf[2] = 0x34
|
| buf[3] = 0x12 ----->高位数据
高地址
实际上通过上面的例子我们也可以知道栈的生长方式…
//测试主机字节序
//方法二:使用共用体
#include <stdio.h>
union un{
int a;
char b;
};
int main(int argc, const char *argv[])
{
union un myun;
myun.a = 0x12345678;
printf("a = %#x\n", myun.a);
printf("b = %#x\n", myun.b);
if(myun.b == 0x78)
{
printf("小端存储\n");
}
else
{
printf("大端存储\n");
}
return 0;
}
//测试主机字节序
//方法一:使用地址(指针)
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a = 0x12345678;
char *p = (char *)&a;
printf("a = %#x\n", a);
printf("*p = %#x\n", *p);
if(*p == 0x78)
{
printf("小端存储\n");
}
else
{
printf("大端存储\n");
}
return 0;
}
有没有一种简单粗暴的codeing来验证是大端还是小端
有当然有,比如:
#include<stdio.h>
int main(void){
int a=0x1234;
printf("%#x\n",(char)a);
return 0;
}
简单粗暴,短短的两行code就确定了,根据结果可以知道,存储的方式输出小端存储了