在没有 implicit/explicit 转换的情况下在 C 中查找字节顺序
Finding Endianness in C without implicit/explicit casting
我期待找到一种方法,借此我可以找到字节顺序 而无需 implicit/explicit 强制转换、循环、切换、内置函数、宏 。我试过一段代码,但它使用显式转换。
int is_little_endian(){
int temp = 1;
return *(char *) temp;//Returns 1 if it's a little endian machine.
}
[编辑]
必须在不使用任何转换的情况下完成。我找不到一个问题,我们可以在不强制转换和使用宏的情况下做到这一点。 Implicit Casting 这里指的是编译器自动转换。说从 char 到 int。
为什么不试试
unsigned int i= 1;
char *p = &i;
if(*p)
printf("Little endian\n");
else
printf("Big endian\n");
没有 "implicit casting" 这样的东西 - 强制转换是一个显式运算符。但是,如果您正在寻找一种无需检查对象的 表示 即可观察字节序的方法,那么没有办法。 Endianness 纯粹是 属性 表示,而不是值,因此如果您限制自己访问表示,它就不存在。这就是为什么大多数好的代码不应该关心字节顺序的原因。
如果您确实想作弊并访问表示,但又不想让它看起来像演员,这里有一些想法:
int i = 1;
char c;
memcpy(&c, &i, 1);
c;
或:
union { int i; char c; } x = { 1 };
x.c;
或:
int i = 1;
FILE *f = tmpfile();
fwrite(&i, sizeof i, 1, f);
rewind(f);
getc(f);
或使用任何可能在后台为您执行此类操作的库函数。如果您使用的是 POSIX 系统或任何其他具有套接字操作的系统,您也可以:
htonl(1) != 1;
但是所有这些要么依赖于检查表示,要么依赖于实现中关于目标字节序是什么的硬编码假设。
这是通过编译器本身完成的。
int is_little_endian(void) {
#ifdef _LITTLE_ENDIAN
return 1;
#else
return 0;
#endif
}
为小端目标构建程序时,在构建命令中定义_LITTLE_ENDIAN(通常通过添加-D_LITTLE_ENDIAN)。如果程序是为大端目标构建的,请在构建命令中定义 _BIG_ENDIAN (-D_BIG_ENDIAN).
以上示例将在 运行 时让您知道它是否是为小端目标构建的。
但是,由于字节顺序不太可能在 运行 时更改,我认为在 运行 时这样做没有多大价值。而是利用 C 预处理器和通过命令行传入定义的能力来完成您需要的。
希望对您有所帮助。
我期待找到一种方法,借此我可以找到字节顺序 而无需 implicit/explicit 强制转换、循环、切换、内置函数、宏 。我试过一段代码,但它使用显式转换。
int is_little_endian(){
int temp = 1;
return *(char *) temp;//Returns 1 if it's a little endian machine.
}
[编辑]
必须在不使用任何转换的情况下完成。我找不到一个问题,我们可以在不强制转换和使用宏的情况下做到这一点。 Implicit Casting 这里指的是编译器自动转换。说从 char 到 int。
为什么不试试
unsigned int i= 1;
char *p = &i;
if(*p)
printf("Little endian\n");
else
printf("Big endian\n");
没有 "implicit casting" 这样的东西 - 强制转换是一个显式运算符。但是,如果您正在寻找一种无需检查对象的 表示 即可观察字节序的方法,那么没有办法。 Endianness 纯粹是 属性 表示,而不是值,因此如果您限制自己访问表示,它就不存在。这就是为什么大多数好的代码不应该关心字节顺序的原因。
如果您确实想作弊并访问表示,但又不想让它看起来像演员,这里有一些想法:
int i = 1;
char c;
memcpy(&c, &i, 1);
c;
或:
union { int i; char c; } x = { 1 };
x.c;
或:
int i = 1;
FILE *f = tmpfile();
fwrite(&i, sizeof i, 1, f);
rewind(f);
getc(f);
或使用任何可能在后台为您执行此类操作的库函数。如果您使用的是 POSIX 系统或任何其他具有套接字操作的系统,您也可以:
htonl(1) != 1;
但是所有这些要么依赖于检查表示,要么依赖于实现中关于目标字节序是什么的硬编码假设。
这是通过编译器本身完成的。
int is_little_endian(void) {
#ifdef _LITTLE_ENDIAN
return 1;
#else
return 0;
#endif
}
为小端目标构建程序时,在构建命令中定义_LITTLE_ENDIAN(通常通过添加-D_LITTLE_ENDIAN)。如果程序是为大端目标构建的,请在构建命令中定义 _BIG_ENDIAN (-D_BIG_ENDIAN).
以上示例将在 运行 时让您知道它是否是为小端目标构建的。
但是,由于字节顺序不太可能在 运行 时更改,我认为在 运行 时这样做没有多大价值。而是利用 C 预处理器和通过命令行传入定义的能力来完成您需要的。
希望对您有所帮助。