Chinaunix首页 | 论坛 | 博客
  • 博客访问: 74208
  • 博文数量: 21
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 241
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-07 14:05
文章分类

全部博文(21)

文章存档

2011年(1)

2008年(20)

我的朋友

分类:

2008-03-13 21:29:45

    #define宏定义指令
 
  宏是可被替换的预处理记号的名字。有效的预处理记号包括有效的C++语言记号, 如标识符、字符串、数字、运算符、预处理指令、头文件名和任何单一的字符等。例如:
    #define MAXLINES 500
    使文本“500”(无引号)与符号MAXLINES相关联。
    预处理器保存着一个由#define指令产生的所有符号的表和相应的替换文本,无论何时当预处理器在注释和带引号的字符串以外遇到符号MAXLINES时,将用“500”代替它。 需要注意的时,这只是文本替换,在编译后期的阶段它将在编译器中出现, 好像实际输入“500”来替代MAXLINES一样。在预处理期间没有语义分析。
  宏定义一般可分为两种:无参数宏和带参数宏。
 
  1.无参数宏
 
  无参数宏就像上面的MAXLINES,有时被称为类对象宏(object-like macros),因为它通常用于定义一个类似于对象的程序常数。
  无参数宏在C中用得很多, 但在C++中很少有必要使用它,应该用const代替。
  例如语句:
        const int MAXLINES = 500;
  比下边的宏定义有很多优越性:
        #define MAXLINES 500
  使用const修饰符,由于编译器知道对象的语义,可以进行编译期的类型检查,也可以用符号调试器来检查const对象,const定义提供了更好的安全性。
 
  2.带参数宏
 
  带参数宏也称作类函数宏(function-like macros),因为使用的时候看起来很像函数。可以定义带有零个或更多个参数的带参数宏,如:
    #define abs(x) ( (x) >=0 ? (x) : ((-x)) )
   abs和(之前不能有空格,否则会产生展开错误.
  
    在替换文本中应该把宏参数用括号括起来,以避免由复杂的参数表达式所引起的优先权问题。
  例如,如果简单地用数学表达式定义一个宏:
        #define abs(x) x >= 0 ? x : -x
  则展开表达式 abs(a-1) 会得到如下结果:
        a-1 >= 0 ? a-1 : -a-1
   
    即使我们这样定义宏:
        #define abs(x) ( (x) >=0 ? (x) : ((-x)) )
  一般的应用看起来不会出问题,但宏调用 abs(i++) 展开后为:
        ( (i++) >=0 ? (i++) : (-(i++)) )
  无论 i 是什么值,自增操作都将进行两次,这并不是我们所希望的。

  类函数宏在C++中几乎是没有必要的, 可以使用内联函数替换绝大多数的类函数宏。例如,可以使用下边的函数替代上面的 max 宏:
    inline int max( int x, int y )
    {
      return x >= y ? x : y;
    }
  这是一个真正的有作用域和类型检查的函数,不必加括号来避免优先权的争议,也无须担心像使用宏那样有其他影响,如以下调用:
    max(x++, y++);
  也许你会说宏的形式具有能接受任何类型参数的优势, 其实C++的函数模板同样可以解决这一问题:
    template
    inline T max( T x, T, y)
    {
        return x >= y ? x : y;
    }
 
    宏定义不是可执行的语句,无需以 ; 分号结束,额外的分号会导致出错。
阅读(986) | 评论(0) | 转发(0) |
0

上一篇:条件编译

下一篇:# ## defined 预处理运算符

给主人留下些什么吧!~~