C语言中的二进制表示

C语言中的二进制表示,c,binary,printf,C,Binary,Printf,在C语言中,为什么没有标准的说明符来打印二进制格式的数字,比如%b。当然,我们可以编写一些函数/黑客来实现这一点,但我想知道为什么这么简单的东西不是语言的标准部分 背后有什么设计决定吗?由于八进制%o和十六进制的%x都有格式说明符,所以八进制和十六进制在某种程度上比二进制表示“更重要” 由于在C/C++中经常会遇到位运算符,我认为使用%b或直接将数字的二进制表示形式输入到变量中是很有用的(就像输入十六进制数字一样,如int I=0xf2) 注意:像这样的线程只讨论了执行此操作的“如何”部分,而不

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

背后有什么设计决定吗?由于八进制%o和十六进制的%x都有格式说明符,所以八进制和十六进制在某种程度上比二进制表示“更重要”

由于在C/C++中经常会遇到位运算符,我认为使用
%b
或直接将数字的二进制表示形式输入到变量中是很有用的(就像输入十六进制数字一样,如
int I=0xf2


注意:像这样的线程只讨论了执行此操作的“如何”部分,而不是“为什么”

一个答案可能是十六进制格式更紧凑。例如,请参见Total Commander列表器的hexa视图


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

我认为主要原因是“历史”。at&T的
printf()
等的原始实现者不需要二进制,但需要八进制和十六进制(以及十进制),因此实现了这一点。C89标准相当谨慎地对现有实践进行了标准化——总体而言。有一些新的部分(区域设置,当然还有函数原型,虽然有C++提供那些“实现体验”)。 您可以使用
strtol()
等工具读取二进制数;指定基数为2。我不认为有一种方便的方法可以将数字格式化为不同的基数(8、10、16除外),这与
strtol()
相反-大概应该是
ltostr()

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

创建K&R C的人是那些设计语言以满足他们认为将成为他们的通用用例的人。一股对立的力量试图使语言规范尽可能简单

ANSI C由一个委员会标准化,该委员会的成员有不同的兴趣。显然,
%b
最终并没有成为获胜的优先权


语言是由人类创造的。

在我看来,主要原因是一个人应该使用什么二进制表示法?补语?二的补码?您期望内存中的实际位还是抽象数字表示

当C不要求字长或二进制数表示时,只有后者才有意义。既然不是内存中的位,那么你肯定更愿意读十六进制的抽象数

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


可能的表述:

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

  • -1111001
    (摘要编号)
  • 11111001
    (补足语)
  • 10000111
    (二者互补)
@埃里克让我相信endianness!=从左到右的顺序

当数字不能放入一个字节时,问题就更加复杂了。同样的数字可以是:

  • 100000000111001
    作为一个一补大端16位数字
  • 111111111 0000111
    作为两位补码的大端16位数字
  • 100001110000000
    作为一个一补小端16位数字
  • 100001111111
    作为两位补码的小端16位数字
endianness和二进制表示的概念不适用于十六进制数,因为它们不可能被视为内存表示中的实际位

所有这些示例都假设一个8位字节,C对此不作任何保证(事实上,有一些历史机器具有10位字节)


为什么没有决定比任何决定都好:

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

  • 如果您试图使用它来调试按位操作(我认为这是使用二进制优于十六进制的唯一令人信服的原因),那么您希望使用与硬件使用相近的东西,这使得无法标准化,因此您需要定义实现
  • 相反,如果试图读取位序列,则需要标准格式,而不是实现定义的格式
  • 您肯定希望printf和scanf使用相同的

所以在我看来,似乎没有快乐的媒介。

我同意。我是最初的ANSI C委员会的一名成员,并提出了在C中包含二进制表示的建议。然而,由于上述一些原因,我被否决了,尽管我仍然认为这在执行时非常有用,例如按位操作等


值得注意的是,ANSI委员会大部分由编译器开发人员组成,而不是用户和C程序员。他们的目标是使编译器开发人员能够理解标准,而不一定是C程序员可以理解,并且能够使用不超过需要长度的文档来理解标准,即使这意味着C程序员很难阅读

如果可以打印十六进制,为什么要打印二进制?基本上是一样的,但密度是400%。只需翻译,
0=0000
1=0001
2=0010
,…,
F=1111
@