C中的预处理器

举报
清雨小竹 发表于 2022/09/25 00:54:10 2022/09/25
【摘要】 【预处理】C语言提供了其他高级语言没有的预处理工具。在源代码通过编译器之前,预处理器先对源代码进行处理,他是在称之为预处理器命令行或指令的控制下操作。预处理指令大致分为三类:宏替换指令、文件包含指令、编译器控制指令 1.宏替换指令 宏替换是程序中的标识符被预定义的字符串取代的过程。在#define语句指令下工作。...
【预处理】
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);
 

文章来源: zzzili.blog.csdn.net,作者:清雨小竹,版权归原作者所有,如需转载,请联系作者。

原文链接:zzzili.blog.csdn.net/article/details/8265300

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。