C++ int* 和 char* 字节顺序已交换

C++ int* and char* byte order swapped

本文关键字:顺序 字节 交换 char int C++      更新时间:2023-10-16

我正在尝试读取和分析二进制文件。我试图将整数转换为字符数组(将 int 转换为字节(并将它们打印为位集。我注意到存储在整数中的相同数据的字节顺序与存储为 char 时相反,数组内部具有相同的数字顺序,字节内部具有相同的位顺序。我想知道为什么会这样,最终如何改变这一点。

显示问题的示例代码:

#include<iostream>
#include<bitset>
using namespace std;
int main()
{
unsigned int a[]={5,4,6};
char *b=(char*)a;
for(int i=0;i<3;++i)
{
cout<<bitset<32>(a[i])<<" ";
}
cout<<"n";
for(int i=0;i<12;++i)
{
cout<<bitset<8>(b[i])<<" ";
}

}

输出:

00000000000000000000000000000101 00000000000000000000000000000100 00000000000000000000000000000110
00000101 00000000 00000000 00000000 00000100 00000000 00000000 00000000 00000110 00000000 00000000 00000000

我注意到存储在整数中的相同数据的字节顺序与存储为 char 时相反

这意味着文件存储的字节字节序与 CPU 使用的字节字节序不同。在示例输出中,您可以看到 CPU 使用小端序(最低有效字节优先(。鉴于文件中的顺序相反,我们可以推断该文件使用大端序(最高有效字节优先(。大端序通常用于数据交换格式。

我想知道为什么会这样,以及最终如何改变这一点。

POSIX 具有将大字节序转换为本机字节序的标准函数(ntoh函数族(。标准C++没有,但实现起来相当简单。但是,有一些错误很容易犯,因此使用现有库会更安全。

正如@Mat简要解释的那样,您遇到了所谓的"字节序"。 有"大端",最重要的部分在开头?!(是的,这有点违反直觉(和"小端序",其中最不重要的部分在开头。

例如:阿拉伯数字是大端序。 "1234"是"一千二百三十四",而不是"四千三百二十一"。 最重要的数字排在第一位。

我会震惊地发现,没有几十个不同的开源函数来处理这个问题。

一个快速的谷歌搜索出现了:https://www.boost.org/doc/libs/1_61_0/libs/endian/doc/index.html

这是由不同的 CPU 架构引起的。 有些是大端序,有些是小端序。 几乎可以肯定的是,在Mat的链接维基百科页面上有一个列表。 当他们将自己的位写出到自己的存储中时,他们通常以自己的字节序格式"本机"写入它们。 当服务器使用各种 CPU 类型(每个 Web 服务器、大多数跨平台网络游戏等(与客户端通信时,这可能是一个大问题。 在这些情况下,通信协议必须指定他们使用的字节序,然后软件必须根据需要进行转换。

编辑编辑:

">

字节序"应该称为"启动性"。 违反直觉的名字是不好的。 "最小惊喜原则"很好。

嗯。

当它很重要时,只需使用现有的库。 POSIX 为完成这项工作的函数提供了一组不太标准化的名称。 有我上面链接的提升库。 我在几个项目中使用了专有库。 我很确定还有其他人,很多是开源的。