资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,第八章 函数与变量,李 书 涛,10/10/,1,第1页,目录,1 函数,1.函数定义,2.函数参数与返回值,3.函数申明和调用,4.函数递归调用,5.外部函数与内部函数,2 变量作用域和寄存类型,1.变量作用域,2.变量寄存类型,3 本章小结,第八章,函数与变量,10/10/,2,第2页,本章简介函数定义一般格式,函数调用措施,函数返回值,函数之间参数传递;函数嵌套,函数递归调用;变量寄存类型,内部变量,外部变量,内部函数和外部函数,难点:,函数间参数传递,函数递归,变量寄存类型,C程序是构造化很强程序,将程序按功能自上向下分解,一种函数实现一种功能模块。,1,函 数,1 函 数,C程序模块化构造,10/10/,3,第3页,4.构成C程序各个函数均彼此平行,独立定义,可以嵌套调用。,1.一种C程序可以由若干个源文献构成。,2.一种源文献可以由若干个函数构成。,3.在构成C程序所有函数中,有且仅有一种主函数main(),位置任意(在哪个源文献中都可以),但程序运行总是从主函数开始。,5.函数类型可按不一样样措施分类如下:,说 明,10/10/,4,第4页,原则函数(库函数),顾客定义函数,从顾客角度,从函数任务,从函数形式,完毕某种运算,实现某种处理(并无计算值),有参函数,无参函数,需使用头文献,#include,带回一种返回值,return(表达式),主调函数与被调函,数间有参数传递,400多种,完毕一组操作,函数类型分类,10/10/,5,第5页,函数定义,函数定义,一、无参函数定义,阐明:定义函数类型是指 函数返回值类型,无参函数一般无返回值,因此可以不写。,标识符为函数名,顾客自定义;括号必须有,内称 函数体,即函数功能语句。,格式:,类型 标识符(),阐明语句,执行语句,f,(),int i;for(i=0;i4;i+),printf(“,*,n”);,函数返回值类型,函数体,函数名,10/10/,6,第6页,f,(),printf(“,*,n”);,main(),int i;,main(),for(i=1;i4;i+),f();,printf(“,*,n”);,f();,f,();,主函数内使用循环构造,函数定义,函数调用,两个程序等价,10/10/,7,第7页,格式:类型 标识符(形参表),形参阐明语句,阐明语句,执行语句,int sum(x,y),int x,y;,int z;z=x+y;,return(z);,main(),int a,b,c;,a=30,b=50;,c=sum(a,b);,printf(“%d,%d,%d”,a,b,c);,定义,形参,函数体,返回语句,调用,c=sum(a,b);,二、有参函数定义,10/10/,8,第8页,三、空函数,阐明:空函数中没有语句,什么也不执行。,作用:作为程序整体框架中一种空模块,临时无内容,待补充。,格式:函数名,(),2.形参是临时定义,形式上,只有在函数调用时,由实参传递一种值,调用结束,其值消失。,1,.函数定义类型为函数返回值类型;假如不定义,系统缺省为整型。,说 明,10/10/,9,第9页,8.1.2,函数参数与返回,值,函数参数与返回,值,主调函数,main,(),调用被调函数,sum(),main(),int a,b,c;,scanf(“%d,%d”,c=sum(a,b);,printf(“%d,%d,%d”,a,b,c);,主调函数,int sum(x,y),int x,y;,int z;z=x+y;,return(z);,被调函数,形参,10/10/,10,第10页,一.函数参数,形参与实参,3.编译时,系统不为形参分派寄存空间,函数调用时,临时分派,调用结束,空间释放。,1.,定义函数时,括号内参数表中参数为形参。,2.,调用函数时,括号内参数为实参。,4.实参在主调函数内部定义,可以是常量,变量或表达式,但必须有值,调用被调函数时,将其值传给形参。,5.实参与形参是单向值传递(实 形)。,max(x,y),c=max(a.b),10/10/,11,第11页,形参,x,y在被调函数sum(x,y)中定义,无值,被主调函数调用时:c=sum(a,b);将实参a,b值传给x,y。,实参 a,b 在主调函数,main(),中定义,并有值(,a为30,b为50),。,50,30,a,b,x,y,30,50,调用函数,时临时分,配空间,int sum(x,y),int x,y;,int z;z=x+y;,return(z);,main(),int a,b,c;,a=30,b=50;,c=sum(a,b);,printf(“%d,%d,%d”,a,b,c);,主调函数,被调函数,实参,形参,c=sum(a,b);,值,程序举例,10/10/,12,第12页,函数调用格式:函数名,(,实参表,),函数调用与返回,main(),int a,b,c;,scanf(“%d,%d”,c=sum(a,b);,printf(“%d,%d,%d”,a,b,c);,主调函数,int sum(x,y),int x,y;,int z;,z=x+y;,return(z);,被调函数,形参,10/10/,13,第13页,函数调用格式:函数名,(,实参表,),例:,输入n,计算并输出s=n!,main(),int n,s;,printf(“Input n:“);,scanf(“%d”,s=fac(n);,printf(“s=%d”,s);,主调函数,fac(a),int a;,int i,z=1;,for(i=1;ib?a:b);,2.return(x);,3.return(0);,4.retrun;,5.无return语句,6.void,怎样使用?,return语句比较,10/10/,17,第17页,main(),int a;,void disp();,printf(“Enter an integer:n”);,scanf(“%d”,disp(a);,void disp(x),int x;,if(x 0)printf(“Positive.n”);,else if(x=0)printf(“Zero.n”);,else printf(“Negative.n”);,无类型函数,void,不返回任何值,无类型函数,10/10/,18,第18页,C语言规定:函数返回值类型是由:,A)return语句中表达式类型决定,B)调用该函数时主调函数类型决定,C)调用该函数时系统临时决定,D)定义该函数时所指定函数类型决定,下面函数调用语句中实参个数为:,func(exp1,exp2),(exp3,exp4,exp5),A)1 B)2 C)4 D)5,函数返回值类型分析,10/10/,19,第19页,8.1.3 函数申明和调用,8.1.3 函数申明和调用,例:,main(),f();,主调函数使用被调函数功能,称为对被调函数调用。,函数f()为某一种具有特定功能函数,函数调用是通过函数名 f 实现。,10/10/,20,第20页,例:,sum(a,b),1.,格式:无参函数:函数名,(),有参函数:函数名,(,实参表,),2.实参求值次序:当函数中实参彼此有关系时,TC下求值次序是 从右向左。,从右向左,一、函数调用一般形式,当i原值为2时,对函数f(i,+i),从左向右,为f(2,3);从右向左,为f(3,3)。,若i=3,printf(“%d,%dn”,i,+i)成果为:4,4,10/10/,21,第21页,简介三种,1.,以语句形式:,函数名,(,参数,),加分号,printf(“KKKKKn”);,2.以表达式形式,(函数调用作为运算分量),x=pow(a,j)+b;,3.,作为函数参数,y=sum(pow(a,j),b),求:,a,j,二、函数调用方式,10/10/,22,第22页,对变量应先定义,再使用;对函数,主调函数使用被调函数之前,要对被调函数做申明,详细规定:,1.首先被调函数必须存在,假如是库函数,需用#include 将函数包括进源程序,假如是顾客定义函数,应做申明。,函数定义,函数申明,类型 函数名,(,参数表,),函数体,类型 函数名,(,参数表,),格式:类型 函数名(参数表),函数定义只,能有一次,说,明可以有一再,一种函数可被多种函数调用,三、对被调函数申明,10/10/,23,第23页,(1),定义,函数时有类型,(2),函数,返回值,有类型,(3)主调函数使用被调函数时需阐明类型,规定:三个类型应一致,假如定义类型与返回值类型不符,以,定义,为准,假如定义类型与阐明类型不一致,程序出随机错误,2.有关函数类型,10/10/,24,第24页,(1)函数返回值是,int ,char,(或函数定义类型为,int 或char)。,(2)被调函数定义出目前主调函数之前。,f2(),.,main(),f2();,.,f2(),为被调函数,主函数调用f2()可不作阐明,(3)在文献开始,所用函数定义之前,已对函数阐明了类型,则文献中所有函数都可调用该函数。,3.C容许在如下状况下不作阐明,10/10/,25,第25页,返回值类型为,float,与定义类型不符,以定义为准int,由于是int,主函数中可以不作阐明,输入:6.8,4.5,输出?,修改程序,输入:6.8,4.5,输出?,main(),float a,b;,int m;,scanf(“%f,%f”,m=max(a,b);,printf(“%d”,m);,max(x,y),float x,y;,float n;n=xy?x:y;,return(n);,定义函数,返回值,调用函数,%f,float m;,不定义类型,缺省:,int,10/10/,26,第26页,1.被调函数在调用过程中,调用其他函数称为函数嵌套调用。,2.函数可以嵌套调用,不容许嵌套定义。,函数外部性,一种函数不能定义在其他函数内部,函数之间是互相独立,是平行。,f1(),.,f2(),.,f3(),.,f1(),.,f2(),.,.,平行,定义,8.1.4,函数,递归调用,8.1.4,函数递归调用,一.,函数嵌套,10/10/,27,第27页,main,函数,调用函,数,A;,函数,A,调用函数,B;,函数,B,函数嵌套调用,10/10/,28,第28页,void beijing();,void shanghai();,void tianjin();,main(),printf(“I m in main.n”);,beijing();,printf(“Im finally back in main().n”);,void beijing(),printf(“I m in beijing.n”);shanghai();,printf(“Here Im back in beijing.n”);,void shanghai(),printf(“Now Im in shanghai.n”);,tianjin();printf(“Now I m back in shanghai.n”);,void tianjin(),printf(“I m in tianjin now.n”);,函数申明,beijing();,shanghai();,tianjin();,程序结束,函数嵌套调用举例,10/10/,29,第29页,main(),beijing();,函数嵌套控制流程,beijing(),shanghai();,shanghai(),tianjin();,tianjin(),printf(“I m,in tianjin now.n”);,10/10/,30,第30页,main,函数,调用函,数,sum(a,b);,函数,sum(x,y),int x,y;,两次,调用函数,n1=fac,(x),;,n2=fac,(y),;,返回,n1+n2,两次调用,函数,fac,(n),int n;,for(,),返回,n!,课堂作业:,输入a,b,求s=a!+b!,10/10/,31,第31页,int sum();int fac();,main(),int a,b,s;,printf(Input a,b:);,scanf(%d,%d,s=sum(a,b);,printf(s=%dn,s);,getch();,sum(x,y),int x,y;,int n1,n2,s;,n1=fac(x);,n2=fac(y);,s=n1+n2;,return(s);,两次调用,fac(n),int n;,int i,z=1;,for(i=1;,i0,10/10/,34,第34页,fac(int,n,),if(,n=0,),return(1);,else,return(n,*,fac,(,n-1,);,fac,(int,n,),int s;,if(,n=0,),s=1;,else,s=,fac,(,n-1,);,s=n,*,s;,return(s);,等价于,理解程序思绪:,n!就是 n*(n-1)!,递归调用,10/10/,35,第35页,n,4,=,4,facto(int n),int s;,if(n=0),s=1;,else,s=fac(n-1);,s=n,*,s;,return(s);,fac(int n),int s;,if(n=0),s=fac(n-1),n,3,=,3,facto(int n),int s;,if(n=0),s=1;,else,s=fac(n-1);,s=n,*,s;,return(s);,fac(int n),int s;,s=fac(n-1),if(n=0),n,2,=,2,facto(int n),int s;,if(n=0),s=1;,else,s=fac(n-1);,s=n,*,s;,return(s);,n,1,=,1,facto(int n),int s;,if(n=0),s=1;,else,s=fac(n-1);,s=n,*,s;,return(s);,n,0,=,0,facto(int n),int s;,if(n=0),s=1;,else,s=fac(n-1);,s=n,*,s;,return(s);,fac(int n),fac(int n),fac(int n),int s;,int s;,int s;,if(n=0),if(n=0),if(n=0),s=fac(n-1),s=fac(n-1),s=1,return(,1,),return(,1,),s=n,*,s=,1,*,1,s=n,*,s=,2,*,1,return(,2,),return(,6,),s=n,*,s=,3,*,2,s=n,*,s=,4,*,6,return(,24,),1,2,3,4,5,4,3,2,1,递归调用执行过程,10/10/,36,第36页,例如:给定整数是 12345,规定输出 54321。,这是用递归措施求解非数值问题,递归措施思绪分析:,“有明确解法部分+性质相似小问题”:,(1)输出一种数字,可以做到。,(2)输出给定 N 位整数个位上数字,,(3)前 N-1 位除以十,,(4)原问题被缩减为 N-1 位整数反向输出问题。,(5)假如?(结束条件)执行(6),否则循环再执行(2)。,(6)递归调用结束。,非数值递归措施分析:反向输出给定整数,10/10/,37,第37页,1,2,3,4 5,5,1,2,3 4,5,4,1,2 3,5,4,3,1 2,5,4,3,2,1,5,4,3,2,1,反向输出(整数 N),if(,N,=10,)then,输出最终一位;,N,除以10取整,N,N-1,;,调用反向输出(N,N-1,);,else,输出,N;,最终一位,:,y=N%10,编程时关注:,1.怎样化简:本题化简为一种数字、N-1个数字。,只要问题化简对旳,化简后工作由递归处理。,2.递归结束条件。,递归调用执行过程,10/10/,38,第38页,main(),int x;,printf(“Enter x:”);,scanf(“%d”,int_turn(x);,int_turn(n),int n;,if(n=10),printf(“%d”,n%10);,int_turn(n/10);,else,printf(“%d”,n);,函数自身调用,反向输出给定整数程序,10/10/,39,第39页,汉诺塔问题,64,片,初始杆,中间杆,目杆,1,n,18,446,744,073,709,551,615次,1844亿亿次。每次1微秒,需要60万年,听说在约十九世纪末欧洲商店中发售一种智力玩具,在一块铜板上有三根杆,最左边杆上自上而下、由小到大次序串着由 64 个圆盘构成塔。,游戏目旳是将最左边杆上圆盘,借助最右边杆,所有移到中间杆上,条件是一次仅能移动一种盘,且不容许大盘放在小盘上面。,10/10/,40,第40页,分析,A,杆,C,杆,B,杆,移动措施:,1.将上面小片移到C杆上。,2.将下面大片由A杆移到B杆上。,3.将C杆上小片移到B杆上。,对A杆上所有N个圆盘从小到大次序编号,最小圆盘为1,次之为2号,则最下面圆盘编号为 N。,第一步:将问题简化。假设 A杆 上只有 2 个圆盘,即汉诺塔有 2 层,N2。移动过程如下:,10/10/,41,第41页,A杆,C杆,B杆,将 A杆上面 N-1 个盘子,借助B杆,移到C杆上;,将 A杆 上剩余 N号 盘子移到 B杆 上;,将 C杆 上 N-1个 盘子,借助A杆,移到B杆上,分析,第二步,对于一种有 N(N1)个圆盘汉诺塔,将N个圆盘分为两部分:上面N-1个圆盘和最下面N号圆盘。将“上面N-1个圆盘”当作一种整体。,第三步,为处理 N 个圆盘汉诺塔,可按如下方式进行操作:,10/10/,42,第42页,整顿分析成果,把第一步中化简问题条件作为递归结束条件,将第三步分析得到算法作为递归算法。,定义函数movedisc(n,fromneedle,toneedle,usingneedle)。将 fromneedle 杆上 N 个圆盘,借助 usingneedle 杆,移动到 toneedle 杆上。,移动N个圆盘递归算法描述如下:,movedisc(n,fromneedle,toneedle,usingneedle),if(n=1)将 n 号圆盘从 fromneedle 上移到 toneedle上;,else,movedisc(n-1,fromneedle,usingneedle,toneedle),将 n 号圆盘从 fromneedle 上移到 toneedle上;,movedisc(n-1,usingneedle,toneedle,fromneedle),10/10/,43,第43页,汉诺塔问题程序,int i=0;/*移动圆盘数量计数器*/,main(),unsigned n;,scanf(%d,movedisc(n,a,b,c);/*将A上N个圆盘借助C将移动到B上*/,printf(t Total:%dn,i);,movedisc(n,fromneedle,toneedle,usingneedle),unsigned n;,char fromneedle,toneedle,usingneedle;,if(n=1),printf(%2d-(%2d):%c=%cn,+i,n,fromneedle,toneedle);,else,movedisc(n-1,fromneedle,usingneedle,toneedle);,printf(%2d-(%2d):%c=%cn,+i,n,fromneedle,toneedle);,movedisc(n-1,usingneedle,toneedle,fromneedle);,10/10/,44,第44页,程序执行过程,当N=3时,程序递归调用完整执行过程,在main函数中 递归调用第一层 递归调用第二层 递归调用第三层,递归 递归,move(1,a,b,c)输出:1-(1):a=b,返回递归第二层,输出:2-(2):a=c,调用 move(1,b,c,a)输出:3-(1):b=c,move(2,a,c,b)返回递归第二层,返回递归调用第一层,move(3,a,b,c)输出:4-(3):a=b,move(2,c,b,a)move(1,c,a,b)输出:5-(1):c=a,返回递归第二层,输出:6-(2):c=b,返回main函数 move(1,a,b,c)输出:7-(1):a=b,返回递归第二层,返回递归调用第一层,10/10/,45,第45页,作函数实参(与变量作实参相似),在主调函数中定义数组,将数组中某元素ai 作为实参,将值传给被调函数形参。,数组作函数参数,有几种状况:,一、数组元素作函数参数,二、数组名作函数参数,1 实参和形参都用数组名。,2 在主调函数和被调函数中分别定义数组。,3 类型必须一致。,4 长度可以不一致。,5 实参与形参之间不是值传递,而是地址传递,将实参数组起始地址传给形参数组(两数组共用内存中部分空间)。,数组作函数参数,10/10/,46,第46页,#define N 5,main(),int i,j,a N;,for(i=0;i N;i+),printf(Enter%2d:,i+1);,scanf(%d,sort(,a,N);,for(i=0;i N;i+),printf(%d,a i);,sort(,b,m),int m,b ;,int i,j,t;,for(i=0;i m-1;i+),for(j=0;j b j+1 ),t=b j;,b j =b j+1 ;,b j+1 =t;,a N;,实参用数组名,形参用数组名,数组名=地址,数组名作函数参数,10/10/,47,第47页,main,函数,sort函数,a0,a1,a2,a3,a4,a5,数组名就是,首元素地址,a,b,形参 b 实质是,一种变量,内,容是数组 a,起始地址,对数组名作为参数解释,10/10/,48,第48页,8.1.5 外部,函数与内部函数,外部,函数与内部函数,一.基本概念,函数库:函数库是由系统建立具有一定功能函数集合。库中寄存函数名称和对应目旳代码,以及连接过程中所需重定位信息。顾客也可根据需要建立自己顾客函数库。,系统函数又称库函数,它不是C语言一部分,而是由编译程序根据一般顾客需要编制并提供顾客使用一组程序。,库函数:寄存在函数库中函数。,库函数具有明确功能、入口调用参数和返回值。,连接程序:将编译程序生成目旳码连接起生成可执行文献。,头文献:也称为包括文献。C语言库函数与顾客程序之间进行信息通信时要使用数据和变量,在使用某一库函数时,都要在程序中嵌入(用#include)。,10/10/,49,第49页,二.Tubro C库函数分为九大类,1.I/O函数,包括多种控制台I/O、缓冲型文献I/O和UNIX式非缓冲型文献I/O操作。需要包括文献:,stdio.h,例如:getchar,putchar,printf,scanf,fopen,fclose,fgetc,fgets,fprintf,fsa f,fputc,fputs,fseek,fread,fwrite等。,10/10/,50,第50页,2.字符串、内存和字符函数,包括对字符串进行多种操作和对字符进行操作函数。,需要包括文献:string.h、mem.h、ctype.h或 string.h,例如:用于检查字符函数:isalnum,isalpha,isdigit,islower,isspace等。,用于字符串操作函数:strcat,strchr,strcmp,strcpy,strlen,strstr等。,10/10/,51,第51页,3.数学函数,包括多种常用三角函数、双曲线函数、指数和对数函数等。需要包括文献:math.h,例如:sin,cos,exp(ex次方),log,sqrt(开平方),pow(xy次方)等。,4.时间、日期和与系统有关函数,对时间、日期操作和设置计算机系统状态等。,需要包括文献:time.h,例如:time返回系统时间;asctime返回以字符串形式表达日期和时间。,10/10/,52,第52页,5.动态寄存分派,包括“申请分派”和“释放”内存空间函数。需要包括文献:alloc.h 或 stdlib.h,例如:calloc,free,malloc,realloc等。,6.目录管理,包括磁盘目录建立、查询、变化等操作函数。,7.过程控制,包括最基本过程控制函数,8.字符屏幕和图形功能,包括多种绘制点、线、圆、方和填色等函数。,10/10/,53,第53页,9.其他函数,库函数使用注意事项:,在使用库函数时应清晰理解如下四个方面内容:,函数功能及所能完毕操作。,参数数目和次序,以及每个参数意义及类型。,返回值意义及类型。,需要使用包括文献。,这些是要对旳使用库函数必要条件。,10/10/,54,第54页,函数仅被本文献内其他函数调用-内部函数,函数容许其他文献中函数调用-外部函数,C中函数都是独立定义,因此都是外部(即在其他函数外定义)。,程序-文献-函数,怎样将多种源文献组装成一种C软件,三.内部函数和外部函数,10/10/,55,第55页,环节如下:,1.在TC下编辑多种源文献,file1.c,file2.c,file3.c,2.在TC下编辑一种“项目文献”,措施:,(1)菜单“文献”下,选“装入”,键入文献名:aaa.prj,(2)键入文献内容:file1.c,file2.c,file3.c,(3)在菜单“项目文献(project)“下,输入项目文献文献名aaa.prj,(4)编译,连接,运行该程序(Alt+R),成果,将多种源文献组装成一种C程序,10/10/,56,第56页,编译,file1.c file1.obj,file2.c file2.obj,file3.c file3.obj,连接,aaa.exe,运行:aaa,aaa.prj,程序-文献-函数,组装过程,10/10/,57,第57页,变量是定义在一种函数内,还是定义在函数之外,是被一种函数所使用,还是被文献中多种函数所使用,或被若干个文献(整个程序)中所有函数所使用,变量值与否容许被其他函数修改。,掌握要点:变量怎样定义。,在什么范围内有效。,变量值能保留多久。,本节简介,全程-文献-函数,存储属性,可见性,生存期,2 变量作用域和寄存类型,2 变量作用域和寄存类型,8.2.1 变量作用域,10/10/,58,第58页,C程序,源文献1,源文献2,源文献3,.,源文献n,预处理命令,函数1,函数2,.,函数,n,阐明语句,执行语句,main(),最小编,译单位,最小功,能单位,必须一种,主函数,全程-文献-函数,C程序层次构造,10/10/,59,第59页,1.在功能函数(或复合语句)内定义。,2,.在定义它函数(或复合语句)内有效。,3.,只有当函数被调用时,才有值,函数调用结束,值不被保留。,4.对其他函数不可见(即不可访问)。,float f(a),int a;,int b,c;,a,b,c,为局部变量,5.阐明:形参为局部变量。,不一样样函数中局部变量可以重名,一、局部变量,10/10/,60,第60页,f(),int,x=1,;,int,x=2,;,int,x=3;,printf(“,*,%dn”,x,);,printf(“,*,%dn”,x,);,printf(“,*,%dn”,x,);,复合语句,成果:,*3,*2,*1,复合语句内定义,复合语句内有效,程序举例,10/10/,61,第61页,程序编译单位是源文献(*.c),一种源文献可以包括一种或若干函数,函数内定义变量是局部变量,函数外定义变量就是外部变量,可为文献内所有函数所共享。,1.,函数外定义。,2.有效范围:从定义开始到本文献结束。,3.所有函数可以访问,变量值在一种函数内发生变化,会影响到其他函数-值保留。,二、全局变量,10/10/,62,第62页,(4)同一种源文献中,局部变量与全局变量同名,在局部变量起作用范围内,全局变量不起作用。,(1)全局变量是在编译时分派寄存空间,自始至终占寄存单元。,(2)假如在定义之前使用某全局变量,用extern阐明。,(,3,)全局变量初始化只能有一次,是在定义时进行。,阐明,10/10/,63,第63页,extern int a;,main(),int I;for(I=1;I=5;I+),+a;,printf(”%dn”,a);,s();,int a=10;,s(),int a=100;,+a;,printf(“%dn”,a);,全局变量阐明,全局变量定义,初始化,局部变量定义,初始化,11,101,12,101,13,101,14,101,15,101,为何,阐明?,课堂作业-1,10/10/,64,第64页,int x=500;,main(),int x=300;,f();,ff();,printf(“x=%dn”,x);,f(),x+=100;printf(“x=%dn”,x);,ff(),int x=10;printf(“x=%dn”,x);,全局变量定义,初始化,局部变量定义,初始化,局部变量定义,初始化,600,10,300,课堂作业-2,10/10/,65,第65页,计算机保留变量目前值寄存单元有:,程序区,静态寄存区,动态寄存区,内,存,CPU寄存器,寄存程序,寄存静态变量,寄存动态变量,(寄存目前途序),(分派固定寄存空间,变量值保留)。,根据需要临时分派空间,变量值不保留。,8.2.2 变量寄存类型,一、动态与静态变量,10/10/,66,第66页,变量作用范围,-作用域(可见性)。,变量值保留期限,-,生存期。,从可见性:变量分,局部变量,和,全局变量。,从生存期:静态寄存变量和动态寄存变量。,auto,static,register,extern,定义变量:int a,b;只有操作属性,static int a10=1,2,3,4,5,6;,有寄存属性和操作属性。,变量寄存在不一样样位置影响,10/10/,67,第67页,凡不定义寄存属性均为自动变量,int a;等价于 auto int a;,float b;等价于 auto float b;,作用域:定义该变量函数。,生存期:函数调用期间(函数调用时才有值,调用结束,值消失)。,寄存在内存,动态寄存区,动,态分派寄存空间,auto,二、变量寄存属性,1.自动变量 auto,10/10/,68,第68页,(,1)在函数之外定义变量(假如在函数内定义,需写,extern)。,(2)外部变量定义后,分派固定寄存空间。,(3)所有函数都可使用,函数调用结束,值保留。,(4)作用域,生存期均为整个程序。,extern,*多种文献中多种函数都可以使用,可以减少形参,实参个数。,*一直占寄存单元。,*影响函数“内聚性”和“耦合性”。,功能单一,互相影响小,2.外部变量,extern,10/10/,69,第69页,静态变量是介于自动变量和外部变量之间,有两类:静态局部变量和静态全局变量,*函数内定义。,*函数内有效,函数外不可见(可见性)。,*函数调用之后,保留原值(生存期)。,*对静态变量如不赋初值,系统自动赋 0值。,*C中规定,只有静态数组和全局变量(数组)才能初始化。,*虽然每次调用函数,该变量值保留,但仅限本函数使用,对其他函数仍不可见。,局部,静态,3.静态变量,static,(1)静态局部变量,10/10/,70,第70页,main(),int i;for(i=1;i=5;i+),f(i);,f(j),int j;,static int a=100;,auto k=1;+k;,printf(“%d+%d+%d=%dn”,a,k,j,a+k+j);,a+=10;,函数调用,函数定义,函数内定义,值不保留。,程序举例,运行成果:,100+2+1=103,110+2+2=114,120+2+3=125,130+2+4=136,140+2+5=147,10/10/,71,第71页,C程序,源文献1,源文献2,源文献3,.,源文献n,预处理命令,函数1,函数2,.,函数,n,阐明语句,执行语句,main(),最小编,译单位,最小功,能单位,必须具有一种,主函数,C语言程序基本构造,10/10/,72,第72页,函数外定义,程序运行中,该值都保留(生存期)。,定义该变量文献内有效,对程序其他源文献中函数,是不可访问(可见性)。,全局,静态,假如但愿变量在本文献内有效,且不被其他,文献调用,使用静态全局变量。,假如但愿变量只在函数内有效,且保留每,次运行函数后值,用静态局部变量。,(2)静态全局变量,10/10/,73,第73页,(1)寄存在硬件寄存器上,(,2,)存取速度快,(,3)只能定义 2,个,(,4)只能是,int 和char 类型,通常用来寄存使用频率较高变量,例如循环变量等。,*只有形参和局部变量才可以作为寄存器变量,静态局部变量不可以作为寄存器变量。,当前优化编译系统自动识别使,用频繁变量,不用用户定义!,4.寄存器变量 register,10/10/,74,第74页,3,本章小结,3 本章小结,一.有关概念,1.函数是C中最小功能单位;,2.源文献(*.c)是C中最小编译单位;,3.程序运行是从,main()开始;,4.主函数,main()位置是任意;,5.函数之间是平行;,6.函数只能嵌套调用,不能嵌套定义。,10/10/,75,第75页,1 函数类型是函数返回值类型;,2 C规定函数定义类型,阐明类型和函数定义,类型一致;,3 定义类型与返回值类型不一致时,以定义为准;,4 不定义函数类型,系统认为是int;,5 当函数是int,char型时,可以不作阐明;,6 无参函数可以不定义类型;,7 不需返回任何值时,应定义无类型void。,二.有关函数类型,10/10/,76,第76页,1.定义函数时,括号内为形参,2.调用函数时,括号内为实参,3.实参与形参需类型相似,个数相等,4.形参在函数被调用时才分派寄存空间,有值,5.实参在主调函数内有值,求值次序是从右向左,6.实参与形参是单向数值传递,7.假如实参与形参都是数组名,是地址传递,8.实参数组与形参数组类型相似,个数可以不一样样,三.有关函数参数,10/10/,77,第77页,1.函数以作运算分量,作函数参数,也可构成语句。,2.函数调用可以嵌套。,3.函数中return语句可以带回一种返回值。,五.有关变量,从变量作用域:局部变量,全局变量,从变量值保留期限:静态寄存变量,动态寄存变量,从变量在硬件上位置:CPU寄存器,内存中静态区,内存中动态区,四.有关函数调用,10/10/,78,第78页,从变量作用域:局部变量,全局变量,从变量值保留期限:静态寄存变量,动态寄存变量,从变量在硬件上位置:CPU寄存器,内存中静态区,内存中动态区,五.寄存特性总结,1.变量寄存特性,10/10/,79,第79页,变量寄存特性,特点,生存期,作用域,未初始化时值,自动变量,定义它函数(局部变量),随机数,外部变量,整个程序中多个文件中多个函数(全程变量),0,静,态,局部,全局,整个程序,定义它函数,(静态局部),定义它文件,(静态全程),0,0,存放器,定义它函数,随机数,2.寄存特性汇总,10/10/,80,第80页,E N D,上机与作业五,1.写一函数s(d)判d与否为素数,验证100以内哥德巴赫猜测。,2.调用函数,计算圆筒体积。,3.调用函数,输出所有水仙花数。所谓“水仙花数”是一种3位数,其各位数字立方和等于该数自身。例如,153是“水仙花数”,由于153=13+53+33。,4.输入x、n,用递归措施计算xn。,先将程序编写在稿纸上,第15周四上机调试运行得到对旳成果。其他为选做
展开阅读全文