泥淖--------------------大小端

声明:文章仅为个人总结所用,鄙人菜鸟,高手勿喷,欢迎批评指正。

经常看到通过联合体Union来判断系统是大端还是小端,而大家的解释通常都是:“联合体union的存放顺序是所有成员都从低地址开始存放,解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。”而我却始终没有找到这句话是出自哪本书。

我知道unsigned short a = 0x1122在大端中存的话就是0x1122,而如果是在小端CPU上运行的话就是0x2211。疑问:

1. 那么如果取a的低八位即a&0xff的话,是不是在大端中是0x22,而在小端中就是0x11呢?

2. 那么如果a向右移位即a>>8取得其高八位的话,是不是再大端中是0x11,而在小端中就是0x22呢?

3. 那么如果将a赋值给unsigned char b,即b = (unsigned char)a,考虑到类型强转,取short型低八位赋值给char型,那么short型的低八位是多少呢?在大端中存的话,低八位是0x22,而在小端中存的话是0x11,那么是不是在不同架构的CPU上,结构就不相同呢?

4. 为什么通过联合体可以判断是大端还是小端?除了那个找不到出处的解释外,还有其他的解释吗?

5. 除了网上盛传的两种判断大小端的方法外,还有其他判断大小端的方法吗?


还是先列出网上盛传的其中一种判断方法吧:

void JudgeEndianByInt()
{
    unsigned short temp = 0x1122;

    if(((char *)&temp)[0] == 0x11)
    {
        printf(_BIG_ENDIAN_);
    }
    else
    {
        printf(_Little_ENDIAN_);
    }
}

我对这个函数的理解:直接根据大小端的定义来判断,如果该数据的低地址为存放的是该数据的低数据位,那么就是小端,否则就是大端。当然我也可以理解为,将指向short型数据的指针强制转换为char型指针,那么就要取其低地址赋值给char型指针,因此如果该低地址存放的是数据的低位,那么就是小端。

另外一种方法:

typedef union
{
    int val_1;
    char val_2;
}Union_Test;

void JudgeEndianByUnion()
{
    Union_Test u;

    u.val_1 = 0x11;

    if(u.val_2 == 0x11)
    {
        printf(_Little_ENDIAN_);
    }
    else
    {
        printf(_BIG_ENDIAN_);
    }

}

我对这个函数的理解:其实这个判断和第一个判断原理是一样的,都是将同一个short型的内存区的值强制转换成char型的内存区,那么就要取其低位,如果地位存储的是低数据位,则是小端。

然后我来分析我的那么些个疑问。

1 2 ,位操作是针对二进制位的,是针对数据的二进制位的,不关乎内存地址的东西,所以不同平台不会有影响。

3. 也不会,强转的是数据的值,不是数据的地址,不会变化。

4. 有很多,只有能获得地址的方法或者根据地址进行判断的都是可行的,比如:

void JudgeEndianByMemory()
{
    unsigned short temp = 0x11;
    unsigned char temp_2 = 0;

    memcpy(&temp_2,&temp,sizeof(temp_2));

    if(temp_2 == 0x11)
    {
        printf(_Little_ENDIAN_);
    }
    else
    {
        printf(_BIG_ENDIAN_);
    }
}

或者调用系统函数htonl ntohl等:

void HostToNet(ElemType val)
{
	printf("val is 0x%x  htonl(val) is 0x%x  htonl(htonl(val))  0x%x
",val,htonl(val),htonl(htonl(val)));
}

void NetToHost(ElemType val)
{
	printf("val is 0x%x  ntohl(val) is 0x%x  ntohl(ntohl(val))  0x%x
",val,ntohl(val),ntohl(ntohl(val)));
}

  因时间关系,今天暂时到此为止。

欢迎大家跟帖讨论,如有纰漏,欢迎指正,谢谢~

原文地址:https://www.cnblogs.com/xiaowenhu/p/3233232.html