C语言 - 左移、右移运算符

news/2025/9/28 17:30:55/文章来源:https://www.cnblogs.com/zhuchunlin/p/19117248

C语言中的左移和右移运算符

左移(<<)和右移(>>)运算符是C语言中对二进制位进行移动的操作符。让我用最简单的方式解释给你听。

1. 基本概念:把二进制位想象成排队的人

想象二进制数就像一排人,每个人代表一个二进制位(0或1):

text
数字 13 的二进制:1 1 0 1
位置:             第3人 第2人 第1人 第0人

2. 左移运算符 <<

左移就是把所有位向移动,右边补0。

语法:

c
结果 = 数字 << 移动位数;

例子:

c
int a = 13;      // 二进制: 1101
int b = a << 1;  // 左移1位

移动过程:

text
原始:   1 1 0 1
左移1位: 1 1 0 1 0  (所有位向左移1位,右边补1个0)
结果:   1 1 0 1 0 = 26 (十进制)

实际效果:

  • 左移1位 ≈ 乘以2

  • 左移n位 ≈ 乘以2^n

c
13 << 1 = 26  (13 × 2 = 26)
13 << 2 = 52  (13 × 4 = 52)  
13 << 3 = 104 (13 × 8 = 104)

3. 右移运算符 >>

右移就是把所有位向移动,左边补0(正数)或补1(负数)。

语法:

c
结果 = 数字 >> 移动位数;

例子:

c
int a = 13;      // 二进制: 1101
int b = a >> 1;  // 右移1位

移动过程:

text
原始:   1 1 0 1
右移1位: 0 1 1 0  (最右边1被挤掉,左边补0)
结果:   0 1 1 0 = 6 (十进制)

实际效果:

  • 右移1位 ≈ 除以2(取整)

  • 右移n位 ≈ 除以2^n(取整)

c
13 >> 1 = 6   (13 ÷ 2 = 6.5 → 取整6)
13 >> 2 = 3   (13 ÷ 4 = 3.25 → 取整3)
13 >> 3 = 1   (13 ÷ 8 = 1.625 → 取整1)

4. 完整示例代码

