编译预处理和数据类型重命名

上传人:宝路 文档编号:47979523 上传时间:2018-07-07 格式:PPT 页数:25 大小:155.66KB
返回 下载 相关 举报
编译预处理和数据类型重命名_第1页
第1页 / 共25页
编译预处理和数据类型重命名_第2页
第2页 / 共25页
编译预处理和数据类型重命名_第3页
第3页 / 共25页
编译预处理和数据类型重命名_第4页
第4页 / 共25页
编译预处理和数据类型重命名_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《编译预处理和数据类型重命名》由会员分享,可在线阅读,更多相关《编译预处理和数据类型重命名(25页珍藏版)》请在金锄头文库上搜索。

1、第第1818讲讲 编译预处理编译预处理和和 数据类型再命名数据类型再命名 第18讲 编译预处理和数据类型再命名本讲主要内容 n 宏定义 u 不带参数的宏 u带参数的宏 n文件包含 u一般形式 u文件包含的有关说明 n条件编译 uifdef-else-endif形式 uifndef-else-endif形式 uif-else-endif形式 n数据类型再命名 utypedef的一般形式 utypedef应用举例第18讲 编译预处理和数据类型再命名n教学目标u了解编译预处理的概念,了解 宏的概念。u了解文件包含的概念,熟练掌 握文件包含命令include的用法。u了解条件编译的概念,熟悉常 用的条

2、件编译命令及其用法。u了解文件重名的意义,掌握 typedef命令的使用方法。一、宏定义 n不带参数的宏 不带参数的宏是用一个标识符代替一个字符 串,其一般形式如下:#define 宏名 宏体 其中的“#”表示这是一条预处理命令。 凡是以“#”开头的均为预处理命令。 “define”为宏定义命令。 宏名是一个标识符,宏体可以是一个字符串 ,也可以是一个数值,也可以是一个表达式 等。 例如:#define PI 3.1415926一、宏定义 n例17-1 宏定义应用举例。 #define TWO 2 #define MSG “I love c language.“ #define FMT “ n

3、umber is %dn“ main() int number=TWO;printf(FMT, number);printf(“%sn“,MSG); 一、宏定义 n例17-2 计算圆面积。 #define PI 3.14 main() float R=16.99;printf(“S=PI*R*R=%fn“,PI*R*R); 一、宏定义 n例17-3 计算圆的周长和面积 。 #define R 3.0 #define PI 3.1415926 #deinfe L 2*PI*R /* 使用宏R和PI定义宏L */ #define S PI*R*R /* 使用宏R和PI定义宏S */ main()

4、printf(“L=%fnS=%fn“,L,S); 一、宏定义 n例17-4输出格式定义为 宏。#define PR printf #define NL “n“ #define D “%d “ #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S “%s“main() int a,b,c,d;char string=“This is a string.“;a=1;b=2;c=3;d=4 ;PR(D1,a);PR(D2,a,b); PR(D3,a,b,c);PR(D4,a,b,c

5、,d);PR(S,string); 一、宏定义 n关于宏定义的说明: 宏名一般使用大写形式。 使用宏可以提高程序的可读性和可移植性。 宏定义是用宏名来表示一个字符串,在宏替换时又以该字符串 取代宏名,这只是一种简单的代换。 宏定义不是C语句,后面不能有分号。如果加入分号,则加入 的分号将作为宏体的一部分。 通常把#define命令放在一个文件的开头,使其在本文件全部 有效。 宏定义终止命令 #undef结束先前定义的宏名。 程序中用双引号括起来的字符串,即使与宏名相同,也不替换 。 宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏 名。在宏展开时由预处理程序层层替换。 宏定义名仅用于编译

6、预处理,不是程序变量,因此系统不会为 它分配内存空间。一、宏定义 n带参数的宏 带参数宏定义的一般形式如下:#define 宏名(参数表) 字符串 其中: 宏名后的参数表可以是一个参数,也可以是多 个参数,当有多个参数时,各参数之间用“,”分割。 用于宏体的字符串部分要包括参数表中的参数 。 例如:#define max(x,y) xy?x:y 宏替换按如下过程进行:对于程序中带实参的宏,按照 宏定义中的字符串从左到右进行替换,当遇到宏中的形 参时,就用程序语句中的宏实参取代它,对于宏定义字 符串(宏体)中的非参数字符,则予以保留。 一、宏定义 n例17-5 利用宏定义求三个数的最大数。 #i

7、nclude “stdio.h“ #define max(x,y) xy?x:y main() int a,b,c,m;scanf(“%d%d%d“,&a,&b,&c);m=max(a,b); /* 使用宏max,a、b为宏实参 */printf(“max=%dn“,max(m,c);/* m、c为宏实参 */ 一、宏定义 n使用带参数的宏时应注意如下问题: 在带参宏定义中,形式参数不分配内存单元,也 不存在类型定义问题。而宏调用中的实参有具体的 值,要用它们去替换形参,因此必须首先进行类型 说明。 如果程序中有使用表达式作为宏实参的情况,那 么在进行宏定义时,出现在宏替换字符串中的宏参 数应

