我试图编写一个程序来检测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;
}
谢谢!
答案 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 - 但是在十进制中。但是66
和88
位于程序中的 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的情况......