[IT认证]第6章 编译预处理与变量的作用域.ppt

上传人:音乐台 文档编号:1995478 上传时间:2019-01-29 格式:PPT 页数:36 大小:616.32KB
返回 下载 相关 举报
[IT认证]第6章 编译预处理与变量的作用域.ppt_第1页
第1页 / 共36页
[IT认证]第6章 编译预处理与变量的作用域.ppt_第2页
第2页 / 共36页
[IT认证]第6章 编译预处理与变量的作用域.ppt_第3页
第3页 / 共36页
亲,该文档总共36页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《[IT认证]第6章 编译预处理与变量的作用域.ppt》由会员分享,可在线阅读,更多相关《[IT认证]第6章 编译预处理与变量的作用域.ppt(36页珍藏版)》请在三一文库上搜索。

1、,第六章 编译预处理与变量作用域,雷艳静 QQ: 42772762,1,基本内容,编译预处理,变量的作用域与可见性,变量的存储类型,6.1,6.2,6.3,2,6.1 编译预处理,3,编译预处理 指C在编译源程序之前,对源程序进行的预处理; 类型 文件包含 宏定义 注意事项 必须以 # 为首字符,尾部不必加分号; 一行最多写一条编译预处理命令; 编译预处理命令可以出现在源程序任意位置。其作用范围从其出现位置到所在源程序的末尾。,6.1.1 文件包含,4,一般格式 # include # include “包含文件名” 功能 编译源程序前,用包含文件的内容置换该预处理命令。 例:# inclu

2、de 两种形式的区别 用尖括号包含文件时,编译系统将按照系统设定的标准目录搜索该文件; 用双括号包含文件时,编译系统将首先在当前目录中查找该文件,再按标准目录查找该文件。,6.1.1 文件包含,5,C语言中系统提供的包含文件都以 .h 为后缀。 常用的包含文件 (函数库) ctype.h:字符处理函数库 math.h:数学函数库 stdio.h:标准输入/输出函数库 stdlib.h:常用函数库 string.h:字符串处理函数 其它文件 编制由多个源程序文件组成的较大程序时,可以用文件包含命令,将一个源文件的文本插入到另一个文件。,6.1.1 文件包含,6,例6-1:一个程序写在多个源文件中

3、,用 # include 连接。,6.1.2 宏定义,7,格式与功能 # define 宏名 宏体 宏名为标识符,宏体为一段文本。 功能 在预处理时,将程序中该命令后所有与宏名相同的文本用宏体置换(宏替换)。 举例 # define EOF -1 # define NULL 0,6.1.2 宏定义,8,宏定义和宏替换的基本规则 宏体文本太长,换行时,需要在行尾加字符“”; # define PRN printf(“Hello”); printf(“Kitty!n”); 宏体中,可以出现已定义(在该命令前)的宏名; # define CR printf(“n”) # define CR2 CR;

4、 CR 对出现在字符串常量中的宏名不作宏替换; 为了和程序中的关键字相区别,一般宏名用大写字母。,6.1.2 宏定义,9,例6-2:分别输出a1, a2, a3, a4, a5和b1, b2, b3, b4中的最大值以及它们的乘积。,# include # define CR printf(“n”) # define CR2 CR; CR # define find_max scanf(“%f”, ,void main() float y1, y2, max, x; int i, n; n=5; find_max; y1=max; n=4; find_max; y2=max; printf(“

5、%f”, y1); CR; printf(“%f”, y2); CR2; printf(“CR%f”, y1*y2); CR; ,输入: 3.1 4.5 6.3 1.2 -5 1.1 3.2 2.13 -1.2,6.1.2 宏定义,10,带参数的宏 格式: # define 宏名( 形参列表 ) 宏体 功能: 在编译预处理时,将程序中、该命令后所有与宏名相同的文本用宏体置换; 置换时宏体中的形参要用相应的实参代替。,6.1.2 宏定义,11,例6-3:输入3个值,判断以这3个值作为边长,能否构成三角形。,# include # define f(a, b, c) a+b=c void main

