C中的二进制表示

时间:2011-12-04 01:54:22

标签: c binary printf

在C中,为什么没有标准说明符以二进制格式打印数字,如%b。当然,人们可以编写一些功能/黑客来做到这一点,但我想知道为什么这么简单的事情不是语言的标准部分。

背后有一些设计决定吗?由于八进制%o和%x的格式说明符是十六进制的,因此八进制和十六进制有点"更重要"比二进制表示。

因为在C / C ++中经常会遇到按位运算符,我会想到让%b或直接将数字的二进制表示输入到变量中是有用的(输入十六进制数字的方式如{{ 1}})

注意:像this这样的话题只讨论'如何'这样做的一部分,而不是'为什么'

5 个答案:

答案 0 :(得分:3)

我相信主要原因是'历史'。 AT& T的printf()等人的原始实现者不需要二进制,但确实需要八进制和十六进制(以及十进制),因此这是实现的。一般而言,C89标准对于标准化现有实践非常谨慎。有几个新的部分(语言环境,当然还有函数原型,尽管有C ++为那些人提供'实现经验'。)

您可以使用strtol()等读取二进制数字;指定2的基数。我认为没有一种方便的方法来格式化不同基数(8,10,16除外)中与strtol()相反的数字 - 可能应该是ltostr()

答案 1 :(得分:3)

你问“为什么”好像必须有明确和令人信服的理由,但事实是没有技术理由不支持%b格式。

K& R C是由那些将语言框起来以满足他们认为将成为他们常见用例的人而创建的。反对力量试图尽可能简化语言规范。

ANSI C由一个委员会标准化,该委员会的成员有不同的兴趣。显然%b并不是最终的优先事项。

语言由男性制作。

答案 2 :(得分:2)

我看到的主要原因是人们应该使用什么二进制表示?一个补充?两个补充?你期待内存中的实际位或抽象数表示吗?

当C不要求字大小或二进制数表示时,只有后者才有意义。因为它不是内存中的位,你肯定宁愿以十六进制读取抽象数字吗?

声称抽象表示是“二元”可能导致相信-0b1 ^ 0b1 == 0可能是真的或-0b1 | -0b10 == -0b11


可能的陈述:

虽然只有一个有意义的十六进制表示 - 抽象表示,但数字-0x79可以二进制表示为:

  • -1111001(摘要编号)
  • 11111001(一个补充)
  • 10000111(二补)

@Eric已经说服了字节序!=从左到右的顺序......

当数字不适合一个字节时,问题进一步复杂化。相同的数字可能是:

  • 1000000001111001作为一个补充大端的16位数字
  • 1111111110000111作为二进制补码大端16位数
  • 1000011110000000作为一个补充小端16位数字
  • 1000011111111111作为二进制补码小端16位数

字节顺序和二进制表示的概念不适用于十六进制数,因为它们无法被视为实际的内存中位表示。

所有这些例子假设一个8位字节,C不保证(确实有历史机器有10位字节)


为什么决定不比任何决定更好:

显然,人们可以任意选择一个表示,或者保留实现定义。 但是:

  • 如果您尝试使用它来调试按位操作(我认为这是使用二进制超过十六进制的唯一令人信服的理由),您希望使用一些与硬件相近的东西,这使得无法标准化,所以你希望实施定义。
  • 相反,如果您尝试读取位序列,则需要标准格式,而不是实现定义格式。
  • 你肯定希望printf和scanf使用相同的。

所以在我看来,没有幸福的媒介。

答案 3 :(得分:1)

一个答案可能是十六进制格式更紧凑。例如,参见Total Commander's Lister的六角视图。

%b在许多实际案例中都很有用。例如,如果您编写代码来分析网络数据包,则必须读取位的值,如果printf具有%b,则调试此类代码会更容易。即使在设计printf时可以解释省略%b,但这绝对是一个坏主意。

答案 4 :(得分:0)

我同意。我是最初的ANSI C委员会的参与者,并且建议在C中包含二进制表示。但是,由于上面提到的一些原因,我被投了票,尽管我仍然认为这样做很有帮助,例如,按位操作等。

值得注意的是,ANSI委员会大部分由编译器开发人员组成,而不是由用户和C程序员组成。他们的目标是使编译器开发人员不必为C程序员理解标准,并且能够使用不再需要的文档来实现,即使这意味着对C程序员来说这是一个困难的阅读。