尝试编写endianess检测程序,但无法比较char值

时间:2017-11-19 23:11:06

标签: c endianness

我试图编写一个程序来检测endianess并返回endianess类型(1表示小,0表示大)或-1(如果没有)。 但是我遇到了这个问题:当我尝试使用unsigned char掩码无符号长字时,然后我尝试将此char与ASCII值进行比较,if条件内的代码显然无法访问...

int is_little_endian() {
    unsigned long word = 0x6600000000000088;
    unsigned char maskedWord = word;
    if (maskedWord == 'X') {
        return 0;
    } else if (maskedWord == 'B') {
        return 1;
    } else return -1;
}

谢谢!

4 个答案:

答案 0 :(得分:2)

您可以在不使用union的情况下检查字节顺序,任何类型至少需要两个字节

uint32_t val = 1;
int big_endian = !(*(char *)&val);

在内存中(对于4字节int),大端将是

     val:  00 00 00 01
- ============(addresses)======> +

Little endian:

     val:  01 00 00 00
- ============(addresses)======> +

答案 1 :(得分:1)

此代码未能成功测试字节顺序。

您定义unsigned long word = 0x6600000000000088。暂时忽略此常量对于unsigned long来说可能太大,当您将该值分配给unsigned char时,它会被模数256截断,因此maskedWord将始终等于0x88。

要进行正确的字节顺序测试,需要创建一个char数组和一个固定大小的整数的并集,并将字节分配给char数组,然后检查整数的值。

union echeck {
    unsigned char bytes[4];
    uint32_t val;
};
echeck e = { .bytes = { 0x01, 0x02, 0x03, 0x04 } };
if (e.val == 0x01020304) {
    printf("big endian\n");
} else if (e.val == 0x04030201) {
    printf("little endian\n");
} else {
    printf("neither big or little endian\n");
}

答案 2 :(得分:0)

代码非常错误。将0x6600000000000088转换为unsigned char的结果将导致八位字节可寻址平台上的0x88,无论是小型还是大型还是中端型。

然后另一个问题是'B'在ASCII机器上是66,是的,'Z'是88 - 但是在十进制中。但是6688位于程序中的 hex 中。 0x66对应'f'88是一些扩展字符。

而不是所有这些混乱,只需使用

union {
    uint64_t test_value;
    unsigned char bytes[sizeof(uint64_t)];
} detect = { .test_value = 0x0102030405060708 };

并检查detector.bytes[0]detector.bytes[7]

的值

答案 3 :(得分:0)

这里是我认为尊重C类型惩罚规则的候选人,假设memcpy没问题。

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

int main(int argc, char *argv[])
{
  uint32_t test;
  uint8_t trial[4] = {0x01, 0x23, 0x45, 0x67};

  memcpy(&test, trial, 4);
  switch(test)
  {
    case 0x01234567: printf("Big Endian\n"); break;
    case 0x67452301: printf("Little Endian\n"); break;
    case 0x45670123:
    case 0x23016745: printf("Middle Endian\n"); break;
    default: printf("WTF?\n"); break;
  };
}

我想如果你必须使用long,你可以把它分成sizeof(long)= 4和sizeof(long)= 8的情况......