当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

C++宏跟函数及常量基础学习

    当你调用一个过程既被声明成函数又被声明成宏时,你可以用如下两种方法来强制编译器使用函数或宏(编译器默认会使用宏)。

    1、使用强制类型转换

    #include <ctype.h>

    a = toupper(a);                             //使用宏

    a = (toupper)(a);                           //使用函数,因为toupper被强制转换成函数指针。

    2、使用#undef

    #include <ctype.h>

    #undef toupper                                   //注意这里是小写,以后调用过程toupper都为函数调用,因为宏定义已被//取消。

    那么,我们应该怎样来选择在一个程序中使用宏还是使用函数调用呢?

    1、时间VS 大小

    使用宏时,因为宏被就地展开,因此,用宏编译出来的代码会比用函数编译出来的代码大。但宏展开后没有了函数的参数传递,所以运行起来比函数要快。

    使用函数时因函数只是被多次执行,因此代码小,但函数调用时增加了开销。

    2、函数可以通过函数指针来调用,而宏则不行。

    如:

    int AddOne(int a) {++a};         //定义一个函数

    int (*plusOne)(int a);                //定义一个函数指针

    pluseOne = Addone;                 //初始化函数指针

    (*pluseOne)(2);                        //通过函数指针调用函数

    3、在多任务并发执行的应用程序中,使用函数时需考虑函数的重入问题。宏因为就地展开,因此,不用考虑重入问题。

    4、使用宏时,要注意宏的参数有可能出错。

    a)         宏定义不当出错

    如:

    宏定义

    #define F (x) (x+1)

    现在假如有一个如下所示的宏调用:

    F(1)

    预处理器展开它,出现下面不希望的情况:

    (x) (x+1) (1)

    出现这个问题是因为在宏定义中F和括号之间存在空格,当这个空格取消后,调用宏时可以有空格空隙,像下面的调用:

    F (1)

    依然可以正确地展开为:

    (1+1)

    b)        当宏传递参数时出错

    如:优先级不同出错

    #define FLOOR(x,b) x>=b ? 0:1

    现在假如用表达式作参数:

    if(FLOOR(a&0x0f,0x07))

    宏将展开成:

    if(a&0x0f>=0x07 ? 0 : 1)

    因为&的优先级比>=的低,所以宏的展开结果将会使我们惊讶。一旦发现这个问题,可以通过在宏定义内的各个地方使用括弧来解决,(这是创建预处理器宏时使用的好方法。)上面的定义可改写成如下:

    #define FLOOR(x,b)   ((x)>=(b) ? 0 : 1)

    c)        当一个宏多次使用参数时出错

    如:

    #define toupper(c)    ((islower(c)) ? _toupper(c) : (c))

    #include <ctype.h>

    int a = ‘m’;

    a = toupper(a++);

    程序运行后,a的值会加2;

    上面的程序被编译器展开后:

    int a = ‘m’;

    a = islower(a++) ? _toupper(a++) : (a++);

    由此可见,变量a被增加了两次。

    5、类型检查

    当定义为函数时,编译器会检查函数的参数,但定义为宏时,编译器只检查参数的个数。

    6、使用内联函数(C++或支技内联函数的编译器中)

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接