《预处理器》PPT课件.ppt
《《预处理器》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《预处理器》PPT课件.ppt(39页珍藏版)》请在三一办公上搜索。
1、第14章,预处理器,本章要点,预处理器的工作原理预处理指令宏定义条件编译,引言,指令如#define 和#include 等是由预处理器进行处理的,而预处理器是一个在编译前编辑C程序的软件.C语言(和 C+语言)因为依赖预处理器而不同于其他的编程语言。预处理器是一个强大的工具,但它同时也可能是许多难以发现的错误的根源。,14.1 预处理器的工作原理,预处理器查找以#开头的预处理指令.前面,我们已经遇到过#define 和#include指令.#define 指令定义一个宏(macro)即一个能够代表其它东西的名字,比如一个常量。预处理器会通过将宏的名字和它的定义存储在一起来响应#define指
2、令。当这个宏在后面的程序中使用到时,预处理器“扩展”了宏,将宏替换为它所定义的值。,预处理器的工作原理,#include指令告诉预处理器打开一个特定的文件,将它的内容作为正在编译的文件的一部分“包含”进来。例如,下面一行:#include 指示预处理器打开一个名字为 stdio.h的文件,并将它的内容加到当前的程序中。,预处理器的工作原理,在编译过程中中,预处理器的角色如图所示:,预处理器的工作原理,预处理器的输入是一个 C语言程序,程序可能包含指令。预处理器会执行这些指令,并在处理过程中删除这些指令。预处理的输出是另一个C程序:原程序编辑后的版本。预处理器的输出被直接交给编译器。,预处理器的
3、工作原理,第二章中的 celsius.c:/*Converts a Fahrenheit temperature to Celsius*/#include#define FREEZING_PT 32.0f#define SCALE_FACTOR(5.0f/9.0f)int main(void)float fahrenheit,celsius;printf(Enter Fahrenheit temperature:);scanf(%f,预处理器的工作原理,预处理过后为:Blank lineBlank lineLines brought in from stdio.hBlank lineBlank
4、 lineBlank lineBlank lineint main(void)float fahrenheit,celsius;printf(Enter Fahrenheit temperature:);scanf(%f,预处理器的工作原理,预处理器不仅仅是执行了指令,还做了一些其他的事情。特别值得注意的是,它将每一处注释都替换为一个空格字符。有一些预处理器还会进一步删除不必要的空白字符,包括在每一行开始用于缩进的空格符和制表符。在 C语言较早的时期,预处理器是一个单独的程序,并将它的输出提供给编译器。如今,预处理器通常和编译器集成在一起(为了提高编译的速度)。在理解上,将预处理器从编译器分开
5、是比较有用的。,预处理器的工作方式,大多数编译器提供查看预处理输出的方法。一些编译器通过使用特定选项来产生预处理结果(如 gcc E)。其它一些编译环境带有类似集成预处理器的独立的程序。注意,预处理器仅知道少量 C语言的规则,因此,它在执行指令时非常有可能产生非法的程序。对于较复杂的程序,检查预处理器的输出可能是找到这类错误的有效途径。,14.2 预处理指令,大多数预处理指令属于下面 3种类型之一:宏定义。#define指令定义一个宏,#undef指令删除一个宏定义。文件包含。#include指令导致一个指定文件的内容被包含到程序中。条件编译。#if、#ifdef、#ifndef、#elif、
6、#else和#endif指令可以根据测试的条件来将一段文本块包含到程序中或排除在程序之外。几条应用于所有指令规则:指令都以#开始。#符号不需要在一行的行首,只要它之前只有空白字符就行。在#后是指令名,接着是指令所需要的其他信息。在指令的符号之间可以插入任意数量的空格或横向制表符。例如,下面的指令是合法的:#define N 100,预处理指令,指令总是在第一个换行符处结束,除非明确地指明要继续。如果想在下一行继续指令,我们必须在当前行的末尾使用字符,例如:#define DISK_CAPACITY(SIDES*TRACKS_PER_SIDE*SECTORS_PER_TRACK*BYTES_PE
7、R_SECTOR)指令可以出现在程序中任何地方。我们通常将#define和#include指令放在文件的开始,其他指令则放在后面,甚至在函数定义的中间。注释可以与指令放在同一行。实际上,在一个宏定义的后面加一个注释来解释宏的意义是一种比较好的习惯:#define FREEZING_PT 32.0f/*freezing point of water*/,14.3 宏定义,我们从第 2章以来使用的宏被称为简单的宏,它们没有参数,预编译器也支持带参数的宏。简单的宏定义有如下格式:#define 标识符 替换列表替换列表是一系列的 C语言记号,包括标识符、关键字、数、字符常量、字符串字面量、运算符和标
8、点符号。在文件后面的内容中,不管标识符在任何位置出现,预处理器都会用替换列表代替它。,14.3.1 简单的宏,不要在宏定义中放置任何额外的符号,否则它们会被作为替换列表的一部分。一种常见的错误是在宏定义中使用=,如:#define N=100/*WRONG*/int aN;/*becomes int a=100;*/在宏定义的末尾使用分号结尾是另一个常见错误,如:#define N 100;/*WRONG*/int aN;/*becomes int a100;*/编译器将会检测到绝大多数由多余符号所导致的错误。编译器会将每一处使用这个宏的地方标为错误,而不会直接找到错误的根源宏定义本身,因为宏
9、定义已经被预处理器删除了。,简单的宏,简单的宏可以定义“明示常量manifest constants”#define STR_LEN 80#define TRUE 1#define FALSE 0#define PI 3.14159#define CR r#define EOS 0#define MEM_ERR Error:not enough memory,简单的宏,#define的优点:使程序更容易读。使程序更容易修改。避免前后不一致的输入错误,例如3.14159,误输入为 3.1416或 3.14195。可以对C语法做小的修改。#define BEGIN#define END#defin
10、e LOOP for(;)对类型重命名。#define BOOL int控制条件编译。#define DEBUG,14.3.2 带参数的宏,带参数的宏定义有如下格式:#define 标识符(x1,x2,xn)替换列表 其中 x1,x2,xn是标识符(宏的参数)。在宏的名字和左括号之间必须没有空格。如果有空格,预处理器会认为是在定义一个简单的宏,其中(x1,x2,xn)是替换列表的一部分。,带参数的宏,带参数的宏举例:#define MAX(x,y)(x)(y)?(x):(y)#define IS_EVEN(n)(n)%2=0)调用这些宏:i=MAX(j+k,m-n);if(IS_EVEN(i)
11、i+;宏替换后:i=(j+k)(m-n)?(j+k):(m-n);if(i)%2=0)i+;,带参数的宏,复杂的类似函数的宏:#define TOUPPER(c)(a 头提供了一个更容易移植的相似函数toupper。带参数的宏也可能具有空的参数列表:#define getchar()getc(stdin)空的参数列表不是一定确实需要,但可以使 getchar更像一个函数。,带参数的宏,使用带参数的宏替代实际的函数有两个优点:程序可能会稍微快些。一个函数调用在执行时通常会有些额外开销 存储上下文信息、复制参数的值等。而一个宏的调用则没有这些运行开销。宏会更“通用”。与函数的参数不同,宏的参数没有
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 预处理器 预处理 PPT 课件

链接地址:https://www.31ppt.com/p-5620293.html