2011-07-16 117 views
2

我很好奇這個函數是否會確定字節序。確定系統是否使用大端或小端使用C

測試是一個位掩碼,如果整數someInt存儲在little endian中,則該位掩碼等於1。

位掩碼,將0x1000轉換爲匹配機器的末端風格還是會「恆定」?

#include <stdio.h> 

int isBigEndian(){ 
    int someInt =0x0001; 
    if(someInt & 0x0100 == 1) 
     return 1; 
    else 
     return 0; 
} 

int main(){ 
    int returnVal = isBigEndian(); 
    printf("return val is %d", returnVal); 
} 
+0

應該有系統調用或其他API。你的目標是哪個平臺? – 2011-07-16 18:29:52

+2

你不想要一個運行時功能。這是編譯時已知的。 –

回答

6

該函數將始終返回零,因爲您的常量也存儲在系統的本地字節序中。更好的選擇是隻使用系統API來回答你的問題。如果你必須是便攜式的,你可以比較val == ntohl(val)來決定字節順序。

+0

謝謝你回答我的問題。 – Jesse

+1

不依賴'ntohl'(包含套接字頭)的答案似乎更好 – bobobobo

1

更好的辦法是將int值轉換爲sizeof(int)元素的char。看看它看看它是什麼樣子。

此外,您的代碼依賴於一個非常具體的sizeof(int)。你不應該那樣做。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    int a = 0xabcdef42; 
    unsigned int i; 
    char *s = calloc(sizeof(a) + 1, sizeof(s[0])); 
    memcpy(s, &a, sizeof(a)); 
    printf("%x\n", a); 
    for (i = 0; i < sizeof(a); i++) 
     printf("%x ", (unsigned char)s[i]); 
    printf("\n"); 
    free(s); 
    return 0; 
} 

導致(我的機器有一個英特爾CPU)

abcdef42 
42 ef cd ab 

雖然打印字符,請務必將其轉換爲無符號,否則你會看到引起符號擴展搞笑ffffffef值。

4

什麼我用的是這個:

union { 
    short s; 
    char b[2]; 
} endian; 

endian.s = 1; 
little_endian = endian.b[0] == 1; 
+0

您可以刪除'== 1'並只使用值'endian.b [0]'。 –

2

嚴格地說,這是完全的唯一方法ANSI C標準將遍歷所有可能的int類型,並檢查他們所有你想要的代表性匹配。但是,如果您可以假設您所使用的所有系統都是小端,大端或混合端(即沒有像灰色編碼或BCD那樣真的很奇怪),則可以這樣做:

static const unsigned int testvec = 0x01020304; 
static const unsigned char letest[4] = { 0x04, 0x03, 0x02, 0x01 }; 
static const unsigned char betest[4] = { 0x01, 0x02, 0x03, 0x04 }; 

int isle() { 
    return !memcmp(&testvec, letest, 4); 
} 

int isbe() { 
    return !memcmp(&testvec, betest, 4); 
} 

請注意,如果您不查看字節表示形式(即,如果您沒有投射指針來查看原始字節),則無法確定正在使用哪種字節順序。因爲0x00010x1000被均等地字節交換(並且因爲0x0001的小端表示是01 00而不是10 00),所以在所有C實現上都是0

+0

你可能意味着最後的'0x03'是'0x04' ... –

+0

@Chris,的確我是這麼做的!你可以知道我實際使用big-endian系統的頻率如何,呃? :) – bdonlan

1

This question有一些非常好的答案(雖然它是在C++和C99的上下文中);還檢查了評論,他們非常有見地。

在Linux/Unix或任何使用glibc(mingw/cygwin)的應用程序中,您也可以使用 endian.h頭文件,並且可以使用宏。 你也可以查看boost implementation,這是跨平臺,如果想要自己實現這個技巧的提示。