使用 htons 确定字节顺序
Determining endianness with 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");
}
}
我想知道这段代码是否适用于检查字节顺序?我已经看到很多问题用各种 pointer/char 技巧来检查它,但我认为这更简单。它假设如果将数字转换为网络字节顺序(大端),如果它与原始数字相同,那么您就在大端系统上。否则你使用的是小端系统。
这个检查有没有错误的假设?也许网络字节顺序并不总是大端,但 it seems it is standardised to be so.
这足以在 运行 时间检查字节顺序。
在大端系统上,htons
(以及 ntohs
、htonl
和 ntohl
)被定义为无操作,而在小端系统上他们执行字节交换。
编辑:
这也可以使用联合来完成。下面的检查检测大端和小端,以及其他更奇特的字节顺序。
#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;
}
原则上,C 允许 uint16_t
表示中的位采用任何实现定义的顺序,而不仅仅是 "little" 或 "big endian"。如所写,您的测试仅告诉您 htons
分别置换位 0,1,3,4,5,6 和 2,7-15,而不混合它们。
如果遍历2的所有次方,在0..15中发现htons(1<<i)==1<<i
for i
,那么可以断定顺序肯定是big endian。相反,如果您在 0..15 中发现 htons(1<<i)==1<<(i^8)
for i
,则可以得出小端法。否则你会有一个非常不寻常的表现。
实际上,奇怪的事情不会发生,你的测试应该足够了。
考虑以下代码:
#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");
}
}
我想知道这段代码是否适用于检查字节顺序?我已经看到很多问题用各种 pointer/char 技巧来检查它,但我认为这更简单。它假设如果将数字转换为网络字节顺序(大端),如果它与原始数字相同,那么您就在大端系统上。否则你使用的是小端系统。
这个检查有没有错误的假设?也许网络字节顺序并不总是大端,但 it seems it is standardised to be so.
这足以在 运行 时间检查字节顺序。
在大端系统上,htons
(以及 ntohs
、htonl
和 ntohl
)被定义为无操作,而在小端系统上他们执行字节交换。
编辑:
这也可以使用联合来完成。下面的检查检测大端和小端,以及其他更奇特的字节顺序。
#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;
}
原则上,C 允许 uint16_t
表示中的位采用任何实现定义的顺序,而不仅仅是 "little" 或 "big endian"。如所写,您的测试仅告诉您 htons
分别置换位 0,1,3,4,5,6 和 2,7-15,而不混合它们。
如果遍历2的所有次方,在0..15中发现htons(1<<i)==1<<i
for i
,那么可以断定顺序肯定是big endian。相反,如果您在 0..15 中发现 htons(1<<i)==1<<(i^8)
for i
,则可以得出小端法。否则你会有一个非常不寻常的表现。
实际上,奇怪的事情不会发生,你的测试应该足够了。