目录

1.宏的优缺点

(1)宏的使用

<1>.宏常量

<2>.宏函数

(2)宏的优点

(3)宏的缺点

2.宏的替代技术


1.宏的优缺点

(1)宏的使用

宏的概念: 将一个数据用一个标识符代替,源程序中的该标识符均用对应的数据来代替。如同代码一这样的。(标识符不可以用关键字)

代码一:此代码是C++代码(本文所有代码运行环境均为win10系统下的vs2019)

//代码一
#include "iostream"
using namespace std;#define PI 3.14int main() {cout << "PI = " << PI << endl;//输出 PI = 3.14
}

<1>.宏常量

宏常量就是如同代码一那样将一个数据用一个标识符代替的操作。但有时如果定义宏的时候不够仔细,就会出现奇奇怪怪的错误。

代码二:宏定义时不要加分号。

//代码二
#include "iostream"
using namespace std;//#define PI 3.14;  报错,定义宏不可以加分号,因为标识符后面的东西都会被默认是宏的一部分int main() {//cout << "PI = " << PI << endl;
}

<2>.宏函数

宏函数:利用宏来实现类似于函数的功能,如同代码三。

代码三:利用宏函数求和。

#include "iostream"
using namespace std;#define SUM(a,b) a+bint main() {cout << "SUM(a,b) = " << SUM(5,10) << endl;//输出 SUM(a,b) = 15
}

貌似宏函数要方便很多,但其实宏函数中也是有坑的,当实现的功能比较复杂时,如果不小心,宏函数就会出错。如同代码四。

代码四:宏函数出错的情况。下面这个宏函数的本意是求两数的乘积。

//代码四
#include "iostream"
using namespace std;#define PRODUCT(a,b) a*b int main() {cout << "PRODUCT(a,b) = " << PRODUCT(1+2,2+3) << endl;//输出 PRODUCT(a,b) = 8
}

上述代码是不是感觉很迷惑,正确结果不应该时15吗,为什么是8。

将传入的数据代入宏函数来算一下:PRODUCT(1+2,2+3) == 1+2 * 2+3 == 1+4+3 == 8。错误在于,宏函数只是将数据代入,而不会检查合理性。这个宏函数的正确写法应该如同代码五。

代码五:正确的求乘积宏函数:

//代码五
#include "iostream"
using namespace std;#define PRODUCT(a,b) ((a)*(b))int main() {cout << "PRODUCT(a,b) = " << PRODUCT(1+2,2+3) << endl;//输出 PRODUCT(a,b) = 15
}

代码六:这段代码更可以体现宏的副作用,这是一个比较大小的宏函数。

//代码六
#include "iostream"
using namespace std;#define MAX(a,b) ((a)>(b))?(a):(b)int main() {int a = 2;int b = 1;int ret = MAX(++a, b);cout << "ret = " << ret << endl;//输出 ret = 4
}

这段代码本应该打印3,为什么却打印4?还是将数据代入宏函数计算一下:MAX(++a, b) == ((++a)>(b)) ? (++a):(b) == ((3)>(1)) ? (4) : (b) == 4。宏函数在比较时已经通过 ((++a)>(b)) 对a加1,在返回结果时 (++a):(b) 再次对a加1,才造成了这样的错误。

通过上述情况,可以发现宏函数其实还是较为麻烦的,仅仅一个乘积宏函数就需要带这么多括号,并且宏函数还具有副作用。所以在使用宏函数时,一定要仔细判断是否合理。

(2)宏的优点

1.增强代码复用性,减少冗余代码。

2.提高性能,提升代码运行效率。

(3)宏的缺点

1.宏不方便调试,很多错误无法在调试中发现。

2.会导致代码可读性差,可维护性差,容易误用。

3.没有安全的检查,具有副作用。

2.宏的替代技术

1.宏常量:用const定义常量来替代宏常量。

2.宏函数:使用内联函数来替代宏函数。(关于内联函数在我的C++初阶的文章中有提到过)

