C/C++进制转换

1.二进制、八进制和十六进制

1.1 二进制、八进制和十六进制数的表示

        一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊的写法,具体来说,就是在数字前面就上特定的字符,也就是加前缀。

(1)、二进制

        二进制由 0 和 1两个数字组成,使用时必须以0b 或0B(不区分大小写)开头,例如:

// 合法的二进制
int a = 0b101;          // 换算成十进制为
int b = -0b110010;      // 换算成十进制为
int c = 0B100001;       // 换算成十进制为

// 非法的二进制
int m = 101010;         // 无前缀 0B,相当于十进制
int n = 0B410;          //  4不是有效的二进制数字

         请注意,标准的C/C++语言并不支持二进制的写法,只是有些编译器自己进行了扩展,才支持二进制数字。换句话说,并不是所有的编辑器都支持二进制数字,只有一部分呢编辑器支持,并且跟编辑器的版本有关系。

(2)、八进制

八进制由0-7 八个数字组成,使用时必须以 0 开头,(注意是数字0,不是字母o),例如:

// 合法的八进制
int a = 015;            // 换算成十进制为
int b = -0101;          // 换算成十进制为
int c = 0177777;        // 换算成十进制为

// 非法的八进制
int m = 256;            // 无前缀 0,相当于十进制
int n = 03A2;           //  A不是有效的八进制数字

(3)、十六进制

        十六进制由数字 0-9、字母A-F或a-f(不区分大小写)组成,使用时必须以0x0X(不区分大小写)开头,例如:

// 合法的十六进制
int a = 0X2A;           // 换算成十进制为
int b = -0XA0;          // 换算成十进制为
int c = 0xffff;         // 换算成十进制为

// 非法的十六进制
int m = 5A;             // 无前缀0X,是一个无效数字
int n = 0X3H;           // H不是有效的十六进制数字

(4)、十进制

        十进制由0-9十个数字组成,没有任何前缀,和我们平时的书写格式一样,不再赘述。

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

        C/C++语言中常用的整数有shortintlong三种类型,通过printf函数,可以将它们以八进制、十进制和十六进制的格式输出。

short

int

long

八进制

%ho

%o

%lo

十进制

%hd

%d

%ld

十六进制

%hx 或者 %hX

%x 或者 %X

%lx 或者 %lX

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

        (1)、%hx%x%lx中的x小写,表明以小写字母的形式输出十六进制;

        (2)、%hX%X%lX中X的大写,表明以大写字母的形式输出十六进制。

八进制数字和十进制数字不区分大小写,所以格式控制符都用小写形式。如果使用大写形式,那么行为是未定义的!

        (1)、有些编辑器支持大写形式,只不过行为和小写形式一样;

        (2)、有些编辑器不支持大写形式,可能会报错,也可能会导致奇怪的输出。

        注意:虽然部分编辑器支持二进制数字的表示,但是却不能使用printf函数输出二进制,这一点比较遗憾。

[实例]

#include <stdio.h>
int main()
{
    short a = 0b1010110;    // 二进制数字
    int b   = 02713;        // 八进制数字
    long c  = 0X1DAB83;     // 十六进制数字

    printf(“a = %ho, a = %hd, a = %hx, a = %hX”, a, a, a, a);
    printf(“b = %o, b = %d, b = %x, b = %X”, b, b, b, b);
    printf(“c = %lo, c = %ld, c = %lx, c = %lX”, c, c, c, c);

    return 0;
}

运行结果:

1.3 输出时加上前缀

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

        (1)、对于八进制数字,它没法和十进制、十六进制区分,因为八进制、十进制和十六进制都包含0-7这几个数字。

        (2)、对于十进制数字,它没法和十六进制区分,因为十六进制也包含0-9这几个数字。如果十进制数字中还不包含89,那么也不能和八进制区分了。

        (3)、对于十六进制,如果没有包含a-f或者A-F,那么就无法和十进制区分,如果还不包含89,那么也不能和八进制区分了。

区分不同进制数字的一个简单办法就是,在输出时带上特定的前缀。在格式控制符中加上#即可输出前缀,例如%#ho,%#hx,%#hX  %#o,%#x,%#X  %#lo,%#lx,%#lX

[实例]

#include <stdio.h>
int main()
{
    short a = 0b1010110;    // 二进制数字
    int b   = 02713;        // 八进制数字
    long c  = 0X1DAB83;     // 十六进制数字

    printf(“a = %#ho, a = %hd, a = %#hx, a = %#hX”, a, a, a, a);
    printf(“b = %#o, b = %d, b = %#x, b = %#X”, b, b, b, b);
    printf(“c = %#lo, c = %ld, c = %#lx, c = %#lX”, c, c, c, c);
    
    return 0;
}

运行结果:

        十进制数字没有前缀,所以不用加#,如果加上了,那么它的行为是未定义的,有的编译器支持十进制加#,只不过输出结果和没有加#一样,有的编译器不支持加#,可能会报错,也可能会导致奇怪的输出;但是,大部分编译器都能正常输出,不至于当成一种错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值