C/C++条件编译

来源:互联网 发布:剑灵免费捏脸数据图 编辑:程序博客网 时间:2024/06/11 11:52

前言

一般的C/C++程序运行会经历如下编译过程:C/C++源代码-->编译预处理-->汇编-->链接-->可执行文件

一般情况下,C/C++源程序中的所有行都参与编译。但是有时候希望程序中的部分代码块,需要在满足一定条件时才有效,即才能进行编译,对这一部分的内容选择性编译的条件,我们称为“条件编译”。


常见的指令含义

#             空指令  无任何效果

#include  头文件包含指令,指定一个源代码头文件(或是库文件)

#define    定义宏

#undef     取消已经定义的宏

#if            如果条件是真,则编译下面代码,如#if true

#else       如果前面的#if给定条件为true,则不编译#else下面的代码;如果#if为false,则编译#else下的代码

#elif         如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,其实就是else if的缩写

#ifdef       如果宏已经定义,则编译下面代码

#ifndef     如果宏没有定义,则编译下面代码

#endif      结束#if...#else..或者#ifdef/#ifndef的条件编译块

#error      停止编译并显示错误信息


条件编译形式

(1)形式一

#ifdef <标识符>
            程序段1

#else
            程序段2
#endif


作用:若指定的<标识符>已经在#define命令中定义过,则在程序编译阶段编译程序段1,否则编译程序段2

如有需要,上述格式还可以省略else分支,直接写成

#ifdef <标识符>
            程序段1

#endif


(2)形式二

#ifndef  <标识符>
             程序段1
#else
             程序段2
#endif

作用:(与形式一相反)若指定的<标识符>已经在#define命令中没有定义过,则在程序编译阶段编译程序段1,否则编译程序


(3)形式三

#if    <常量表达式1>
           程序段1

#elif  <常量表达式2>

           程序段2

 ...

 ...

#elif  <常量表达式n>
           
程序段n

#else
         程序段n+1
#endif


作用:依次计算常量表达式的值,当为逻辑真时,则用相应的程序段参与编译;如果全部常量表达式的值都为逻辑假,则用else后的程序段参与编译。


条件编译扩展应用

1.在程序调试时,经常需要在源程序中插入一些程序调试语句(主要是一些条件判断语句和输出语句)。

这些语句是为了帮助程序调试而插入的,在调试完成后还需要逐一删除。如果用手工删除就显得比较麻烦,而且容易出错。这时,可以用条件编译命令来实现自动处理,其代码如下:
        #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之间的调试用程序段将不再参与编译。

    
2.在头文件“assert.h”中定义的宏assert可用来测试表达式的值。

如果表达式的值为0,则assert就输出错误报告,并调用通过函数库stdlib.h中的函数abort终止程序的执行。


assert是一个十分有用的调试工具,可用于测试一个变量是否具有某个正确的值。例如,假定程序中的变量应该大于10,那么可用assert测试x的值,并在x的值不正确时输出错误报告。所用的语句为:
        assert( x <=10 );


在遇到这条语句时,如果x大于10,那么就会打印出包含行号和文件名的错误报告并终止该程序的执行。这样,程序员就可以把查错的重点放在相关代码上。


如果定义了符号常量NDEBUG,其后的assert将被忽略。因此,如果不再需要assert时,可把代码行:
        #define NDEBUG
插入源程序中。而无需手工删除assert。


原创粉丝点击