news 2026/7/17 7:43:03

聊聊 C 里的进制转换、移位操作与算术转换

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
聊聊 C 里的进制转换、移位操作与算术转换

前言

学 C 语言时,总绕不开 “进制怎么转”“移位操作符怎么用”“表达式为啥这么算” 这些问题 —— 它们不算多高深,但都是写代码、调 Bug 的基础。

比如写个简单的位运算,若搞不清二进制和十进制的转换逻辑,很容易算错结果;处理表达式时,要是忽略了整型提升的规则,可能会碰到莫名其妙的运行错误。

这篇就整理了自己对进制转换、移位操作符、算数转换这些内容的理解,不求讲得多深,只希望把这些基础知识点理清楚,方便自己回头翻,也给刚入门的朋友做个参考。


目录

一、2进制与进制转换

1、2进制 —> 10进制

2、10进制 —> 2进制

3、2进制 —> 8进制

4、8进制 —> 2进制

5、2进制 —> 16进制

6、16进制 —> 2进制

【2进制、8进制、16进制转10进制总结】

二、原码、反码、补码

三、移位操作符

1、<< 左移操作符

2、>> 右移操作符

四、整型提升

五、算术转换

【整数类型参数表】


一、2进制与进制转换

咱日常说的 “二进制 / 八进制 / 十进制 / 十六进制”,其实就是数字的 “不同穿搭”—— 本质都是同一个数,换身衣服罢了~

比如数字 “15” 的 “穿搭秀”:

二进制款:1111(主打一个极简,就 0 和 1 俩元素)

八进制款:17(穿它得加个前缀0,不然认不出来)

十进制款:15(咱生活里最常穿的 “基础款”)

十六进制款:F(拽哥款,前缀得配0x才够范儿)

二进制的 “穿衣规则”别觉得它高冷,其实和十进制是 “亲戚”:

十进制:凑够 10 个就升级(满 10 进 1),元素是 0~9

二进制:凑够 2 个就跑路(满 2 进 1),元素只有 0 和 1

所以像1101这种 “01 串串”,就是二进制本进制啦~


1、2进制 —> 10进制

其实10进制的123表⽰的值是⼀百⼆⼗三,为什么是这个值呢?其实10进制的每⼀位是有权重的,
10进制的数字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10^0 , 10^1 , 10^2 ...

如下图:

10进制123每一位权重的理解
2进制和10进制是类似的,只不过2进制的每⼀位的权重,从右向左是:2^0 , 2^1 , 2^2 ...
如果是2进制的1101,该怎么理解呢?
2进制1101每一位的权重理解
你看,二进制1101这么一拆,每一位对应 “2 的次方面额”,乘完一加就得到 13 啦!所以二进制1101
转成十进制,就是咱们算出来的 13—— 这招 “按位拆算”,就是二进制转十进制的万能小妙招~

2、10进制 —> 2进制

这招主打一个 “拆了再拼”:把十进制数当成 “待拆分的大蛋糕”,每次用 2 除它,把剩下的 “余数小块” 记下来,直到除到 0 为止。

比如转 125:

  1. 拿 125÷2,商 62,余 1 → 记个 1
  2. 62÷2,商 31,余 0 → 记个 0
  3. 31÷2,商 15,余 1 → 记个 1……(就这么一直除,一直记余数)最后把记下来的余数从下往上倒着读,就是 1111101—— 这就是 125 对应的二进制啦!

简单说就是:除 2 取余,余数倒排,搞定~


3、2进制 —> 8进制

八进制的特点:每一位是 0~7,而 0~7 的数字转成二进制,最多只需要 3 位(比如 7 的二进制是 111)。

转换规则:从二进制的右边低位开始,每 3 位分为一组,每组转成对应的八进制数;不足 3 位的组直接换算。


4、8进制 —> 2进制

核心逻辑:八进制的每一位(0~7),刚好对应 “3 位二进制数”(比如八进制的 7 对应二进制 111),所以转的时候直接 “1 位八进制→3 位二进制” 展开就行。

操作步骤:

  1. 把八进制的每一位数字,单独转成对应的 3 位二进制数;
  2. 要是某一位转成二进制不足 3 位,就在左边补 0 凑够 3 位;
  3. 把所有位转好的二进制数连起来,就是最终结果。
8进制0153转2进制

5、2进制 —> 16进制

