何为大小端问题?

大端模式(BE big-endian):数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中(低对高,高对低)

小端模式(LE little-endian):数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中(低对低,高对高)

实例:

A=0x12345678存入地址1000H~1003H中

小端模式:1000H=78,1001H=56,1002H=34,1003H=12

大端模式:1000H=12,1001H=34,1002H=56,1003H=78

大小端数据储存示意

区分大小端

  1. 利用指针来区分大小端

void Judge_duan()
{
	int a = 1;  //定义为1是为了方便 如果你喜欢你可以随意,
	            //只要你能搞清楚 例如:0x11223344;
 
	char *p = (char *)&a;//在这里将整形a的地址转化为char*;
	                     //方便后面取一个字节内容
 
	if(*p == 1)//在这里解引用了p的一个字节的内容与1进行比较;
		printf("小端\n");
	else
		printf("大端\n");
 
}
利用指针来区分大小端
  1. Linux操作系统的源码中大小端的判断

    static union{
        char c[4];
        unsigned long mylong;
    }endian_test = {{'l','?','?','b'}};

    这是利用了联合体union的存放顺序是所有成员都从低地址开始存放的特性。由于联合体的各个成员共用内存,并同时只有一个成员获得该块地址的读取使用权。如果结果‘l’为小端模式,结果是‘b’为大端模式。

  1. 利用联合体来检测大小端

/* 利用联合体来检测大小端 */
#include<stdio.h>
#include<stdlib.h>
 
void Judge_duan(void)
{
	union t
	{
         int i;
         char c;
	} t1;
     t1.i = 1;
     if(t1.c == 1)
		 printf("小端\n");
	 else
	     printf("大端\n");
}
 
int main()
{
	Judge_duan();//在这里我们封装成一个函数,可以有参数和返回值也可以不需要
	system("pause");
	return 0;
}

大小端的转换

int endian_convert(int t)
{
    int result = 0;
    int i;
    
    for(i = 0; i < sizeof(t); i++)
    {
        result <<= 8;
        result |= (t & 0xff);
        t >>= 8;
    }
    return result;
}

参考:关于机器大小端的判定