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

操作符详解:从入门到精通

操作符详解:从入门到精通

前言

操作符是C语言的灵魂,掌握好操作符的使用,就能写出更加高效、优雅的代码。本文将全面系统地讲解C语言中的各类操作符,包括它们的分类、使用方法和注意事项,帮助你彻底搞懂操作符的方方面面。

1. 操作符的分类

C语言中的操作符非常丰富,大致可以分为以下几类:

类别操作符
算术操作符+-*/%
移位操作符<<>>
位操作符&`
赋值操作符=+=-=*=/=%=<<=>>=&=`
单目操作符!++--&*+-~sizeof(类型)
关系操作符>>=<<===!=
逻辑操作符&&`
条件操作符?:
逗号表达式,
下标引用[]
函数调用()
结构成员访问.->

今天我们将重点介绍与二进制相关的操作符(移位、位操作符),以及其他尚未详细讲解的操作符。

2. 二进制与进制转换

在深入位操作符之前,我们需要先了解二进制的基础知识。

2.1 什么是进制?

2进制、8进制、10进制、16进制只是数值的不同表示形式。比如数值15:

  • 2进制:1111
  • 8进制:17(以0开头)
  • 10进制:15
  • 16进制:F(以0x开头)

2.2 2进制转10进制

2进制每一位都有权重,从右向左依次是:(2^0, 2^1, 2^2, \ldots)

例如:二进制1101= (1 \times 8 + 1 \times 4 + 0 \times 2 + 1 \times 1 = 13)

2.3 10进制转2进制

使用除2取余法,不断除以2,将余数从下往上排列。

例如:125转换为2进制 →1111101

2.4 2进制转8进制和16进制

  • 转8进制:从右向左每3位一组,转换为对应的8进制数字(最高位不足3位时直接转换)
  • 转16进制:从右向左每4位一组,转换为对应的16进制数字

💡 小贴士:8进制数以0开头,16进制数以0x开头。

3. 原码、反码、补码

整数的二进制表示有三种形式:原码、反码、补码

3.1 基本规则

类型符号位正数负数
原码最高位,0正1负同原码数值位不变
反码不变同原码符号位不变,数值位取反
补码不变同原码反码+1

重要:整数在内存中存储的是补码

3.2 为什么用补码?

  • 符号位和数值位可以统一处理
  • 加法和减法可以统一处理(CPU只有加法器)
  • 补码与原码的转换过程相同,不需要额外硬件

4. 移位操作符

移位操作符的操作数只能是整数

4.1 左移操作符<<

规则:左边抛弃,右边补0

intnum=10;// 二进制:1010intn=num<<1;// 结果:10100 = 20

4.2 右移操作符>>

右移分为两种:

类型规则
逻辑右移左边补0,右边丢弃
算术右移左边补符号位,右边丢弃

⚠️警告:不要移动负数位,如num >> -1是未定义行为!

5. 位操作符:&、|、^、~

位操作符的操作数必须是整数

操作符名称规则
&按位与对应位都是1,结果为1
``按位或
^按位异或对应位不同,结果为1
~按位取反0变1,1变0
intnum1=-3;intnum2=5;printf("%d\n",num1&num2);// 按位与printf("%d\n",num1|num2);// 按位或printf("%d\n",num1^num2);// 按位异或printf("%d\n",~0);// 按位取反

5.1 经典面试题:不创建临时变量交换两个整数

inta=10,b=20;a=a^b;b=a^b;// b = (a ^ b) ^ b = aa=a^b;// a = (a ^ b) ^ a = bprintf("a = %d, b = %d\n",a,b);

原理:异或运算满足自反性:(a ^ b) ^ b = a

5.2 练习1:求二进制中1的个数

方法1(有缺陷,不能处理负数):

while(num){if(num%2==1)count++;num/=2;}

方法2(循环32次):

for(i=0;i<32;i++){if(num&(1<<i))count++;}

方法3(最优解):

while(num){count++;num=num&(num-1);// 每次消去最右边的1}

💡num & (num - 1)这个技巧非常经典,可以快速消去二进制中最右边的1。

5.3 练习2:二进制位置0或置1

将13的第5位(从0开始计数)修改为1,再改回0:

inta=13;// 第5位置为1a=a|(1<<4);// 第5位置为0a=a&~(1<<4);

6. 单目操作符

单目操作符的特点是只有一个操作数

操作符名称说明
!逻辑反真变假,假变真
++自增前置或后置
--自减前置或后置
&取地址获取变量的地址
*解引用通过地址访问变量
+正号正数
-负号负数
~按位取反二进制位取反
sizeof取大小计算类型或变量的大小
(类型)强制类型转换转换数据类型

7. 逗号表达式

逗号表达式从左向右依次执行,整个表达式的结果是最后一个表达式的结果

inta=1,b=2;intc=(a>b,a=b+10,a,b=a+1);// c的结果是 b = a + 1 = 13// 实用场景:简化while循环while(a=get_val(),count_val(a),a>0){// 业务处理}

8. 下标访问与函数调用

8.1 下标引用操作符[]

操作数:数组名 + 索引值

intarr[10];// 创建数组arr[9]=10;// [] 的操作数是 arr 和 9

8.2 函数调用操作符()

操作数:函数名 + 传递给函数的参数

test1();// () 的操作数是 test1test2("hello");// () 的操作数是 test2 和 "hello"

9. 结构成员访问操作符

9.1 结构体声明

structStu{charname[20];// 名字intage;// 年龄charsex[5];// 性别charid[20];// 学号};

9.2 直接访问:.

structStus={"张三",20};printf("%s %d\n",s.name,s.age);

9.3 间接访问:->

structStu*ptr=&s;ptr->age=21;// 等价于 (*ptr).age = 21

10. 操作符的优先级与结合性

10.1 优先级

优先级决定哪个运算符先执行。乘法优先级高于加法:

3+4*5;// 先算 4*5=20,再加3得23

10.2 结合性

当优先级相同时,结合性决定执行顺序:

  • 左结合:从左到右执行(大部分运算符)
  • 右结合:从右到左执行(赋值运算符等)
5*6/2;// 左结合,先算5*6=30,再除以2得15

10.3 常用优先级速查表

优先级运算符结合性
1(最高)()[].->左到右
2++--&*+-~!sizeof右到左
3*/%左到右
4+-左到右
5<<>>左到右
6<<=>>=左到右
7==!=左到右
8&左到右
9^左到右
10``
11&&左到右
12`
13?:右到左
14=及复合赋值右到左
15(最低),左到右

