C++ 条件编译

来源:互联网 发布:猪八戒淘宝刷流量 编辑:程序博客网 时间:2024/05/17 23:07

7.3   条件编译命令

    在一般情况下,源程序的所有程序行都会参加编译,以生成目标代码。但在某些特殊情况下,也许只希望对部分满足条件的程序行进行编译,这就是条件编译。
    程序员可在调试程序中增加一些调试语句,以达到跟踪的目的。当程序调试好后,再利用条件编译重新编译,使调试语句不参与编译,以生成高效的代码。
    常用的条件编译命令有如下三种格式:
    1.格式一
        #ifdef <标识符>
            程序段1
        #else
            程序段2
        #endif
    其中,ifdef、else和endif都是关键字。<程序段1>和<程序段2>由若干条预处理命令或C++语句组成。该条件编译命令的功能是:如果在程序中定义了指定的<标识符>时,就用<程序段1>参与编译;否则,用<程序段2>参与编译。
    如果在该格式中省略else分支,也可直接写为如下形式:
        #ifdef <标识符>
            程序段
        #endif
   
 2.格式二
        #ifndef <标识符>
            程序段1
        #else
            程序段2
        #endif
    或者
        #ifndef <标识符>
            程序段
        #endif
    其中,ifndef、else和endif都是关键字。该条件编译命令的功能是:如果在程序中末定义<标识符>时,就用<程序段1>参与编译;否则,用<程序段2>参与编译。
    3.格式三
        #if <常量表达式1>
            程序段1
        #elif <常量表达式2>
            程序段2
        ……
        ……
        #elif <常量表达式n>
            程序段n
        #else
            程序段n+1
        #endif
    其中,if、elif、else和endif都是关键字。该条件编译命令的功能是:依次计算常量表达式的值,当为逻辑真时,则用相应的程序段参与编译;如果全部常量表达式的值都为逻辑假,则用else后的程序段参与编译。
     Visual C++还提供一种类似于函数的运算符defined(),它的格式如下:
        defined( <标识符> )
    其功能是:当<标识符>已被定义且没有被取消时,其表达式的值为非0;当<标识符>末定义或已被取消时,其表达式的值为0。它经常被用来判断某个标识符是否已宏定义。
    条件编译在程序设计中具有十分广泛的应用。例如,在程序调试时,经常需要在源程序中插入一些程序调试语句(主要是一些条件判断语句和输出语句)。这些语句是为了帮助程序调试而插入的,在调试完成后还需要逐一删除。如果用手工删除就显得比较麻烦,而且容易出错。这时,可以用条件编译命令来实现自动处理,其代码如下:
        #define DEBUG 1 
        ……
        ……
        #if DEBUG
        cout << "OK!"<<endl;
        #endif
        ……
        ……
        #if DEBUG
        if (x<0)
        cout << "Error : x < 0 "<<endl;
        #endif
        ……
        ……
    在该例中,#if和#endif之间的程序段是专门用于程序调试的。当程序调试完成后,应取消这些语句。这时,可将DEBUG的宏定义改为:
        #define DEBUG 0
    则在重新编译时,由于表达式为逻辑假,因此原#if和#endif之间的调试用程序段将不再参与编译。

    
    在头文件“assert.h”中定义的宏assert可用来测试表达式的值。如果表达式的值为0,则assert就输出错误报告,并调用通过函数库stdlib.h中的函数abort终止程序的执行。
     assert是一个十分有用的调试工具,可用于测试一个变量是否具有某个正确的值。例如,假定程序中的变量应该大于10,那么可用assert测试x的值,并在x的值不正确时输出错误报告。所用的语句为:
        assert( x <=10 );
    在遇到这条语句时,如果x大于10,那么就会打印出包含行号和文件名的错误报告并终止该程序的执行。这样,程序员就可以把查错的重点放在相关代码上。
    如果定义了符号常量NDEBUG,其后的assert将被忽略。因此,如果不再需要assert时,可把代码行:
        #define NDEBUG
插入源程序中。而无需手工删除assert。
    例如,在申请动态内存时。。。。。
        assert assert