C++ 14中二进制文字的字节顺序是什么?

Lev*_*son 42 c++ endianness c++14

我试过四处寻找,但一直没能找到关于二进制文字和字节序的东西.二进制文字是little-endian,big-endian还是其他什么东西(比如匹配目标平台)?

举个例子,十进制值是0b0111多少?是7吗?平台具体?别的什么?编辑:我选择了一个错误的值7,因为它表示在一个字节内.尽管如此,这个问题仍得到了充分的回答.

一些背景:基本上我试图找出最低有效位的值是什么,并用二进制文字掩盖它似乎是一个很好的方法...但只有在有一些关于字节序的保证.

Rya*_*ing 71

简短的回答:没有一个.

答案很长:除非您真的试图将其结束(例如使用指针技巧),否则Endianness永远不会直接暴露在代码中.0b0111是7,它与十六进制,写作的规则相同

int i = 0xAA77;
Run Code Online (Sandbox Code Playgroud)

并不意味着0x77AA在某些平台上,因为这是荒谬的.32位整数中缺少的额外0会在哪里?他们会在前面填充,然后整个东西翻转到 0x77AA0000,或者他们会在之后添加?如果是这样的话,我不知道会有人期待什么.

关键是C++没有对机器的字节序做出任何假设,如果用原语和它提供的文字编写代码,机器之间的行为将是相同的(除非你开始规避类型系统,你可能需要这样做)

要解决您的更新:数字将是您写出来的方式.这些位不会被重新排序或任何这样的事情,最重要的位在左侧,最低位在右侧.


这里似乎存在关于字节序的误解.字节顺序指的是字节在内存中的排序方式以及它们必须如何解释.如果我给你的号码为"4172"并说"如果这是四千七百二十二,那么会有什么样的结尾"你无法给出答案,因为这个问题没有意义.(有人认为左边最大的数字意味着大端,但没有内存地址,字节序的问题是不负责任的或相关的).这只是一个数字,没有要解释的字节,没有内存地址.假设4字节整数表示,与之对应的字节为:

        low address ----> high address
Big endian:    00 00 10 4c
Little endian: 4c 10 00 00
Run Code Online (Sandbox Code Playgroud)

因此,给出其中任何一个并告诉"这是计算机4172的内部表示",你可以确定它的小端还是大端.

所以现在考虑你的二进制文字,0b0111 这4位表示一个nybble,并且可以存储为

              low ---> high
Big endian:    00 00 00 07
Little endian: 07 00 00 00
Run Code Online (Sandbox Code Playgroud)

但你不必关心,因为这也是由硬件处理的,语言规定编译器从左到右读取,最重要的位到最不重要的位

字节序不是关于个别位.假设一个字节是8位,如果我递给你0b00000111并说"这是小端还是大端?" 再说一次你不能说因为你只有一个字节.字节顺序不对一个字节中的位重新排序,指的是整个字节的重新排序(当然除非你有一位字节).

您无需关心计算机在内部使用的内容. 0b0111只需节省你写东西的时间

unsigned int mask = 7 // only keep the lowest 3 bits
Run Code Online (Sandbox Code Playgroud)

通过写作

unsigned int mask = 0b0111;
Run Code Online (Sandbox Code Playgroud)

无需评论解释数字的重要性.

  • @Medinoc人们通常应该编写与endian无关的代码. (8认同)
  • 我想指出的是,在编程水平足够低的情况下,你无法避免字节顺序,因为你所实现的任何规范要求它们的输入或输出都是小/大/任何字节序.这包括网络协议,加密算法等.仅仅因为你不做这些事情并不意味着它们不存在,并且在这些情况下,endianness*会泄漏出漂亮的舒适类型系统.因此,"对自己的利益过于聪明"这一部分似乎是没有根据的. (6认同)
  • 执行`union`检查的@πάνταῥεwould会违反工会的规则,你可以这样做:`int i = 1; char*cp =(char*)i;`然后`*cp == 1`如果是小端,则为真 (2认同)

Mic*_*nda 40

所有整数文字(包括二进制文字)的解释方式与我们通常读取的数字相同(最左边的数字最重要).