💡建议:记不住优先级没关系,使用圆括号()明确表达式的计算顺序即可!

11. 表达式求值的陷阱

11.1 整型提升

C语言中,charshort等类型在进行算术运算时,会先转换为intunsigned int,这就是整型提升

提升规则

  • 有符号数:按符号位提升
  • 无符号数:高位补0
chara,b,c;a=b+c;// b和c先提升为int,计算后再截断存入a

11.2 算术转换

当操作数类型不同时,会进行算术转换,向更高精度转换:

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

11.3 问题表达式

有些表达式虽然语法正确,但计算结果不确定,应避免写出:

// 问题1:操作数的求值顺序不确定a*b+c*d+e*f;// 问题2:i的修改和读取顺序不确定c+--c;// 问题3:函数调用顺序不确定fun()-fun()*fun();// 问题4:不同编译器结果不同intret=(++i)+(++i)+(++i);

⚠️核心原则:不要写出过于复杂的表达式,保持代码清晰、可读性强!

总结

本文全面介绍了C语言中的各类操作符,包括:

  1. 进制转换:理解二进制、八进制、十六进制
  2. 原反补码:理解整数在内存中的存储
  3. 移位和位操作:高效处理二进制位
  4. 优先级与结合性:理解表达式求值顺序
  5. 常见陷阱:避免写出有歧义的表达式

掌握好这些知识,你就能写出更加高效、准确的C语言代码。记住:简单清晰的代码比巧妙的代码更有价值


如果觉得这篇文章对你有帮助,欢迎点赞、收藏、分享!

http://www.gsyq.cn/news/1427370.html

相关文章:

  • Lindy效应如何重塑你的分析工作流:7个被90%团队忽略的自动化关键节点
  • 中国财政科学研究院考研辅导班强烈推荐【独峰考研】全解析 - michalwang
  • 无线通信系统设计:如何根据场景在ZF、MMSE、ML、MRC中做出选择?
  • 从客户分群到异常检测:轮廓系数在实际业务场景中的高级用法与避坑指南
  • UWB高精度测距实战:基于RYUW122_Lite模块的AT命令快速上手
  • 验收驱动提示词:让企业 AI 输出可控、可复用
  • 如何用SMUDebugTool深度掌控你的AMD Ryzen处理器:新手快速入门指南
  • 深度解析:如何通过本地化处理彻底解决Cookie安全风险
  • Quick 自定义应用实战:不写代码,用自然语言搭一个内部数据看板
  • 2026年商务出行,哪家口碑好的品牌能成为你的不二之选?
  • 如何学习和掌握最新的编程技术趋势?
  • Unity SLG游戏开发实战:从零搞定六边形地图的坐标转换与平铺(附完整C#代码)
  • 如何突破百度网盘限速:pan-baidu-download 完整指南与实战教程
  • 2026 编程趋强化期 主线框架精通 + 核心 API 使用
  • HarmonyOS TempUtil 气象应用实战:多温度单位显示与用户偏好设置开发指南
  • 终极魔兽争霸3优化指南:WarcraftHelper让你的经典游戏焕然一新
  • 神经渲染对抗训练全解析:从原理到产业,一篇就够了!
  • 国家大基金领投!DeepSeek首轮融资700亿,450亿美元估值背后有何底气?
  • 从零搭建企业虚拟化平台:Vcenter 8.0 + ESXi 8.0 完整配置与资源整合实战
  • Lindy数据流水线构建全周期(从手动脚本到自愈式Pipeline大揭秘)
  • 告别低效循环:用NumPy向量化加速你的深度学习代码(附逻辑回归实战对比)
  • LinkSwift网盘直链下载解决方案:为技术爱好者和普通用户提供的高速下载体验
  • 太原市尖草坪区宇馨家具:专业的太原沙发维修哪家好 - LYL仔仔
  • 2026 AI-CRM TOP6深度测评:生成式AI如何重构客户管理 - Joyky
  • NetTools Web版本终于有了它该有的样子
  • 揭秘:为什么Windows用户需要一款专属的AirPods桌面伴侣?
  • 保姆级教程:用Arduino IDE给CH552G小键盘烧录固件(附HFS本地服务器搭建避坑指南)
  • 2026 净水器十大品牌推荐:全屋净水优选,安全省心之选
  • 终极AMD Ryzen调试工具:专业硬件调校完全指南
  • 终极视频修复指南:使用Untrunc免费拯救损坏的MP4/MOV文件