位字节顺序如何影响 C 中的按位移位和文件 IO?
令L和B为两台机器。 L 从 LSB 排序其位 (最低有效位)到 MSB(最高有效位),同时 B 顺序 从 MSB 到 LSB。或者,换句话说,L 使用 Little Endian,而 B 使用 Big Endian bit - 不要与字节排序混淆。
问题 1 已解决:
我们正在编写以下我们希望可移植的代码:
#include <stdio.h>
int main()
{
unsigned char a = 1;
a <<= 1;
printf("a = %d\n", (int) a);
return 0;
}
在 L 上,它将打印 2,但是在 B 上会发生什么>?是否会改变 1 输出并打印 0?
解决方案: 6.5.7 中的 C99 定义表明,至少在
无符号整数类型,<<
和 >>
将乘以 2 并除以 2
分别。
问题 2:
我们正在编写以下希望可移植的代码:
READ 程序:
/* program READ */
#include <stdio.h>
int main()
{
FILE* fp;
unsigned char a;
fp = fopen("data.dat", "rb");
fread(&a, 1, 1, fp);
fclose(fp);
return 0;
}
和 WRITE 程序:
/* program WRITE */
#include <stdio.h>
int main()
{
FILE* fp;
unsigned char a = 1;
fp = fopen("data.dat", "wb");
fwrite(&a, 1, 1, fp);
fclose(fp);
return 0;
}
如果我们在 L 上运行 WRITE,将数据文件移动到 B 会发生什么强>和 在那里运行 READ?如果我们在 B 上运行 WRITE,然后在 L 上运行 READ 呢?
抱歉,如果这是常见问题解答。我用谷歌搜索了几个小时但没有运气。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
位字节顺序不会影响以字节为单位存储在磁盘上的数据。字节尾数会。
位字节顺序对于串行接口来说很重要,在串行接口中,一次发送一位字节,并且发送者和接收者需要就字节顺序达成一致。例如,SPI 设备中的位顺序有所不同,您需要在尝试读取之前参考数据表从设备。
以下是 Wikipedia 关于位字节序的说法:
在您的情况下,物理硬盘驱动器接口定义了位顺序,而不管要读取或写入它的处理器如何。
Bit Endianness doesn't affect data stored on disks in bytes. Byte Endianness will.
Bit Endianness is something that matters for serial interfaces where a byte is sent one bit at a time, and the sender and receiver need to agree on the byte order. For example, bit order in SPI devices varies and you need to reference the data sheet before attempting to read from the device.
Here's what Wikipedia says on bit endianness:
In your case, the physical hard drive interface defines the bit order, regardless of the processor that's going to read or write it.
实际上并不存在位字节序这样的东西,至少就 C 而言是这样。根据规范,CHAR_BIT 必须至少为 8,因此访问任何小于该值的对象对于标准 C 程序来说几乎没有意义。无论硬件如何存储字节(首先是 LSB 还是 MSB),它都不会影响您的程序。
myVar & 1
在任何一种情况下都会返回正确的位。如果您需要与某种串行接口交互并从中重构字节,那就是另一回事了。您自己的机器的“位字节顺序”仍然不会影响任何内容,但接口的位顺序肯定会影响。
现在,关于您的具体问题和您所展示的程序。您的程序几乎 100% 可移植。位字节顺序和字节字节顺序都不会影响它们。 可能影响它们的是
CHAR_BIT
在每个平台上是否不同。一台计算机写入的数据可能多于另一台计算机读取的数据,反之亦然。There isn't really such a thing as bit-endianness, at least as far as C is concerned.
CHAR_BIT
has to be at least 8 according to the spec, so accesses to any objects smaller than that is pretty much meaningless to a standard C program. Regardless of how the hardware stores a byte - LSB or MSB first - it doesn't affect your program at all.myVar & 1
returns the right bit in either case.If you need to interact with some kind of serial interface and reconstitute bytes from it, that's a different story. Your own machine's 'bit-endianness' still doesn't affect anything, but the bit order of the interface certainly does.
Now, as to your specific question and the program you've shown. Your programs are almost 100% portable. Neither bit- nor byte-endianness affects them. What might affect them is if
CHAR_BIT
were different on each platform. One computer might write more data than the other one would read, or vice versa.number>>n
和number< 不会向右和向左推和拉位。它们将
number
除以2^n
。值得注意的是,如果n
为负数或大于number
数据类型的宽度,则不会定义这些移位的行为。根据 第 6.5.7 节C99标准:
对于所有编译器关心的问题,这些位可以垂直堆叠:)
The
number>>n
andnumber<<n
do not push and pull bits right and left. They divide and multiplynumber
by2^n
. It's worth noting that the behavior of these shifts is not defined ifn
is negative or is larger than the width of the datatype ofnumber
.According to section 6.5.7 from the C99 standard:
For all the compiler cares, the bits could be stacked vertically :)
位移位不受字节顺序的影响。二进制文件 I/O 通常是,但在你的情况下不是,因为你只写一个字节。
Bit-shifting is not affected by endianness. Binary file I/O normally is, but not in your case since you are only writing a single byte.
字节序不会影响您,除非 a) 您使用与写入时不同的类型从内存中读取某些内容,或者从使用不同字节序的机器写入的文件中读取某些内容。
即
或者您的示例二,假设您使用的类型大于 char。
Endianness will not affect you unless a) you read something from memory using a different type than you used to write it to, or if you read something from a file that was written with a machine using different endianness.
i.e.
Or your example two, assuming you're using a type larger than char.