C语言课件-8实用教案

上传人:ni****g 文档编号:568770443 上传时间:2024-07-26 格式:PPT 页数:91 大小:2.66MB
返回 下载 相关 举报
C语言课件-8实用教案_第1页
第1页 / 共91页
C语言课件-8实用教案_第2页
第2页 / 共91页
C语言课件-8实用教案_第3页
第3页 / 共91页
C语言课件-8实用教案_第4页
第4页 / 共91页
C语言课件-8实用教案_第5页
第5页 / 共91页
点击查看更多>>
资源描述

《C语言课件-8实用教案》由会员分享,可在线阅读,更多相关《C语言课件-8实用教案(91页珍藏版)》请在金锄头文库上搜索。

1、共90页第1页 本章要点函数的定义函数的调用函数间的数据传递变量的存储类型变量的作用范围内部(nib)函数和外部函数第1页/共90页第一页,共91页。共90页第2页C C程序是函数的集合体,每个函数是一个独立的程序模块。有一个主函数,若干个子函数,程序总是从主函数开始执行(zhxng)(zhxng)。函数可集中或分散存放在一个或多个源程序文件中。所有子函数地位平等,可互相调用、自我调用。 引入函数的优点: 减少重复编写程序的工作量;使程序便于调试和阅读。函数(hnsh)F1 ( )main ( )F11 ( )F2 ( )F21 ( )F22 ( )C C语言程序语言程序(chngx)(chn

2、gx)的结构的结构8.1 8.1 函数的概念和函数的定义第2页/共90页第二页,共91页。共90页第3页数学函数(hnsh) math.h(hnsh) math.h字符和字符串函数(hnsh) ctype.h, (hnsh) ctype.h, string.hstring.h输入/ /输出函数(hnsh) stdio.h(hnsh) stdio.h动态存储分配函数(hnsh) calloc(),malloc(hnsh) calloc(),malloc()()形式无参函数有参函数空函数库函数用户定义函数: :C C函数函数(hnsh)(hnsh)的分类的分类第3页/共90页第三页,共91页。共9

3、0页第4页例 输入三个整数(zhngsh),计算它们的和并输出运算结果。int add(int x, int y, int z) int s; s=x+y+z; return s;函数(hnsh)示例定义的求和(qi h)函数main( ) int a, b, c, sum ; scanf(%d,%d,%d,&a,&b,&c); sum=add(a,b,c); printf( sum= %dn,sum); 调用求和函数第4页/共90页第四页,共91页。共90页第5页8.1.2 8.1.2 函数(hnsh)(hnsh)的定义定义函数应包括的内容:(1)指定函数的名字,以便以后按名调用;(2)指定

4、函数的类型,即函数值的类型;(3)指定函数的参数(cnsh)的名字和类型(有参);(4)指定函数执行的操作,即函数完成的功能。在程序中用到的所有函数,必须先定义(dngy),后使用。第5页/共90页第五页,共91页。共90页第6页定义函数的一般形式类型标识符 函数名(形式参数表) 说明部分(b fen) 语句若无参数,写void或空。是被初始化的内部变量,寿命和可见性仅限于函数内部不说明类型,自动按整型处理.建议都指定类型函数体(一段程序,实现函数的功能)第6页/共90页第六页,共91页。共90页第7页1.无参函数的定义形式类型标识符函数名()说明部分(bfen)语句例8-1 void pri

5、nt_message( ) printf(How are you !n); 第7页/共90页第七页,共91页。共90页第8页例8-2intmax(intx,inty)intz;z=xy?x:y;returnz;类型标识符 函数名(形式参数表列) 说明(shumng)部分 语句 int max ( x, y) int x,y; int z; z=xy?x : y; return z; 形参变量的说明(传统(chuntng)形式)形参变量的说明(现代(xindi)形式)2. 有参函数的定义形式第8页/共90页第八页,共91页。共90页第9页3.形式参数说明形式参数:在定义函数时函数名后面括弧中的变

