繁体   English   中英

C中的二进制表示

[英]Binary representation in C

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

背后有一些设计决定吗? 因为对于十六进制有八进制%o和%x的格式说明符,所以八进制和十六进制比二进制表示更“重要”。

由于在C / C ++中经常会遇到按位运算符,我会想到有%b或直接将数字的二进制表示输入到变量(输入十六进制数字的方式,如int i=0xf2 )会int i=0xf2

注意:像这样的线程只讨论这样做的“如何”部分,而不是'为什么'

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

你可以用strtol()等读取二进制数。 指定2的基数。我认为没有一种方便的方法来格式化不同基数( ltostr() )的数字,这是strtol()的反转 - 可能它应该是ltostr()

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

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

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

语言由男性制作。

我认为它的主要原因是应该使用什么二进制表示? 一个补充? 两个补充? 你期望内存中的实际位或抽象数表示?

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

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


可能的陈述:

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

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

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

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

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

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

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


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

显然,人们可以任意选择一个表示,或者让它实现定义。 然而:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM