确定数组中整数的字节顺序
Determining endianness of integers in array
我的代码应该检测存储在数组中的整数是大端还是小端。
这是我的代码:
#include <iostream>
using namespace std;
int main()
{
int num[] = {0,0,0x04030201,0,0};
//int num = 0x04030201;
for (int i=0;i<5;i++) {
if(*(char *)&num[i] == 1) {
printf("\nLittle-Endian\n");
}
else {
printf("Big-Endian\n");
}
}
return 0;
}
因为我的电脑是intel的,所有的数字都应该是little endian。这意味着我希望代码遍历数组中的每个整数并打印小端,所以它应该只打印小端 5 次。但这是我目前得到的输出:
Big-Endian
Big-Endian
我该如何解决这个问题?
您无法测试任意值或未知值的字节顺序。如果 int
的所有字节都是零,那么它们的顺序无关紧要。
您的代码打印
Big-Endian
Big-Endian
Little-Endian
Big-Endian
Big-Endian
在我的 x86-64 系统上符合预期,因为你的测试方法是错误的。你的问题听起来像是 always 印刷 Big-Endian!
您的数组元素中只有一个 1
作为值的 least-significant 字节。 (int)0
的all-zero字节当然不会是== 1
.
您无法检查所有字节都具有相同值的数字的字节顺序,因为无论字节顺序如何,您都将加载相同的值。
== 1
检查适用于 0x04030201
,因为该值的低字节是 1
。它一般不起作用。您同样可以在 0x4455667788
中执行类似 == 0x88
的操作,以查看内存中的第一个字节是否为 0x88
字节。
(我说 "byte" 而不是 char
因为我们谈论的是 x86-64,它确实有 8 位字节,所有主流 C++ 实现都使用 1 位字节char
和 32 位 int
。)
如何修复
字节序是属性特定目标体系结构的实现,不同的数组元素不能不同。
int endian_test = 0x12345678;
char *p = (char*)&endian_test;
const char *endian_string = "unknown endian";
if (p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] = 0x12)
endian_string = "Little-Endian";
if (p[3] == 0x78 && p[2] == 0x56 && p[1] == 0x34 && p[0] = 0x12)
endian_string = "Big-Endian";
// test for PDP-endian if you want
for (int i=0;i<5;i++) {
// It's guaranteed that all elements of the array have the same endianness as endian_test
puts(endian_string);
}
大和小并不是唯一可能的字节顺序。
另请注意,您可以使用 CPP 宏检测到这一点。 gcc at least provides macros那让你做
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
#endif
但是这些宏不是 ISO C++ 标准。 "runtime" 检查可以优化到什么都没有(因为结果是 compile-time 常量 true 或 false),但预处理器允许您禁用甚至无法编译的代码。
在 C++20 中,use std::endian
type_traits
。
我的代码应该检测存储在数组中的整数是大端还是小端。
这是我的代码:
#include <iostream>
using namespace std;
int main()
{
int num[] = {0,0,0x04030201,0,0};
//int num = 0x04030201;
for (int i=0;i<5;i++) {
if(*(char *)&num[i] == 1) {
printf("\nLittle-Endian\n");
}
else {
printf("Big-Endian\n");
}
}
return 0;
}
因为我的电脑是intel的,所有的数字都应该是little endian。这意味着我希望代码遍历数组中的每个整数并打印小端,所以它应该只打印小端 5 次。但这是我目前得到的输出:
Big-Endian
Big-Endian
我该如何解决这个问题?
您无法测试任意值或未知值的字节顺序。如果 int
的所有字节都是零,那么它们的顺序无关紧要。
您的代码打印
Big-Endian
Big-Endian
Little-Endian
Big-Endian
Big-Endian
在我的 x86-64 系统上符合预期,因为你的测试方法是错误的。你的问题听起来像是 always 印刷 Big-Endian!
您的数组元素中只有一个 1
作为值的 least-significant 字节。 (int)0
的all-zero字节当然不会是== 1
.
您无法检查所有字节都具有相同值的数字的字节顺序,因为无论字节顺序如何,您都将加载相同的值。
== 1
检查适用于 0x04030201
,因为该值的低字节是 1
。它一般不起作用。您同样可以在 0x4455667788
中执行类似 == 0x88
的操作,以查看内存中的第一个字节是否为 0x88
字节。
(我说 "byte" 而不是 char
因为我们谈论的是 x86-64,它确实有 8 位字节,所有主流 C++ 实现都使用 1 位字节char
和 32 位 int
。)
如何修复
字节序是属性特定目标体系结构的实现,不同的数组元素不能不同。
int endian_test = 0x12345678;
char *p = (char*)&endian_test;
const char *endian_string = "unknown endian";
if (p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] = 0x12)
endian_string = "Little-Endian";
if (p[3] == 0x78 && p[2] == 0x56 && p[1] == 0x34 && p[0] = 0x12)
endian_string = "Big-Endian";
// test for PDP-endian if you want
for (int i=0;i<5;i++) {
// It's guaranteed that all elements of the array have the same endianness as endian_test
puts(endian_string);
}
大和小并不是唯一可能的字节顺序。
另请注意,您可以使用 CPP 宏检测到这一点。 gcc at least provides macros那让你做
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
#endif
但是这些宏不是 ISO C++ 标准。 "runtime" 检查可以优化到什么都没有(因为结果是 compile-time 常量 true 或 false),但预处理器允许您禁用甚至无法编译的代码。
在 C++20 中,use std::endian
type_traits
。