6、量(binling)名在形参表中说明的形参,在函数体中不再说明,可以同一般变量(binling)一样直接使用。形参调用前不占内存单元,调用时分配内存单元。调用结束后释放。形参是函数的内部变量(binling),只在函数内部才有意义。对每个形参必须指明其名字和数据类型。多个形参用逗号分隔。第9页/共90页第九页,共91页。共90页第10页例:有函数调用语句: int i=3; printf(”%d,%d”,i,+i);输出(shch)结果为:4,4 分析(fnx)输出函数的结果:自右向左:4,4自左向右:3,4避免这种不确定性:改为(i wi): int i=3, j; j=i; printf(

7、”%d,%d”,i,+j);输出结果为:3,4第10页/共90页第十页,共91页。共90页第11页8.1.3函数(hnsh)的调用1.函数调用的一般形式为:函数名(实际参数列表);或函数名(实际参数列表)说明:实参必须有确定的值,可以是常量、变量(binling)、表达式及函数调用。实参与形参的类型、个数、顺序必须一致。多个实参用逗号分隔。 2. 执行过程:执行过程:计算各个表达式(计算各个表达式(TC2.0,VC+6.0实参求值顺序实参求值顺序(shnx)按按自右至左自右至左);把得到值赋给对应的形参把得到值赋给对应的形参;执行函数体执行函数体;遇到遇到return语句或执行完最后一条语句语

8、句或执行完最后一条语句,返回到函数调用处返回到函数调用处.第11页/共90页第十一页,共91页。共90页第12页(1)函数语句:(把函数调用(dioyng)作为一个语句)一般形式:函数名(实际参数表);使用情况:这种方式常用于调用(dioyng)一个可以忽略返回值或没有返回值的函数,只要求函数完成一定的操作。例如:print_message();3.函数调用的具体(jt)方式(2) 函数表达式:(函数调用出现在一个表达式中)函数表达式:(函数调用出现在一个表达式中) 一般形式:变量名一般形式:变量名=函数表达式函数表达式 使用情况:这种表达式称为函数表达式。要求函数带使用情况:这种表达式称为函

9、数表达式。要求函数带回回 一个确定的值参加表达式的运算。一个确定的值参加表达式的运算。 例如:例如:c=3+max(a, b); d=pow(c, i); e= f(x1,x2,x3),(y1,y2); 函数有几个函数有几个(j )参数?参数?第12页/共90页第十二页,共91页。共90页第13页值传递:在函数调用时,实参将其值传递给形参。实参对形参的数据传递是“值传递”,即单向传递,只由实参传递给形参,而不能由形参传回来给实参。实参与形参占用不同的单元。在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束(jish)后,形参单元被释放,实参单元仍保留并维持原值。在执行一个被

10、调用函数时,形参的值如果发生变化,并不会改变主调函数中实参的值。8.1.4 函数参数的传递(chund)方式 值传递的优点: :被调用的函数不可能(knng)(knng)改变调用函数中变量的值,而只能改变它的局部的临时副本。 值传递的缺点: :每个形式参数仅能传递一个数据,不适用需要在函数之间传递大量数据。 地址传递:将实参的地址传递给形参,实参和形参指向同一内存空间,对形参的修改,可以直接影响实参。第13页/共90页第十三页,共91页。共90页第14页例8-3 编写函数交换(jiohun)两个变量的值。 #include void swap ( int x, int y) int temp;

11、 temp=x; x=y; y=temp; printf ( x=%d, y=%dn, x, y); int main ( ) int a, b; a=5; b=10; printf ( a=%d, b=%dn, a, b); swap(a, b); printf ( a=%d, b=%dn, a, b);运行(ynxng)结果:a=5 ,b=10x=10 ,y=5a=5 ,b=10第14页/共90页第十四页,共91页。共90页第15页8.1.5函数(hnsh)的返回值 2. 2. 函数的返回值语句 一般形式: return return 表达式; ; 或 return return (表达式

12、); 功能:退出函数,将表达式的值带回主调函数,回到程序原来的位置继续执行。 return return 语句也可以没有表达式,其作用(zuyng)(zuyng)是使程序执行的流程返回到调用函数。 1.定义:通过定义:通过(tnggu)函数调用使主调函数得到一个函数调用使主调函数得到一个确定确定2. 的值,称为函数的返回值。的值,称为函数的返回值。第15页/共90页第十五页,共91页。共90页第16页说明:returnreturn语句只能把一个返回值传递(chund)(chund)给调用函数。返回值的类型为定义的函数类型,若returnreturn语句中表达式类型与函数类型不一致,以函数类型为

13、准。返回值可以是有确定值的常量、变量或表达式,也可以是地址。当返值是地址时,应该用指针接受。无返回值的函数,定义为voidvoid类型( (无类型函数)。一个函数中可以有多个返回语句。exit()exit()函数由ANSC CANSC C定义的,功能是终止和关闭所有程序,结束程序执行,忽略返回值。0 0 为正常退出 非0 0 为非正常退出。第16页/共90页第十六页,共91页。共90页第17页 main( ) int a,b,c; scanf (“%d,%d”,&a,&b); c=max(a,b); printf(“Max is %d”,c); 例8-4 int max(int x, int

14、y) int z; z=xy? x:y; return(z); 形参:通知系统(xtng) 要预留内存位置.实参:在运行(ynxng)时把值传给函数.把函数(hnsh)的 结果赋给函数(hnsh)名形参与实参、函数名与返回值之间的关系第17页/共90页第十七页,共91页。共90页第18页例8-5用函数(hnsh)计算浮点数x的n次方,其中n为整型(n=0)doublepower(doublex,intn)doublep=1;inti;if(n0)for(i=1;i=n;i+)p=p*x;returnp;main() int n; double x; scanf(“%d%lf”,&n,&x);

15、printf(“%f”, power(x,n); 第18页/共90页第十八页,共91页。共90页第19页例8-6编写(binxi)函数,将一个给定的整数转换成字符串。#include void to_str(int n) char string10; int i=0; if(n0) stringi+=n%10+0; n/=10; while(-i=0) putchar(stringi);int main() printf(The converted string: ); to_str(-123); return 0;运行(ynxng)结果:The converted string:-123第1

16、9页/共90页第十九页,共91页。共90页第20页例8-7 编写函数(hnsh),求1+1/2+1/3+1/n的值,并在主函数(hnsh)中调用它。#include double count(int n) int i; double sum=0; if(n=0) printf(Data error!n); return 0; else for(i=1;i=n;i+) sum+=1.0/i; return sum; int main() int n; double s; printf(Please input the value: ); scanf(%d, &n); s=count(n); pr

17、intf(s=%6.2lfn, s);运行(ynxng)结果:Please input the value:5s= 2.28第20页/共90页第二十页,共91页。共90页第21页8.1.6函数(hnsh)的声明问题的提出:C语言程序可由若干文件组成,每一个文件可以单独编译(biny)。一个源程序文件由一个或多个函数组成。在一个函数中调用另一个函数需要具备如下条件:1)函数必须是已经定义的函数;2)如果使用库函数,应该在文件开头包含库函数的信息;3)若函数使用在定义之前,必须在调用函数前对函数进行声明。 同变量一样,函数的调用也应该(ynggi)遵循“先说明,后使用”的原则。 1. 函数声明的一

