二进制数、八进制数和十六进制数的细致技能

二进制数、八进制数和十六进制数的输出

C语言中常用的整数有 short、int 和 long 三种类型,通过 printf 函数,可以将它们以八进制、十进制和十六进制的形式输出。上节我们讲解了如何以十进制的形式输出,这节我们重点讲解如何以八进制和十六进制的形式输出,下表列出了不同类型的整数、以不同进制的形式输出时对应的格式控制符:

  short int long
八进制 %ho %o %lo
十进制 %hd %d %ld
十六进制 %hx 或者 %hX %x 或者 %X %lx 或者 %lX



十六进制数字的表示用到了英文字母,有大小写之分,要在格式控制符中体现出来:

  • %hx、%x 和 %lx 中的x小写,表明以小写字母的形式输出十六进制数;
  • %hX、%X 和 %lX 中的X大写,表明以大写字母的形式输出十六进制数。



八进制数字和十进制数字不区分大小写,所以格式控制符都用小写形式。如果你比较叛逆,想使用大写形式,那么行为是未定义的,请你慎重:

  • 有些编译器支持大写形式,只不过行为和小写形式一样;
  • 有些编译器不支持大写形式,可能会报错,也可能会导致奇怪的输出。



注意,虽然部分编译器支持二进制数字的表示,但是却不能使用 printf 函数输出二进制,这一点比较遗憾。当然,通过转换函数可以将其它进制数字转换成二进制数字,并以字符串的形式存储,然后在 printf 函数中使用%s输出即可。考虑到读者的基础还不够,这里就先不讲这种方法了。



【实例】以不同进制的形式输出整数:


  1. #include <stdio.h>
  2. int main()
  3. {
  4. short a = 0b1010110; //二进制数字
  5. int b = 02713; //八进制数字
  6. long c = 0X1DAB83; //十六进制数字
  7.  
  8. printf("a=%ho, b=%o, c=%lo\n", a, b, c); //以八进制形似输出
  9. printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十进制形式输出
  10. printf("a=%hx, b=%x, c=%lx\n", a, b, c); //以十六进制形式输出(字母小写)
  11. printf("a=%hX, b=%X, c=%lX\n", a, b, c); //以十六进制形式输出(字母大写)
  12.  
  13. return 0;
  14. }

运行结果: a=126, b=2713, c=7325603 a=86, b=1483, c=1944451 a=56, b=5cb, c=1dab83 a=56, b=5CB, c=1DAB83 从这个例子可以发现,一个数字不管以何种进制来表示,都能够以任意进制的形式输出。数字在内存中始终以二进制的形式存储,其它进制的数字在存储前都必须转换为二进制形式;同理,一个数字在输出时要进行逆向的转换,也就是从二进制转换为其他进制。

输出时加上前缀

请读者注意观察上面的例子,会发现有一点不完美,如果只看输出结果:

  • 对于八进制数字,它没法和十进制、十六进制区分,因为八进制、十进制和十六进制都包含 0~7 这几个数字。
  • 对于十进制数字,它没法和十六进制区分,因为十六进制也包含 0~9 这几个数字。如果十进制数字中还不包含 8 和 9,那么也不能和八进制区分了。
  • 对于十六进制数字,如果没有包含 a~f 或者 A~F,那么就无法和十进制区分,如果还不包含 8 和 9,那么也不能和八进制区分了。

区分不同进制数字的一个简单办法就是,在输出时带上特定的前缀。在格式控制符中加上#即可输出前缀,例如 %#x、%#o、%#lX、%#ho 等,请看下面的代码:


  1. #include <stdio.h>
  2. int main()
  3. {
  4. short a = 0b1010110; //二进制数字
  5. int b = 02713; //八进制数字
  6. long c = 0X1DAB83; //十六进制数字
  7.  
  8. printf("a=%#ho, b=%#o, c=%#lo\n", a, b, c); //以八进制形似输出
  9. printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十进制形式输出
  10. printf("a=%#hx, b=%#x, c=%#lx\n", a, b, c); //以十六进制形式输出(字母小写)
  11. printf("a=%#hX, b=%#X, c=%#lX\n", a, b, c); //以十六进制形式输出(字母大写)
  12.  
  13. return 0;
  14. }

运行结果: a=0126, b=02713, c=07325603 a=86, b=1483, c=1944451 a=0x56, b=0x5cb, c=0x1dab83 a=0X56, b=0X5CB, c=0X1DAB83 十进制数字没有前缀,所以不用加#。如果你加上了,那么它的行为是未定义的,有的编译器支持十进制加#,只不过输出结果和没有加#一样,有的编译器不支持加#,可能会报错,也可能会导致奇怪的输出;但是,大部分编译器都能正常输出,不至于当成一种错误。

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章