6、() float x, y, z; scanf(“%f%f%f”, ,6.1.2 宏定义,12,带参数宏与函数的区别 带参宏中所谓的“形参列表”,其实是“标识符列表”,没有变量的含义。而函数形参是具体的变量。 函数调用时,先求出实参表达式的值,然后代入形参。而带参的宏只是进行简单的字符替换,不存在实参与形参之间值传递的问题。 函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是在编译前进行的,展开时并不分配内存单元,不进行值的传递,也没有“返回值”的概念。 函数要求实参和形参都要定义类型,且类型一致。而宏不存在类型的问题,它的参数只是一个符号代表。 宏替换不占运行时间,只占编译

7、时间。而函数调用则占运行时间(分配单元、保留现场、值传递和返回等)。,6.1.2 宏定义,13,例6-4:写出下列程序的输出结果。,# include # define f(a, b) a*b void main() float x=2, y=3, z; z=f(x, y); printf(“%ft”, z); z=f(x+5, y-2); z=f(x*x+2*x-5, y+3); ,# include # define f(a, b) (a)*(b) # define g(a, b) (a)-(b) void main() float x=2, y=3, z; z=f(x*x+2*x-5,

8、y+3); z=g(x+5, y-2); ,6.1.2 宏定义,14,宏定义的优缺点 缺点: 宏替换时,要用宏体替换宏名,往往使源程序体积膨胀,增加了系统的存储开销。故一般情况下,宏只能用来实现简单的函数功能。 优点: 不像函数调用那样,需要进行参数传递、保存现场、返回等操作,所以比函数调用节省时间。 使用宏,可提高程序的通用性,便于修改和维护。例如:# define PI 3.14,6.2 变量的作用域与可见性,15,变量的作用域 定义 C程序中的变量能够被使用的范围称为其作用域。 分类 块作用域 函数作用域 文件作用域,全局变量,6.2.1 变量的作用域,16,(1) 块作用域 声明位置

9、在复合语句或结构内部(块)声明的变量具有块作用域。 作用域 始于声明处,终止于块结束处,且存储单元被系统回收。,# include void main() int i, s=0; int i; for(i=1; i=10; i+) s=s+i; printf(“s=%d, i=%dn”, s, i); ,for (int i=1; i=10; i+) s=s+i; /* 循环体结束后存储单元释放 */,6.2.1 变量的作用域,17,(2) 函数作用域 声明位置 在函数内部、块的外部声明的变量具有函数作用域。 作用域 始于声明处,终止于函数结束处,且存储单元被系统回收。,# include v

10、oid main() int i, s=0; int i; for(i=1; i=10; i+) s=s+i; printf(“s=%d, i=%dn”, s, i); ,由函数的作用域可知: 同一程序的不同函数中,变量即使同名也不是同一个变量,因为它们的地址空间不同,分别作用于各自的函数。,6.2.1 变量的作用域,18,(3) 文件作用域 声明位置 在函数外部声明。又称外部变量,或全局变量。 作用域 从该变量声明处开始,直到文件末尾。,6.2.1 变量的作用域,19,例6-6:输入长方体的长、宽、高,求其体积及正、侧、顶3个面的面积。,# include float s1, s2, s3;

11、 float vs(float a, float b, float c) float v; v=a*b*c; s1=a*b; s2=b*c; s3=a*c; return v; void main() float v, l, w, h; printf(“input length, width and height:”); scanf(“%d%d%d”, ,6.2.2 变量的可见性,20,变量的作用域 指变量能够被使用的范围。 变量的可见性 指在某个范围内是否可引用该变量。,6.2.2 变量的可见性,21,变量可见性总结 (1) 具有块作用域的变量只有在块内可见。,# include void

12、main() int i, s=0; int i; for(i=1; i=10; i+) s=s+i; printf(“s=%d, i=%dn”, s, i); ,6.2.2 变量的可见性,22,(2) 具有函数作用域的变量只有在函数内可见。,# include int f1(int), f2(int); void main() int i, x; printf(“%d, %dn”, f1(10), f2(10); int f1(int n) x=0; for (i=1; i=n; i+) x=x+i; return x; /* ? */ int f2(int n) x=1; for (i=1

13、; i=n; i+) x=x*i; return x; /* ? */,6.2.2 变量的可见性,23,特别注意:变量的作用域和可见性并非完全等价。 例:函数内部声明了具有函数作用域的变量i, 如果函数内部的某语句块中声明了同名的变量i, 在块内只有块局部变量可见。,# include void main() int i=3; printf(“i=%dn”, i); int i=1; printf(“i=%dn”, i); i+; printf(“i=%dn”, i); ,6.2.2 变量的可见性,24,(3) 函数内部声明了与全局变量同名的变量,则全局变量在函数内部不可见。即全局变量被“屏蔽

