C语言 端序也适用于位顺序



我在SO上没有发现一个具体的问题,如果这是重复的,请指出给我,我将删除它。

那么,字节序和有什么关系吗?点菜了吗?

这似乎暗示答案是否定的,而其他来源(我现在找不到一个,但肯定我在一段时间前读过一些文章)暗示端序是字节和位的顺序。.

更具体地说:在Big Endian架构中,MSB在任何字节中都是第一位的,也是MSB优先?相反,在小端系统中,LSB是第一位的,那么LSB也是第一位的吗?

LAST EDIT:我发现这个说">位顺序通常遵循与给定计算机系统的字节顺序相同的端序"

其他回答并不完全准确。是的,内存是字节可寻址的,所以通常端序到此为止。但是可寻址性并不是创建定义良好的端序的唯一方法。

在C语言中,您可以定义位字段。位字段有特定的布局;例如,第一个位字段(如果是一个位)可以存储在MSB或lsb中,并且以大端序方式跨字节边界包装位字段与以小端序方式包装位字段明显不同。因此,如果您定义了位字段,则可能具有位端序。

但是它们的排列方式与编译器有关,而不是与体系结构有关,至少在规则上是这样。

只适用于字节顺序。而不是位顺序。位顺序保持不变。

为什么?

内存是字节可寻址的。这只是说每个地址存储一个字节的一种奇特的方式。所以你可以改变字节的顺序,而不是内存中的位。

端序只有在你想把一个大值(比如一个单词)分解成几个小值的时候才有意义。你必须决定把它放在内存中的顺序。

Endianness只有在分解多字节数量并试图将字节存储在连续的内存位置时才有意义。但如果你用寄存器,就没有意义了。寄存器只是一个32位的数量(取决于你的处理器/控制器),并且端序不适用于它。

位顺序通常遵循与给定计算机系统的字节顺序相同的端序-为True

查看更多信息

不能,因为你不能单独给比特赋地址。

在现代计算中,端序制只适用于字节排序,而不适用于位排序。

小端cpu通常使用"LSB 0"位编号,但是在大端机器中可以看到这两种位编号惯例。一些架构如SPARC和Motorola 68000使用"LSB 0"位编号,而S/390, PowerPC和PA-RISC使用"MSB 0"。[2]

请参见

http://en.wikipedia.org/wiki/Bit_numbering

http://en.wikipedia.org/wiki/Mostrongignificant_bit

回顾几年前我提出的这个问题,今天我可以添加一个部分响应,其中位端序存在并且在通信协议中很重要。任何协议规范都需要定义当一个八位元被推入位流时,首先发送哪个位。

Endianness基于字节而不是位。位不可寻址。

"位不可寻址"是什么意思 对于傻瓜来说(像我和我的学生)?

计算机可以存储/移动/更改的最小值/实体是一个字节= 8位。你不能指示它读/写3位,然后是1位,然后是11位,并告诉计算机将它们作为单独的值来记忆。不,它只处理单个字节或字节包/范围。

然后任何应用程序/进程/硬件都可以处理字节中的位(或原生整数类型,总是一个字节的倍数)。

然而,一旦完成播放,存储在内存/存储中的值仍然是"range"每个字节的值——尽管它们的位被修改了——直接在字节级别上用它们的新值进行更新。.

这意味着,除非你构建处理器,否则你实际上只处理字节, 0-255,句号。

In records ?是的。内存地址?是的。文件数据/流?是的。网络传输?是的,该死的!

例如:假设我在我的LittleEndian上在我的应用程序中内存中有3字节(24位)记录的计算机:
structure Test24 {
var16 : 0xC1D3, // 49619 = 1100 0001 1101 0011
var8  : 0xCA    //   202 = 1100 1010
}

记录我保存raw在一个文件中,我把它传递给他的朋友,在他的BigEndian机器上. 在同一应用程序中加载记录时,他在自己的机器上得到的结果是:

structure Test24 {
var16 : 0xD3C1, // 54209 = 1101 0011 1100 0001 (bytes swapped)
var8  : 0xCA    //   202 = 1100 1010 (same value)
}

var16略有不同(损坏),但这是因为我没有将应用程序编码为在BigEndian架构上处理IO数据。但是,他没有得到以下记录,其中位完全交换了:

structure Test24 {
var16 : 0xCB83, // 52099 = 1100 1011 1000 0011 (bits swapped)
var8  : 0x53    //    83 = 0101 0011 (different value)
}