核心逻辑:十六进制每位是 0~9、a~f,这些数字转成二进制最多需要 4 位(比如 f 的二进制是 1111),因此转换时按 “4 位二进制→1 位十六进制” 分组即可。

转换规则:从二进制的右边低位开始,每 4 位分为一组,每组换算成对应的十六进制位;剩余不足 4 位的组直接换算。


6、16进制 —> 2进制

核心逻辑:十六进制的每一位(0~9、a~f),刚好对应 “4 位二进制数”(比如 16 进制的 f 对应二进制 1111),所以转的时候直接 “1 位 16 进制→4 位二进制” 展开即可。

操作步骤

  1. 把 16 进制的每一位数字 / 字母,单独转成对应的 4 位二进制数;
  2. 若某一位转成二进制不足 4 位,在左边补 0 凑够 4 位;
  3. 将所有位转好的二进制数连起来,就是最终结果。

    核心逻辑:十六进制的每一位(0~9、a~f),刚好对应 “4 位二进制数”(比如 16 进制的 f 对应二进制 1111),所以转的时候直接 “1 位 16 进制→4 位二进制” 展开即可。

16进制0xA3转2进制

【2进制、8进制、16进制转10进制总结】

进制转换类型基数位权规则(从右往左,第 k 位)核心计算方式
二进制→十进制22^(k-1)每位 ×2ⁿ 相加
八进制→十进制88^(k-1)每位 ×8ⁿ 相加
十六进制→十进制1616^(k-1)每位 ×16ⁿ 相加

二、原码、反码、补码

整数(有符号整型才用原反补表示)的二进制表示有三种方式:原码、反码、补码。

【通用规则】

有符号整数的这三种表示,都分成符号位数值位两部分:

  • 二进制的最高位是符号位:0代表 “正”,1代表 “负”;
  • 剩下的位是数值位,用来表示具体数值。

【正整数的表示】

正整数的原码、反码、补码完全一样,直接把数值转成二进制,最高位补0(表示正数)就行。比如 + 5(假设是 8 位):

  • 原码 / 反码 / 补码:0000 0101

【负整数的表示】