宏的优缺点宏的替代技术相关推荐

  1. C++起始(内联函数,宏的优缺点,const关键字,auto关键字(C++11)基于范围的for循环(C++11). 指针空值nullptr(C++11))

    内联函数 概念 以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行的效率 函数前增加inline关键字将其改成内联函数,在编 ...

  2. C语言编程宏定义的优缺点,C语言重要知识点总结(二)--内存结构、函数调用过程(栈帧)、宏的优缺点以及##和#的使用...

    一.内存结构 内存大致可以分为四个部分:代码段,静态存储区,堆,栈. 具体划分如下图所示: 栈:在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束后会自动释放内存.栈内存的分配运算 ...

  3. 【C++---10】有参宏,无参宏,宏的优缺点

    目录 1.宏格式: 2.无参宏详解: 3.宏和typedef: 4.有参宏详解: 5.无参宏说明: 6.有参宏说明: 7.宏的优点: 8.宏的缺点: 9.define与const的区别的简单总结: 1 ...

  4. Nature子刊:HUMAnN2实现宏基因组和宏转录组种水平功能组成分析

    HUMAnN2实现宏基因组和宏转录组种水平功能组成分析 Species-level functional profiling of metagenomes and metatranscriptomes ...

  5. Nature Method:HUMAnN2实现宏基因组和宏转录组种水平功能组成分析

    文章目录 HUMAnN2实现宏基因组和宏转录组种水平功能组成分析 简介 热心肠日报导读 摘要 主要图表 图1. HUMAnN2分层式搜索在同类软件中准确率最高 图2. 人类核心微生物组的贡献多样性 图 ...

  6. Excel VBA(宏):添加宏

    写在前面:1.编写宏,打开VBA,双击ThisWorkbook对当前工作薄进行编写宏:双击Sheet1,对整个sheet编写宏: 或者创建模块,在模块里,编写.调试代码. 打开VBA的方法见第一讲,结 ...

  7. java supplier_现代化的 Java (二十一)——宏和生成宏

    一般来说,我们会避免在应用项目中编写宏,无论是 c 那种比较简单的宏,还是rust 那种约束明确的,或者 Lisp 那种功能比较完善的宏机制.这主要是因为宏写起来比较困难,容易写错.项目开发通常来说有 ...

  8. 宏文件下载_EPLAN~宏资源获取

    EPLAN画图最重要的就是宏,窗口宏,集值宏,3D宏等等,画图的过程就是不断的插入宏,插入符号.但是这个宏我们最开始画的时候是很麻烦很费时的,而且往往画的也比较简单,显得不那么专业: 小编不止一次说过 ...

  9. 土壤微生物组——从宏基因组学到宏表型组学

    本文转载自"微生态笔记",己获授权. 摘要 土壤微生物主导着包括植物生长和碳等元素循环在内的各种重要过程.但是大部分土壤微生物目前还不能分离培养,它们的功能还处在未知状态.尽管现在 ...

最新文章

  1. 蚂蚁金服开源增强版 Spring Boot 的研发框架!
  2. 升级vue-cli为 cli3 并创建项目
  3. 阿里云企业邮箱收费吗
  4. mysql jdbc url设置时区
  5. mysql导出单表数据
  6. BZOJ - 2186 欧拉函数
  7. SortedDictionaryTKey,TValue正序与反序排序及Dicttionary相关
  8. wordcount linux java_linux下在eclipse上运行hadoop自带例子wordcount
  9. 知方可补不足~sqlserver中使用sp_who查看sql的进程
  10. Linux系统下的权限详解-1
  11. 移动硬盘WINPE启动盘安装方法图解
  12. UINavigation​Controller 的详解(基于 API )
  13. C盘文件分析(如何减小C盘容量)
  14. 基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图
  15. Java8的其它 新特性(笔记二十四)
  16. 把kali linux 装进 U盘并实现数据可存储
  17. 谷歌学术的搜索原理_谷歌搜索引擎产品的工作原理研究
  18. 在python中设置静态变量
  19. 前端json格式的介绍,转换以及解析
  20. Oracle从零开始-关系型数据库介绍

热门文章

  1. MCE | ATM 激酶活化变单体后的神奇开挂!
  2. Mac安装oh-my-zsh网络错误curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to raw.github解决方案
  3. Android bluetooth介绍(二): android 蓝牙代码架构及其uart 到rfcomm流程
  4. 基于图像的三维重建——P3P求解相机位姿(5)
  5. MongoDB 聚合管道
  6. 三星的OLED面板市占率首次跌穿七成,中国面板市占首破两成
  7. 计算机毕业设计ssm免费音乐分享平台
  8. textmate快捷键 汇总
  9. SciencePub学术 | 计算机工程类重点SCIEI征稿中
  10. JZ2440:busybox构建根文件系统