2011-07-16 38 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,这是跨平台,如果想要自己实现这个技巧的提示。