今年7月初,我作为课程设计的一名负责人,领导了一个连我在内4人的开发团队,开发了一个简易的“航班订票系统”。我定义了所需的数据结构,包括这样一个struct:
typedef struct _passenger |
这之后每每要新建结点的时候,都得这么写:
PPASSENGER p = (PPASSENGER)malloc( sizeof( PASSENGER ) ); |
这一长串的代码使我厌烦,我便灵机一动,借用了C++之中operator new的形式,在我的头文件中写下了如下的一个宏:
#define NEW( type, count ) (type *)malloc( sizeof( type ) * count ) |
于是,我新建结点的代码便成了:
PPASSENGER p = NEW( PASSENGER, 1 ); |
足足少用了20个字符,我极为得意,自认为这是我十年来写下的最有创意的代码之一。
也许有的朋友不以为意,认为这算不了什么。那么请听我算上一笔帐吧:假如我是一个程序员,打字速度是1ch/s(当然慢得过分了,好在是假设),而我的身价奇高,挣钱速度是1RMB/s。以此计算,如果我在我的程序中需要写10行新建结点的代码,那么这个宏将为我节省20 * 10 - 75 = 125 (s)的时间(注:所谓75s,为加上NEW宏中换行符之后的回车符之故)。换算成人民币,就是125元。
正是以上的这件小事,成为了我这《随想》的缘起。
C++之父Bjarne Stroustrup曾经说过,绝不应该去使用宏,除非你不得不这样做。是的,自C诞生以来,宏便承载了太多的大是与大非——很多精巧的设计来自于令人拍案叫绝的宏,比如微软MFC类库中的消息映射;很多难以察觉的错误亦是来自于斯,比如这个老掉牙的例子:
#define macro( a, b ) a * b |
C++之中倒是为宏设计了替代品:const常量、inline函数与模板。比如以下的宏:
#define NULL 0 |
在C++中就可以用以下的代码代替:
const int NULL = 0; |
另外,还有宏函数:
#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) |
也可以由inline模板函数代替:
template < typename T > inline max( const T& a, const T& b ) |
如此说来,宏倒大有被取代之势了。
不过,宏所能给我带来的那125元的收益,却是const、inline和template不能取代的。