11 C 语言进制前缀表示与占位符、进制转换详解(二进制、八进制、十进制、十六进制)

1 进制

        在计算机科学中,数据的底层表示与运算均建立在二进制体系之上。无论是简单的数字、字符,还是诸如图片、音频、视频之类的复杂信息,它们在计算机内部进行存储与处理时,均会被转化为二进制代码

1.1 常见进制概述

        二进制:使用 0 和 1 两个数字进行数值的表示。在二进制中,当某一位上的数值增加到 2 时,就会向高一位进位,即 “满 2 进 1”。

        八进制:使用 0 到 7 共八个数字进行数值的表示。在八进制中,当某一位上的数值增加到 8 时,就会向高一位的进位,即 “满 8 进 1”。

        十进制:使用 0 到 9 共十个数字进行数值的表示。在十进制中,当某一位上的数值增加到 10 时,就会向更高一位进位,即 “满 10 进 1”。

        十六进制:使用 0 到 9 的数字以及 A 到 F(或 a 到 f,不区分大小写)共十六个字符进行数值的表示。在十六进制中,A 到 F 分别代表十进制的 10 到 15。当某一位上的数值达到 16 时,会向更高一位进位,即 “满 16 进 1”。

二进制八进制十进制十六进制
0000
1111
10222
11333
100444
101555
110666
111777
10001088
10011199
10101210A
10111311B
11001412C
11011513D
11101614E
11111715F
10000201610
10001211711

1.2 整数的不同进制前缀表示

        在 C 语言里,整数的数值可通过不同前缀来明确其进制,具体规则如下:

  • 二进制:以 0b 或 0B 开头
  • 八进制:以数字 0 开头
  • 十进制:直接书写正常数字。
  • 十六进制:以 0x 或 0X 开头,其中字母 A 至 F(或 a 至 f)分别表示十进制中的 10 至 15。

        以下示例展示了如何使用不同进制的前缀来表示整数,并将它们以十进制形式(%d)输出:

#include <stdio.h>

int main()
{
    // 二进制表示的整数(使用 0b 或 0B 前缀)
    int binary1 = 0b1010101; // 二进制,表示 85(十进制)
    int binary2 = 0B1010101; // 二进制,同样表示 85(十进制)

    // 八进制表示的整数(使用数字 0 前缀)
    int octal = 0127; // 八进制,表示 87(十进制)

    // 十进制表示的整数(直接书写)
    int decimal = 210; // 十进制,直接表示 210

    // 十六进制表示的整数(使用 0x 或 0X 前缀)
    int hex1 = 0x1f; // 十六进制,表示 31(十进制)
    int hex2 = 0X1F; // 十六进制,同样表示 31(十进制)

    // 输出结果(以十进制形式)
    printf("binary1 (十进制表示) = %d\n", binary1); // 输出 85
    printf("binary2 (十进制表示) = %d\n", binary2); // 输出 85
    printf("octal (十进制表示) = %d\n", octal);     // 输出 87
    printf("decimal (十进制表示) = %d\n", decimal); // 输出 210
    printf("hex1 (十进制表示) = %d\n", hex1);       // 输出 31
    printf("hex2 (十进制表示) = %d\n", hex2);       // 输出 31

    return 0;
}

        程序在 VS code 中的运行结果如下所示:

1.3 整数的不同进制格式占位符

        为了以不同的进制形式输出整数,C 语言提供了特定的格式占位符,这些占位符可以与 printf 函数一起使用,以控制输出的格式。以下是一些常用的格式占位符及其功能说明:

  • %d:以十进制形式输出整数
  • %o:以八进制形式输出整数,不包含前缀 0
  • %x 或 %X:分别以小写或大写的十六进制形式输出整数,不包含前缀 0x 或 0X

        此外,还可以使用带有前缀显示功能的格式占位符:

  • %#o:在八进制输出前添加前缀 0
  • %#x 或 %#X:在十六进制输出前添加前缀 0x 或 0X

注意:

        对于二进制输出,标准的 printf 函数并没有专门的格式占位符支持。如果需要以二进制形式输出整数,则需要编写自定义函数或使用其他库函数来实现。

        以下示例展示了如何利用不同进制的前缀定义整数,并通过多种格式占位符输出它们的表示形式(包括十进制、八进制、十六进制及带前缀的格式):

#include <stdio.h>

