1回顾:模块化程序设计1.主函数,库函数和自定义函数的区别2.自定义函数的定义、设计3.递归函数的定义和用途回顾:模块化程序设计课程目标:–了解变量作用域的概念–掌握全局变量与局部变量的区别(重点)–掌握变量的存储类别(难点)参考课本P168~P175–了解预编译的概念–掌握宏的概念及#define的使用(重点)–掌握文件包含及#include的使用参考课本P230~P2392本次课内容本次课内容3变量的使用范围与存储类型“变量”—是指在程序运行过程中其值可以发生变化的量。通常是用来表示在程序中对数据存储空间的一种抽象的描述。当我们在学习C语言中的变量时,必须要掌握变量的有关属性:1、变量的数据类型及其定义方法2、变量的初始化3、变量的使用范围及其说明方法4、变量的存储类别及其定义方法一、变量的使用范围与存储类型4变量的使用范围包括有在一个函数内部使用的变量---局部变量;在函数之外部使用的变量---全局变量;main(){inta,b;……}在一个函数内部定义的变量称为局部变量intfun(intx){inti,j;……}局部变量局部变量1、局部变量1.1变量的使用范围:局部变量51、主函数中定义的变量也只用在主函数中有效;关于局部变量使用的几点说明2、不同函数中可以使用相同的变量名,且它们代表不同的存储单元,互不干扰;3、形式参数也是局部变量。其它函数是不能调用该形参的;4、在一个函数内部,可以在复合语句中定义变量,这些变量只能在本复合语句中有效。1.1.1关于局部变量使用的几点说明6在函数内部(包括主函数)定义的变量,称为局部变量,其作用范围只在函数内部有效,如下代码#includestdio.hvoidfund1(void){intnX=100;//局部变量printf(“nXinfund1=%d\n”,nX);}voidfund2(void){intnX=200;//局部变量printf(“nXinfund2=%d\n”,nX);}voidmain(void){intnX=50;//局部变量printf(nXinmain=%d\n”,nX);fund1();fund2();}程序代码本例中定义了三个局部变量nX,其作用范围分别作用于fund1,fund和main函数打印结果:nXinmain=50nXinfund1=100nXinfund2=200示例:局部变量示例:局部变量7charc1,c2;intp=1,q=5;main(){inta,b;a=p;b=q;……}在函数之外定义的变量称为全局变量全局变量可以为本文件中其它函数所共用。它的使用范围:从定义变量的位置开始到本源程序文件结束全局变量f1(intx){inti,j,z;z=p+x;……}f2(inty){charch=‘a’,c2=‘b’;c1=ch;ch=c2;……}2、全局变量1.2变量的使用范围:全局变量81、若在同一个源文件中,如有全局变量与局部变量同名时,则在局部变量的作用范围内,全局变量不起作用。2、设置全局变量的作用是:增加函数间数据联系的渠道。由于同一个文件中的所有函数都能引用全局变量的值,因此如果在一个函数中改变了全局变量的值,就能影响到其它函数,相当于各个函数间有直接的传递通道。关于全局变量使用的几点说明1.2.1关于全局变量使用的几点说明9示例:全局变量intd=1;main(){inta=3;fun(a);d+=a++;printf(“%d\n”,d);}fun(intp){intd=5;d+=p++;printf(“%d\n”,d);return;}1d3a3p5d84844示例:全局变量10#includestdio.hintnX=999;//全局变量voidfund1(void){printf(“nXinfund1=%d\n”,nX);}voidfund2(void){intnX=0;//局部变量printf(“nXinfund2=%d\n”,nX);}voidmain(void){printf(nXinmain=%d\n”,nX);fund1();fund2();}程序代码在此范围中,局部变量nX的作用范围替代了全局变量nX的作用范围。本例中函数fund2中的nX作用范围与全局变量nX有重叠部分,在重叠部分中使用局部变量,屏蔽掉了全局变量打印结果:nXinmain=999nXinfund1=999nXinfund2=0变量作用范围重叠问题1.2.2变量作用范围重叠问题11数据区(动态)数据区(静态)内存存储区程序区在程序运行期间分配固定的存储空间(如全局变量)。静态数据区动态数据区只有当函数被调用时才开始分配存储空间,在函数执行结束时就释放这些空间。在程序执行过程中,这种分配和释放是动态的(如局部变量)。内存存储区内存存储区12在C语言中,每一个变量和函数有两个属性:数据类型和数据的存储类别。数据类型,如整型、实型等;存储类别,指的是数据在计算机中的存储方式,也可以说数据的存储地点。内存储器(memory)寄存器(CPU)变量的存储类型1.3、变量的存储类型13关键词auto函数中的局部变量通常默认为动态分配存储空间的,即存储在动态存储区中。对它们分配和释放空间都是由编译系统自动处理的,因此这类局部变量也称为自动变量。动态存储autointb=1,c=2;1、局部变量的存储方式:auto1.3.1局部变量的存储方式:auto14关键词static有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。静态存储staticintb=1,c=2;2、局部变量的存储方式:static1.3.2局部变量的存储方式:static参见源码:9_1exp090115intf(inta){autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);}main(){inta=2,i;for(i=0;i3;i++)printf(“%d\n”,f(a));}0b3c12a2a470158069示例:局部变量的存储方式示例:局部变量的存储方式161、当需要保留函数上一次调用结束时的值;2、如果初始化后,变量只被引用而不改变其值,则这时用静态局部变量比较方便,以每次调用时重新赋值。main(){inti;for(i=1;i=5;i++)printf(“%d!=%d\n”,i,fac(i));}intfac(intn){staticintt=1;t=t*n;return(t);}1!=12!=23!=64!=245!=120局部变量的用途1.3.3局部变量的用途17全局变量的扩展调用。我们知道一个C语言程序可以有一个或多个源程序文件组成。如果程序是由多个源文件组成时,为了保障某个全局变量能提供多个源文件中的函数调用,则可采全局变量的扩展调用。关键词extern只能用来定义全局变量intx;……main(){…}a1.ccharcc;……externintx;……a2.c……externcharcc;……a3.c3、全局变量的扩展调用extern1.4全局变量的扩展调用extern参见源码:9_1exp0902如果一个函数只能被它所在文件中的其他函数所调用,则称为内部函数或静态函数,如:Staticintfun(inta,intb){…..}在多文件组成的程序中,如果在一个源程序文件中定义的函数,除了能在本程序内使用,还可以在其他源程序文件中使用.如:Externintfun(inta,intb){…}外部函数不用引用头文件.18内部函数和外部函数1.4.1内部函数和外部函数参见源码:9_1exp090319但是,在有些情况下需要某些变量中的值频繁地读写(如某循环变量需要执行10000次循环,显然为了读写变量的值就需要花费许多的时间。因此,为了提高程序的执行效率,在C语言中允许将这些变量的值可以储存在CPU中的寄存器中,需要时可直接从寄存器中读出参加运算,而不必再到内存中去读写。由于寄存器的存取速度远高于内存的存取速度,因此可以提高执行效率。这种变量称为“寄存器变量”。寄存器CPU运算器关键词registerregisterinta,b;intfac(intn){registerinti,f=1;for(i=1;i=n;i++)f=f*i;return(f);}4、使用寄存器变量register1.5使用寄存器变量register20运算器一般情况下,变量(包括静态和动态)的值都是存放在内存中的,当程序中用到哪一个变量的值时,则由控制器发出指令将内存中该变量的值送到运算器中进行运算,之后再将运算结果送回内存中存放。内存寄存器存储区(了解)1.5.1寄存器存储区(了解)211、只有局部自动变量和形参可以作为寄存器变量。寄存器变量使用的几点说明5、局部静态变量不能作为寄存器变量。registerstaticinta,b,c;不能把变量a,b,c既放在静态存储区中,又放在寄存器中,二者只能居其一。对于一个变量只能定义为一个存储类别。2、对于占用字节数多的变量,如:long、float、double型变量不能说明为寄存器型变量。3、由于寄存器中的数据可以直接访问,因此比其它存储类别的变量运算速度要快。所以对于反复使用的变量均可作为寄存器变量。4、寄存器型变量都是在某个函数中定义的,所以一旦退出该函数后就会被释放。1.5.2寄存器变量使用的几点说明22序号存储类型存储类别标识符存储地点1234自动型auto内存动态数据区CPU中的通用寄存器内存静态数据区静态型寄存器型扩展型registerstaticextern内存静态数据区存储类别标识符表1.6存储类别标识符表23预编译语句是在程序编译之前由编译器进行的源代码处理工作。处理完成后的源代码再进入编译工作。C++语言提供的预编译语句主要有以下三种:•宏定义•文件包含•条件编译预编译指令均以“#”号标识注意预编译语句二、预编译语句24定义一般形式:#define标识符字符串取消宏定义:#undef标识符作用:在预处理过程中将源程序中的标识符替换成字符串例:#includestdio.h#defineWM“Welcom”#defineUINTunsignedint#definePI3.14159voidmain(void){printf(WM);UINTna=100;UINTnb=200;doubledbA=PI*na*na;}源程序代码#includestdio.hvoidmain(void){printf(“Welcom”);unsignedintna=100;unsignedintnb=200;doubledbA=3.14159*na*na;}预编译后的源程序代码编译预处理宏定义----#define指令2.1宏定义----#define指令参见源码:exp0904~exp090625文件包含预处理控制有两种形式:#includefilename//包含系统标准库文件#include“filename”//包含自定义文件作用:在预处理过程中用包含文件的内容取代#include命令.例:#includestdio.h#include“test.h”voidmain(void){intna=nV;doubledba=dbV;}源程序代码#includestdio.hintnV=10;doubledbV=0.5;voidmain(void){intna=nV;doubledba=dbV;}预编译后的源程序代码编译预处理文件包含----#includeintnV=10;doubledbV=0.5;2.2文件包含----#include参见源码:exp0907本次课课程总结1全局变量及局部变量的作用域2变量的4种存储类型3预编译概念,#define#include的使用作业布置与要求1、设计一个程序,定义带参数的宏MAX(A