C语言之编译预处理

  • Post author:
  • Post category:其他


编译预处理是指在c编译程序对c源程序进行编译之前,对预处理命令进行“预先“处理的过程。编译预处理是通过编译预处理程序实现的。

预处理命令不是c语言的组成部分,c语言的编译程序无法识别他们。

比如#include<stdio.h>就是一个预处理命令,其功能是在将源程序编译成目标程序之前,将文件“stdio.h“中的内容替换该命令,然后由编译程序将源程序翻译成目标程序。

C语言中的预编译处理命令主要有以下3种:宏定义、文件包含、条件编译

为了与一般的c语句相区分,编译预处理命令必须以#为首字符、尾部不能加分号结尾(c语句必须加分号),一行只能写一条编译预处理命令。

宏定义

不带参数的宏定义

#define 宏名 字符串

功能:在编译预处理的时候,将程序种该命令后所有与宏名相关的文本用字符串置换。

使用宏定义,可以用一个简单的名字(宏名)来代替一个较长的字符串,以增加程序的可读性。

在编译预处理时将宏名替换成字符串的过程称为“宏展开“。

以下时关于宏定义和宏展开的说明:

  1. 宏名一般习惯用大写字母表示,以便与一般变量相区分。但是这并非规定,也可以用小写字母。
  2. 一个宏名只能被定义一次,否则会出错,被认为是重复定义。
  3. 在进行宏定义时,可以引用已定义的宏名,可以层层替换
  4. 对在字符串常量以及用户标识符中,与宏名相同的部分不做替换。
  5. 宏定义的作用域:从定义开始到程序结束
  6. 若宏定义在一行中写不下时,换行时,需要在行尾加上字符\

带参数的宏定义

#define 宏名(形参表) 字符串

形参表中的不同形参之间用逗号隔开,字符串中包含形参表中的参数。

在编译预处理时,将程序中该命令后所有与宏名相关的文本用字符串替换,但是替换时字符串中的形参要用相应的实参替换。

带参数的宏与函数形式相似但是本质不同。区别如下:

  1. 函数调用时先求实参表达式的值,然后传给形参。而使用带参数的宏只是进行简单的字符替换。
  2. 函数调用实在程序运行时处理的,分配临时内存单元。而宏展开则是在预处理时(编译之前)进行的,在展开时并不分配内存单元。
  3. 在使用带参数的宏时,要注意括号的使用。

在程序设计时,经常把那些反复使用的运算表达式定义为带参数的宏。

定义带参数的宏时,对形参的数量没有限制。但是一般情况下以不超过3个为宜。

终止宏定义

#undef 宏名

文件包含

文件包含预处理命令有以下两种格式:

#include”文件名”

#include<文件名>

功能:在编译预处理时,把命令中指定的文件内容复制到该命令处,使得指定文件de额内容成为当前源文件的一部分。

执行第一种格式的命令的时候,需要现在当前目录中查找,如果没有找到再到系统指定的标准目录下去查找(通常在#include目录下)

执行第二种格式的命令时,则只到系统指定的标准命令下查找。

一般来说,如果为调用库函数而用#include命令来包含相关的头文件,则用尖括号,以节省查找时间。如果要保护的是用户自己编写的文件(这种文件一般在当前目录中),一般使用双引号。若文件不在当前目录中,则可以在双引号内给出文件路径。

在程序设计时,可以把一批常用的符号常量、函数说明、宏定义以及某些有用的数据类型说明和类型定义,组织在一个独立的文件中,在程序需要使用这些信息的时候,可以用#include命令把他们包含到所需要的位置上面去。

在使用#include命令时还需要注意以下2点:

  1. 每个#include命令只能包含一个文件。
  2. 文件包含嵌套,即包含一个被包含的源文件可以包含另一个源文件

条件编译

一般情况下,源程序的所有行都要参加编译.

条件编译:当条件成立时去编译一组语句,而当条件不成立时编译另一组语句.

条件编译命令有3种形式:

1,#ifdef标识符

程序段1

#else

程序段2

#endif

功能:当指定的标识符在此之前已经被#define语句定义过时,程序段1就被编译,否则,程序段2被编译.其中#else的内容可以被省略.

比如,在调试程序的时候经常需要输出一些信息,一旦调试结束,这些信息也就不再需要了.

2,#ifndef标识符

程序段1

#else

程序段2

#endif

功能:当指定的标识符在此之前,没有被#define语句定义过,程序段1就被编译,否则程序段2被编译.

3,#if表达式

程序段1

#else

程序段2

#endif

功能:如果指定的表达式的值为真(非0)则编译程序段1,否则编译程序段2.



版权声明:本文为qq_51196701原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。