为什么十六进制数字前缀为0x?

unj*_*nj2 385 c syntax hex

为什么十六进制数字前缀为0x?我理解前缀的用法,但我不明白为什么0x选择的重要性.

Řrř*_*ola 411

简单地说:0告诉它在处理一个恒定的(而不是一个标识符/保留字)的解析器.仍然需要一些东西来指定数字基数:这x是一个任意的选择.

长篇:在60年代,流行的编程数字系统是十进制和八进制 - 大型机每字节有12,24或36位,可以很好地被3 = log2(8)整除.

BCPL语言使用8 1234八进制数的语法.当Ken Thompson从BCPL创建B时,他使用了0前缀.这很棒,因为

  1. 一个整数常量现在总是由一个令牌组成,
  2. 解析器仍然可以立即告诉它有一个常数,
  3. 解析器可以立即告诉基础(0两个碱基都相同),
  4. 它在数学上是理智的(00005 == 05),和
  5. 不需要珍贵的特殊字符(如#123).

当从B创建C时,需要十六进制数字(PDP-11具有16位字),并且上述所有点仍然有效.由于其他机器仍然需要octals,因此0x被任意选择(00可能被排除为尴尬).

C#是C的后代,因此它继承了语法.

  • 我不认为`0x`超过'00`是偏好/尴尬.`00`将破坏现有代码.'0010`作为八进制是'8`,而`0010`作为十六进制将是'16`.他们不能使用任何数字作为第二个数字指示符(除了'8`或'9`,并且都没有任何与十六进制相关的重要性)所以一封信是必须的.并留下"0h"或"0x"(**H**e**X**idecimal).从这一点来看,它似乎真正回到了偏好. (102认同)
  • 使用八进制的"0"前缀多年来引起了很多问题.特别是在英国这样的国家,电话号码以"0"开头.Javascript和许多其他语言会将这些解析为八进制,在存储之前对数字进行修改.为了增加乐趣,如果数字包含"8"或"9",一个流行的数据库产品将_silently_切换回十进制解析. (22认同)
  • @LưuVĩnhPhúc可能是因为十六进制不是很相关.大多数时间的硬件,软件和文档都更适合八进制.BCPL首先在[36位IBM 7094](https://en.wikipedia.org/wiki/IBM_7090#IBM_7094)上实现,指令格式分为两个3位部分和2个15位部分; 6位字符; 和八进制文档.B的早期实现是在PDP-7(18位)和霍尼韦尔GE-945(36位,但具有18位寻址,并支持6和9位字节).16位PDP-11在B之后出现,因此不会对B的设计产生太大影响. (4认同)
  • 相关:http://stackoverflow.com/questions/18987911/bcpl-octal-numerical-constants和http://stackoverflow.com/questions/11483216/why-are-leading-zeroes-used-to-represent-octal-数字 (2认同)

Ash*_*ain 93

注意:我不知道答案是否正确,但以下仅仅是我的个人猜测!

如前所述,数字前面的0表示它是八进制的:

04524 // octal, leading 0
Run Code Online (Sandbox Code Playgroud)

想象一下,需要提出一个系统来表示十六进制数字,并注意我们正在C风格的环境中工作.如何以汇编结束?不幸的是你不能 - 它会允许你制作有效标识符的标记(例如,你可以将变量命名为同一个东西),这会产生一些令人讨厌的含糊之处.

8000h // hex
FF00h // oops - valid identifier!  Hex or a variable or type named FF00h?
Run Code Online (Sandbox Code Playgroud)

出于同样的原因,你不能带领角色:

xFF00 // also valid identifier
Run Code Online (Sandbox Code Playgroud)

使用哈希可能会被抛出,因为它与预处理器冲突:

#define ...
#FF00 // invalid preprocessor token?
Run Code Online (Sandbox Code Playgroud)

最后,无论出于何种原因,他们决定在前导0后面加一个x来表示十六进制.它是明确的,因为它仍然以数字字符开头,因此不能是有效的标识符,并且可能基于前导0的八进制约定.

0xFF00 // definitely not an identifier!
Run Code Online (Sandbox Code Playgroud)

  • 有趣.我想他们可以使用前导0和尾随h来表示十六进制.尾随h可能会与类型说明符后缀混淆,例如0xFF00l vs 0FF00hl (3认同)
  • 这个论点意味着使用前导零表示八进制数字比使用十六进制"0x"前缀更早.这是真的? (2认同)
  • @zdan他们很久以前就用过它了.在x86英特尔程序集中,如果以字符开头,则十六进制文字必须始终以0为前缀.例如,`0xFFAB1234`必须写为`0FFAB1234h`.我在年轻时从Pascal的内联asm中记得它http://stackoverflow.com/q/11733731/995714 (2认同)

loy*_*ola 24

它是一个前缀,表示该数字是十六进制而不是其他一些基数.C编程语言使用它来告诉编译器.

例:

0x6400转换为 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. 当编译器读取时0x6400,它在0x term 的帮助下理解数字是十六进制的.通常我们可以通过(6400)16或(6400)8等理解.

对于二进制文件,它将是:

0b00000001

希望我能以某种方式帮助过.

美好的一天!

  • 从C ++ 14开始,二进制文字仅在C ++中受支持,而在C中则完全不支持。 (2认同)
  • 这并不能解释*为什么*。特别是,为什么不能将第一个示例写为“x6400”?“x”仍然可以用来推断十六进制。 (2认同)

Adv*_*kar 14

我不知道0x作为表示十六进制数字的前缀背后的历史原因 - 因为它肯定可以采取多种形式。这种特殊的前缀样式来自计算机科学的早期。

由于我们习惯于十进制数字,因此通常不需要指示基数/基数。然而,出于编程目的,我们经常需要将基数与二进制 (base-2)、八进制 (base-8)、十进制 (base-10) 和十六进制 (base-16) 区分开来,这些是最常用的基数。

目前,它是用于表示数字基数的约定。我已经用上述所有基数及其前缀写出了数字 29:

  • 0b11101:二进制
  • 0o35:八进制,用 o 表示
  • 0d29:十进制,这很不寻常,因为我们假设没有前缀的数字是十进制
  • 0x1D: 十六进制

基本上,我们最常将字母表与基数(例如 b 表示二进制)结合起来,0以便轻松区分数字的基数。

这特别有用,因为较小的数字可能会在所有基数中出现相同的混淆:0b1、0o1、0d1、0x1。

如果您使用的是富文本编辑器,您也可以使用下标来表示基数: 1 2 , 1 8 , 1 10 , 1 16

  • 为什么十六进制不选择 0h?0x 看起来很奇怪。 (2认同)
  • @DawnSong 这只是一个非常流行的惯例,现在我们必须忍受它。有时这些事情是任意的。你可以尝试推广你的方式,但是很难改变这么多人的习惯。我发现八进制在视觉上是最令人困惑的。 (2认同)

小智 10

前面的0用于表示基数2,8或16中的数字.

在我看来,选择0x表示十六进制,因为'x'听起来像十六进制.

只是我的意见,但我认为这是有道理的.

美好的一天!

  • 这个答案很好地区分了观点和事实。 (5认同)
  • 谢谢你的回答!我知道这是你在StackOverflow上的第一篇文章.如果意见与事实分开,答案可能会更有帮助. (2认同)