2016-02-29 84 views
0

我只是做了樹莓派一個小實驗我正在用下面的代碼:C小端,但產生大端結果?

//tutorialspoint.com/unix_sockets/network_byte_orders.htm 

#include <stdio.h> 

int main(int argc, char **argv) { 

    union { 
     short s; 
     char c[sizeof(short)]; 
    }un; 

    un.s = 0x0102; 

    if (sizeof(short) == 2) { 
     if (un.c[0] == 1 && un.c[1] == 2) 
     printf("big-endian\n"); 

     else if (un.c[0] == 2 && un.c[1] == 1) 
     printf("little-endian\n"); 

     else 
     printf("unknown\n"); 
    } 
    else { 
     printf("sizeof(short) = %d\n", sizeof(short)); 
    } 

    exit(0); 
} 

,我得到的是小尾數結果。

現在,當我轉換的整數字節數組,出來的結果是在大端

unsigned char c[4]; 
int num = 170; // suppose to give 0000 0000 0000 00AA 
memcpy(c, (char*)&num, sizeof(int)); 
printf("c[0] = %04x \n", c[0]); 
printf("c[1] = %04x \n", c[1]); 
printf("c[2] = %04x \n", c[2]); 
printf("c[3] = %04x \n", c[3]); 
memcpy((char *)&num, c, sizeof(int)); 
printf("%d\n", ntohl((long)num)); 

輸出:

C [0] = 00AA

C [ 1] = 0000

c [2] = 0000

C [3] = 0000

-1442840576

我不得不做一個轉變,以便讓它成爲小尾數

//c[0] = (num >> 24) & 0xFF; 
//c[1] = (num >> 16) & 0xFF; 
//c[2] = (num >> 8) & 0xFF; 
//c[3] = num & 0xFF; 

我現在很困惑,如果我的樹莓派是小endian或big endian?

此外,我要通過套接字傳遞這些數據,所以我需要確保它是網絡字節順序,還是沒關係,只要我標準化了我將使用哪個endian我正在嘗試與之通信的所有設備?

PS。另外,如果我需要手動將整數數組中的所有整數從小端轉換爲大端,我應該怎麼做?我在網上找到的大多數解決方案只是轉換整數而不是整數數組。

+1

代碼'0000 0000 0000 00AA'爲人類從左向右讀取的方式將在低字節中存儲'AA',小字節中給出了您準確得到的結果。 –

+0

爲什麼不使用相同的值0x0102進行兩種測試?你會看到你得到相同的結果:02是第一個。 –

+0

使用正確的序列化與位移/掩碼。不要依賴實現定義的或可能未定義的行爲。使用好的編譯器不會有或者只是邊際速度懲罰 – Olaf

回答

4

這兩種情況都是小尾數。

在你的第一個案例中,最不重要的字節是2,並且匹配c [0] - 小尾數。

在你的第二種情況下,最不重要的字節是170(所有其他都是零)並且匹配c [0] - 小尾數。

如果您通過套接字複製數據,那麼您只需確保數據格式一致。它並不重要。

對於複製數據數組,只需執行與單個項目相同的操作,但重複該操作即可。

1
int num = 170; // suppose to give 0000 0000 0000 00AA 

號這應該給你AA, 00, 00, 00(或AA, 00, 00, 00, 00, 00, 00, 00如果int是64位)。
在小端佈局中,最低有效字節存儲在最低地址處。 0x000000AA(170)的最低有效字節是0xAA

+0

好吧我知道了!謝謝 :) –