18、般形式: 类型标识符 函数名( (类型1 1 形参1 1,类型2 2 形参2,2,) ); ;功能:通知编译程序函数值类型、参数个数及类型,为编译程序进行类型检查提供依据。第21页/共90页第二十一页,共91页。共90页第22页main() float add(float x,float y); float a, b, c; scanf(“ %f, %f”, &a, &b); c=add(a,b) ; printf(“ sum is %f ”, c );/*定义(dngy)add函数*/float add (float x,float y) float z; z=x+y; return (z)

19、; 对被调用函数的说明(shumng)作为(zuwi)表达式被调用第22页/共90页第二十二页,共91页。共90页第23页2. 函数声明和函数定义(dngy)的区别 函数声明的作用是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统(xtng),以便在调用该函数时系统(xtng)按此进行对照检查。 函数定义是指对函数功能的确立,包括指定(zhdng)函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。 函数声明与函数定义的首部唯一区别:函数说明语句的()之后必须有分号,而函数定义头部的()之后没有分号。第23页/共90页第二十三页,共91页。共90页第24页(

20、1) 被调用函数在主调函数之前(zhqin)定义 float add (float x, float y) float z; z=x+y; return (z); main() float a, b; scanf(“ %f, %f, “&a, &b); printf(“ sum is %f ”, add(a, b) ); 3. 可省略被调用函数声明(shngmng)的二种情况 第24页/共90页第二十四页,共91页。共90页第25页(2) 在所有函数(hnsh)定义之前说明char letter( char,char);float f(float,float );int i(float,flo

21、at);main( ) .char letter (char c1,char c2)float f(float x,float y)int i(float,float)在所有函数之前(zhqin)说明函数类型定义(dngy)函数letter、f和i第25页/共90页第二十五页,共91页。共90页第26页8.2 数组作函数参数数组元素可以作函数(hnsh)的实参 数组元素作为表达式的组成部分做函数(hnsh)的实参可以单向将值传递给形参。 例如: int a10; x=power( a6,5);数组名可以作函数(hnsh)的实参和形参 实现批量数据的传递第26页/共90页第二十六页,共91页。共

22、90页第27页一维数组作函数参数,形参的写法(xif)为:类型说明符形参数组名数组长度例如:floataverage(floatarray10)main()floatb10;inti;for(i=0;i10;i+)scanf(“%f”,&bi);average(b);8.2.1 一维数组作函数参数说明:形参和实参分别(fnbi)定义数组数组做函数参数时,实参用数组名, 必须有确切值实参数组和形参数组类型应一致。第27页/共90页第二十七页,共91页。共90页第28页说明:实参数组和形参数组大小不一定一致,一维形参数组可以不指定大小。数组名除作为变量的标识外,还代表该数组在内存中存放区域的首地址

23、。数组名做函数实参与形参之间是“地址传递”,实参数组将数组的起始地址传递给形参数组。编译系统不再(bzi)为形参数组分配存储单元。在函数体中对形参数组的元素操作时就是对实参数组的元素进行操作。形参数组各元素的值发生变化会使实参数组各元素的值发生同样的变化。数组名作函数参数可实现大量数据的传递,无须返回数组值。第28页/共90页第二十八页,共91页。共90页第29页例8-8 阅读如下(rxi)程序,给出打印结果。 void swap( int a ) int t; t=a0; a0=a1; a1=t; main( ) int b2=1,2 ; swap(b); printf(“b0=%d,b1=

24、%dn”,b0,b1); 结果(ji gu):程序运行演示(ynsh)可不定义 长度b数组a数组在调用函数过程中改变了原数组的值,实参数组与形参数组共享一组存储空间,第29页/共90页第二十九页,共91页。共90页第30页例8-9:编写(binxi)函数用选择法对数组中10个整数由小到大排序.程序设计(chn x sh j)思想:函数(hnsh)sort(array, n) :实现数组元素由小到大排序。主程序 :输入array数组,调用 sort 函数比较,输 出排序后的array数组。void sort (int array , int n) int i, j, k, t; for (i=0

25、; in-1; i+) k=i; for (j=i+1; jn; j+) if (arrayjarrayk) k=j; if (k!=i) t=arrayk; arrayk=arrayi; arrayi=t; 用另外一个参数表示数组的长度第30页/共90页第三十页,共91页。共90页第31页main ( ) int a10, i; printf(“enter array: n”); for (i=0; i10; i+) scanf (“ %d ”,&ai); sort(a, 10); printf(“the sorted array: n”); for (i=0; i10; i+) print

26、f (“ %d ”, ai); printf(“n”);由于地址传递(chund),实参数组 a 改变数组名做参数(cnsh)的好处:由于(yuy)只需复制一个地址值,而无须复制全部需要处 理的数据,因此节约存储空间并提高效率。 由于主调函数和被调函数是在相同的内存区域上对 数据进行操作,因此可以实现数据的同步更新。 函数调用第31页/共90页第三十一页,共91页。共90页第32页例8-10 将给定(i dn)字符串复制到另一字符串。#include “stdio.h”void strcopy(char str1 ,char str2 ) int i=0; while(str1i!=0) st

27、r2i=str1i; i+; str2i=0;main() char s150,s250; printf(“Input string s1:”); gets(s1); strcopy(s1,s2); printf(“%s”,s2);第32页/共90页第三十二页,共91页。共90页第33页【例8-11】函数del(s,i,n)的功能是从字符串s中删除从第i个字符开始(kish)的n个字符。主函数调用del函数,从字符串management中删除从第3个字符开始(kish)的4个字符,然后输出删除子串后的字符串。voiddel(chars,inti,intn)intj,k,length=0;whi

