这不是对所述问题的回答——其他人已经很好地回答了它——而是一个解释一些术语的脚注,希望它能澄清相关概念。特别是,这根本不是特定于c的。
字节序和字节顺序
当大于 byte 的值被存储或序列化为多个字节时,选择存储组件字节的顺序称为byte order或endian或endianness。
历史上,使用过三种字节顺序:“ big-endian ”、“ little-endian ”和“ PDP-endian ”或“ middle-endian ”。
Big-endian和little-endian字节顺序名称源自它们对字节的排序方式:big-endian 将最重要的字节(对逻辑值影响最大的字节)放在首位,随后的字节按重要性降序排列;little-endian 将最低有效字节放在首位,连续字节按重要性递增的顺序排列。
请注意,整数类型和浮点类型的字节顺序可能不同;它们甚至可以在单独的硬件单元中实现。不过,在大多数硬件上,它们确实具有相同的字节顺序。
位顺序
位顺序与字节顺序非常相似,只是它涉及单个位而不是字节。这两个概念是相关的,但并不相同。
位顺序仅在位被串行化时才有意义,例如通过串行或 SPI 或 I 2 C 总线;相继。
当位在一个更大的并行使用的组中被称为一个单元时,就像在一个字节或一个字中一样,没有顺序:只有标签和重要性。(这是因为它们作为一个组被并行访问和操作,而不是一个接一个地连续访问和操作,所以没有特定的顺序。它们作为一个组的解释对每个组产生不同的意义,我们人类可以标记或编号它们便于参考。)
位意义
当一组位被视为二进制值时,有一个最低有效位和一个最高有效位。这些名称源于这样一个事实:如果您更改最低有效位,则位组的值会以最小的可能变化;如果您更改最高有效位,则位组的值会发生最大可能的变化(通过单个位更改)。
假设您有一组五位,例如a、b、c、d和e,它们形成一个五位无符号整数值。如果a是最重要的,e是最不重要的,并且其他三个是按照重要性递减的顺序,则无符号整数值为
value = a ·2 4 + b ·2 3 + c ·2 2 + d ·2 1 + e ·2 0
即
值= 16 a + 8b + 4 c + 2 d + e
换句话说,位的重要性源自一组位的数学(或逻辑)解释,并且与位在某些总线上的序列化顺序以及任何人工分配的标签或数字完全分开.
对于逻辑构造数值的所有位组都是如此,即使对于浮点数也是如此。
位标签或位编号
例如,为了便于参考文档,标记各个位通常很有用。这本质上是任意的;实际上,我在上面的示例中使用了字母a到f 。通常,数字比字母更容易——用单个字母标记超过 27 位并不容易。
有两种方法可以用数字标记位。
目前最常见的一种是根据位的重要性来标记位,位 0 指的是最低有效位。这很有用,因为位i具有逻辑值 2 i。
在某些体系结构的文档中,例如 IBM 的 POWER 文档,最高有效位标记为 0,按重要性降序排列。在这种情况下,位的逻辑值取决于该单元中的位数。如果一个单元有N位,则位i的逻辑值为 2 N -i-1。
虽然这种排序可能会让人感觉很奇怪,但这些架构都是大端的,对于人类来说,记住/假设这些系统上最重要的是最重要的可能很有用。
但是请记住,这是一个完全任意的决定,在这两种情况下,文档都可以使用其他位标记方案编写,而不会对系统的实际性能产生任何影响。这就像选择是从左到右,还是从右到左(或自上而下,就此而言):只要您知道并理解约定,内容不受影响。
虽然字节顺序和位标记之间存在一些相关性,但上述所有四个概念都是独立的。
字节顺序和位标记之间存在相关性——从某种意义上说,许多大端硬件的文档使用位标记,其中最高有效位为零位——但这仅仅是因为人类做出的选择。
在c中,C 编译器在结构中打包位域的顺序因编译器和体系结构而异。C标准根本没有规定它。因此,将二进制文件读入带有位域的结构类型通常是个坏主意。(即使它适用于某些特定的机器和编译器,也不能保证它适用于其他机器;通常情况下,它不会。因此,它肯定会降低代码的可移植性。)相反,读入缓冲区和数组unsigned char
,和使用辅助访问器<<
函数通过位移 ( , >>
)、二进制 ors ( |
) 和掩码(二进制和, )从数组中提取位字段&
。