为什么十六进制数字以0x开头?


414

为什么十六进制数字以前缀0x?我了解前缀的用法,但不了解0x选择为什么的意义。


9
现在,我意识到标题和文本提出了两个完全不同的问题。大多数答复都集中在标题中的问题上。文本中问题的答案很简单:“它没有任何意义,它只是一个前缀,告诉编译器整数以十六进制表示”。
Andreas Rejbrand

30
为了学究,可能还会以两种不同的方式解释标题中的问题:1)“为什么十六进制数字以0x为前缀,而不是其他任何前缀或指示符?” 2)“为什么在输入十六进制数字时需要使用前缀?即使没有前缀,编译器肯定会识别58A为十六进制数字吗?” 对问题的第二种解释的答案很简单。“ 123”也是十六进制数。
Andreas Rejbrand

Answers:


440

简单地说: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位字),并且以上所有点仍然有效。由于其他机器仍需要八进制数,0x因此可以任意选择八进制数(00可能被排除在尴尬之外)。

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


112
我不认为0x00为偏好/尴尬。00会破坏现有代码。0010如八进制一样8,而0010如十六进制一样16。他们不能使用任何数字作为第二位数字指示符(8或除外9,也不具有与十六进制有关的任何意义),因此必须输入字母。剩下的就是0h0xH e X十进制)。从这一点来看,似乎真的回到了偏好。
GManNickG 2013年


23
0多年来,为八进制使用前缀已经引起了很多问题。尤其是在像英国这样的国家中,电话号码以开头0。Javascript和许多其他语言会将它们解析为八进制,在存储之前先处理数字。为了助兴,一个流行的数据库产品将悄无声息,如果数字包含在切换回十进制解析89
2015年

1
12、24和36也可以被4整除,那么为什么他们不想到十六进制呢?
phuclv

4
@LưuVĩnhPhúc可能是因为十六进制不是很重要。大多数时间的硬件,软件和文档都更适合八进制。BCPL首先在36位IBM 7094上实现,其指令格式分为两个3位部分和2个15位部分;6位字符;和八进制文档。B的早期实现是在PDP-7(18位)和Honeywell GE-945(36位,但具有18位寻址,并支持6和9位字节)上实现的。16位PDP-11在B之后问世,因此对B的设计影响不大。
8bittree '17

97

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

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

04524 // octal, leading 0

想象一下,需要提出一个表示十六进制数字的系统,并注意我们正在C风格的环境中工作。以h结尾像汇编怎么样?不幸的是,您不能-它会允许您制作作为有效标识符的令牌(例如,您可以将变量命名为同一名称),这会带来一些令人讨厌的歧义。

8000h // hex
FF00h // oops - valid identifier!  Hex or a variable or type named FF00h?

出于相同的原因,您不能以字符开头:

xFF00 // also valid identifier

使用散列可能被抛弃了,因为它与预处理器冲突:

#define ...
#FF00 // invalid preprocessor token?

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

0xFF00 // definitely not an identifier!

3
有趣。我想他们可以使用前导0和后跟h表示十六进制。尾随的h可能已与类型说明符后缀混淆,例如0xFF00l与0FF00hl
zdan 2010年

2
该论点暗示使用前导零表示八进制数早于使用十六进制“ 0x”前缀。这是真的?
Andreas Rejbrand

1
它们不是同时被发明的吗?为什么会有一个而不是另一个呢?
AshleysBrain,2010年

AshleysBrain看到@Řrřola的回答,说明为什么同时可能存在八进制而不是十六进制。
2012年

2
@zdan他们很久以前就使用过它。在x86 Intel汇编中,如果十六进制文字以字符开头,则必须始终以0为前缀。例如0xFFAB1234必须写为0FFAB1234h。我还记得我年轻时在Pascal的嵌入式asm中获得的代码stackoverflow.com/q/11733731/995714
phuclv 2015年

27

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

例:

0x6400转换为 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. 编译器读取时0x6400,它借助0x 术语了解数字为十六进制。通常我们可以通过(6400)16或(6400)8来理解或其他任何东西。

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

0b00000001

希望我有所帮助。

美好的一天!


2
从C ++ 14开始,二进制文字仅在C ++中受支持,而在C中则完全不支持。
Ruslan

1
这不能解释原因。特别是为什么您不能将第一个示例编写为x6400?将x仍然可以用来推断十六进制。
亚伦·弗兰克

12

前面的0表示以2、8或16为基数的数字。

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

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

美好的一天!


2
感谢您的回答!我了解这是您关于StackOverflow的第一篇文章。如果意见与事实分开,答案可能会更有帮助。
vivek_ganesan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.