用htons确定字节序

考虑下面的代码:

#include <stdio.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { uint16_t num = 123; if (htons(num) == num) { printf("big endian\n"); } else { printf("little endian\n"); } } 

我想知道这个代码是否适用于检查字节序? 我已经看到很多问题用各种指针/字符技巧检查它,但我认为这是更简单。 它的工作假设,如果您将一个数字转换为networking字节顺序(大端),如果它是原来的数字相同,那么你在一个大端系统。 否则,你在一个小端系统。

这个检查有假设吗? 或许也许networking字节顺序并不总是大端的,尽pipe看上去是标准化的 。

原则上,C允许uint16_t表示中的位是任何实现定义的顺序,而不仅仅是“小”或“大端”。 正如你所写的,你的测试只会告诉你, htons分别将位0,1,3,4,5,6和2,7-15置换而不混合它们。

如果你遍历所有权力的两个,并发现htons(1<<i)==1<<ii在0..15,那么你可以得出结论,顺序肯定是大端。 如果你在0..15的范围内找到htons(1<<i)==1<<(i^8) ,那么可以得出小尾数。 否则你有一个非常不寻常的代表。

事实上,奇怪的事情不会发生,你的测试应该是足够的。

这足以在运行时检查字节顺序。

在大端系统中, htons (以及ntohshtonlntohl )被定义为no-ops,而在little endian系统上,它们执行字节交换。

编辑:

这也可以使用联合来完成。 下面的检查检测大小写,以及其他更奇特的字节顺序。

 #include <stdio.h> #include <stdint.h> union echeck { uint32_t i; char c[4]; } echeck = { .c = { 0x01, 0x02, 0x03, 0x04 } }; int main() { if (echeck.i == 0x01020304) { printf("big endian\n"); } else if (echeck.i == 0x04030201) { printf("little endian\n"); } else if (echeck.i == 0x02010403) { printf("pdp endian\n"); } else { printf("other endian\n"); } return 0; }