^^,这是因为文件是按字节读取的,而不是按位读取的。

这就是位不可寻址的原因"暗示。


学生:但是为什么人们对LSBit (LSB-0), MSBit,有时是位元序,比如这是非常重要的知识?

因为这种调用的方式实际上把端序问题从等式中排除了. 以正确的方式使用事物的意义,至少,使用逻辑。当我们把谈论数据和谈论(处理器)架构混为一谈时,就会产生误解。They-are-un-re-la-ted !

一个数据需要一个上下文,如&;这个地址的这个字节包含定义您在系统上的访问权限的八个标志&;。这不是端序问题,这是给定索引上的位在定义数据的上下文中使用的。

我们人类被训练成水平阅读。但是问题来了:

What is byte 241 ? How we may represent what it contains ?
perhaps on little endian, LSB-0 on the left (?)
bit index : 0, 1, 2, 3, 4, 5, 6, 7 => 10001111b ?
or on big endian, LSB-0 on the right (?)
bit index : 7, 6, 5, 4, 3, 2, 1, 0 => looks more intuitive 11110001b
STOP SHOOTING YOURSELF IN THE FOOT ! Consider looking at it this way :
LSB 0 <- see : here it is, it doesn't matter where it is, it's just there
1
2
3
4
5
6
MSB 7 <- and here the other one, on the opposite side.
or this way :
MSB 7
6
5
4
3
2
1
0 LSBit

只要一个在另一个的对面,LSB-0 MSBit在哪里并不重要。把端序去掉! 使用LSB-0术语来固定数据编码的开始。

^^现在当你定义"数据标志顺序从lbs -0">开始时,标志是,"目录打开,打开pwd保护,目录复制,复制pwd保护,目录写,写pwd保护,目录删除,删除pwd保护">,这意味着:

LSB 0 directory open
1 open pwd protected
2 directory copy
3 copy pwd protected
4 directory write subitem
5 write to pwd protected
6 delete subitem
MSB 7 delete pwd protected

所以241 = LSB-0 : 1, 0, 0, 0, 1, 1, 1, MSB : 1的字节值意味着

LSB 0 = 1 -> you can open directory
1 = 0 -> directory access is not password protected
2 = 0 -> you cannot copy directory
3 = 0 -> noop
4 = 1 -> you may create files or sub directories
5 = 1 -> but a password is required to create file or dir
6 = 1 -> you may delete the things in the directory
MSB 7 = 1 -> but a password is required to delete

当涉及到数据时,在位级别上不涉及端序,当你给字节的值赋予意义时,只有位位置重要,并且LSB-0总是0x01,无论它是大端序机器还是小端序机器。

字节值与机器如何处理位无关,无论是否最高有效。所以当你问"我的数据会被损坏吗?">,没有人应该谈论左边或右边的MSBit或LSBit。如果你问"这个CPU上最易失的位是什么?",那么LSB/MSB的位置就在讨论的中间(但是你是处理器工程的吗?)


  • 这里的实际SO问题不是大多数架构如何被假定为行为(内存寻址),或者能/不能做,那,我们应该问理论计算机科学或软件工程。
  • 真正的潜在问题是我的应用程序通过网络时产生的数据,IO,COM硬件,无论如何,的位被交换,或者在我的应用程序中处理位顺序失败时损坏。

答案是:这不会发生,只要您不是在硬件级别写入ROM数据,并且在通过不同的体系结构/协议传输数据时,您只关心字节级别的端序。人们因为不必要的尾数剧而感到困惑,而尾数的东西潜伏在它不应该出现的地方。


至少,这就是我在这里的原因,让学生们开始理解什么对给定的挑战/关注是重要的。如果他们已经知道了,就不会来了。大多数人的电脑要么是小端,要么是大端,没有交叉检查的特权。他们只是不确定,他们通过谷歌到达这里,而"位是不可寻址的">errrmm…怎么啦?这是什么意思?我是否应该以字节或位级别交换游戏数据,以便在所有平台上正确读取?我还是不知道:/这就是为什么有人会问的潜在原因。除了"比特是不可寻址的"这一技术事实之外,还有一些人没有充分掌握这种说法的含义的背景。

你只需要关心字节序,在非常罕见的情况下,你实际上编码自己的(或公司指定的)二进制数据通过您的应用程序通过您的专有或借用流读/写逻辑。

不想处理端序,使用内置读写的引擎/框架(如数据库,云等)或使用纯文本,如Json或XML。