负整数的原、反、补码各不相同,得按步骤转换:

  1. 原码:把数值转成二进制,最高位补1(表示负数)。比如 - 5(8 位):1000 0101

  2. 反码:原码的符号位不变,数值位按位取反(0 变 1,1 变 0)。比如 - 5 的反码:1111 1010(符号位1不变,数值位000 0101取反成111 1010

  3. 补码:反码的基础上加 1。比如 - 5 的补码:1111 1011(反码1111 1010+1 =1111 1011

【补码转原码】

如果已知补码,想转原码,步骤是:补码按位取反,然后加 1(和 “原码转补码” 的操作一样)。比如补码1111 1011(对应 - 5):

  • 取反:1000 0100
  • 加 1:1000 0101(刚好是 - 5 的原码)

计算机里所有有符号整数的运算(不管是加还是减),全程都是用补码来算的

这是因为 CPU 硬件只有加法器,而补码能把减法 “伪装” 成加法 —— 比如算3-2,实际会变成3 + (-2的补码),用加法就能得到正确结果。

显而易见,用补码计算的结果是正确的 —— 不过这只针对有符号整数;如果是无符号整数,直接用二进制数值计算即可。

三、移位操作符

1、<< 左移操作符

移位规则:左边抛弃、右边补0

左移操作符演示

2、>> 右移操作符

移位规则:⾸先右移运算分两种:
  1. 逻辑右移:左边⽤0填充,右边丢弃
  2. 算术右移:左边⽤原该值的符号位填充,右边丢弃
逻辑右移演示
算术右移演示

通过在 VS 中的实际运行结果可以看出,C 语言中带符号整数的右移操作符(>>),底层遵循的是算术右移规则。

警告⚠️:对于移位运算符,不要移动负数位,这个是标准未定义的。
int num = 10; num>>-1;//error

四、整型提升

关于整型提升,其实是 C 语言里小整型参与运算的 “隐形规则”—— 因为 CPU 的整型运算器默认是int长度,所以charshort这类比int短的类型,在做加减、位运算前,都会先转成int(或unsigned int),这个过程就叫整型提升。

它的核心逻辑很简单:

1、有符号整数提升是按照变量的数据类型的符号位来提升的

2、⽆符号整数提升,⾼位补0
整型提升演示

注意,提升只是运算时的临时转换,运算结束后如果存回小整型变量,结果会被截断回原类型的长度。

五、算术转换

当运算符的两个操作数类型不同时,不能直接运算 —— 得先把类型 “等级低” 的那个,转换成 “等级高” 的类型,这个转换规则就是 “寻常算术转换”。

它的核心是一个 “类型优先级层级表”(等级越靠前,优先级越高):

long double double float unsigned long int long int unsigned int int

转换逻辑很简单:

看两个操作数的类型在层级表里的位置 ——把 “排名靠后”(优先级低)的类型,转换成 “排名靠前”(优先级高)的类型,然后再运算。

总结:

算术转换的目的是 “让不同类型的操作数统一成同一种高优先级类型”,避免运算出错 —— 本质是按 “类型优先级” 向上对齐。

【整数类型参数表】

类型分类位数 (bit)取值范围(十进制)最大值公式
无符号整数80 ~ 2552^8 - 1
160 ~ 655352^16 - 1
320 ~ 42949672952^32 - 1
640 ~ 184467440737095516152^64 - 1
有符号整数(补码)8-128 ~ 1272^7 - 1
16-32768 ~ 327672^15 - 1
32-2147483648 ~ 21474836472^31 - 1
64-9223372036854775808 ~ 92233720368547758072^63 - 1

核心规则:

无符号整数:n 位全部用于表示数值,取值范围是 0 ~ 2^n - 1(无符号位)。

有符号整数(补码):最高位是符号位(1 表示负数,0 表示正数),取值范围是 -2^(n-1) ~ 2^(n-1) - 1 (比无符号少 1 位数值位)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 0:45:00

用自然语言生成界面草图?Excalidraw AI功能实测

用自然语言生成界面草图&#xff1f;Excalidraw AI功能实测 在一次深夜的技术评审会上&#xff0c;团队正在讨论一个新模块的架构设计。白板前&#xff0c;后端工程师手忙脚乱地画着服务调用关系&#xff0c;前端同事皱眉追问&#xff1a;“这个鉴权流程到底是先走网关还是直接…

作者头像 李华
网站建设 2026/7/16 11:04:42

28、高级线程同步技术深度解析

高级线程同步技术深度解析 1. 线程同步实现的性能对比 在进行线程同步实现时,不同的方法会有不同的性能表现。通过对比不同生产者/消费者对数量下的实现情况,能更清晰地了解各种方法的优劣。 - Run 10 - 5a :对比了两种使用互斥锁的实现,其中使用广播机制的实现性能较…

作者头像 李华
网站建设 2026/7/14 17:32:08

Excalidraw绘图支持嵌入视频链接,多媒体融合展示

Excalidraw&#xff1a;当手绘白板开始“播放”视频 想象这样一个场景&#xff1a;你正在远程评审一份微服务架构图&#xff0c;每个模块都清晰标注了职责。但当你看到“用户鉴权服务”时&#xff0c;心里仍有疑问——这个组件到底是如何与前端交互的&#xff1f;传统的做法是翻…

作者头像 李华
网站建设 2026/7/17 2:44:08

Excalidraw在文化遗产数字化保护中的创新应用

Excalidraw在文化遗产数字化保护中的创新应用 在敦煌莫高窟的一个临时工作站里&#xff0c;三位考古队员围坐在平板电脑前。他们刚完成对一处新发现墓室的初步测绘&#xff0c;但传统的手绘草图和文字记录方式效率低下&#xff0c;且难以实时共享。这时&#xff0c;其中一人打开…

作者头像 李华
网站建设 2026/7/15 14:33:16

Excalidraw与Asana集成,项目进度可视化再升级

Excalidraw与Asana集成&#xff1a;让项目进度“看得见” 在一次产品迭代会议上&#xff0c;团队正围绕一张系统架构草图激烈讨论。突然有人问&#xff1a;“这个模块对应的开发任务在哪&#xff1f;” 会议室瞬间安静——没人记得上次更新的Figma链接藏在哪个Slack频道里。这并…

作者头像 李华
网站建设 2026/7/17 1:29:10

手搓简单 string 库:了解C++ 字符串底层

今天带大家来手搓简单的 string 库了&#xff0c;顺便一起了解它的底层逻辑&#xff0c;有利于后面STL的学习1.简单实现string的头文件我们用 .h 和 .cpp 文件分离的方式书写&#xff0c;我先给出它的类&#xff1a;代码语言&#xff1a;javascriptAI代码解释#pragma once#incl…

作者头像 李华