int main()
{
    // 定义不同进制表示的整数
    int binary1 = 0b1010101; // 二进制(0b 前缀),表示 85(十进制)
    int binary2 = 0B1010101; // 二进制(0B 前缀),表示 85(十进制)
    int octal = 0127;        // 八进制(数字 0 前缀),表示 87(十进制)
    int decimal = 210;       // 十进制,直接表示 210
    int hex1 = 0x1f;         // 十六进制(0x 前缀),表示 31(十进制)
    int hex2 = 0X1F;         // 十六进制(0X 前缀),表示 31(十进制)

    // 1. 以 %d 十进制形式输出上述变量
    printf("binary1 (十进制表示) = %d\n", binary1); // 输出 85
    printf("binary2 (十进制表示) = %d\n", binary2); // 输出 85
    printf("octal (十进制表示) = %d\n", octal);     // 输出 87
    printf("decimal (十进制表示) = %d\n", decimal); // 输出 210
    printf("hex1 (十进制表示) = %d\n", hex1);       // 输出 31
    printf("hex2 (十进制表示) = %d\n", hex2);       // 输出 31

    printf("\n------------------------------------\n\n");

    // 2. 以不同的进制形式输出整数
    // 注意:二进制没有专门的格式占位符,这里仍用十进制表示
    printf("binary1 (仍用十进制表示) = %d\n", binary1); // 输出 85
    printf("binary2 (仍用十进制表示) = %d\n", binary2); // 输出 85

    // 输出八进制
    printf("octal (八进制表示) = %o\n", octal); // 输出 127
    // 输出含前缀 0 的八进制
    printf("octal (带前缀的八进制表示) = %#o\n", octal); // 输出 0127

    // 输出十进制
    printf("decimal (十进制表示) = %d\n", decimal); // 输出 210

    // 输出十六进制
    printf("hex1 (十六进制表示) = %x\n", hex1); // 输出 1f
    printf("hex2 (十六进制表示) = %X\n", hex2); // 输出 1F
    // 输出含前缀 0x 和 0X 的十六进制
    printf("hex1 (带前缀的十六进制表示) = %#x\n", hex1); // 输出 0x1f
    printf("hex2 (带前缀的十六进制表示) = %#X\n", hex2); // 输出 0X1F

    return 0;
}

        程序在 VS code 中的运行结果如下所示:

        以下示例展示了如何将一个整数以十进制、八进制和十六进制格式输出,包括是否带前缀的多种表示形式:

#include <stdio.h>

int main()
{
    // 定义变量 x 并初始化为 255(十进制)
    int x = 255;

    // 打印 x 的十进制表示
    printf("十进制表示:%d\n", x); // 输出 255

    // 打印 x 的八进制表示(不包含前缀 0)
    printf("八进制表示:%o\n", x); // 输出 377
    // 打印 x 的八进制表示(包含前缀 0)
    printf("八进制表示(带前缀):%#o\n", x); // 输出 0377

    // 打印 x 的十六进制表示(不包含前缀 0x 或 0X)
    printf("十六进制表示(小写):%x\n", x); // 输出 ff
    printf("十六进制表示(大写):%X\n", x); // 输出 FF

    // 打印 x 的十六进制表示(包含前缀 0x 或 0X)
    printf("十六进制表示(带前缀,小写):%#x\n", x); // 输出 0xff
    printf("十六进制表示(带前缀,大写):%#X\n", x); // 输出 0XFF

    return 0;
}

        程序在 VS code 中的运行结果如下所示:

1.4 整数的进制表示与内存存储一致性

        在 C 语言中,整数的不同进制表示(如二进制、八进制、十进制、十六进制)仅仅是书写方法上的差异,并不会影响整数在计算机内存中的实际存储方式

        计算机内部始终以二进制形式存储和处理整数,这意味着无论采用何种进制表示,整数的运算和存储都是一致的。因此,不同进制的整数可以混合使用,例如表达式 10 + 015 + 0x20 是完全合法的,其中 10 是十进制,015 是八进制(等于十进制的 13),0x20 是十六进制(等于十进制的 32)。

        以下是一个完整的 C 语言示例程序,展示了如何以不同进制表示整数并在表达式中混合使用,同时验证了这些整数在计算机内存中始终以二进制形式统一存储和处理:

#include <stdio.h>

int main()
{
    // 不同进制的整数
    int decimal = 10; // 十进制,表示 10
    int octal = 015;  // 八进制,表示 13(十进制)
    int hex = 0x20;   // 十六进制,表示 32(十进制)

    // 表达式混合使用不同进制的整数
    int result = decimal + octal + hex;

    // 输出结果
    printf("decimal = %d\n", decimal);                        // 输出 10
    printf("octal (十进制表示) = %d\n", octal);                // 输出 13
    printf("hex (十进制表示) = %d\n", hex);                    // 输出 32
    printf("result = decimal + octal + hex = %d\n", result); // 输出 55

    // 解释:
    // decimal = 10
    // octal = 015 (八进制) = 13 (十进制)
    // hex = 0x20 (十六进制) = 32 (十进制)
    // result = 10 + 13 + 32 = 55

    return 0;
}

        程序在 VS code 中的运行结果如下所示:


2 进制的转换

2.1 二进制 ↔ 十进制

2.1.1 二进制 → 十进制

        规则:采用按权展开法,从最低位(右端)起,将每一位的值乘以 2 的(位数索引 - 1)次方(即权值),然后累加求和

        案例:将二进制数 1011 转换为十进制数。

