C++预处理实用经验

文章内容均整理自    刘光《C++程序员不可不知的101条实用经验》

1.使用#define定义字面值和伪函数
①简单的宏定义形式为: #define <宏名> <字符串>
注意:
(1)在程序中,如果#define出现在函数外面,宏的有效范围为宏定义之后到本源文件结束。 用#undef可以终止宏定义的作用域
(2)在进行宏定义时,可以用已经定义的宏名,可层层替换,但对于用引号引起来的字符串内的字符,即使与宏名相同,也不进行替换。
(3)宏定义是专门用于预处理的专用名词,它与定义变量的含义不同,只做字符替换,不分配内存空间
const与#define的区别:
(1)const定义的常量有数据类型,而#define定义的常量无数据类型
(2)有些调式程序可以对const进行调试,但无法对#define进行调试
(3)当定义局部变量是,const变量作用域同普通局部变量,而#define是从定义点到整个程序结束,也可使用#undef限定作用范围
②带参数的宏定义形式为:#define <宏名>(<参数表>) <宏体>
带参数的宏与函数的区别:
(1)函数调用时,先求实参表达式的值,然后传递给形参,而使用带参数的宏只是进行简单的字符串替换,不进行表达求值
(2)函数调用是在程序运行时处理的,为形参分配临时的内存空间,而宏展开是在编译前进行的,在展开时并不分配内存单元,不进行值的传递,同样也没有返回值的概念
(3)函数的实参可形参都必须定义类型,二者类型还要一致,不一致要进行类型转化。而宏参数是无类型的。
(4)调用函数智慧获得一个返回值,而宏不然,可以设法获得多个返回值
(5)函数调用不会增加代码长度,而宏展开会使程序变长
(6)宏替换不占用运行时间,只占用编译时间。函数调用占用运行时间用于分配单元,保存线程,值传递,返回等。
请谨记:
(1)宏可以定义字面值常量,也可以定义带参数的伪函数
(2)应用时如果要定义一个字面值常量建议用const替换#define
(3) 宏定义不受名字空间的限制,在名字空间外依然可见

2.#define的使用陷阱
①由操作符优先级引起的问题
②使用宏定义,不允许参数发生变化
③使用do{}while(false);将宏定义包含的多条表达式放到大括号里
④关于变参宏的使用,注意宏替换后多出的逗号
⑤消除多余的分号,即定义宏语句时最后一个分号不要加

3.防止重复包含头文件
①#ifndef  #define  #endif方式
②#pragma once方式
两种方式的区别:
(1)#ifndef方式依赖于宏名不能冲突,这不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被同时包含。缺点就是如果不同头文件的宏名一样话编译器会找不到声明。
(2)#pargma once保证同一个文件不会被包含多次,则不需要想宏名。缺点是如果某个头文件有多分拷贝,则该方法不能保证他们不会被重复包含

4.assert的副作用
assert的作用:计算表达式,若其值为假,先向stderr打印一条出错信息,然后通过调用abort来终止程序运行
好的做法:
(1)每个assert值检验一个条件
(2)不能使用改变环境的语句,如assert(i++ < 100),如果在执行前i=100,则i++就不会被执行

5.关于#和##的讨论
①#,参数名字符串。只能用于有传入参数的宏定义中,且必须置于宏定义体的参数名前
如#define exp(input) #input,调用时string s = exp(hello),展开成string s = "hello";
注意:
(1)会忽略传入参数名前后的空格,如str=exp( hello );将会展开成str = "hello"
(2)若传入参数中有空格,编译器会自动连接各个子字符串,每个字符串中由一个空格隔开,如str = exp(  hello  c++  ),将会展开成str = "hello c++";
②#@,字符化操作符,其同样只能用于有传入函数的宏定义中,且必须置于宏定义体中的参数名前,作用为将传入的单字符参数转换成字符,以一对单引号引起来
如#define exp(input) #@input,调用时string s = exp(a),展开成 string s = 'a';
③##,符号链接操作符。只能用于有传入参数的宏定义中,作用是将宏定义的多个形参扩展成一个实际参数名
如#define exp(input) num##input,调用int num = exp(9);展开成int num = num9;
注意:
(1)单用##连接形参时,##前后的空格可有可无
(2)连接后的实际参数名必须为实际存在的参数名或是编译器已知的宏定义















猜你喜欢

转载自blog.csdn.net/sinat_39061823/article/details/80569330