C语言提供的预处理指令主要有3种:宏定义、文件包含和条件编译等。

C语言提供预处理指令主要有3种:宏定义、文件包含和条件编译等。

C语言提供的预处理指令主要有3种:宏定义、文件包含和条件编译等。

1.宏定义

定义的作用是用宏名来代替一个字符串,宏名由标识符构成,通常采用大写字母来表示。一旦对字符串命名,就可以在源程序中使用宏名,以达到简化程序书写的目的。C编译系统在编译之前会将标识符替换成字符串。

定义有两种:不带参数的宏和带参数的宏。

(1)不带参数的宏

 不带参数的宏定义形式:#define 宏名 字符串

 

define是关键字,表示宏定义。

宏名必须符合标识符的定义,为了区别于变量,宏名一般采用大写字母,如:#define PI 3.14159。

宏的作用:在程序中的任何地方都可以直接使用宏名,编译器会先将程序中的宏名用字符串替换,然后再进行编译。这个过程叫宏替换,宏替换不进行语法检查。

宏名的有效范围是从定义命令之后,直到源程序文件结束,或遇到宏定义终止命令#undef为止。

【例6-12】阅读以下程序,了解不带参数的宏的作用。

#include <stdio.h>

#define TEST "This is a test!"

int main()

{

printf(TEST);

printf("\n");

printf("TEST");

#undef TEST

return 0;

}

程序运行结果:

This is a test!

TEST

编译系统遇到TEST时,就用” This is a test!”替换,但是如果是字符串中包含宏名则不会进行替换。#undef命令可以用来终止宏定义的作用域。

(2)带参数的宏

带参数的宏定义形式:#define 宏名(参数表) 字符串

 

字符串应包含有参数表中的参数。

宏替换时,是将字符串中的参数用实参表中的参数进行替换。

【例6-13】阅读以下程序,了解不带参数的宏的作用。

#include <stdio.h>

#define F(a) a*b

int main()

{

int x=4,y=5;

int b,z;

b=(x-y);

z=F(x+y);

printf("b=%d\nF(x+y)=%d\n",b,z);

return 0;

}

程序运行结果:

b=-1

F(x+y)=-1

这个程序的结果可能并不是我们想要得到的,因为z=F(x+y)这个语句在编译之前会被替换成z=x+y*b;其结果自然就是-1。如果我们希望将z=F(x+y)替换成z=(x+y)*b,那么我们之前宏定义要改写成:#define F(a) (a)*b,这样就可以避免二义性。

2.文件包含

在一个源文件中使用#include指令可以将另一个源文件的全部内容包含进来,也就是将另外的文件包含到本文件之中。在对源文件进行编译之前,用包含文件的内容取代该预处理命令。

文件包含命令的一般形式为:

#include <包含文件名>

#include "包含文件名"

 

(1)include是命令关键字,表示文件包含,一个include命令只能包含一个文件。

(2)<>表示被包含文件在标准目录中。

(3)""表示被包含文件在指定的目录中。如果文件名不带路径,则在当前目录中,若找不到,再到标准目录中寻找。

(4)包含文件名可以是.c源文件或.h头文件。

【例6-14】阅读以下程序,理解文件包含命令的作用。

1.file1.c

int sum(int a,int b) 

{

           return a+b;

}

2.file2.c

        int dif(int x,int y) 

{

           return x-y;

}

3.example6-14.c

#include <stdio.h>

#include “file1.c”

#include “file2.c”

int main(){

int result;

result=sum(9,5)*dif(9,5);

printf(“result=%d\n”,result);

return 0;

}

程序运行结果:

result=56

3.条件编译

一般情况下,源程序中所有的行都参加编译,但是有时希望部分代码行在满足一定条件时才进行编译,这时就需要使用一些条件编译命令。

(1)#if指令,用于判断是否满足给定条件的编译形式。主要包含以下形式:

#if<表达式>

      语句段1

   [#else

语句段2]

#endif

       作用:如果“表达式”的值为真,则编译“语句段1”,否则编译“语句段2”,方括号表示表示可以缺省,不论是否有#else,#endif都是必不可少的。另外一种形式:

#if<表达式1>

      语句段1

   #else if <表达式2>

语句段2

       #else

语句段3

#endif

其作用与if分支语句相似,只要符合嵌套规则就可以,但是这里是条件编译,只有符合条件的代码段才能被编译。

(2)#ifdef和#ifndef指令:用于判断是否有宏定义的条件编译。

#ifdef的一般形式:

   #ifdef 宏名

      语句段

#endif

   如果在此之前已经定义了这样的宏名,则编译语句段。

#ifndef的一般形式

  #ifndef 宏名

      语句段

#endif

   如果在此之前没有定义这样的宏名,则编译语句段。