C中的预处理器

简介: C中的预处理器

【预处理】

C语言提供了其他高级语言没有的预处理工具。在源代码通过编译器之前,预处理器先对源代码进行处理,他是在称之为预处理器命令行或指令的控制下操作。

预处理指令大致分为三类:宏替换指令、文件包含指令、编译器控制指令

1.宏替换指令

宏替换是程序中的标识符被预定义的字符串取代的过程。在#define语句指令下工作。一般形式是

#define identifier string

宏替换包括:简单宏替换、参数化宏替换、嵌套宏替换。

简单宏替换:略。

参数化宏替换:

例:#define CUBE(x) (x*x*x)

则在程序中CUBE(a)=a*a*a;类似于函数的调用,当调用宏时,预处理器将替换该字符串。此种替换预处理器只是盲目的将x替换成a。如果CUBE(a+b)则替换成了(a+b*a+b*a+b)显然不和常理,可以修改为

#define CUBE(x) ((x)*(x)*(x))

宏的参数替换可以是任意的字符串系列。

宏嵌套:

我们在定义宏时,可以让下面的宏嵌套上面已经定义的宏,如:

#define M  5
#define N  M+1
.......

2.文件包含

#include"filename"
#include<filename>

3.编译器控制命令

(1)已包含的一个文件中含有某些宏定义,但是不知道某个宏是否已经定义了。想确认一下TEST宏是否被定义,如:

#include"define.h"
#ifndef TEST
#define TEST 1
#endif

假设在define.h里没有定义TEST那么下面的语句#define TEST 1就被执行。如果没有#ifndef的判断,重复定义是会出错的。当然也可以取消定义

#include"define.h"
#ifndef TEST
#undef TEST
#endif

(2)假设在两个不同类型的计算机中,要求编写一个可以在两个计算机上运行的程序。因为机器不同,所以可能代码也有所不同,但是也不能写两个程序啊。可以采用

main()
{ 
  ......
   #ifdef IBM_PC
   {
    .........
   }
   #else 
   {
   .............
   }
   #endif
}

如果运行在IBM机上,只需在开始,宏定义下#define IBM_PC即可

(3)在测试系统时,希望在某些位置加入特定的语句来测试系统。例如插入printf语句来显示中间结果和消息,成为调试语句。你可以把这些语句称为程序的一部分,但是只在需要是起作用。

main()
{
   .......
     #ifdef TEST
     {
       printf(.....);
     }
     #endif
     ......
}

在测试阶段可以定义宏TEST如果测试结束就可以删去宏TEST这样测试代码也就不再起作用了。

**C预处理器还支持一个更通用的测试条件形式 #if指令

#if constant_expression
{
.....
}
#endif

4.ANSI C的其他预处理指令

(1)#elif 指令,相当于if...else...if语句系列。

例:

 #if  expression1
        ......
   #elif expression2
        ......
   #endif

(2)#pragma  基于实现的指令,可以用来制定提交给编译器的不同指令。

  #pragma message("文本消息")  遇到这个指令就输出文本信息

  #pragma code_seg(["section-name"[,"section-class"]])设置程序中函数代码存放的代码段,开发驱动程序是用到

  #pragma once  保证头文件编译一次

  #pragma hdrstop 表示预编译头文件到此为止,后面的不再编译。

  #pragma startup 指定编译优先级,

  #pragma package(smart_int)根据优先级大小来编译

  #pragma resource"*.dfm" 把文件*.dfm添加到工程中

  #pragma comment(...)   把一个注释放入对象文件或可执行文件,常用的lib关键字可以连入一个库文件

  #pragma loop_opt(on)/loop_opt(off)用来激活或终止该编译程序支持的一些编译功能。

  #pragma warning(...)处理警告信息

(3)#error  用来在调试时产生诊断消息


(4)字符串化运算

ANSI C支持一种成为字符串化的运算符#,用在宏函数的定义中。该运算符允许在宏定义中使用一个形参,它将被转化为一个字符串。

类似与参数化宏替换,可以讲替换内容直接转化成字符串,例如:

#define sum(x) printf(#x"=%f\n",x)
main()
{
  .....
   sum(a+b);
  ......
}

预处理器把此语句替换为

printf("a+b""=%f\n",a+b);

等价于

printf("a+b=%f\n",a+b);

(5)标记符粘贴运算符##

 ANSI标准定义的标记符粘贴运算符##可以把宏定义中的两个标记符组合成一个标记符。

#define combine(s1,s2) s1##s2
main()
{
  printf("%f",combine(a,5));
}

则替换结果为

printf("%f",a5);  
相关文章
|
6月前
|
编译器 C++
C 预处理器
C 预处理器。
88 10
|
1月前
|
编译器 Linux C语言
|
6月前
|
编译器 C语言
预处理深入
预处理深入
39 0
预处理深入
|
6月前
|
编译器 C语言
c预处理器
c预处理器
41 0
|
6月前
|
Linux C语言 Windows
C预处理分析
C预处理分析
42 2
|
6月前
|
安全 C语言
程序预处理:全解版-1
程序预处理:全解版
41 0
|
6月前
|
编译器 C语言
程序预处理:全解版-2
程序预处理:全解版
39 0
|
6月前
|
编译器 C++
c++预处理器
c++预处理器
39 0
|
安全 编译器 C语言
详解预处理(1)
详解预处理(1)
80 1