c
#include <stdio.h>// 打印二进制形式的函数
void printBinary(int num) {for (int i = 31; i >= 0; i--) {printf("%d", (num >> i) & 1);if (i % 4 == 0) printf(" "); // 每4位加空格,方便阅读}
}int main() {int number = 13;printf("原始数字: %d\n", number);printf("二进制: ");printBinary(number);printf("\n\n");// 左移示例printf("=== 左移运算 ===\n");for (int i = 1; i <= 3; i++) {int result = number << i;printf("%d << %d = %d\n", number, i, result);printf("二进制: ");printBinary(result);printf("\n");}printf("\n=== 右移运算 ===\n");for (int i = 1; i <= 3; i++) {int result = number >> i;printf("%d >> %d = %d\n", number, i, result);printf("二进制: ");printBinary(result);printf("\n");}return 0;
}

5. 运行结果示例

text
原始数字: 13
二进制: 0000 0000 0000 0000 0000 0000 0000 1101 === 左移运算 ===
13 << 1 = 26
二进制: 0000 0000 0000 0000 0000 0000 0001 1010 
13 << 2 = 52
二进制: 0000 0000 0000 0000 0000 0000 0011 0100 
13 << 3 = 104
二进制: 0000 0000 0000 0000 0000 0000 0110 1000 === 右移运算 ===
13 >> 1 = 6
二进制: 0000 0000 0000 0000 0000 0000 0000 0110 
13 >> 2 = 3
二进制: 0000 0000 0000 0000 0000 0000 0000 0011 
13 >> 3 = 1
二进制: 0000 0000 0000 0000 0000 0000 0000 0001 

6. 特殊情况说明

负数的情况:

c
int a = -13;
int b = a >> 1;  // 对于负数,左边补1而不是0

边界情况:

c
int a = 1;
int b = a << 31; // 可能溢出,得到负数

7. 实际应用场景

快速乘除法:

c
// 比乘法快
int fastMultiplyBy4 = num << 2;    // num × 4
int fastDivideBy8 = num >> 3;      // num ÷ 8

位掩码操作:

c
// 检查第3位是否为1
if (value & (1 << 3)) {printf("第3位是1\n");
}// 设置第5位为1
value = value | (1 << 5);// 清除第2位
value = value & ~(1 << 2);

8. 重要注意事项

  1. 移位位数不能为负数a << -1 是未定义行为

  2. 移位位数不能超过数据类型位数:对于32位int,不要 a << 32

  3. 有符号数的右移:结果取决于编译器实现(算术右移或逻辑右移)

  4. 溢出问题:左移可能导致数值溢出变成负数

记忆口诀:

  • 左移:往左走,尾巴补零,数值变大(×2)

  • 右移:往右走,脑袋补零,数值变小(÷2)

现在你应该对C语言中的左移和右移运算符有了清晰的理解!它们本质上就是在二进制层面上移动位的位置。

 
 
 
 
 
 
 
 
 
 
 
 
再举一个例子吧 假如二进制数:1001, 左移动和右移怎么处理的
 
 
 
 
 
 
 

我们以二进制数1001(十进制9)为例,分别进行左移和右移操作。
注意:我们假设这个二进制数在一个至少4位的系统中,但实际在C语言中,我们通常处理的是整型,比如32位。
为了简单起见,我们先考虑4位的情况,然后扩展到8位或32位。

原始二进制: 1001 (十进制9)

左移操作(<<):
左移1位:所有位向左移动一位,最左边一位移出,最右边补0。
1001 左移1位 -> 10010 (注意,现在有5位了,但在计算机中,我们固定位数,比如8位,则表示为00010010)
在4位系统中,左移1位后,我们只取4位,则0010(十进制2),但实际在C语言中,我们是用整型,所以不会截断为4位。

在C语言中,我们通常用整型(比如32位)来存储数字。所以:
9的32位二进制表示:00000000 00000000 00000000 00001001
左移1位:00000000 00000000 00000000 00010010 -> 十进制18

右移操作(>>):
右移1位:所有位向右移动一位,最右边一位移出,最左边补0(对于无符号数)或补符号位(对于有符号数)。
我们以无符号数为例:9的二进制1001,右移1位 -> 0100(十进制4)
在32位中,9的二进制表示右移1位:00000000 00000000 00000000 00000100 -> 十进制4

注意:如果是有符号数,且是负数,右移补1。但9是正数,所以补0。

下面我们用代码演示:

 

二进制数 1001 的左移和右移详解

让我们用二进制数 1001 作为例子,详细演示左移和右移的操作过程。

1. 首先确定原始数值

二进制 1001 转换为十进制:

text
1    0    0    1
↓    ↓    ↓    ↓
2^3  2^2  2^1  2^0
8    0    0    1
总和 = 8 + 0 + 0 + 1 = 9

所以:二进制 1001 = 十进制 9

2. 左移操作 (<<)

左移1位:1001 << 1

操作过程:

text
原始:   1 0 0 1
左移1位: 1 0 0 1 0  (所有位向左移动1位,右边补1个0)
结果:   1 0 0 1 0

数值计算:

  • 原始:1001 = 9

  • 左移1位后:10010 = 16 + 2 = 18

  • 验证:9 × 2 = 18 ✓

左移2位:1001 << 2

操作过程:

text
原始:     1 0 0 1
左移2位: 1 0 0 1 0 0  (所有位向左移动2位,右边补2个0)
结果:     1 0 0 1 0 0

数值计算:

  • 左移2位后:100100 = 32 + 4 = 36

  • 验证:9 × 4 = 36 ✓

左移3位:1001 << 3

操作过程:

text
原始:       1 0 0 1
左移3位: 1 0 0 1 0 0 0  (所有位向左移动3位,右边补3个0)
结果:       1 0 0 1 0 0 0

数值计算:

  • 左移3位后:1001000 = 64 + 8 = 72

  • 验证:9 × 8 = 72 ✓

3. 右移操作 (>>)

右移1位:1001 >> 1

操作过程:

text
原始:   1 0 0 1
右移1位: 0 1 0 0  (所有位向右移动,左边补0,最右边1被丢弃)
结果:   0 1 0 0

数值计算:

  • 原始:1001 = 9

  • 右移1位后:0100 = 4

  • 验证:9 ÷ 2 = 4.5 → 取整4 ✓

右移2位:1001 >> 2

操作过程:

text
原始:     1 0 0 1
右移2位: 0 0 1 0  (所有位向右移动2位,左边补2个0,最右边2位被丢弃)
结果:     0 0 1 0

数值计算:

  • 右移2位后:0010 = 2

  • 验证:9 ÷ 4 = 2.25 → 取整2 ✓

右移3位:1001 >> 3

操作过程:

text
原始:       1 0 0 1
右移3位: 0 0 0 1  (所有位向右移动3位,左边补3个0,最右边3位被丢弃)
结果:       0 0 0 1

数值计算:

  • 右移3位后:0001 = 1

  • 验证:9 ÷ 8 = 1.125 → 取整1 ✓

4. C语言代码验证

c
#include <stdio.h>// 打印二进制形式的函数(只显示低8位)
void printBinary(int num) {for (int i = 7; i >= 0; i--) {printf("%d", (num >> i) & 1);if (i % 4 == 0) printf(" ");}
}int main() {int number = 0b1001;  // C语言中0b前缀表示二进制数printf("原始数字: %d\n", number);printf("二进制: ");printBinary(number);printf("\n\n");// 左移示例printf("=== 左移运算 ===\n");for (int i = 1; i <= 3; i++) {int result = number << i;printf("%d << %d = %d\n", number, i, result);printf("二进制: ");printBinary(result);printf("\n");}printf("\n=== 右移运算 ===\n");for (int i = 1; i <= 3; i++) {int result = number >> i;printf("%d >> %d = %d\n", number, i, result);printf("二进制: ");printBinary(result);printf("\n");}return 0;
}

5. 运行结果

text
原始数字: 9
二进制: 0000 1001 === 左移运算 ===
9 << 1 = 18
二进制: 0001 0010 
9 << 2 = 36
二进制: 0010 0100 
9 << 3 = 72
二进制: 0100 1000 === 右移运算 ===
9 >> 1 = 4
二进制: 0000 0100 
9 >> 2 = 2
二进制: 0000 0010 
9 >> 3 = 1
二进制: 0000 0001 

6. 重要观察

左移时的现象:

  • 每左移1位,数值翻倍(乘以2)

  • 如果最高位的1被移出数据范围,就会发生溢出

右移时的现象:

  • 每右移1位,数值减半(除以2,取整)

  • 移出的低位信息永久丢失

边界情况:

c
// 如果继续右移
9 >> 4 = 0  // 0000 0000,所有有效位都被移出了// 如果左移太多导致溢出
9 << 4 = 144  // 1001 0000 = 128 + 16 = 144

7. 实际应用举例

快速计算:

c
// 快速计算 9 × 5
int result = (9 << 2) + 9;  // 9×4 + 9×1 = 36 + 9 = 45// 快速计算 9 ÷ 2(取整)
int half = 9 >> 1;  // 结果是4

位操作:

c
// 提取第2位(从右往左数,从0开始)
int bit2 = (9 >> 2) & 1;  // (1001 >> 2) = 0010, 0010 & 0001 = 0// 设置第3位为1
int setBit3 = 9 | (1 << 3);  // 1001 | 1000 = 1001(不变,因为第3位已经是1)

现在你应该对二进制数 1001 的左移和右移操作有了清晰的理解!记住:左移是乘法,右移是除法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 最新权威推荐:防火皮革厂家 排行榜,B1 级阻燃 + E0 级环保实力品牌甄选B1级/建筑/审讯室/邮轮级防火皮革厂家推荐

随着 2025 年阻燃建材市场规模预计突破 120 亿元,防火皮革在司法、建筑、高端家居等领域的需求呈爆发式增长,但行业乱象仍亟待破解:部分产品阻燃仅达 B2 级,无法满足公检法等特殊场所要求;环保指标残缺,有害挥发…

格雷厄姆指数

什么是格雷厄姆指数?什么是格雷厄姆指数? 如何计算? 如何使用确认股市的 底部和顶部区域? 用全部A股的股票收益率,去除以中国的十年期国 债收益率,得出的结果 就是格雷厄姆指数。例如:东方财富全A指数 的市盈率…

reLeetCode 热题 100- 42 接雨水 - MKT

reLeetCode 热题 100- 42 接雨水 class Solution { public:/*关键 左边界 height[zuo]>height[zuo+1]右边界 1 是否比height[you]》height[zuo] break;2 不是最后一个 height[you]>height[you-1] &&am…

2025 防撞软包生产厂家权威推荐排行榜:E0 级环保 + B1 级阻燃,公检法 / 幼儿园场景最新优选厂家谈话室/留置病房/教育中心/体育馆防撞软包厂家推荐

防撞软包作为公检法审讯室、幼儿园等场景的核心安全保障材料,近年来市场需求持续扩张,但行业乱象却愈发凸显:部分产品环保等级仅达 E2 级,甲醛等有害物挥发超标,长期使用危害人体健康;阻燃性能不足 B1 级,难以通…

企业门户网站服务器c 做网站

变量初始值为A&#xff0c;修改成B,通过AtomicReference的compareAndSet去改变。就会先比较原来的值是否为A&#xff0c;如果为A则修改成功&#xff0c;否则修改失败。 但是如果在这个过程中&#xff0c;A变成D然后又变成A, 那么再调用compareAndSet去改变也能修改成功B。这个…

ppt成品免费下载的网站网站建设旗帜条幅

几张图看懂列式存储 转载于:https://www.cnblogs.com/apeway/p/10870211.html

ssti模板注入

ssti模板注入 1. SSTI漏洞 SSTI,即服务器端模板注入漏洞; ​ 在渲染模板时,代码不严谨并且没有对用户的输入做严格过滤,将导致SSTI漏洞,造成任意文件读取和RCE命令执行; 2. SSTI类型判断绿线表示执行成功,…

2025 年章丘二手磁选机厂家最新权威推荐排行榜:TOP 级企业设备全型号覆盖与五年质保深度解析二手立环磁选机/二手华特磁选机/章丘二手磁选机厂家推荐

在矿产加工与原料提纯行业,磁选机作为核心分选设备,其品质与适配性直接决定生产效率和产品纯度。当前二手磁选机交易市场乱象丛生,不少商家设备型号单一,无法满足不同产能需求;品牌选择受限,采购灵活性低;更有甚…

中位数定理

https://codeforces.com/contest/2149/problem/D点击查看代码 #include <bits/stdc++.h> #define int long long using namespace std;int f(const vector<int> x){if(x.empty())return 0;int pos = (int)…

数据集Dataset

Dataset:提供一种方式去获取数据及其label 目的:如何获取每一个数据及其label;告诉我们总共有多少个数据 tensorboard 用于可视化 TensorFlow 等深度学习框架训练过程等数据的工具。

301网站目录个人主页模板设计

思路&#xff1a; 外层循环控制循环次数(i<len)&#xff0c;设置swapFlagfalse内层循环j1(j<len-i)&#xff0c;两两(j和j-1)比较&#xff0c;逆序则交换内层每次循环结束&#xff0c;没有交换&#xff0c;则break结束 内层循环j从1开始&#xff0c;小于len&#xff0c;…

2025 年三维扫描仪厂家最新权威推荐排行榜:覆盖空间 / 高精度 / 专业 / 手持激光 / 工业等类型,精选实力企业深度解析

在数字化转型浪潮席卷各行业的当下,三维扫描技术已成为文博保护、工业检测、医疗诊断、教育科研等领域的核心支撑工具,市场对高品质三维扫描仪的需求呈爆发式增长。然而,当前市场品牌鱼龙混杂,产品从消费级到工业级…

深入解析:华为全系列机型发展简史 机型与芯片的对照表

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

计算机网络---网络层 - 详解

计算机网络---网络层 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco",…

2025 年染井吉野樱厂商最新推荐排行榜:权威筛选优质苗木供应商,聚焦分枝点规格与景观适配五公分/十公分/染井吉野樱批发厂商推荐

当前染井吉野樱苗木市场面临分枝点规格混乱、培育标准缺失等问题,从 0.5 米到 3 米的分枝点标注随意,导致采购方难以匹配绿化项目需求。部分供应商忽视科学培育,苗木移栽后树形失衡,严重影响城市绿化、景区打造等项…

一个网站怎么绑定很多个域名国家备案网查询系统

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

2025 货架厂家权威推荐排行榜: 实力厂家深度解析,金塔领衔全业态定制服务新标杆云南/昆明/西南货架厂家推荐

在零售与仓储行业加速升级的当下,货架作为空间利用与商品运营的核心载体,其品质、设计适配性与服务效率直接决定业态盈利水平。然而当前市场乱象频发:部分小厂缺乏核心技术,产品承重不足、易变形,存在安全隐患;多…

国标GB28181视频平台EasyGBS公网平台实时视频播放方案

国标GB28181视频平台EasyGBS公网平台实时视频播放方案支持平台级联功能,可以实现多个平台之间的互联互通和数据共享。这对于构建大规模、跨地域的安防监控网络具有重要意义。随着科技的飞速发展,视频监控技术已经成为…

怎样免费设计网站建设网站cms相关知识

文章目录 顺序表一&#xff1a;线性表1.1概念&#xff1a; 二&#xff1a;顺序表2.1概念与结构&#xff1a;2.2分类&#xff1a;2.2.1静态顺序表2.2.2动态顺序表 2.3动态顺序表的实现声明&#xff08;初始化&#xff09;检查空间容量尾插头插尾删头删查找指定位置之前插入数据指…

2025 展会搭建公司权威推荐排行榜:服务商创意定制与全流程服务能力深度解析站台展会搭建/展台搭建活动策划/展台搭建展台制作公司推荐

会展经济的蓬勃发展推动展会搭建成为品牌展示的核心载体,但其行业痛点却日益凸显:传统服务商设计同质化严重,难以匹配品牌个性化表达;施工团队专业度参差导致进度延误、安全隐患频发;服务链条断裂需客户多方协调,…