14、”。,# include char int i=3; void p1() printf(“i=%dn”,i); void main() int i=5; printf(“i=%dn”,i); p1(); i=i+2; printf(“i=%dn”, i); ,i=5 - in main() i=3 - in p1() i=7 - in main(),6.2.2 变量的可见性,25,(4) 全局变量在其声明位置之前不可见,使用extern语句可改变其作用域。,# include void main() printf(“A=%d, B=%dn”, A, B); int A=13, B=-8;,ex

15、tern int A, B;,用extern改变变量作用域时,其类型名可省略。,6.2.2 变量的可见性,26,程序 #include int a; /全局变量 void main() void fun(); fun(); printf(“%d“, a); void fun() a=9*9; 程序运行: 81,6.3 变量的存储类型,27,变量的两种属性 数据类型:表示存储在变量中数据的格式; 存储类别:表示系统为变量分配存储空间的方式。 声明变量的一般格式: 存储类型标识符 类型标识符 变量名列表; 存储类别 auto自动类型 register寄存器类型 static静态类型 extern外

16、部类型,6.3 变量的存储类型,28,(1) auto自动类型 函数内部定义的局部变量、块变量、形参等都属于auto存储类别; 特点:系统调用该函数时会给它们分配存储空间,调用结束时自动释放这些存储空间。因此又称为自动变量。 auto型变量存储在动态存储区。 auto为缺省存储类别。如果不写,则缺省为auto类别。,6.3 变量的存储类型,29,(2) register 寄存器型 一般情况下,变量存放在内存中。当程序用到哪个变量时,就从内存中将此变量送到CPU进行运算;运算完毕若需要存数,则再从CPU将数据送到内存存放。,对于一些频繁使用的局部变量,可将其存在CPU内部的寄存器中,需要时可直接

17、取出参与运算,而不必到内存中取。由于访问寄存器的速度远远大于访问内存的速度,因此可大大提高执行效率。,6.3 变量的存储类型,30,(2) register 寄存器型,register long i; for (i=1; i=1000000; i+) ,register 型变量存在动态存储区。 只有局部自动变量和形参可以作为寄存器变量。 一个计算机系统的寄存器数目是有限的,不能定义任意多个寄存器变量。 当今的优化编译系统能够识别使用频繁的变量,从而自动将这些变量放在寄存器中,而不需程序设计者指定。,6.3 变量的存储类型,31,(3) static 静态型 函数内定义的auto型变量,会随着函

18、数调用的结束而消失。如果希望再次调用该函数时,这些变量仍能保持原来的值,应将这些变量声明为static类型。 static型变量存储在静态存储区。该类数据在程序执行前被分配存储空间,无论static在哪一个函数中声明,在程序运行的整个过程中,该存储空间总是被占用。 static型变量只在最开始时赋一次值,以后使用时,均使用其里面已保存的值。,6.3 变量的存储类型,32,例:编程,输入m和n,分别计算 1m 和 1n 的和。,# include int sum(int k) static int y=0; for (int i=1; i=k; i+) y+=i; return y; void

19、main() int m, n; m=sum(10); n=sum(5); printf(“%d %dn”, m, n); ,只进行一次初始化,实地练习,33,请分析下列程序结果。 #include int i=1, reset(), next(int), last(int), New(int); void main() int i, j; i=reset(); for (j=1; j=3; j+) printf(“i=%d, j=%dn”, i, j); printf(“next(%d)=%dn”, i, next(i); printf(“last(%d)=%dn”, i, last(i);

20、 printf(“new(%d+%d)=%dn”, i, j, New(i+j); ,int reset() return i; int next(int j) return j=i+; int last(int j) static int i=10; return j=i-; int New(int i) int j=10; return i=j+=i; ,实地练习,34,答案 i=1, j=1 next(1)=1 last(1)=10 new(1+1)=12 i=1, j=2 next(1)=2 last(1)=9 new(1+1)=13 i=1, j=3 next(1)=3 last(1)=8 new(1+1)=14,本章作业,35,作业 P113: 2,3,更换老师说明,谢谢!,谢谢!,36,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1