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

C++ 表达式求值优先级、结合律与求值顺序(五十九)

1. 运算符优先级与结合律

  • 优先级(Precedence) 决定未加括号时运算符如何“绑”在一起:
    5 + 10 * 20 / 2;  // 等同于 5 + ((10 * 20) / 2)
    
  • 结合律(Associativity) 决定同级运算符的结合方向:
    • 左结合(大多数二元运算符):20 - 15 - 3(20 - 15) - 3
    • 右结合(赋值、条件、一些复合赋值运算符):a = b = ca = (b = c)

技巧:遇复杂表达式,加括号明确意图。

2. 求值顺序与短路

  • 默认情况下,C++ 并不保证子表达式的求值顺序——除非运算符明确规定。
  • 短路求值
    • &&:只有左侧为真时才求右侧
    • ||:只有左侧为假时才求右侧
    • ?::仅求选中的那分支
  • 逗号运算符 ,:先求左侧(结果丢弃),再求右侧,返回右侧结果。
int x = (f1(), f2());  // 只调用 f1() 后再调用 f2()

3. 算术运算符

运算符功能结合律
+ - (一元)符号取正/取负
* / %乘、除、取余
+ - (二元)加、减
  • 整数除法 向零截断(C++11 起)。
  • 取余 遵循 (a/b)*b + a%b == a

4. 关系与逻辑运算符

运算符功能结合律
< <= > >=关系比较
== !=相等/不等
!逻辑非
&&逻辑与
``

注意:不能把布尔字面值 true/false 与非布尔表达式比较,易引发歧义。

5. 赋值与复合赋值

  • 普通赋值 =右结合,左侧必须是非常量左值,返回左值本身。
  • 复合赋值 +=-=*=|=、…:等价于 a = a op b,但只评估一次 a
// 更安全、更高效
sum += val;
mask |= (1UL << bit);

6. 递增/递减运算符

形式含义求值结果
++i前置:先加 1,再返回左值左值
i++后置:先返回旧值,再加 1右值

警惕 在同一表达式中同时修改和读取同一变量,会导致未定义行为!

7. 条件与逗号运算符

  • 条件 cond ? A : B右结合,只计算所选分支。
  • 逗号 E1, E2左结合,顺序求值,返回 E2
// 条件表达式须两边类型可兼容或可转换
auto grade = (score < 60 ? "Fail" : "Pass");// for 循环中同时更新两个变量
for (int i = 0, c = 100; i < 10; ++i, --c) {}

8. 位运算符

运算符功能结合律
~按位取反
<<左移
>>右移
&按位与
^按位异或
|按位或

提示:用于掩码、标志位或快速乘除以 2 的幂。但要注意符号扩展与未定义行为。

9. sizeof 运算符

  • 编译时 常量表达式,不触发构造/析构、函数调用或解引用。
  • 返回 size_t:可用于数组维度、static_assert
  • 数组名不退化sizeof arr == N * sizeof(arr[0])
int a[10];
static_assert(sizeof a / sizeof a[0] == 10, "元素个数应为 10");

结语

透彻理解 C++ 的运算符优先级、结合律与求值顺序,能帮你:

  • 避免未定义行为:防止同时修改与读取、写错括号导致逻辑混乱
  • 提高性能和可读性:恰当运用复合赋值、短路逻辑、位运算
  • 写出更健壮的模板代码:掌握 sizeof、常量表达式与 static_assert

下次再碰到复杂表达式,请先画出运算符“优先级地图”,加上必要的括号,写出让人“一眼就懂”的 C++ 代码。祝你编码愉快!

http://www.xdnf.cn/news/195553.html

相关文章:

  • 关于https请求丢字符串导致收到报文解密失败问题
  • 第二章:Agent System
  • RestRequest ,newtonsoft解析
  • 大模型(LLMs)强化学习—— PPO
  • 【angular19】入门基础教程(一):项目的搭建与启动
  • 如何查看电脑电池使用情况
  • 北京市延庆区“禅苑茶事“非遗项目挂牌及茶事院正式启用
  • Adobe Lightroom Classic v14.3.0.8 一款专业的数字摄影后期处理软件
  • 测试反馈陷入死循环?5大策略拆解新旧Bug难题
  • if consteval
  • 多模态大型模型,实现以人为中心的精细视频理解
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: 跨平台开发同样支持retain()引用计数器处理.
  • 【氮化镓】质子辐照对 GaN-on-GaN PiN 二极管电导调制的影响
  • 后端Web实战之登录认证,JWT令牌,过滤器Filter,拦截器Interceptor一篇文章so easy!!!
  • 【python】-基础语法1
  • 颖儿生活提案:用海信璀璨505U6真空冰箱重建都市鲜食自由
  • 蓝桥杯 3. 压缩字符串
  • 树莓派5+edge-tts 语音合成并进行播放测试
  • EtherCAT转EtherNet/IP网关CEI-382实现罗克韦尔PLC与和利时伺服电机通讯
  • FFmpeg源码学习---ffmpeg
  • 《Operating System Concepts》阅读笔记:p821-p897
  • awk之使用详解(Detailed Explanation of Using AWK)
  • python10天- 文件操作模式详解
  • C++高性能日志库spdlog
  • 深入浅出限流算法(二):更平滑的滑动窗口
  • Python 如何操作数据库,让你使用 DeepSeek 开发数据库应用更加快 (Orm Bee)
  • MySQL复合查询
  • HTML 从标签到动态效果的基础
  • react-navigation-draw抽屉导航
  • ArkTS基础实验 (二)