C++编程规范 编程风格 学习 (2) -- 避免使用宏

避免使用宏

实不相瞒:宏是C和C++语言的抽象设施中最生硬的工具,它是披着函数外衣的饥饿的狼,很难驯服,它会我行我素地游走于各处。要避免使用宏。

由于几方面的原因,宏已经成为讨厌、恶心、杂乱的混合体,其中最主要的原因在于它们被吹捧为一种文本替换设施,其效果在预处理阶段就产生了,而此时C++的语法和语义规则还都没起到作用。

在C++中几乎从不需要宏。可以用const或者enum定义易于理解的常量,用inline避免函数调用的开销,用template制定函数系列和类型系列,用namespace避免名字冲突。

关于宏的第一规则就是:不要使用它,除非不得不用,几乎每个宏都说明程序设计语言、程序或者程序存在缺陷。

宏和模板不同,template是C++类型的一部分,宏和语言本身是割裂开来的,template可以借助编译器,而宏不行,template的错误可在编译的时候就发现,编译器也能更好地处理它,而宏里的错误只有在宏展开的时候才能被发现,而不是定义宏的时候。

但是,
宏还是必不可少的,比如#include保护,条件编译中的#ifdef和#if defined,以及assert的实现。
在条件编译中,要避免在代码中杂乱的插入#ifdef,相反,应该对该代码进行组织,利用宏来驱动一个公共接口的多个实现,然后始终使用该接口。
如果不想到处复制和粘贴代码段,可以使用宏,但是要非常小心。

关于预处理:

预处理可能是C++翻译过程中最危险的阶段,预处理器注重构成C++源码的”word“,但是它会忽略C++的细节,包括语法和语义,实际上,预处理器并不知道它的能力有多大,其实它的破坏力是巨大的。
使用预处理器最好是,需要强大的力量,但是不需要过多的了解C++,并避免需要技巧的工作。

#define 字面值
C++中使用#define定义字面值会导致错误或潜在的问题,所以C++程序员并不使用#define来定义字面值,考虑C中的#define的标准用法。

#define MAX 1<<16
使用预处理器符号的基本问题在于,预处理器在C++编译器检查这些符号之前,就展开了这些符号,预处理器对C++作用域或者类型规则一无所知。
void f( int );
void f( long );
//...
f(MAX);     //这里改用哪个f呢?
这里编译器进行重载分析时,MAX这个符号的值就是整数1<<16,而1<<16可能是int也可能是long,这就要取决于编译目标的平台,不同平台下编译上述代码,会调用不同的函数。
#define 指令不会关心作用域。现在多处C++工具都封装在namespace中,这有不少优点,而不仅仅是降低了不同工具互相干扰的可能性,而#define的作用域不止限于某个namespace内。
namespace A
{
#define MAX 1<<16
//....
}

namespace B
{
    const int max = 512;
    //....
}

int arr[MAX];
如果在此忘记了导入名称max,而误写为MAX。预处理器会把1<<16替换为MAX, 所以可以编译代码。这个预处理器就跨越了C++的作用域。

如果这么用问题就会更大
int arr2[MAX*2];
这个数组大小就会超出自己当初的预料,它实际上是arr2[1<<16*2];
这就是不正确地构造#define而引起的。如果使用初始化好的常量就不会出这种语义问题。
const int max = 1<<16;
int arr3[max*3];
这才是我想要的。

#define 伪函数
在C中,#define 通常用于定义伪函数,这种情况就要更多地考虑避免函数调用的代价,而不是安全性。

#define MULTIPLE( a, b )  (a * b)
这么写就有问题,如果是MULTIPLE(2+3,4)
其实你想要(2+3)*4,但是实际是2+3*4,这差了很远,不如用inline来实现岂不更好,
int inline multiple(int a, int b){return a*b;};
这绝不会产生歧义。
当然你给带上括号,给好约束就好了#define MULTIPLE( a, b )  ((a) * (b)),是不是觉得OK了?其实不然,看下面
#define SQUARE( a ) ((a) * (a))  这个看似没啥问题。
但是还会有可能有问题
#define SQUARE( a ) ((a) * (a))  
int nValue = 10; 
int nSquare = SQUARE(nValue++); // nSquare=110, nValue=12
想想为啥是这个结果?
这就是宏在展开时,对其参数的多次取值替换所带来的副作用。为了避免这种副作用,禁止在使用宏的时候,参数有变化。
这就是伪函数的恐怖之处。
另外,有很多宏是很有用的,比如说断言ASSERT,但是它也是伪函数,是伪函数就有它致命的地方,所以需要正确的使用它才能达到目的。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值