不能忽视宏定义中的空格,宏并不是函数,宏并不是语句,宏并不是类型定义——《C陷阱与缺陷》
首先看一段程序,然后会比较容易理解本文意图:
#include <iostream>
using namespace std;
#define max(a,b) ((a) > (b) ? (a) : (b))//宏定义中各个参数与整个结果表达式都要用括号括起来;一个操作数若在两处被用到,就会被求值两次!!!
int main()
{
int p = 2,q = 4;
cout << max(p++,q++) << endl;
cout << p << "," << q << endl;//p=3,q=6.q++运行了两次:第一次在问号左部分,第二次在问号右部分;
return 0;
}
输出结果为p=3,q= 6;而本意是想求出p,q后其各自加1,即p=3,q= 5。
但是如果不是用宏定义,而是直接在程序中定义了这样的函数:
int max(int a,int b)
{
int max = a > b ? a : b;
return max;
}
则符合本意。这姑且算是宏定义的一个缺陷吧。
另一个缺陷是宏展开后可能产生非常庞大的表达式,占用的空间远远超过了编程者所期望的空间。如下面的宏定义:
#define max(a,b) ((a) > (b) ? (a) : (b))当时用它来求解四个数的最大值时候,显而易见的写法为:
max(a,max(b,max(c,d)))
显然,此式子展开后很长!
此外,在C++增加了内联函数inline,实现起来比带参数的宏更方便,宏在C++中已经很少使用;
而且,定义常量时,在C++程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
下面引用的http://www.hamguy.info/?p=45的讨论:
优点:
1. 提高了程序的可读性,同时也方便进行修改;
2. 提高程序的运行效率:使用带参的宏定义既可完成函数调用的功能,又能避免函数的出栈与入栈操作,减少系统开销,提高运行效率;
3.宏是由预处理器处理的,通过字符串操作可以完成很多编译器无法实现的功能。比如##连接符。
缺点:
1. 由于是直接嵌入的,所以代码可能相对多一点;
2. 嵌套定义过多可能会影响程序的可读性,而且很容易出错;
3. 对带参的宏而言,由于是直接替换,并不会检查参数是否合法,存在安全隐患。

宏定义在C语言中使用时存在一些缺点,例如空格处理不当可能导致意料之外的结果,宏展开可能产生庞大的表达式占用额外空间。随着C++的内联函数和const常量的引入,宏在C++中的使用逐渐减少。宏定义虽然能提高程序可读性和运行效率,但其不检查参数合法性、嵌套过多影响可读性等问题不容忽视。
3823

被折叠的 条评论
为什么被折叠?



