当前位置: 首页 > news >正文

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

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.hskmm.com/?act=detail&tid=20127

相关文章:

  • 2025 最新权威推荐:防火皮革厂家 排行榜,B1 级阻燃 + E0 级环保实力品牌甄选B1级/建筑/审讯室/邮轮级防火皮革厂家推荐
  • 格雷厄姆指数
  • reLeetCode 热题 100- 42 接雨水 - MKT
  • 2025 防撞软包生产厂家权威推荐排行榜:E0 级环保 + B1 级阻燃,公检法 / 幼儿园场景最新优选厂家谈话室/留置病房/教育中心/体育馆防撞软包厂家推荐
  • ssti模板注入
  • 2025 年章丘二手磁选机厂家最新权威推荐排行榜:TOP 级企业设备全型号覆盖与五年质保深度解析二手立环磁选机/二手华特磁选机/章丘二手磁选机厂家推荐
  • 中位数定理
  • 数据集Dataset
  • 2025 年三维扫描仪厂家最新权威推荐排行榜:覆盖空间 / 高精度 / 专业 / 手持激光 / 工业等类型,精选实力企业深度解析
  • 2025 年染井吉野樱厂商最新推荐排行榜:权威筛选优质苗木供应商,聚焦分枝点规格与景观适配五公分/十公分/染井吉野樱批发厂商推荐
  • 2025 货架厂家权威推荐排行榜: 实力厂家深度解析,金塔领衔全业态定制服务新标杆云南/昆明/西南货架厂家推荐
  • 国标GB28181视频平台EasyGBS公网平台实时视频播放方案
  • 2025 展会搭建公司权威推荐排行榜:服务商创意定制与全流程服务能力深度解析站台展会搭建/展台搭建活动策划/展台搭建展台制作公司推荐
  • Volcano——配置理解
  • 国标GB28181视频平台EasyGBS:强大的视频监控与一站式视频服务解决方案
  • 题解:AT_abc425_f [ABC425F] Inserting Process
  • [转]bat/cmd将命令执行的结果赋值给变量
  • 题解:P13507 [OOI 2024] Three Arrays
  • 题解:AT_abc424_f [ABC424F] Adding Chords
  • 如何在不同区域/网络环境下评估 reCAPTCHA 的表现 - 详解
  • 2025 年最新编织袋生产厂家权威推荐排行榜:聚焦 TOP5 优质企业,助力企业精准甄选可靠合作伙伴牛皮纸/塑料/PP彩膜/化工/化肥编织袋厂家推荐
  • P11854 [CSP-J2022 山东] 宴会
  • 2025 年试验机厂家权威推荐榜:TOP5 优质厂家综合实力解析,助力科研与工业客户精准选型电子万能材料/橡胶拉力/塑料拉力/扬州拉力试验机厂家推荐
  • win 系统安装
  • 2025 年节能咨询公司最新权威推荐排行榜:覆盖工业 / 建筑 / 数据中心等领域 TOP5 优质企业综合测评与选型指南发电厂/燃气/全域增效/服务器节能公司推荐
  • 微算法科技(NASDAQ MLGO)探索全同态加密与安全多方计算融合,开启区块链隐私执行新时代
  • 国产SUB-1G芯片DP4363F支持119-1050mhz超低功耗 - 动能世纪
  • 2025 年棕刚玉源头厂家最新推荐排行榜:TOP 级生产厂家原料与烧结工艺权威解析,助力企业精准选购一级棕刚玉/棕刚玉磨料/优质棕刚玉/棕刚玉喷砂废料回收厂家推荐
  • 杀疯了!GitHub 发布 Copilot CLI!!!
  • 2025 年无尘金刚砂源头厂家最新推荐排行榜:权威精选企业产能与品质深度解析无尘金刚砂材料/无尘金刚砂批发/无尘金刚砂喷砂厂家推荐