C++实用经验(四)

本文探讨C++编程中常见的陷阱,如运算符混淆、表达式求值顺序不确定、switch-case误用等,同时介绍如何利用C++转换操作符避免类型转换问题,提升代码质量和可读性。


声明:以下内容总结自《C++程序员不可不知的101条实用经验》

运算符引发的混乱

  1. 粗心导致的混乱:为防止=和使用混乱,将 if(b10)写成if(10==b),这样当因为粗心写出if(10=b)时,编译器报错,能够及时发现问题
  2. 优先级导致的混乱:三元运算的条件操作符exp1?exp2:exp3优先级较低,可通过括号强制提高优先级cout << (exp1?exp2:exp3);
  3. 结合性导致的混乱:a=b=c等价于a=(b=c),具有向右结合特性
  4. 优先级决定表达式中各种不同运算符起作用的优先次序,而结合性则在相邻两个运算符具有同等优先级时,决定表达式的结合方向
  5. 最好使用括号设置期望的优先级,防止引入不确定性

尽量使用C++转换操作符

为了解决C语言中旧式类型转换存在的问题,C++中引入了4种新类型转换操作符:static_cast、const_cast、dynamic_cast、reinterpret_cast

  1. static_cast:(1)用于类层次结构中基类和子类之间指针或引用的转换 (2)进行上行转换是安全的 (3)把空指针转换成目标类型的空指针 (4)把任何类型的表达式转换为void类型 (5)可将一个void*类型的指针强制转换为原来的指针类型 (6)进行下行转换(把基类指针或引用转换成子类指针或引用)没有动态类型检查,所以不安全
  2. dynamic_cast:(1)用于类层次间的上行转换和下行转换以及类之间的交叉转换 (2)下行转换时,dynamic_cast具有类型检查的功能,比static_cast更加安全 (3)dynamic_cast要求派生类有虚拟函数,否则编译不通过
  3. reinterpret_cast:(1)比static_cast更接近C的强制类型转换,但比static_cast更加危险 (2)除非有必要,否则在C++编程中尽量避免使用reinterpret_cast
  4. const_cast:把常量指针或引用转换为非常量指针或引用,并仍然指向原来的对象

表达式求值顺序不要想当然

  1. 操作数的求值顺序
int x = 1;
int y = (x + 2) * (++ x);
//x+2和x++的顺序无法确定,所以y的值可能为6或8

//p(), q(), r()为三个函数, 都对同一个全局变量进行操作
int a = p() + q() + r(); //三个函数的运行顺序无法确定,导致a值无法确定
//使用指定中间变量的方式解决
int b = p(), c = q(), d = r();
int a = b + c + d;
  1. 函数参数的求值顺序
//p(), q(), r()为三个函数, 都对同一个全局变量进行操作
print("%d %d %d", p(), q(), r()); //三个函数返回值作为参数,但三个函数的执行顺序不确定

int a = 10;
int &aa = a;
int res = Func(a, aa *= 2); //无法确定时Func(10, 20)还是Func(20, 20)
int res = Func(a, a * 2); //正确

swtch-case陷阱

  1. 使用switch-case时,最好在每个标号后提供一个break语句,即使最后一个标号也不例外,如果因为某种特殊需要在switch的最后一个标号后面又要添加一个新的标号,则不用在前面加break语句了
  2. 故意省略break是特别罕见的做法,因此在这种形式的代码附近,务必添加一下注释说明运行逻辑
  3. 在switch-case结构中,只能在最后一个case标号或default中定义内部变量,避免出现代码跳过变量定义和初始化的情况
  4. case的标号必须是整型常量表达式

悬挂else

if(0 == x)
		if(0 == y) printf("abc");
else
		printf("ddd");
//else会和最近的if(0 == y)匹配,使得程序逻辑出现问题

解决方式:使用良好的编程风格,在if和else后都加上{}

goto真的一无是处吗

反对goto的论点:(1)含有goto的代码很难安排好格式 (2)使用goto会破坏编译器的优化特性 (3)使用goto会使运行速度变慢,代码更大 (4)使用goto难以维护代码
适合使用goto的两种情况:(1)跳出多层嵌套循环 (2)错误处理以及资源释放

条件操作符和逗号操作符

  1. 条件操作符:(1)最好为每个子表达式添加括号(expression1) ? (expression2) : (expression3) (2)提高代码简洁性
  2. 逗号操作符:
int a = expression1, expression2, expression3, expression4; //每个表达式都会被求值,整个表达式的值是最后一个表达式的值,即a=expression4 

同魔鬼数字说再见

  1. 魔鬼数字:上下文出现的字符常量,虽然不会影响程序功能,但没有抽象语义,影响程序的可读性
  2. 为了避免代码难以理解,应将数字定义为名称有意义的常量,使得代码更易理解

