尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

第4章 运算符

第4章 运算符
📅 发布时间:2026/6/20 15:25:51

4 运算符

4.1 基本概念

4.1.1 decltype与左右值

  • 表达式结果为左值 →decltype得到引用类型
  • 如decltype(*p)为int&(p是int*)
  • 表达式结果为右值 →decltype得到普通类型
  • 如decltype(&p)为int*

4.1.2 未指定求值顺序的风险

  • 大多数运算符不规定运算对象的求值顺序

  • 典型问题示例:

cout << i << ++i; // 未定义行为

可能输出:

  • 0 1(先i后++i)
  • 1 1(先++i后i)
  • 或其他结果

4.1.3 表达式求值三要素对比

要素 作用 示例 f() + g() * h() + j()
优先级 决定乘法先于加法 g()*h()先组合
结合律 决定加法从左到右 (f()+g()*h())+j()
求值顺序 不规定函数调用顺序 f(),g(),h(),j()调用顺序未定

4.1.4 安全编程建议

  1. 使用括号明确意图
// 明确表达计算顺序
(a + b) * (c - d)
  1. 避免同一表达式修改并访问变量
// 错误示例
arr[i] = i++; // 未定义行为// 正确做法
arr[i] = i;
i++;
  1. 例外情况
    当修改本身就是子表达式的一部分时是安全的:
*++iter // 安全:先++再解引用

重要结论

  • 优先级和结合律只决定表达式如何分组,不决定计算顺序
  • 修改变量后在同一表达式中再次使用是未定义行为的主要来源
  • 4种特殊运算符是唯一有明确求值顺序的情况

4.2 运算

优先级组 运算符 结合律
最高 一元运算符(+、-、*、&等) 右结合
中 乘法/除法/取模(*、/、%) 左结合
最低 加法/减法(+、-) 左结合

正号运算符(+)

+ptr // 返回“指针副本”
+3.14 // 返回double值3.14

4.3 逻辑和关系运算符

4.3.1 浮点数比较注意事项

// 避免直接相等比较(使用误差范围)
double a = 0.1 + 0.2;
if (fabs(a - 0.3) < 1e-10) {...}

4.3.2 布尔值比较最佳实践

正确写法

// 测试整数真值
if (val) {...} // val != 0
if (!val) {...} // val == 0// 明确比较数值
if (val == 1) {...} // 明确测试是否为1

错误写法及问题

if (val == true) {...}
// 等价于 if(val == 1),可能非预期
// 当val为2时:true被转为1,2==1为false

4.3.3 类型安全比较建议

  1. 避免布尔值与数值混用比较

  2. 使用static_cast显式转换

bool b = static_cast(val); // 明确转换意图
  1. C++17起可用std::cmp_equal等安全比较函数
#include
if (std::cmp_equal(val, 1)) {...} // 类型安全比较

4.3.4 转化符

4.4 四种类型转换运算符

4.4.1 static_cast(静态类型转换)

用途:用于明确定义的类型转换,是最常用的类型转换运算符

特点:

  • 编译时完成类型检查
  • 不能转换掉const/volatile属性
  • 相对安全,但仍需注意精度损失

适用场景:

// 基本数据类型转换
double d = 3.14;
int i = static_cast(d); // 浮点转整型// 类层次结构中的上行转换(安全)
class Base {};
class Derived : public Base {};
Derived* d = new Derived();
Base* b = static_cast<Base*>(d);// void*与其他指针互转
int x = 10;
void* p = static_cast<void*>(&x);
int* px = static_cast<int*>(p);

4.4.2 const_cast(常量性转换)

用途:专门用于修改类型的const或volatile属性

特点:

  • 唯一能去除const属性的转换
  • 不能改变基础类型
  • 滥用可能导致未定义行为

适用场景:

// 去除const属性
const char* str = "hello";
char* s = const_cast<char*>(str); // 去const// 函数重载调用
void func(int&);
void func(const int&);const int x = 10;
func(const_cast<int&>(x)); // 调用非const版本

注意事项:

const int ci = 5;
int* pi = const_cast<int*>(&ci);
*pi = 10; // 未定义行为!原始对象是const

4.4.3 reinterpret_cast(重新解释转换)

用途:提供低层次的重新解释位模式

特点:

  • 最危险的类型转换
  • 完全不进行类型检查
  • 高度依赖平台和实现
  • 应尽量避免使用

适用场景:

// 指针类型间的转换
int* ip = new int(65);
char* cp = reinterpret_cast<char*>(ip);// 指针与整数间的转换
intptr_t i = reinterpret_cast(ip);// 不相关类型指针转换
struct A { int x; };
struct B { int y; };
A a;
B* b = reinterpret_cast<B*>(&a);

危险示例:

float f = 3.14f;
int i = reinterpret_cast<int&>(f); // 直接解释位模式

4.4.4 dynamic_cast(动态类型转换)

用途:用于类层次结构中的安全下行转换

特点:

  • 运行时类型检查(RTTI)
  • 失败时返回nullptr(指针)或抛出异常(引用)
  • 只适用于多态类型(有虚函数)
  • 有一定性能开销

适用场景:

class Base { virtual void foo() {} };
class Derived : public Base {};Base* bp = new Derived();// 指针转换
Derived* dp = dynamic_cast<Derived*>(bp);
if (dp) { /* 转换成功 */ }// 引用转换
try {
Derived& dr = dynamic_cast<Derived&>(*bp);
} catch (std::bad_cast& e) {
// 处理转换失败
}

注意事项:

class NonPolymorphic {}; // 无虚函数
NonPolymorphic* np = new NonPolymorphic();
// 错误!不能对非多态类型使用dynamic_cast
// auto p = dynamic_cast<OtherType*>(np);

总结对比表

转换类型 检查时机 安全性 主要用途 性能开销
static_cast 编译时 高 相关类型转换 无
const_cast 编译时 中 修改const属性 无
reinterpret_cast 编译时 低 低级重新解释 无
dynamic_cast 运行时 高 安全下行转换 有

最佳实践建议:

  1. 优先考虑设计改进,避免不必要的类型转换
  2. 使用最严格的能满足需求的转换运算符
  3. 对每次类型转换添加注释说明必要性
  4. 避免C风格强制转换(type)expr,改用C++风格
  5. 对dynamic_cast的结果总是检查是否成功

相关新闻

  • 本地运行可以打印东西,docker run后却没有日志产生?记录一次AI编程的小蠢行为
  • 排序--基数排序
  • 好友圈模块 Cordova 与 OpenHarmony 混合开发实战

最新新闻

  • Claude工作流实战:50条覆盖认知-操作-集成的工程化技巧
  • WSL2+llama.cpp部署Qwen 3.6-35B-A3B全指南
  • 2026年比较好的提升机链钩/山东提升机链轮实力工厂推荐 - 品牌宣传支持者
  • Helmholtz方程边界元法:核正则化与H矩阵加速技术详解
  • XNB文件解包打包终极指南:xnbcli命令行工具深度解析
  • P89LPC924/925 ADC触发模式与中断优先级配置实战指南

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号