C++中的宏
来源:互联网 发布:走好网络群众路线 编辑:程序博客网 时间:2024/06/07 23:20
宏
宏在C语言里非常重要,而在C++里则很少应用。关于宏的首要规则是:除非极其必要,否则不应该去使用宏。几乎每个宏都代表了程序设计语言里,或者程序里,或者程序员的一个缺陷,因为它将在编译器看到程序的正文之前重新修改这些正文(即宏的替换)。宏也是许多程序设计工具的主要麻烦。所以,如果你使用了宏,你就应该准备着只能从各种工具(如排错系统、交叉引用工具、轮廓程序等)得到较少的服务。如果你必须使用宏,请仔细阅读你所用的C++预处理器实现的手册。还要警告读者 ,应该按照习惯,在为宏命名时尽量使用大写字母。
简单的宏定义就像下面这样:
#define NAME rest of line当NAME作为一个单词被遇到时,它就会被字符序列rest of line取代。
例如,
named = NAME将被展开为
named = rest of line
也可以定义带参数的宏,例如,
#define MAC(x, y) argument1 : x argument2 : y在使用MAC时必须提供两个字符串,它们将在MAC()被展开时用于取代x和y,例如,
expanded = MAC(foo bar, yuk yuk)将展开成
expanded = arugment1 : foo bar argument2 : yuk yuk宏名字不能重载,而且宏预处理器不能处理递归调用:
#define PRINT(a, b) cout << a << b #define PRINT(a, b, c) cout << a << b << c // 错误:不允许重载,编译器会提示重复定义#define FAC(n) (n > 1) ? n * FAC(n - 1) : 1 // 错误:递归的宏
宏对字符串进行处理操作,但它对C++的语法知之甚少,根本不知道C++的类型和作用域规则。编译器能看到的只是宏展开后的形式,所以在宏中的错误是在宏被展开之后报告的,而不是在它定义的时候,这可能导致非常难以理解的错误信息。
下面是一些可能有用的宏:
#define CASE break;case#define FOREVER for(; ;)下面是一些完全没有必要的宏:
#define PI 3.14#define BEGIN {#define END }下面是一些很危险的宏:
#define SQUARE(a) a * a#define INCR_xx (xx)++想知道它们为什么危险,请试着展开这个程序片段:
int xx = 0; // 全局计数器void f() { int xx = 0; // 局部变量 int y = SQUARE(xx + 2); // y = xx + 2 * xx + 2,即y = xx + (2 * xx) + 2 INCR_xx; // 增加局部的xx}如果你要使用宏,在引用全局名字时一定要使用作用域解析运算符::,并在所有可能的地方将出现的宏参数都用括号围起来。例如,
#define MIN(a, b) (((a) < (b)) ? (a) : (b))通过利用宏,你可以设计出自己的私有语言。即使与C++相比你更偏爱自己的这种“增强的语言”,但对于大部分C++程序员而言,它也是不可理解的。进一步说,C预处理器是一种很简单的宏处理器。当你试图去做某些不那么简单的事情时,你多半会发现不能做好,或者做起来有不必要的困难。const,inline,template,enum和namespace机制等都是为了用作预处理器结构的许多传统使用方式的替代品。
引用书目:Bjarne Stroustrup.贝尔实验室著《The C++ Programming Language》
阅读全文
0 0
- C中的宏定义
- C/C++中的宏
- C语言中的宏
- C中的宏展开
- C语言中的宏
- C中的宏定义
- c/c++中的宏
- C/C++ 中的宏
- c中的宏定义
- c语言中的宏 .
- C/C++中的宏
- C宏定义中的 #,##,#@
- C/C++中的宏
- C中的宏
- C语言中的宏
- c语言中的宏
- C中的宏操作
- C 语言中的宏
- Bug生命周期
- 傅盛认知三部曲之一:所谓成长就是认知升级
- UML9种图(1)
- Spring-JDBC-3
- 几种线程池的实现算法分析
- C++中的宏
- 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)
- HTML基础学习-18- div css容器 盒子模型学习1
- Listview优化
- 母函数总结
- 名字的漂亮度
- Qt槽机制及简单规则
- 【博弈】(一)拿硬币,巴什博奕,一些简单的规律
- Spark<集群搭建Centos7.3+Spark2.1.1>