条件编译

一、概述

一般情况下,C语言源程序中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译。此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译(conditional compile)。


二、功能

1.方便程序的移植

      预处理程序提供了条件编译的功能。条件编译允许只编译源文件中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销,并提高程序的效率,可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植是很有用的。

      另外,条件编译是为了让程序在各种不同的软硬件环境下都可以运行。即,提高了程序的可移植性和灵活性。例如一个商业性的软件,用户可能在不同的操作系统、处理器下运行,可能会导致同一段程序代码在不同用户的电脑上产生不同的运行效果(有的流畅、有的卡顿、有的甚至无法运行)。解决这类问题可以有两种方法:①针对不同环境编写不同的代码。②同一段代码,针对不同的环境,预编译成不同的代码,从而使得生成的程序最大程度上适应用户的软硬件环境。显然第②种方法更为简便。


2.方便程序的调试

       在调试程序时,往往不需要编译所有的代码段而是部分。

例如在算法竞赛比赛中,评判机一般都是标准输入输出,而在自我测试时一般采用文件重定向简化过程。但是许多选手容易忘记注释掉重定向语句导致评判错误。这时候如果将重定向语句加上条件编译指令则会在提交到比赛时自动“删除”重定向语句。


三、条件编译格式

1.if格式

#if 表达式
     语句序列①
[#else
     语句序列②]
#endif

功能:当表达式为真时,编译语句序列①,否则编译语句序列②。其中,#else和语句序列②可有可无。


2.ifdef格式

#ifdef 标识符
     语句序列①
[#else
     语句序列②]
#endif

功能:当标识符已被定义时(用#define定义),编译语句序列①,否则编译语句序列②。其中#else和语句序列②可有可无。


3.ifndef格式

#ifndef     标识符
     语句序列①
[#else
     语句序列②]
#endif

功能:与ifdef相反

四、条件编译排版

条件编译语句排版时,需考虑以下三种位置:
 

(1)条件编译语句块与函数定义体之间不存在相互嵌套(主要在(.h)文件中)
 

  ◆ 条件编译关键字语句顶格左对齐;
 

  ◆ 所含的#include语句(块) #define语句(块)甚至是被嵌套下级条件编译语句块,按照语句块嵌套的排版方式进行缩进排版 。
 
 
(2)条件编译语句块嵌套在函数体之外(主要在(.c)文件中)
 

  这种情况下,条件编译语句块不影响函数体
 

  ◆ 条件编译关键字语句顶格左对齐;
 

  ◆ 所含的函数体定义无需缩进,依旧按照单个函数体定义的排版方式进行。
 
 
(3)条件编译语句嵌套在函数体内 (主要在(.c)文件中)
 

  a)当条件编译语句块与被包语句所属的语句块之间没有逻辑路径交叉时,以下两种方式均可
 

  ◆ 按照语句块嵌套方式进行缩进排版 (推荐);
 

  ◆ 条件编译语句不影响原先语句块排版,条件编译语句与所包含的关键字语句块左对齐 。
 

  b)当条件编译语句块与被包语句所属的语句块之间存在逻辑路径交叉时
 
 

  ◆ 条件编译语句顶格左对齐,其它语句按照正常顺序排版。


五、代码示例(ifdef格式为例)

#define LOCAL
#include<bits/stdc++.h>
using namespace std;

int main()
{
    #ifdef LOCAL
        cout<<"1"<<endl;
    #endif // LOCAL
        cout<<"2"<<endl;
    return 0;
}


注释标识符之后

//#define LOCAL
#include<bits/stdc++.h>
using namespace std;

int main()
{
    #ifdef LOCAL
        cout<<"1"<<endl;
    #endif // LOCAL
        cout<<"2"<<endl;
    return 0;
}



一个更好的方法是在编译选项里而不是程序里定义这个LOCAL符号,这样,如果是在进行算法比赛时,提交之前不需要修改程序(注释重定向语句),降低了出错的可能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值