28、le(slength!=0)A;j=-i;k=i+n;while(klength)sj+=sk+;sj=0;main()charstr=management;del(B);printf(Thenewstringis:%sn,str);答案(d n) A: length+ B: str,3,4第33页/共90页第三十三页,共91页。共90页第34页8.2.2二维数组作函数参数二维数组作函数参数,形参的写法为:类型说明符形参名数组长度(chngd)1数组长度(chngd)2说明:形参数组定义时可以指定或省略第一维的大小例如:intarray310;或intarray10;intarray3;和in

29、tarray;错误 实参数组可以(ky)大于形参数组 例如:实参数组定义为:int array 510; 形参数组定义为:int array 310; 这时形参数组只取实参数组的一部分,其余部分不起作用。第34页/共90页第三十四页,共91页。共90页第35页 例8-12 8-12 编写函数(hnsh)(hnsh),求3*43*4矩阵中的最大值。 int max_value(int array 4) int max_value(int array 4) int i, j, max; int i, j, max; max=array00; max=array00; for(i=0 ; i3 ;

30、i+) for(i=0 ; i3 ; i+) for(j=0; j4; j+) for(j=0; jmax) if(arrayijmax) max=arrayij;max=arrayij; return (max); return (max); int main() int main() int int a34=1,3,5,7,2,4,6,8,10,12,15,17;a34=1,3,5,7,2,4,6,8,10,12,15,17; printf(“max=%dn”,max_value(a); printf(“max=%dn”,max_value(a); 函数调用第35页/共90页第三十五页,共

31、91页。共90页第36页8.3 函数(hnsh)的嵌套调用和递归调用8.3.1 函数的嵌套调用嵌套定义:在定义一个函数时,该函数体内包含(bohn)另一个函数的定义。嵌套调用:在调用一个函数的过程中,又调用另一个函数。 C语言不能嵌套定义,但可以嵌套调用!第36页/共90页第三十六页,共91页。共90页第37页main函数调用A函数结 束A函数调用B函数B函数192873456 两层嵌套的例子(l zi)第37页/共90页第三十七页,共91页。共90页第38页 8.3.2 8.3.2 函数(hnsh)(hnsh)的递归调用f 函数(hnsh)调用(dioyng) f函数1. 1. 递归的概念:

32、 在调用一个函数的过程中直接或间接地调用该函数本身。直接调用:int f(x)int f(x)int x;int x; int y,z; int y,z; z=f(y); z=f(y); return (2*z); return (2*z); 第38页/共90页第三十八页,共91页。共90页第39页int f1(x)int x; int y,z; . z=f2( y); return (2*z); int f2(t)int t; int a,c; . c=f1(a); return (3+c); 间接(jin ji)调用:f 1函数调用 f2函数f 2函数调用 f1函数第39页/共90页第三十

33、九页,共91页。共90页第40页递归函数的执行过程: -递归调用:记住本次现场,递归调用。 -终了调用:返回上次调用现场。特点: -是无终止(zhngzh)的递归调用,因此,应该给定一 个限制递归次数的条件。 -结构简练。第40页/共90页第四十页,共91页。共90页第41页float fac( int n) float f; if(n0) printf(“n1)例8-13 用递归法求n!调用阶乘函数不能赋给函数(hnsh)名第41页/共90页第四十一页,共91页。共90页第42页递归函数facfac的求解(qi ji)(qi ji)过程,以求9 9的阶乘为例:fac(9)=9*fac( 8)

34、fac(8)=8*fac( 7)fac(2)=2*fac( 1)fac(1)=1fac(9)=9*fac( 8)fac(8)=8*fac( 7)fac(2)=2*1fac(3)=3*fac( 2)fac(3)=3*2*1下推回代第42页/共90页第四十二页,共91页。共90页第43页例8-14用递归法将一个整数n转换成字符串。例如输入(shr)256,应输出“256”,n的位数不固定,可以是任意位数的整数。void void tranverstranvers(int n)(int n) if(n/10!=0) if(n/10!=0) tranvers(n/10);tranvers(n/10);

35、 printf(%c,n%10+0); printf(%c,n%10+0); main( )main( ) int n; int n; printf(“please input an printf(“please input an integral number”);integral number”); scanf(%d,&n); scanf(%d,&n); if(n0) if(n0) printf(“-); printf(“-); n=-1*n; n=-1*n; tranvers(n);tranvers(n); 第43页/共90页第四十三页,共91页。共90页第44页main()函数第一次调

36、用tranvers函数递归函数tranvers的求解过程示意图第二次调用tranvers函数第三次调用tranvers函数tranvers(25)输出字符2tranvers(2)输出字符5输出字符6tranvers( 256)结束第44页/共90页第四十四页,共91页。共90页第45页变量变量(binling)(binling)的数据类型的数据类型 char 型 int 型 float 型 double 型总结:数据类型决定为变量分配的内存单元的长度,数据的存放总结:数据类型决定为变量分配的内存单元的长度,数据的存放总结:数据类型决定为变量分配的内存单元的长度,数据的存放总结:数据类型决定为变

37、量分配的内存单元的长度,数据的存放 形式。(从程序设计角度,决定了可以表示形式。(从程序设计角度,决定了可以表示形式。(从程序设计角度,决定了可以表示形式。(从程序设计角度,决定了可以表示(biosh)(biosh)的数的范围)的数的范围)的数的范围)的数的范围)问题:问题:问题:问题:1. 1. 何时为变量分配内存何时为变量分配内存何时为变量分配内存何时为变量分配内存(ni cn)(ni cn)单元?单元?单元?单元? 2. 2. 变量位于内存变量位于内存变量位于内存变量位于内存(ni cn)(ni cn)的什么位置?的什么位置?的什么位置?的什么位置? 3. 3. 变量的有效作用范围?变量

38、的有效作用范围?变量的有效作用范围?变量的有效作用范围?8.4变量的作用域和存储方法(VC+6.0环境)第45页/共90页第四十五页,共91页。共90页第46页 变量的作用域和生存期: : 变量的作用域 指一个变量在程序中的有效范围。(也称为可见性) C C语言规定:凡是在函数内定义的变量,它的作用域仅仅是包含这个变量定义的复合(fh)(fh)语句;而在函数体外定义的变量,它的作用域是从定义点到文件尾。 变量的生存期 指程序在执行期间,变量存在的时间间隔,即从给变量分配内存,至所分配内存被系统收回的那段时间。 C C语言规定:凡是出现在静态数据区的变量,生存期都是从程序开始执行到程序结束;而出

39、现在静态区之外的变量,生存期仅仅是从函数开始执行到函数执行结束这段时间。第46页/共90页第四十六页,共91页。共90页第47页1.1.局部变量(内部变量) 定义:在函数内部定义的变量,只能在本函数内部使用。 说明(避免了函数间的相互干扰,增加了函数的独立性)主函数 main main 定义的变量只在主函数中有效,主函数不能使用其它(qt)(qt)函数定义的变量。不同函数可以使用相同名字的变量。形式参数也是局部变量。可以在一个函数内部,也可以在复合语句中定义变量,这些变量只在本复合语句中有效。8.4.1 局部变量和全局变量char search(char s) char ch; int k;

40、变量(binling)s、ch、k的作用域编译系统不为局部变量分配内存单元,只是当被调用时,根据需要分配临时单元,调用结束,空间(kngjin)释放。第47页/共90页第四十七页,共91页。共90页第48页例:main()int m,n; int x,y;变量x,y的作用域变量m,n的作用域第48页/共90页第四十八页,共91页。共90页第49页阅读以下程序(chngx),写出程序(chngx)的运行结果。main()inti=3,j=2,k;k=i+j;intk=8;if(i=4)printf(%d,k);elseprintf(%d,j);printf(%d,%d,i,k);2,3,5第49

41、页/共90页第四十九页,共91页。共90页第50页2. 2. 全局变量定义(dngy)(dngy):在函数之外定义(dngy)(dngy)的变量是全局变量( (外部变量) )。语法:类型说明 变量名 ;使用范围:可以为本文件中所有的函数公用。从定义(dngy)(dngy)变量的位置开始到本文件结束,这段程序中的函数可直接使用全局变量,int a,b=3;main( ) float k;char str(char s20) 全局变量a、b的作用域全局变量k的作用域第50页/共90页第五十页,共91页。共90页第51页 int p=1,q=5; /*外部变量(binling)*/ f1( int

42、a) /*定义函数*/ int b,c; char c1,c2; /*外部变量(binling)*/ f2( int a, int b) /*定义函数*/ . main() int m,n 全局变量c1、c2的作用(zuyng)范围全局变量p、q的作用(zuyng)范围第51页/共90页第五十一页,共91页。共90页第52页例如(lr):#include “stdio.h”int a=7,b=10;main( ) int a=5,c; c=a+b; printf(“c=%dn”,c); 在同一源文件中,全局变量和局部变量可以(ky)同名,在局部变量的作用范围内,全局变量不起作用。C=15全局变

43、量局布变量(binling)局部变量全局变量第52页/共90页第五十二页,共91页。共90页第53页优点:函数间数据联系:同一文件中的一些函数引用全局变量,当某个函数中改变了全局变量的值,其它函数中的全局变量值也随之改变。函数可以得到多个返回值。(在所有(suyu)函数之外说明的变量是全局变量,它在所有(suyu)函数中都是可见的。利用全局变量的这个特性,可以在函数间传递数据。)缺点:全局变量在程序的全部执行过程中都占用存储单元。降低函数的通用性。使用过多,降低程序的清晰性。全局变量应尽可能少用。第53页/共90页第五十三页,共91页。共90页第54页例8-15编写函数(hnsh),利用全局变

44、量求一维数组中正数的平均值和负数的平均值传递给调用函数(hnsh)输出。#include float zaver=0,faver=0;void saver(int array ,int n) int i,z=0,f=0; for(i=0 ; i0) zaver+=arrayi;z+; if(arrayi0) faver+=arrayi;f+; if(z!=0) zaver=zaver/z; if(f!=0) faver=faver/f; main() int a10=1,-3,4,6,-2,7,9,-8,-5,0; saver(a,10); printf(“正数(zhngsh)平均值=%f,负

45、数平均值=%fn”,zaver,faver);第54页/共90页第五十四页,共91页。共90页第55页下面(ximian)程序的运行结果是()。#include“stdio.h”intx1=30,x2=40;voidsub(intx,inty)x1=x;x=y;y=x1;main()intx3=10,x4=20;sub(x3,x4);sub(x2,x1);printf(“%d,%d,%d,%dn”,x3,x4,x1,x2);答案(d n)10,20,40,40 第55页/共90页第五十五页,共91页。共90页第56页 变量的存储类别静态存储方式:程序运行期间分配固定(gdng)(gdng)存储

46、空间的方式。动态存储方式:程序运行期间根据需要进行动态的分配存储空间的方式。程序区静态存储区动态存储区全局变量,局部静态变量形式参数局部变量(自动)函数调用的现场保护和返回地址8.4.2 8.4.2 变量(binling)(binling)的存储方法第56页/共90页第五十六页,共91页。共90页第57页动态存储变量特点函数开始调用时为变量分配存储空间,函数结束时释放这些(zhxi)空间。一个程序两次调用同一函数,其中同一个局部变量的内存地址可能不同。静态存储变量特点在静态存储区分配存储单元,整个程序运行期间都不释放。变量存贮(cn zh)类型有四种:自动变量(auto)静态变量(static

47、)外部变量(extern)寄存器变量(register)auto、static、extern和register为存贮(cn zh)类型说明符。第57页/共90页第五十七页,共91页。共90页第58页(1)自动变量 (auto) 函数中的局部变量,不做任何存储类别的说明都为自动变量。 定义形式(xngsh):auto 类型说明符 变量名 ; 说明:“auto”可以省略。 以前所使用的全部变量都是自动变量。 自动变量必须在一个函数体的内部。 函数的形参也是自动变量。 例如:int b, c=3 等价于 auto int b, c=3; 作用域:包含变量定义的复合语句或所说明的函数内部 ; 在函数被

48、调用时才存在,从函数中返回时即消失, 值也仅限于说明它的函数,在其它的函数中不能存取, 在两个不同的函数中可以分别使用同名的变量。1.局部变量的存储(cn ch)方法第58页/共90页第五十八页,共91页。共90页第59页(2)局部静态变量 定义形式:在变量名前面加 关键字static static 类型说明符 变量名;局部静态变量编译时赋初值,每次调用时不赋初值,只保留调用结束时变量的值。如果不赋初值,编译时自动赋0值。局部静态变量只允许所在(suzi)函数引用,其它函数不能引用。其值整个程序运行期间都不释放。自动变量不赋初值,其值不确定。每调用一次,重新赋值一次。第59页/共90页第五十九

49、页,共91页。共90页第60页例如(lr):intf(inta)intb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);main()inta=2,i;for(i=0;i3;i+)printf(“%d,”,f(a);运行(ynxng)结果为:7,8,9第一次调用(dioyng)开始第一次调用结束第二次调用开始0b34410c局部静态变量第60页/共90页第六十页,共91页。共90页第61页例如(lr):#include“stdio.h”intfun(intx,inty)staticintm=0,i=2;i+=m+1;m=i+x+y;returnm;main()

50、inta=2,b=3;printf(%d,fun(a,b);printf(%dn,fun(b,a);8,17运行(ynxng)结果:第61页/共90页第六十一页,共91页。共90页第62页(3)寄存器变量 (register) 直接放置在运算器的寄存器中的变量称为寄存器变量. 定义形式: register 类型说明符 变量名; 作用:对于使用频繁的变量,定义为寄存器变量,不必从内存而是直接从寄存器中取出参加运算,提高程序执行效率。 说明:只有局部自动变量和形式参数可作为寄存器变量,其它如局部静态变量和全局变量不可以。属于动态存储方式,函数开始调用时为变量分配寄存器空间,函数结束(jish)时释

51、放寄存器空间。只有int、char和指针类型可定义为寄存器变量,而long、double和float型变量不能设定为寄存器型 。可用于变量空间分配的寄存器个数依赖于具体的机器。通常为2到3个,若在一个函数中说明多于2到3个寄存器变量,编译程序会自动地将它们变为自动变量。 第62页/共90页第六十二页,共91页。共90页第63页2.全局变量的存储(cnch)类型(外部全局变量、静态全局变量)(1)外部全局变量在多个源程序文件的情况下,如果在一个文件中要引用在其它文件中定义的全局变量,则应该在需要引用此变量的文件中,用extern做说明。例如:prog1.c的内容(nirng)如下:int a;m

52、ain( ) x=6; f1( );void f1( ) a+=2; printf(a=%dn, a); f2( );prog2.c的内容(nirng)为:extern int a;void f2( ) a+; printf(a=%dn, a); 第63页/共90页第六十三页,共91页。共90页第64页(2)静态(jngti)全局变量在一个文件中定义的全局变量仅限于本文件引用,而不能被其它文件访问,则可以定义为静态(jngti)全局变量。例如:staticintx;说明:外部全局变量与静态(jngti)全局变量在同一文件内的作用域一样外部全局变量可以被多个文件引用,而静态(jngti)全局变量

53、仅在定义它的文件内有效,在程序的其它文件中不可使用。例如:file1.cfile2.cstaticinta;externinta;staticinta只能用于file1.c,虽然file2.c中将同名变量inta说明为extern,但仍无法使用file1.c中的a变量。第64页/共90页第六十四页,共91页。共90页第65页8.5 8.5 内部函数(hnsh)(hnsh)和外部函数(hnsh)(hnsh)1 . 内部函数(静态函数)定义:如果一个函数只能被本文件(wnjin)中其它函数调用,称为内部函数。定义格式: static 类型标识符 函数名(形参表)函数体 例如:static int

54、fun(a, b) 作用:函数的作用域限于所在文件(wnjin),不同文件(wnjin)中同名函数互不干扰,便于程序的格式化。第65页/共90页第六十五页,共91页。共90页第66页2.外部函数(hnsh)定义:如果一个函数(hnsh)允许被其它文件调用,称为外部函数(hnsh)。定义格式:extern类型标识符函数(hnsh)名(形参表)函数(hnsh)体例如:externintfun(inta,intb)或intfun(inta,intb)通常不加static标识符的函数(hnsh)都是外部函数(hnsh)。第66页/共90页第六十六页,共91页。共90页第67页3.标号的生存期及作用域生

55、存期 在C语言中,由于函数的生存期是全程的,即从程序开始至程序结束,标号是函数的一部分,标号的生存期自然是全程的。作用域 C语言规定,标号的作用域仅为定义标号的函数,即不允许(ynx)用goto语句从一个函数转向另一个函数。 第67页/共90页第六十七页,共91页。共90页第68页有关函数有关函数(hnsh)的类型的类型1 1 函数的类型是函数返回值的类型2 C2 C要求(yoqi)(yoqi)函数定义的类型,说明的类型和函数定义类型一致3 3 定义的类型与返回值类型不一致时,以定义为准4 4 不定义函数类型,系统默认是intint。(VC+6.0(VC+6.0必须指定函数类型)5 5 不需返

56、回任何返回值时,应定义无类型voidvoid。 总 结第68页/共90页第六十八页,共91页。共90页第69页有关有关(yugun)函数的参数函数的参数1 1 定义函数时,括号内为形参2 2 调用函数时,括号内为实参3 3 实参与形参需类型相同,个数相等4 4 形参在函数被调用时才分配存储空间,有值5 5 实参在主调函数内有值,求值顺序是从右向左6 6 实参与形参是单向的数值传递(chund)(chund)7 7 如果实参与形参都是数组名,是地址传递(chund)(chund)8 8 实参数组与形参数组类型相同,个数可以不同函数函数(hnsh)(hnsh)间的数据传递间的数据传递( (三种传递

57、方式三种传递方式): ):返回值、参数、全局变量。返回值、参数、全局变量。第69页/共90页第六十九页,共91页。共90页第70页1 1 函数可以作运算分量(fn ling)(fn ling),作其他函数的参数,可构成语句2 2 函数调用可以嵌套3 3 函数中的returnreturn语句可以带回一个返回值有关有关(yugun)变量变量从变量的作用域:从变量的作用域: 局部变量局部变量 全局变量全局变量从变量值保留从变量值保留(boli)(boli)(boli)(boli)的期限:的期限: 静态存储变量静态存储变量 动态存储变量动态存储变量从变量在硬件上的位置:从变量在硬件上的位置: CPU

58、CPU CPU CPU寄存器寄存器 内存中静态区内存中静态区 内存中动态区内存中动态区有关函数的调用有关函数的调用第70页/共90页第七十页,共91页。共90页第71页存储存储(cn ch)特性特性特点生存期作用域未初始化时值自动变量定义它的函数 (局部变量)随机数外部变量整个程序中多个文件中的多个函数(全程变量 )0 0静态局部全局整个程序 定义它的函数(静态局部)定义它的文件(静态全程) 0 0 0 0寄存器变量定义它的函数随机数第71页/共90页第七十一页,共91页。共90页第72页file1.c程序(chngx):intplus(intx,inty)intz;z=x+y;returnz

59、;例:现已定义函数plus求两个数的和,包含在文件file1.c中,在file2.c程序文件中要调用此函数,请将下列(xili)程序补充完整,使程序正确。file2.c程序(chngx):# include _A_main() int a=4,b=5,c; _B_ plus(int ,int); c=plus(a,b); printf(“a+b=%d”n”,c);答案 A: “file1.c” B: extern 第72页/共90页第七十二页,共91页。共90页第73页例下面程序由两个文件(wnjin)组成,请分析运行结果。/* 文件(wnjin)一 prog1.c*/#include std

60、io.h#include prog2.cint x=10,y=10; extern void sub() ; void add() int y=5; y=10+x; x*=2; printf(add:y=%d; ,y); main() x+=5; add(); sub();printf(main:x=%d; main:y=%dn,x,y); /* 文件(wnjin)二 prog2.c*/#include “stdio.h”extern int x;void sub() int y=5; x-=y; printf(“sub:y=%d;”,y); 运行结果:第73页/共90页第七十三页,共91页。

61、共90页第74页C的源程序 预处理 编译(biny) 目标程序 (*.C) _ (*.OBJ)编译系统中有 : 预处理程序(chngx) 编译程序(chngx)宏替换 #define N 20 文件(wnjin)包含 #include条件编译 #if( . ) C中的预处理命令分类8.6 8.6 编译预处理第74页/共90页第七十四页,共91页。共90页第75页宏定义有两种类型(lixng):字符串替换和带参数的宏替换 ( 1) 字符串宏替换字符串宏替换(t hun) 功能:在预处理时 ,将程序中宏定义之后出现的所有(suyu)的宏名,用宏替换体代替。宏替换名宏替换体例如:#define PI

62、 3.14159 格式:#define 宏名宏定义字符串 C的编译程序调用预处理程序检查有否宏名,若有,用宏替换体将其替换,完成之后,将替换后的源程序交给编译程序。1.1.宏定义第75页/共90页第七十五页,共91页。共90页第76页 用途: 提高程序(chngx)的可读性,便于修改、调试。 - 符号常量(chngling),如 PI、 数组的长度 - 为程序书写带来方便(将程序中多次出现相同内容写成宏)#define N 10 /* 编译之前用10替换(t hun)所有的N */.int aN 说明:v 通常放在程序开头, ,不加分号v 是代替, ,不是赋值( (不作语法检查) )v 可将多

63、个语句或表达式定义为一个宏替换v 为区别变量和关键字, ,习惯用大写第76页/共90页第七十六页,共91页。共90页第77页#define R 3.0#define PI 3.145926#define L 2.0*PI*R#define S PI*R*Rv 双引号中的不替换(t hun)(t hun)v 有效范围, ,从定义开始到程序(chngx)(chngx)结尾例: #define PI 3.14159main( ) printf (“PI=%fn”,PI); 结果(ji gu):PI=3.14159main( ) printf(“PI=%sn”,”PI”); v 可以嵌套, ,后定义的

64、宏可以包含先定义的宏名结果:PI=PI第77页/共90页第七十七页,共91页。共90页第78页(2) 带参数带参数(cnsh)的的宏定义宏定义 带参数的宏不仅(bjn)能进行字符串代替,而且还能进行参数代换。 格式(g shi): #define 宏名(参数表) 表达式 功能: 带参数的宏将一个带形参的表达式定义为一个带参数的宏名,预处理程序对程序中所有带实参表的宏名进行宏展开替换,用表达式代替宏名,用参数表中的实参代替表达式中对应的形参。例:#define S( a, b) a*b程序中 S(3, 2) 3*2第78页/共90页第七十八页,共91页。共90页第79页 用途(yngt):用带参

65、数的宏可以代表(dibio)一些简短的表达式,提高程序执行的效率。* * 对常用的格式(g shi)(g shi)输入输出函数printfprintf可以进行宏定义,使程序简化* *宏名与参数的圆括号之间不能有空格 s (a,b)s (a,b) 说明:* 宏定义命令要求在一行内写完,如换行,用“”表示下一行继续。* * 对于宏定义的形参要根据需要加上圆括号,以免 发生运算错误第79页/共90页第七十九页,共91页。共90页第80页例1 使用(shyng)有参宏替换求圆的面积。 #define PI 3.1415926 #define S(r) PI*r*r main() float a=3.6

66、,area; area=S(a); printf(“r=%fnarea=%fn”,a,area); 宏展开(zhn ki)替换后:area=3.1415926*3.6*3.6;第80页/共90页第八十页,共91页。共90页第81页例2 求下列(xili)语句的循环次数。 #include “stdio.h” #define N 2 #define M N+1 #define NUM (M+1)*M/2 main() int i,n=0; for(i=1;i=NUM;i+) n+; printf(“%d”,n); 8第81页/共90页第八十一页,共91页。共90页第82页函数要求(yoqi)形参

67、,实参有类型(相同) 宏的形参,实参不要求(yoqi)类型,仅是符号函数需事先计算(j sun)实参表达式的值,再代入形参宏展开中不求表达式的值,仅替换, 没有值传递函数(hnsh)是在运行时处理宏是在编译之前进行带参数的宏与函数的区别函数调用影响运行时间,源程序无变化宏展开影响编译时间,通常使源程序加长函数调用有一个返回值 宏可以有多个结果第82页/共90页第八十二页,共91页。共90页第83页 文件包含是指一个(y )程序文件将另一个(y )指定文件的全部内容包含进来。 格式(g shi): #include 或: #include “文件名”2.2.文件(wnjin)(wnjin)包含

68、功能: 用指定文件的全部内容代换该预处理行 ,C程序通过#include预处理,把一个指定的文件的内容嵌入。(注:只能包含ASCII文本文件。) 与“ ”的区别: : 在系统指定目录下搜索文件 “ ” 在用户当前目录下找指定文件, ,如用户当前目录下没有找到, ,再到系统指定目录下查找。 说明 第83页/共90页第八十三页,共91页。共90页第84页 只包含(bohn)(bohn)源文件, ,不包含(bohn)(bohn)可执行文件和目标文件。 可以嵌套例如(lr):file1.c(lr):file1.c需包含file2.c,file2.c,file2.cfile2.c包含file3.cfil

69、e3.c,必须将file3.hfile3.h放在前面#include #include #include #include 一个(y )#include(y )#include只能包含一个(y )(y )文件第84页/共90页第八十四页,共91页。共90页第85页用途(yngt) 将符号常量 , 带参数的宏及构造类型的变量等定义在一个独立(dl)的文件中,为其他文件共享。 程序员可将工作中积累的有价值的符号,带参数的宏定义,或一些外部变量,通用的子程序定义成一个文件,需要时,包含进源程序。 使用C中的库函数,需将所在的头文件包含进源程序。第85页/共90页第八十五页,共91页。共90页第86页

70、3.条件(tiojin)编译条件编译命令的形式(xngsh)常用的形式(xngsh):形式(xngsh)一:#ifdef宏名程序段1;#else程序段2;#endif功能:如果之前定义过宏名,直接选择程序段1 1进行编译(biny)(biny),否则选择程序段2 2进行编译(biny)(biny)。 将源程序中的一部分语句生成目标代码,广泛用于商业软件,可以为一个软件提供多个版本,不同的用户使用不同的版本。第86页/共90页第八十六页,共91页。共90页第87页形式二:#ifndef宏名程序段1;#else程序段2;#endif其中,#ifndef语句的功能与#ifdef相反,如果(rgu)宏

71、名未定义则编译程序段1,否则编译程序2。或者(huzh):#ifndef 宏名 程序段;#endif第87页/共90页第八十七页,共91页。共90页第88页形式三:#if常数表达式程序段1;#else程序段2;#endif功能:首先计算“常数表达式”的值,如果为真(非零),就编译“程序段1”,否则(fuz)编译“程序段2”。如果没有#else部分,则当“常数表达式”的值为0时,直接跳过#endif。或者(huzh):#if 常数表达式 程序段;#endif第88页/共90页第八十八页,共91页。共90页第89页例:阅读程序。#includemain()#ifNULLprintf(NULLisn

72、on-zerovalue!n);#elseprintf(NULLiszerovalue!n);#endif运行(ynxng)结果:NULLiszerovalue!第89页/共90页第八十九页,共91页。共90页第90页谢谢您的观看(gunkn)!第90页/共90页第九十页,共91页。内容(nirng)总结共 90 页 第 1 页。函数可集中或分散存放在一个或多个源程序文件中。p=p*x。数据进行操作,因此可以(ky)实现数据的同步更新。例8-10 将给定字符串复制到另一字符串。= 0)。sj= 0。C语言不能嵌套定义,但可以(ky)嵌套调用。静态存储方式:程序运行期间分配固定存储空间的方式。结果:PI=PI。未定义则编译程序段1,否则编译程序2。谢谢您的观看第九十一页,共91页。

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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