8、使用括号()进行限定,否则宏替换后有可能产生 错误的结果。 带参宏定义中,宏名和形参表之间不能有空格出 现,一旦出现了空格,就变成了不带参数的宏定义 。 一、宏定义 n带参数的宏与函数调用的区别: 函数调用时要先计算实参表达式的值,然后传给形参。 而带参的宏只是进行简单的符号替换,不存在计算表达式的 值的问题。 函数调用在程序运行过程中发生作用,而宏在程序的编 译预处理阶段发生作用。 函数调用只能得到一个返回值,使用宏能够得到多个结 果。 宏替换不占运行时间,只占编译时间,而函数调用则占 用运行时间。 在函数中,形参和实参是两个不同的量,各有自己的作 用域,调用时要把实参值赋予形参,进行“值传

9、递”。而在带 参宏中,只是符号替换,不存在值传递的问题。一、宏定义 n例17-6 计算圆的周长和面积。 #define PI 3.1415926 #define CIRCLE(R,L,S) L=2*PI*R;S=PI*R*R; main() float r,l,s;printf(“Input r:“);scanf(“%f“,&r);CIRCLE(r,l,s); /* 源程序中使用带参数的宏 */printf(“L=%f,S=%fn“,l,s); 二、文件包含 为了在一个源程序中使用另一个源程序的代码, C语言提供了文件包含命令include, 它的一般使用形式如下:#include “文件名“

10、 文件包含命令的功能是把指定的文件插入该命令 行位置取代该命令行, 从而把指定的文件和当 前的源程序文件连成一个源文件。 二、文件包含 n例17-7 创建源文件userdef.h并在程序e1707.c中使用 它。 如下是userdef.h文件的内容: #define PRINT printf /* 定义符号常量PRINT */ #define INPUT scanf /* 定义符号常量INPUT */ #define PI 3.1415926 /* 定义符号常量PI */ 如下是e1707.c文件的内容: #include “userdef.h“ main() float s,r;PRINT(

11、“r=“);INPUT(“%f“,&r);s=PI*r*r;PRINT(“AREA=%fn“,s); 二、文件包含 n对文件包含命令还要说明以下几点: 包含命令中的文件名可以用双引号括起来,也可以用尖括 号括起来,以下写法都是允许的:#include “stdio.h“ #include 但是这两种形式是有区别的: 使用双引号则表示首先在当前 的源文件目录中查找,若未找到才到包含目录中去查找;使 用尖括号表示在包含文件目录中去查找, 而不在源文件目录 去查找。 一个include命令只能指定一个被包含文件, 若有多个文 件要包含,则需用多个include命令。 文件包含允许嵌套,即在一个被包含

12、的文件中又可以包含 另一个文件。 三、条件编译 nifdef-else-endif形式 一般形式如下: #ifdef 标识符 程序段1 #else 程序段2 #endif 该形式的条件编译的过程:如果“标识符”已被“ #define”命 令定义过,则对“程序段1”进行编译;否则对“程序段2”进行 编译。如果没有“程序段2”,上述格式中的“#else”即不再使 用,条件编译成为如下形式: #ifdef 标识符 程序段 #endif 三、条件编译 n例17-8 条件编译举例1。 #define NUM ok struct stu int num;char *name;char sex;float

13、score;*ps; main() ps=(struct stu*)malloc(sizeof(struct stu);ps-num=102;ps-name=“Zhang ping“;ps-sex=M;ps-score=62.5;#ifdef NUMprintf(“Number=%dnScore=%fn“,ps-num,ps-score);#elseprintf(“Name=%snSex=%cn“,ps-name,ps-sex);#endiffree(ps); 三、条件编译 nifndef-else-endif形式 一般形式如下: #ifndef 标识符 程序段1 #else 程序段2 #en

14、dif 它与第一种形式的区别是将“ifdef”改为了 “ifndef”。它的功能是,如果标识符未被#define 命令定义过则对程序段1进行编译, 否则对程序段2 进行编译。这与第一种形式的功能正相反。 三、条件编译 nif-else-endif形式 一般形式如下: #if 常量表达式 程序段1 #else 程序段2 #endif 它的功能是,如常量表达式的值为真(非0),则 对程序段1 进行编译,否则对程序段2进行编译。因 此可以使程序在不同条件下,完成不同的功能。 三、条件编译 n例17-9 条件编译举例2。 #define R 1 main() float x,s;printf (“in

15、put a number: “);scanf(“%f“,&x);#if Rs=3.14159*x*x;printf(“Area of round is: %fn“,s);#elses=x*x;printf(“Area of square is: %fn“,s);#endif 四、数据类型再命名 所谓数据类型再命名就是为已经存在的数据类 型再定义一个另外的名字,目的是为了增强程 序的可读性,使用的命令是typedef,它以C语 句的形式出现在程序中。 typedef 的一般形式如下:typedef 已定义的类型名 新类型名; 例如: typedef int INTEGER;typedef float REAL; 四、数据类型再命名 例17-10 用typedef命令改写例13-3简单的密码加密程序 。 #include “stdio.h“ struct table char input; char output; ; typedef struct table TABLE; main( ) char ch;int length, i;TABLE translate=a,f,b,g,w,d,f,9,y,*,x,s,m,3,h,k,p,f,u,? ; length=sizeof

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 教学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号