1 / 15

第七章 预处理

第七章 预处理. 宏定义. 文件包含. 条件编译. 预编译处理. 预编译命令 与源程序 一同编译. 与源程序 一同编译. 生成执行文件. 生成执行文件. 预处理命令 : 预处理命令不是 C 的组成部分,为了 扩充 C 的功能 C 提供了预处理功能,预处理命令不 能直接编译,要先编译,再和其源程序一起编译, 执行过程:. 系统 角度. 用户 角度. 预处理. 作用:对源程序编译之前做一些处理 , 生成扩展 C 源程序 种类 宏定义 #define 文件包含 #include

idola
Download Presentation

第七章 预处理

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第七章 预处理 宏定义 文件包含 条件编译

  2. 预编译处理 预编译命令 与源程序 一同编译 与源程序 一同编译 生成执行文件 生成执行文件 预处理命令:预处理命令不是C的组成部分,为了 扩充C的功能C提供了预处理功能,预处理命令不 能直接编译,要先编译,再和其源程序一起编译, 执行过程: 系统 角度 用户 角度

  3. 预处理 • 作用:对源程序编译之前做一些处理,生成扩展C源程序 • 种类 • 宏定义 #define • 文件包含 #include • 条件编译 #if--#else--#endif #ifdef #ifndef等 • 格式: • “#”开头 • 占单独书写行 • 语句尾不加分号

  4. 宏体可缺省,表示宏名 定义过或取消宏体 7.1 宏定义 • 不带参数宏定义 • 一般形式: #define 宏名 [宏体] • 功能:用指定标识符(宏名)代替字符序列(宏体) • 定义位置:任意(一般在函数外面) • 作用域:从定义命令到文件结束 • #undef可终止宏名作用域 • 格式: #undef 宏名 • 宏展开:预编译时,用宏体替换宏名---不作语法检查 • 引号中的内容与宏名相同也不置换 • 宏定义可嵌套,不能递归 例 #define MAX MAX+10 () • 宏定义中使用必要的括号()

  5. 带参数宏定义 不能加空格 • 例 #define S(a,b) a*b • ……….. • area=S(3,2); • 宏展开: area=3*2; • 一般形式: #define 宏名(参数表) 宏体 • 宏展开:形参用实参换,其它字符保留 • 宏体及各形参外一般应加括号() 例 #define S (r) PI*r*r 相当于定义了不带参宏S,代表字符串“(r) PI*r*r” 例 #define POWER(x) x*x x=4; y=6; z=POWER(x+y); 宏展开:z=x+y*x+y; 一般写成: #define POWER(x) ((x)*(x)) 宏展开: z=((x+y)*(x+y));

  6. 例 用宏定义和函数实现同样的功能 #define MAX(x,y) (x)>(y)?(x):(y) ……. main() { int a,b,c,d,t; ……. t=MAX(a+b,c+d); …… } 宏展开:t=(a+b)>(c+d)?(a+b):(c+d); int max(int x,int y) { return(x>y?x:y); } main() { int a,b,c,d,t; ……. t=max(a+b,c+d); ……… }

  7. 带参宏 函数 编译时 处理时间 程序运行时 无类型问题 定义实参,形参类型 参数类型 不分配内存 简单的字符置换 分配内存 先求实参值,再代入形参 处理过程 不变 变长 程序长度 运行速度 不占运行时间 调用和返回占时间 带参的宏与函数区别

  8. file2.c #include “file2.c” B A A file2.c file1.c file1.c 7.2 文件包含 <> 直接按标准目录搜索 “” 先在当前目录搜索,再搜索标准目录 可指定路径 • 功能:一个源文件可将另一个源文件的内容全部包含进来(共用公用模块) • 一般形式: #include “文件名” 或 #include <文件名> • 处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译

  9. file3.c file2.c file1.c A #include “file2.c” #include “file3.c” C A B file3.c file1.c file2.c 被包含文件内容 宏定义 数据结构定义 函数说明等 • 源文件(*.c) • 头文件(*.h) • 文件包含可嵌套

  10. 例 文件包含举例 /* reg51.h */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; /*ch8_10.c*/ #include <reg51.h> #include "d:\fengyi\bkc\powers.h" #define MAX_POWER 10 void main() { P0= MAX_POWER ; }

  11. 一般情况下,编译一个源程序都是所有语句行都编译(前面所有例子),为了需要可以将满足条件的一部分语句进行编译, 称条件编译。 7.3 条件编译 条件编译命令的3种形式: (2) #ifndef 标识符 程序段1 #else 程序段2 #endif (3) #if 表达式 程序段1 #else 程序段2 #endif (1) #ifdef 标识符 程序段1 #else 程序段2 #endif

  12. 条件编译灵活运用会带来很多巧妙的用途。 1.利用#ifdef/#endif将某程序功能模块包括进去,以向某用户提供该功能。   在程序首部定义#ifdef HNLD:   #ifdef HNLD   #include"n166_hn.c"   #endif   如果不许向别的用户提供该功能,则在编译之前将首部的HNLD加一下划线即可。

  13. 2.在每一个子程序前加上标记,以便追踪程序的运行。2.在每一个子程序前加上标记,以便追踪程序的运行。   #ifdef DEBUG printf(" Now is in hunan !");   #endif

  14. 3.避开硬件的限制。有时一些具体应用环境的硬件不一样,但限于条件,本地缺乏这种设备,于是绕过硬件,直接写出预期结果。具体做法是:3.避开硬件的限制。有时一些具体应用环境的硬件不一样,但限于条件,本地缺乏这种设备,于是绕过硬件,直接写出预期结果。具体做法是:   #ifndef TEST i=dial(); //程序调试运行时绕过此语句   #else i=0;   #endif   调试通过后,再屏蔽TEST的定义并重新编译,即可发给用户使用了。

  15. 4.引用外部函数时 编写include.h中如下定义: #ifdef ds_globals #define ds_ext #else #define ds_ext extern #endif ds_ext void v_Get1302(uchar *ucCurtime); ds_ext void v_Set1302(uchar *pSecDa); 在mian.c和DS1302.C中均包含头文件include.h #include“include.h” Mian() { 。。。。。。} #defined ds_globals #include“include.h”

More Related