2.1.2 十进制 → 二进制

        规则:采用除基取余,逆序排列法,将十进制数反复除以基数 2,记录每次的余数,直到商为 0,然后将余数按逆序排列,即可得到对应的二进制表示。

        案例:将十进制数 56 转换为二进制数。

2.2 八进制 ↔ 十进制

2.2.1 八进制 → 十进制

        规则:采用按权展开法,从最低位(右端)起,将每一位的值乘以 8 的(位数索引 - 1)次方(即权值),然后累加求和

        案例:将八进制数 101 转换为十进制数。

2.2.2 十进制 → 八进制

        规则:采用除基取余,逆序排列法,将十进制数反复除以基数 8,记录每次的余数,直到商为 0,然后将余数按逆序排列,即可得到对应的八进制表示。

        案例:将十进制数 156 转换为八进制数。

2.3 十六进制 ↔ 十进制

2.3.1 十六进制 → 十进制

        规则:采用按权展开法,从最低位(右端)起,将每一位的值乘以 16 的(位数索引 - 1)次方(即权值),然后累加求和

        案例:将十六进制数 0x34A 转换为十进制数。

2.3.2 十进制 → 十六进制

        规则:采用除基取余,逆序排列法,将十进制数反复除以基数 16,记录每次的余数,直到商为 0。若余数大于 9,需用对应的十六进制字母(A=10,B=11,…,F=15)表示。最后将余数按逆序排列,即可得到对应的十六进制表示。

        案例:将十进制数 356 转换为十六进制数。

2.4 二进制 ↔ 八进制

2.4.1 二进制 → 八进制

        规则:采用取三合一法,从最低位(右端)起,将二进制数每三位一组(不足三位时左侧补零),每组转换为对应的八进制数

        案例:将二进制数 1101011 转换为八进制数。

2.4.2 八进制 → 二进制

        规则:采用取一分三法,将八进制数的每一位转换为对应的三位二进制数(直接查表或按权展开)

        案例:将八进制数 153 转换为二进制数。

2.5 二进制 ↔ 十六进制

2.5.1 二进制 → 十六进制

        规则:采用取四合一法,从最低位(右端)起,将二进制数每四位一组(不足四位时左侧补零),每组转换为对应的十六进制数。

        案例:将二进制数 1011011 转换为十六进制数。

2.5.2 十六进制 → 二进制

        规则:采用取一分四法,将十六进制数的每一位转换为对应的四位二进制数(直接查表或按权展开)

        案例:将十六进制数 0x23B 转换为二进制数。

提示:在进行不同进制转换时,二进制可作为高效 “桥梁” 简化计算

  • 十进制转八进制/十六进制:若直接除以 8 或 16 的运算较复杂,可先将十进制数转换为二进制,再通过三位一组转八进制四位一组转十六进制完成目标转换。
  • 优势:利用二进制与八进制(3 位对应 1 位)、十六进制(4 位对应 1 位)的天然分组关系,避免直接除法的繁琐计算。
  •  示例:
    • 十进制 156 转八进制:156 → 二进制 10011100 → 分组 010 011 100 → 八进制 234。
    • 十进制 255 转十六进制:255 → 二进制 11111111 → 分组 1111 1111 → 十六进制 FF。

        通过二进制中转,可显著降低计算复杂度,提升转换效率。


3 十进制 ↔ 其他进制的转换

3.1 整数部分转换规则

3.1.1 其他进制 → 十进制

        规则:按权展开法

3.1.2 十进制 → 其他进制

        规则:除基取余,逆序排列

3.2 小数部分转换规则

3.2.1 十进制小数 → 其他进制

        规则:乘基取整,顺序排列

3.2.2 其他进制小数 → 十进制 

        规则:按权展开法

3.3 注意事项

  1. 无限循环小数:某些十进制小数在转换为目标进制时可能无法精确表示(如 0.1 转二进制为无限循环 0.000110011…)。
  2. 精度控制:实际应用中需设定转换精度(如保留 6 位小数)。
  3. 混合数处理:整数和小数部分需分别转换后合并(如 12.625 转二进制为 1100.101)

4 进制转换工具

        在日常开发或工作讨论中,我们经常会遇到进制转换的问题。对于一些简单的数据,我们应该熟练掌握其进制转换方法,以便在需要时能够迅速准确地完成转换。这不仅有助于提升我们的工作效率,还能在交流中展现出我们的专业素养。

        然而,对于较大的数据,手动进行进制转换可能会变得困难且耗时。在这种情况下,我们可以借助一些工具来简化转换过程。例如,电脑自带的计算器程序就提供了二进制、八进制、十进制和十六进制之间的相互转换功能,非常方便实用。

        1. 打开计算器:按下电脑上的 Win 键,输入 “计算器” 并搜索,点击打开计算器程序。

        2. 切换模式:点击计算器左上角的菜单按钮,选择 “程序员” 模式。

        3. 输入数据:在相应的进制输入框中输入需要转换的数据,其他进制栏会自动显示转换后的结果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thanks_ks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值