目录
9.3条件编译
一般情况下,源程序中所有行都参加编译。但是有时希望程序中的一部分内容只在满足条件是才进行编译,也就是对这一部分内容指定编译的条件,这就是“条件编译”。有时,希望在满足某条件时,对某一组语句进行编译,而党条件不满足时则编译另一组语句。
条件编译命令有以下几种形式。
第一种
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的作用是若所指定的标识符已经被#define定义过,则程序编译阶段编译程序段1;否则编译程序段2.其中#else部分可以没有。
#ifdef 标识符
程序段1
#else
程序段2
这里的“程序段”可以是语句组,也可以是命令行。这种条件编译对于提高C源程序的通用性是很有好处的。如果一个C源程序在不同计算机系统上运行,而不同计算机又有一定的差异,这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译来处理:
#ifdef COMPUTER_A
#define INTEGER_SIZE 16
#else
#define INTEGER_SIZE 32
#endif
如果在这组条件编译命令之前曾出现以下命令行:
#define COMPUTER_A 0
或将COMPUTER_A定义为任何字符串,甚至是
#define COMPUTER_A
即只要COMPUTER_A已被定义过,则在程序编译时就编译下面的命令行:
#define INTEGER_SIZE 16
否则,就编译下面的命令行:
#define INTEGER_SIZE 32
则预编译后程序中的INTEGER_SIZE都用16代替;否则用32代替。
这样,源程序可以不必做任何修改就可以用于不同类型的计算机系统。当然,以上只是简单介绍其中一种情况,我们可以根据此思路设计出其他编译条件。
例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:
#ifdef DEBUG
printf("x=%d,y=%d,z=%d\n",x,y,z);
#endif
如果它前面有以下命令行:
#ifdef DEBUG
则在程序运行时输出x、y、z的值,以便调试时分析。调试完成后只需要将这个#define命令行删去即可。
第二种
#ifndef 标识符
程序段1
#else
程序段2
#endif
只是第一行与第一种形式不同:将“ifdef”改为“ifndef”。
作用:若标识符未被定义过则编译程序段1;否则编译程序段2。这种形式与第一种形式相反。
以上两种形式的用法差不多,任选一种使用即可。例如,上面调试时输出信息的条件编译段也可以改为:
#ifndef RUN
printf("x=%d,y=%d,z=%d\n",x,y,z);
#endif
如果在此之前未对RUN定义,则输出x、y、z的值。调试完成后,在运行之前,加以下命令行:
#define RUN
则不再输出x、y、z的值。
第三种
#if 表达式
程序段1
#else
程序段2
#endif
作用:当指定的表达式值为真(非零)时就编译程序段1;否则编译程序段2。可以事先给定条件,使程序在不同条件下执行不同功能。
输入一行字母字符,根据需要设置编译条件,使之能将字母全改为大写输出,或全改为小写字母输出。
#include<stdio.h>
#define LETTER 1
int main()
{
char str[20] = "C Language",c;
int i;
i = 0;
while((c=str[i])!='\0')
{
i++;
#if LETTER
if(c>='a'&&c<='z')
{
c = c - 32;
}
#else
if(c>='A'&&c<='Z')
{
c = c + 32;
}
#endif
printf("%c",c);
}
printf("\n");
return 0;
}
//输出:
C LANGUAGE
这里先定义LETTER为1,这样在对条件编译命令进行预处理时,由于LETTER为真(非零),则对第一个if语句进行编译处理,运行时使小写字母变为大写字母。如果将程序第一行改为:
#define LETTER 0
则在预处理时,对第二个if语句进行编译处理,使大写字母改为小写字母,此时运行情况为:
c language
小结:
这些功能,不用条件编译命令,而直接用if语句也能达到要求,那么用条件编译命令有什么好处呢?
的确,对于这个问题完全可以不用条件编译而用if语句处理,但是那样做,目标程序长(因为所有语句都要编译),运行时间长(因为在程序运行时对if语句进行测试)。而采用条件编译,可以减少被编译的语句,从而减少目标程序的长度,减少运行时间。当条件编译段较多时,目标程序长度可以大大减少。以上举例是最简单的情况,只是为了说明怎样使用条件编译,有人会觉得其优越性不太明显,但是如果程序比较复杂而善于实用条件编译,其优越性是比较明显的。
到这里,本章学完啦!
本章主要介绍了预编译功能是C语言特有的,有利于程序的可移植性,增加程序的灵活性。
声明:本文章为个人学习笔记,资料整理参考谭浩强《C程序设计(第三版)》如有错误,欢迎大家指正