C++标准保证对文字的相同解释,而不必关心您所处的特定环境.因此,在这种情况下,您不必关心字节序.

你的例子0b0111总是等于七.

C++标准在数字文字方面没有使用字节顺序.相反,它只是简单地描述了文字具有一致的解释,并且解释是您期望的解释.

C++标准 - 整数文字 - 2.14.2 - 第1段

整数文字是一个没有句点或指数部分的数字序列,可选地分隔单引号,在确定其值时会被忽略.整数文字可以具有指定其基数的前缀和指定其类型的后缀.数字序列的词汇第一个数字是最重要的.二进制整数文字(基数为2)以0b或0B开头,由一系列二进制数字组成.八进制整数文字(基数为8)以数字0开头,由一系列八进制数字组成.十进制整数文字(十进制)以0以外的数字开头,由一系列十进制数字组成.十六进制整数文字(基数为16)以0x或0X开头,由十六进制数字序列组成,包括十进制数字和字母a到f和A到F,十进制值为十到十五.[例子:12号可以写成12,014,0XC或0b1100.文字1048576,1'048'576,0X100000,0x10'0000和0'004'000'000都具有相同的值. - 结束例子]

维基百科描述了什么是字节序,并以我们的数字系统为例来理解大端.

术语字节序和字节序是指当这些字节存储在计算机存储器中时用于解释构成数据字的字节的约定.

Big-endian系统将字的最高有效字节存储在最小地址中,最低有效字节存储在最大地址中(也见最高有效位).相反,小端系统将最低有效字节存储在最小地址中.

关于字节序的一个例子是考虑如何以位值表示法写入和读取十进制数.假设编写系统从左到右写入数字,最左边的位置类似于所使用的最小内存地址,最右边的位置是最大的.例如,第一百二十三写为1 2 3,最左边有数百个.读取此数字的任何人都知道最左边的数字具有最大的位置值.这是日常生活中遵循的大端会议的一个例子.

在这种情况下,我们将整数文字的数字视为"单词的字节",并将该字视为文字本身.此外,文字中最左侧的字符被认为具有最小的地址.

对于文字1234,数字一,二,三和四是"单词的字节",并且1234是"单词".对于二进制文字0b0111,数字零,一,一和一是"一个字的字节",而单词是0111.

这种考虑使我们能够理解C++语言环境中的字节序,并表明整数文字类似于"big-endian".

  • @cmaster最小的地址=左=第一.当然,我们通常根本不对数字字符串使用术语字节顺序,而只对内存中的布局使用.因此,人们可以说术语"字节序"根本不适用于文字,或者说它们总是bigendian.说文字总是小端是绝对错误的. (2认同)

jth*_*ill 9

您错过了源代码中编写的字节序和目标代码中表示的字节序之间的区别.每个答案是不足为奇的:源代码文本是大尾端,因为这是人类如何阅读,以目标代码的他们写的,不过目标读取它们.

由于字节根据定义是存储器访问的最小单位,因此我认为甚至不能将字节顺序归结为字节中任何内部位的表示 - 这是发现更大数字的字节顺序的唯一方法(无论是有意还是令人惊讶的是通过分段从存储中访问它们,并且字节根据定义是最小的可访问存储单元.


小智 7

C/C++语言不关心多字节整数的字节顺序.C/C++编译器可以.编译器会解析您的源代码并为特定目标平台生成机器代码.通常,编译器以与存储整数相同的方式存储整数文字; 这样目标CPU的指令将直接支持在内存中读取和写入它们.

编译器会处理目标平台之间的差异,因此您不必这样做.

您需要担心字节顺序的唯一时间是与其他具有不同字节顺序的系统共享二进制值.然后您将逐字节读取二进制数据,并按正确顺序排列内存中的字节.您的代码正在运行的系统.


Zol*_*nda 5

一张图有时候胜过千言万语。

源与内存字节顺序

  • 最佳答案。C++ 源代码中的文字是大端字节序,就像我们通常在数学中表示以 10 为基数的数字一样。字节的内存顺序将根据您的硬件而有所不同。 (2认同)