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


聲明:文章僅為個人總結所用,鄙人菜鳥,高手勿噴,歡迎批評指正。

經常看到通過聯合體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\n",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\n",val,ntohl(val),ntohl(ntohl(val)));
}

  因時間關系,今天暫時到此為止。

歡迎大家跟帖討論,如有紕漏,歡迎指正,謝謝~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM