C++ 为使用Little或Big-endian的计算机编写程序。结果是一样的

C++ 为使用Little或Big-endian的计算机编写程序。结果是一样的,c++,C++,这个问题是关于endian的 目标是在计算机上为游戏在文件中写入2个字节。我想确保使用不同计算机的人无论是使用小端还是大端都能得到相同的结果 我应该使用这些代码段中的哪一个 char a[2] = { 0x5c, 0x7B }; fout.write(a, 2); 或 非常感谢 我应该使用这些代码段中的哪一个 char a[2] = { 0x5c, 0x7B }; fout.write(a, 2); 第一个。它具有相同的输出,而不考虑本机endianness 但您会发现,如果需要将这些字节解

这个问题是关于endian的

目标是在计算机上为游戏在文件中写入2个字节。我想确保使用不同计算机的人无论是使用小端还是大端都能得到相同的结果

我应该使用这些代码段中的哪一个

char a[2] = { 0x5c, 0x7B };
fout.write(a, 2);

非常感谢

我应该使用这些代码段中的哪一个

char a[2] = { 0x5c, 0x7B };
fout.write(a, 2);
第一个。它具有相同的输出,而不考虑本机endianness

但您会发现,如果需要将这些字节解释为某个整数值,那么这就不那么简单了
chara[2]={0x5c,0x7B}
可以表示0x5c7B(大端序)或0x7B5c(小端序)。那么,你打算选哪一个

整数跨平台解释的解决方案是确定读写的特定字节顺序。事实上,跨平台数据的“标准”是使用big-endian

要用big-endian写一个数字,首先将输入值右移,使最高有效字节取代最低有效字节。屏蔽所有其他字节(在第一次迭代中技术上是冗余的,但我们很快就会返回)。将此字节写入输出。按重要性顺序对所有其他字节重复此操作

这种算法产生相同的输出,而不管本机端序是什么——如果遇到外来的“中间”端序系统,它甚至可以工作。向little endian写入类似内容,但顺序相反

要读取大端值,请读取输入的第一个字节,将其向左移位,使其位于最高有效字节的位置。使用按位或将移位字节与结果(最初为零)组合。通过移动到第二个最高有效位置,对下一个字节重复此操作,依此类推

了解计算机的持久性

要了解系统的endian,可以在即将发布的C++20中使用
std::endian
。在此之前,您可以从
endian.h
头使用特定于实现的宏。或者你可以像你建议的那样做一个简单的计算

但你永远不需要知道系统的持久性。您可以简单地使用我描述的算法,这些算法可以在所有端点的系统上工作,而不必知道端点是什么。

来自维基百科:

在最常见的用法中,endianness表示多字节数中字节的顺序

所以对于
chara[2]={0x5c,0x7B}
a[1]
将始终为0x7B


然而,对于
inta=0x7B5C,字符*单字节=(字符*)&a;(char*)一字节[0];可以是0x7B或0x5C,但正如您所看到的,您必须使用强制转换和字节指针(请记住char[1]时的未定义行为,这仅用于解释目的)。

经常使用的一种方法是将“签名”或“魔法”数字作为文件中的第一个数据写入文件-通常是一个16位整数,其值在读回时,将取决于阅读平台是否与写作平台具有相同的结尾。如果随后检测到不匹配,从文件读取的所有数据(超过一个字节)将需要进行字节交换

下面是一些概要代码:

void ByteSwap(void*缓冲区,大小\u t长度)
{
无符号字符*p=静态_转换(缓冲区);
对于(尺寸i=0;i1)){
对于(size_t i=0;i
当然,在现实世界中,您不需要为每个输入/输出操作写入/读取“魔法”数字-每个文件只需写入/读取一次,并存储
is_reversed
标志,以便将来在读取数据时使用

另外,如果正确使用
C++
代码,您可能会使用
std::stream
参数,而不是我显示的
文件*
——但是我发布的示例是从我在项目中实际使用的代码中提取出来的(只做了很少的修改)(仅用于此测试)。但是,转换为更好地使用现代
C++
应该很简单

请随时要求进一步澄清和/或解释


注意:我提供的
ByteSwap
功能并不理想!它几乎肯定会打破严格的别名规则,如果不小心使用,很可能在某些平台上导致未定义的行为。此外,对于小型数据单元(如
int
变量),它不是最有效的方法。人们可以(也应该)提供自己的字节反转函数来处理特定类型的变量,这是用不同的参数类型重载函数的一个很好的例子,我不同意提议的复制,因为它只是关于检测endianess,而不是更多的
目标是在计算机上为一个游戏在一个文件中写入2个字节
,如果你想将
0x5c
0x7B
按该顺序写入文件,那么
char a[2]={0x5c,0x7B}将在所有系统上保持一致。但问题是,这两个字节是什么