关于循环语句的讨论

  1. for循环:(1)不可在for循环体内修改循环变量,防止for循环失去控制,最终导致死循环 (2)建议for循环使用半闭半开的写法,更加直观 for(int i = 0; i < N; ++i)
  2. do{}while():(1)do{}while()是指向效率最低的循环语句,但它的特点是一定会执行一次 (2)do{}while(0)被用于宏定义中,使用do{…}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行,比如:
#define foo() {p();q();}
if(true == k)
		foo(); 
else
		printf("sss");
等价于
if(true == k){
		p();
		q();
}; //多了一个分号
else
		printf("sss");
改进:
#define foo() do{p();q();}while(0)
if(true == k)
		do{
				p();
				q();
		}while(0);
else
		printf("sss");

(3)在多重循环中,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数,这样可以提高cache命中率,降低因为循环跳转造成cache的miss以及流水线的flush造成的延时
(4)当循环体内存在逻辑判断,并且循环次数很大时,宜将逻辑判断放到循环体的外面
(5)++i比i++效率更高,i!=N比i<N效率高,应为!=是按位运算,而<需要做减法

下载前可以先看下教程 https://pan.quark.cn/s/a426667488ae 标题“仿淘宝jquery图片左右切换带数字”揭示了这是一个关于运用jQuery技术完成的图片轮播机制,其特色在于具备淘宝在线平台普遍存在的图片切换表现,并且在整个切换环节中会展示当前图片的序列号。 此类功能一般应用于电子商务平台的产品呈现环节,使用户可以便捷地查看多张商品的照片。 说明中的“NULL”表示未提供进一步的信息,但我们可以借助标题来揣摩若干核心的技术要点。 在构建此类功能时,开发者通常会借助以下技术手段:1. **jQuery库**:jQuery是一个应用广泛的JavaScript框架,它简化了HTML文档的遍历、事件管理、动画效果以及Ajax通信。 在此项目中,jQuery将负责处理用户的点击动作(实现左右切换),并且制造流畅的过渡效果。 2. **图片轮播扩展工具**:开发者或许会采用现成的jQuery扩展,例如Slick、Bootstrap Carousel或个性化的轮播函数,以达成图片切换的功能。 这些扩展能够辅助迅速构建功能完善的轮播模块。 3. **即时数字呈现**:展示当前图片的序列号,这需要通过JavaScript或jQuery来追踪并调整。 每当图片切换时,相应的数字也会同步更新。 4. **CSS美化**:为了达成淘宝图片切换的视觉效果,可能需要设计特定的CSS样式,涵盖图片的排列方式、过渡效果、点状指示器等。 CSS3的动画和过渡特性(如`transition`和`animation`)在此过程中扮演关键角色。 5. **事件监测**:运用jQuery的`.on()`方法来监测用户的操作,比如点击左右控制按钮或自动按时间间隔切换。 根据用户的交互,触发相应的函数来执行...
垃圾实例分割数据集 一、基础信息 • 数据集名称:垃圾实例分割数据集 • 图片数量: 训练集:7,000张图片 验证集:426张图片 测试集:644张图片 • 训练集:7,000张图片 • 验证集:426张图片 • 测试集:644张图片 • 分类类别: 垃圾(Sampah) • 垃圾(Sampah) • 标注格式:YOLO格式,包含实例分割的多边形点坐标,适用于实例分割任务。 • 数据格式:图片文件 二、适用场景 • 智能垃圾检测系统开发:数据集支持实例分割任务,帮助构建能够自动识别和分割图像中垃圾区域的AI模型,适用于智能清洁机器人、自动垃圾桶等应用。 • 环境监控与管理:集成到监控系统中,用于实时检测公共区域的垃圾堆积,辅助环境清洁和治理决策。 • 计算机视觉研究:支持实例分割算法的研究和优化,特别是在垃圾识别领域,促进AI在环保方面的创新。 • 教育与实践:可用于高校或培训机构的AI课程,作为实例分割技术的实践数据集,帮助学生理解计算机视觉应用。 三、数据集优势 • 精确的实例分割标注:每个垃圾实例都使用详细的多边形点进行标注,确保分割边界准确,提升模型训练效果。 • 数据多样性:包含多种垃圾物品实例,覆盖不同场景,增强模型的泛化能力和鲁棒性。 • 格式兼容性强:YOLO标注格式易于与主流深度学习框架集成,如YOLO系列、PyTorch等,方便研究人员和开发者使用。 • 实际应用价值:直接针对现实世界的垃圾管理需求,为自动化环保解决方案提供可靠数据支持,具有重要的社会意义。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值