第08章函数.ppt

上传人:s****8 文档编号:67243050 上传时间:2022-12-24 格式:PPT 页数:105 大小:407KB
返回 下载 相关 举报
第08章函数.ppt_第1页
第1页 / 共105页
第08章函数.ppt_第2页
第2页 / 共105页
点击查看更多>>
资源描述

《第08章函数.ppt》由会员分享,可在线阅读,更多相关《第08章函数.ppt(105页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、1 函数的定义、说明与调用函数的定义、说明与调用 函数之间参数传递规则函数之间参数传递规则 变量的存储类型与特性变量的存储类型与特性 函数递归的概念与执行过程函数递归的概念与执行过程 递归程序的编程方法递归程序的编程方法本本 章章 要要 点点2第一节第一节 C C程序结构程序结构第二节第二节 函数定义函数定义第三节第三节 函数的调用与返回函数的调用与返回第四节第四节 在函数之间传递数据在函数之间传递数据第五节第五节 变量的存储属性变量的存储属性第六节第六节 函数的递归调用函数的递归调用第七节第七节 库函数简介库函数简介38.1 C8.1 C程序结构程序结构程序程序文件程序文件1 1函数函数11

2、函数函数1m。程序文件程序文件2 2函数函数21程序文件程序文件n n。C C程序的模块化结构程序的模块化结构41 1 一个一个C C程序由一个或多个源程序文件组成。程序由一个或多个源程序文件组成。将若干函数和其它内容分别放在若干个源将若干函数和其它内容分别放在若干个源文件中,以达到分别编写,分别编译,提文件中,以达到分别编写,分别编译,提高运行效率的目的。同时一个源文件可以高运行效率的目的。同时一个源文件可以为多个为多个C C程序公用。程序公用。2 2 一个源程序文件由一个或多个函数组成。一个源程序文件由一个或多个函数组成。每一个源文件可以独立编译,即一个源程每一个源文件可以独立编译,即一个

3、源程序文件是一个编译单位。序文件是一个编译单位。说明:说明:53 3 函数是最小的功能单位,一个函数可函数是最小的功能单位,一个函数可以被位于不同的源文件中的其它函数以被位于不同的源文件中的其它函数调用调用4 4 一个一个C C语言程序有且仅有一个主函数语言程序有且仅有一个主函数mainmain()(),主函数可以放在任何一个源文件,主函数可以放在任何一个源文件中,无论主函数在程序的什么位置,中,无论主函数在程序的什么位置,程序一定是从主函数开始执行的,并程序一定是从主函数开始执行的,并且在且在mainmain函数中结束整个程序的运行函数中结束整个程序的运行6 5 5 除除mainmain函数

4、外,所有函数都是平行函数外,所有函数都是平行的,即所有函数都是互相独立的,一的,即所有函数都是互相独立的,一个函数并不从属于另一个函数,函数个函数并不从属于另一个函数,函数间可以互相调用,但不能调用间可以互相调用,但不能调用mainmain函函数数 6 6 将属于同一程序的不同源文件组装成将属于同一程序的不同源文件组装成一个程序可以通过工程文件实现一个程序可以通过工程文件实现 7 模块化是结构化程序设计的基础。模块化是结构化程序设计的基础。采用模块化程序设计有很多优越性:采用模块化程序设计有很多优越性:n n控制程序设计的复杂性控制程序设计的复杂性n n提高软件的可靠性提高软件的可靠性n n提

5、高软件开发的效率提高软件开发的效率n n提高软件的可维护性提高软件的可维护性n n提高程序的重用性提高程序的重用性8 函数分类:函数分类:从用户使用的角度看,函数分为:从用户使用的角度看,函数分为:库函数库函数,库函数是由系统提供的,用户不必,库函数是由系统提供的,用户不必自己编写这些函数,可以直接使用它们。自己编写这些函数,可以直接使用它们。用户函数用户函数,即用户自己定义的函数,用以解,即用户自己定义的函数,用以解决用户的专门需要。决用户的专门需要。从函数的形式看,函数分为:从函数的形式看,函数分为:无参函数无参函数。在调用无参函数时,不必将数据。在调用无参函数时,不必将数据传递给被调用函

6、数。传递给被调用函数。有参函数有参函数。在调用有参函数时,在主调函数。在调用有参函数时,在主调函数和调用函数之间有数据传递。和调用函数之间有数据传递。9数据类型数据类型 函数名(形参表说明)函数名(形参表说明)声明语句声明语句 执行语句执行语句 8.2 函数定义函数定义函数定义的一般形式:函数定义的一般形式:无参函数的定义形式:无参函数的定义形式:数据类型数据类型 函数名(函数名()声明语句声明语句 执行语句执行语句 函数头函数头函数体函数体101.1.函数定义中的类型是指函数返回值的函数定义中的类型是指函数返回值的类型。函数返回值不能是数组,也不类型。函数返回值不能是数组,也不能是函数,除此

7、之外如何合法的数据能是函数,除此之外如何合法的数据类型都可以是函数的类型。类型都可以是函数的类型。2.2.函数的类型可以省略,当不指明函数函数的类型可以省略,当不指明函数类型时,系统默认的函数类型是整型。类型时,系统默认的函数类型是整型。说明:说明:113.3.函数名是标识符,是函数定义中唯一不函数名是标识符,是函数定义中唯一不可省略的,用于标识函数,并用该标识可省略的,用于标识函数,并用该标识符调用函数。符调用函数。4.4.形式参数表是用逗号分隔开的一组变量形式参数表是用逗号分隔开的一组变量说明,包括形参的类型和形参标识符。说明,包括形参的类型和形参标识符。其作用是当调用函数时,接受来自主调

8、其作用是当调用函数时,接受来自主调函数的数据。无参函数函数的数据。无参函数()()不可省略。不可省略。125.5.有参函数的形参声明放在函数头当中,有参函数的形参声明放在函数头当中,而形参的作用域也仅仅存在于本函数之而形参的作用域也仅仅存在于本函数之中。中。6.6.括起来的部分是函数体。函数体括起来的部分是函数体。函数体是一段程序,确定该函数应执行的规定是一段程序,确定该函数应执行的规定动作,集中体现了函数的功能。动作,集中体现了函数的功能。不可省略不可省略13n函数定义实例函数定义实例 1.1.语言中一个最简单的函数:语言中一个最简单的函数:dummy()/*dummy()/*函数名:函数名

9、:dummy*/dummy*/没有数据类型说明、形参和形参说明,函数体为空。没有数据类型说明、形参和形参说明,函数体为空。2.2.求阶乘函数求阶乘函数factofacto的定义。的定义。long facto(long facto(intint x)x)long y;long y;for(y=1;x0;-x)for(y=1;x0;-x)y=y*x;y=y*x;return(y);return(y);函数名函数名形式参数列表形式参数列表函函数数类类型型函数体函数体函数返回函数返回14nmain()main()intint a,b,ca,b,c;printf(printf(”EnterEnter a

10、,bna,bn”););scanf(scanf(”%d,%d%d,%d”,&a,&a,&b);,&b);c=max(c=max(a,ba,b););printf(printf(”MaxMax=&d=&d”,c);,c);intint max(max(intint x,x,intint y)y)intint z;z;z=x y?x:y;z=x y?x:y;return(z);return(z);形式参数列表形式参数列表:是用是用是用是用,分开分开分开分开的一组变量,用的一组变量,用的一组变量,用的一组变量,用来接收调用时传来接收调用时传来接收调用时传来接收调用时传入的数据入的数据入的数据入的数据

11、函数调用函数调用3.3.求两个变量的最大值求两个变量的最大值15有参函数调用的形式为:有参函数调用的形式为:函数名(实参表列);函数名(实参表列);无参函数调用的形式为:无参函数调用的形式为:函数名();函数名();在函数调用过程中,实参与形参的个数应当在函数调用过程中,实参与形参的个数应当相等,并且按顺序一一对应。实参可以是相等,并且按顺序一一对应。实参可以是常量、变量或是表达式,甚至是另外一个常量、变量或是表达式,甚至是另外一个函数调用的返回值。函数调用的返回值。8.3 函数的调用与返回函数的调用与返回16 函数调用的过程函数调用的过程:在一个函数中调用另一个函数时,程在一个函数中调用另一

12、个函数时,程序将控制从调用函数处转移到被调用函数,序将控制从调用函数处转移到被调用函数,并执行被调用函数。并执行被调用函数。在执行完被调用函数的所有语句或者在执行完被调用函数的所有语句或者遇到遇到returnreturn语句时,程序的控制要返回到语句时,程序的控制要返回到调用函数中原来调用函数的地方继续执行。调用函数中原来调用函数的地方继续执行。171 1 函数语句函数语句被调函数在主调函数中以语句的方式出现,被调函数在主调函数中以语句的方式出现,通常只完成一种操作,不带回返回值。通常只完成一种操作,不带回返回值。funcfunc()()printf(“Thisprintf(“This is

13、a program!”);is a program!”);main()main()funcfunc();();函数的调用方式有三种形式:函数的调用方式有三种形式:182 2 函数表达式函数表达式 将函数的调用结果作为运算符的运算分量,将函数的调用结果作为运算符的运算分量,这种调用方式下被调用函数必须有返回值。这种调用方式下被调用函数必须有返回值。main()main()intint a,b,i,j,c;a,b,i,j,c;scanf(“%dscanf(“%d%d%d%d%d%d”,&a,&i,&b,&jd”,&a,&i,&b,&j););c=c=pow(a,ipow(a,i)+)+pow(b,

14、jpow(b,j););printfprintf(“%d”,c);(“%d”,c);193 3 函数参数函数参数 函数的调用结果可以作为其它函数的实函数的调用结果可以作为其它函数的实参,此时函数必须有返回值参,此时函数必须有返回值 c=c=powpow(a,(a,powpow(b,i);(b,i);20 主调函数调用被调函数之前,必须对被主调函数调用被调函数之前,必须对被调函数做声明,声明的目的是告诉编译系调函数做声明,声明的目的是告诉编译系统函数值是什么类型,有多少个参数,每统函数值是什么类型,有多少个参数,每一个参数是什么类型,为编译系统进行类一个参数是什么类型,为编译系统进行类型检查提供

15、依据。型检查提供依据。函数说明的一般形式函数说明的一般形式 函数类型函数类型 函数名(形参类型函数名(形参类型1 1 形形参名,形参类型参名,形参类型2 2 形参形参2 2,););函数的声明函数的声明21 函数说明与函数头唯一区别:函函数说明与函数头唯一区别:函数说明语句的(数说明语句的()之后必须有分号,)之后必须有分号,而函数定义头部的(而函数定义头部的()之后没有分号。)之后没有分号。“说明说明”与与“定义定义”的区别:的区别:n“说明说明”仅是向编译系统的一个说仅是向编译系统的一个说明,不包含具体的执行动作。明,不包含具体的执行动作。n“定义定义”是给出函数的程序体。是给出函数的程序

16、体。221 1 当函数的返回值为整型或字符型时,如果当函数的返回值为整型或字符型时,如果在同一个文件中既定义函数,又调用该函在同一个文件中既定义函数,又调用该函数,则不论定义函数与调用函数在源程序数,则不论定义函数与调用函数在源程序中的位置关系如何,都可以省略函数声明。中的位置关系如何,都可以省略函数声明。2 2 当被调函数返回值是其它类型时,如果函当被调函数返回值是其它类型时,如果函数定义和函数调用在同一个文件中,且函数定义和函数调用在同一个文件中,且函数定义在源文件中的位置在调用该函数之数定义在源文件中的位置在调用该函数之前,则可以省略函数的声明。前,则可以省略函数的声明。在下列情况下可以

17、省略函数声明:在下列情况下可以省略函数声明:231 1 如果函数定义在源文件中的位置在调用如果函数定义在源文件中的位置在调用该函数之后,则必须给出被调函数的声该函数之后,则必须给出被调函数的声明。明。2 2 如果函数的定义与调用在两个不同的文如果函数的定义与调用在两个不同的文件中,则不论函数返回值的类型是什么,件中,则不论函数返回值的类型是什么,在调用该函数之前,都必须给出函数声在调用该函数之前,都必须给出函数声明。明。在下列情况必须对函数进行声明:在下列情况必须对函数进行声明:24main()main()intint m;long n;m;long n;long long facto(int

18、facto(int x);x);scanf(%dscanf(%d,&m);,&m);n=facto(m);n=facto(m);printf(%dprintf(%d!=%ld.n,m,n);!=%ld.n,m,n);long facto(long facto(intint x)x)long y;long y;for(y=1;x0;-x)y*=x;for(y=1;x0;-x)y*=x;return(y);return(y);函数执行过程函数执行过程 main()mm=facto(m);facto (x)return(y);调用调用返回返回例例:用函数用函数factofacto计算计算 m m 阶

19、乘阶乘函数声明函数声明函数调用函数调用函数定义函数定义函数返回值函数返回值25 main()main()intint m,n;long m,n;long cmncmn;long facto(long facto(intint x);x);scanfscanf(%(%d%dd%d,&m,&n);,&m,&n);cmncmn=facto(mfacto(m)/()/(facto(nfacto(n)*)*facto(m-nfacto(m-n););printfprintf(%ldn,(%ldn,cmncmn););long facto(long facto(intint x)x)long y;long

20、 y;for(y=1;x0;for(y=1;x0;-x)y*=x;x)y*=x;return(yreturn(y););例例:计算:计算:C(m,nC(m,n)=)=m!/(nm!/(n!*(!*(m-nm-n)!)!)26对被调函数的声明可以简化为:对被调函数的声明可以简化为:函数类型函数类型 函数名(形参类型函数名(形参类型1 1,形参,形参类型类型2 2,););上式称为函数原型上式称为函数原型long facto(long facto(intint););通常将一个文件中需要调用的所有函数原通常将一个文件中需要调用的所有函数原型写在文件的开始。型写在文件的开始。函数原型函数原型27 从

21、函数返回的两种方法从函数返回的两种方法n用用returnreturn语句从被调函数中退出,返回调用它的程语句从被调函数中退出,返回调用它的程序中(也称为主调函数);序中(也称为主调函数);n被调函数如果没有被调函数如果没有returnreturn语句,被调函数执行结束语句,被调函数执行结束遇到最外面的遇到最外面的 ,返回主调函数。,返回主调函数。return return的两重作用:的两重作用:n控制程序从当前函数控制程序从当前函数(被调用函数被调用函数)中退出,返回到中退出,返回到调用函数中继续执行;调用函数中继续执行;n从被调用函数向主调函数返回一个值(称为返回值)从被调用函数向主调函数返

22、回一个值(称为返回值)。函数的返回函数的返回28 函数除了函数除了voidvoid类型之外,均有一个返回值,返回类型之外,均有一个返回值,返回值的类型就是在定义函数时说明的函数类型。值的类型就是在定义函数时说明的函数类型。n当返回值类型为整型当返回值类型为整型intint时,在定义函数时可时,在定义函数时可省去函数的数据类型定义说明。省去函数的数据类型定义说明。max(max(intint x,x,intint y)y)intint z;z;z=x y?x:y;z=x y?x:y;return(z);return(z);n对于返回值的类型为非整型的函数,在定义函对于返回值的类型为非整型的函数,

23、在定义函数时,必须明确地给出函数数据类型说明;数时,必须明确地给出函数数据类型说明;返回值规定:返回值规定:29n返回语句的格式与功能返回语句的格式与功能 格式格式1 1:returnreturn;功能:功能:将控制从被调函数返回到主调函数。将控制从被调函数返回到主调函数。格式格式2 2:return return (表达式);表达式);或:或:return return 表达式表达式 ;功能:在被调函数中计算表达式的值,将计算功能:在被调函数中计算表达式的值,将计算结果按照函数说明的结果按照函数说明的函数类型返回到主调函数,函数类型返回到主调函数,并将控制返回主调函数。并将控制返回主调函数。

24、30main()int a,c;scanf(“%d”,&a);c=func(a);printf(“%d”,c);func(int x)int z;if(x=0)z=2*x*x-x;else z=2*x*x;return z;2x2 x x=02x2 xy?x:y;return z;Output:MAX is 633(3 3)一个函数体内可以有多个返回语)一个函数体内可以有多个返回语句,不论执行哪一个,函数都将结束,句,不论执行哪一个,函数都将结束,并将控制流程返回到主调函数。并将控制流程返回到主调函数。if(x=0)return (2*x*x-x);else return(2*x*x);34

25、C C语言中,函数的定义是平行的,语言中,函数的定义是平行的,不允许进行函数的嵌套定义,即不允不允许进行函数的嵌套定义,即不允许在一个函数体中再定义一个新的函许在一个函数体中再定义一个新的函数。而函数之间的调用可以是任意的,数。而函数之间的调用可以是任意的,即允许在一个函数内再调用其它函数,即允许在一个函数内再调用其它函数,这种调用称为函数的嵌套调用。这种调用称为函数的嵌套调用。函数的嵌套调用函数的嵌套调用35mainmainmainmain函数函数函数函数 调用函调用函调用函调用函数数数数 A;A;A;A;函数函数函数函数 A A A A 调用函数调用函数调用函数调用函数 B B;函数函数函

26、数函数 B B B B 调用调用调用调用返回返回返回返回36void func1()func2();printf(“Function1!”);void func2()printf(“Function2!”);main()func1();printf(“Main!”);37 在不同的函数之间传递数据,可以使用:在不同的函数之间传递数据,可以使用:n参数参数:通过形式参数和实际参数:通过形式参数和实际参数n返回值返回值:用:用returnreturn语句返回计算结果语句返回计算结果n全局变量全局变量:外部变量:外部变量 函数参数的传递规则:函数参数的传递规则:C C语言中,函数参数遵守语言中,函数

27、参数遵守“值传递值传递”规则,即在规则,即在调用函数时,将实参变量的值取出来,复制给形参变调用函数时,将实参变量的值取出来,复制给形参变量,使形参变量在数值上与实参相等。量,使形参变量在数值上与实参相等。在函数内部使用从实参中复制来的值进行处理。在函数内部使用从实参中复制来的值进行处理。中的实参可以是一个表达式,调用时先计算表中的实参可以是一个表达式,调用时先计算表达式的值,再将结果(值)复制到形参变量中。达式的值,再将结果(值)复制到形参变量中。8.4 8.4 在函数之间传递数据在函数之间传递数据38 main()main()intint a=5,b=10;a=5,b=10;printf(b

28、rfortprintf(brfort swap a=%swap a=%d,bd,b=%=%dn,a,bdn,a,b););swap(aswap(a,b);,b);printf(afterprintf(after swapaswapa=%=%d,bd,b=%=%dn,a,bdn,a,b););swap(swap(intint x,x,intint y)y)intint temp;temp;temp=x;x=y;y=temp;temp=x;x=y;y=temp;printf(inprintf(in swap x=%swap x=%d,yd,y=%=%dn,x,ydn,x,y););例例:用函数交换

29、两个变量的值用函数交换两个变量的值39 5main main a=5;a=5;b=10;b=10;swap(aswap(a,b);,b);swap(x,y)swap(x,y)temp=x;temp=x;语句语句 x=y;x=y;语句语句 y=temp;y=temp;语句语句 510实参变量实参变量 a实参变量实参变量 b形参变量形参变量 x形参变量形参变量 y变量变量 temp复制复制复制复制 temp=x x=y y=temp调用调用swap函数函数51010540 main()main()intint i;i;for(i=0;i=5;i+)for(i=0;i0;for(p=1;n0;-n)

30、p*=x;n)p*=x;return(p);return(p);例例:计算计算 2 2 和和-3 -3 的的 0 0 到到 5 5 次幂次幂41 值传递的优点值传递的优点:值传递的优点在于:被调用的函数不可能值传递的优点在于:被调用的函数不可能改变调用函数中变量的值,而只能改变它的局改变调用函数中变量的值,而只能改变它的局部的临时副本。这样就可以避免被调用函数的部的临时副本。这样就可以避免被调用函数的操作对调用函数中的变量可能产生的副作用。操作对调用函数中的变量可能产生的副作用。值传递的缺点值传递的缺点:在值传递方式下,每个形式参数仅能传递在值传递方式下,每个形式参数仅能传递一个数据,当需要在

31、函数之间传递大量数据时,一个数据,当需要在函数之间传递大量数据时,值传递方式显然不适用。值传递方式显然不适用。42数组作为函数的参数数组作为函数的参数数组名作为函数的参数,必须遵循以下原则:数组名作为函数的参数,必须遵循以下原则:1 1 如果实参是数组名,则形参可以是同样维数的数如果实参是数组名,则形参可以是同样维数的数组名或是指针。组名或是指针。2 2 实参数组和形参数组必须类型相同,形参数组可实参数组和形参数组必须类型相同,形参数组可以不指明长度。以不指明长度。3 3 数组名作为函数参数时,实参与形参都对应的为数组名作为函数参数时,实参与形参都对应的为数组的首地址,此时函数调用为传址调用方

32、式。数组的首地址,此时函数调用为传址调用方式。这样两个数组就共用同一段内存单元。因此形参这样两个数组就共用同一段内存单元。因此形参数组中元素的值如果发生变化会使实参数组元素数组中元素的值如果发生变化会使实参数组元素的值同时发生变化。的值同时发生变化。43void sort(int array,int n)int i,j,k,t;for(i=0;i n 1;i+)k=i;for(j=i+1;j n;j+)if(arrayj arrayk)k=j;t=arrayk;arrayk=arrayi;arrayi=t;main()int a10,i;for(i=0;i 10;i+)scanf(“%d”,&

33、ai);sort(a,10);for(i=0;i 10;i+)printf(“%d”,ai);对数组中的对数组中的1010个整数由小到大进个整数由小到大进行排序行排序444-4 4-4 变量的存储类型与作用域变量的存储类型与作用域 数据类型决定为变量分配的内存单元的数据类型决定为变量分配的内存单元的长度,数据的存放形式。(从程序设计角度,长度,数据的存放形式。(从程序设计角度,决定了可以表示的数的范围)决定了可以表示的数的范围)问题:问题:1.1.何时为变量分配内存单?何时为变量分配内存单?2.2.变量位于内存的什么位?变量位于内存的什么位?3.3.变量的有效作用范围?变量的有效作用范围?45

34、1 1 静态存储:变量存储在内存中的静态存储区,静态存储:变量存储在内存中的静态存储区,在编译时就分配了存储空间,在整个程序运在编译时就分配了存储空间,在整个程序运行期间,该变量占有固定的存储单元,变量行期间,该变量占有固定的存储单元,变量的值始终存在,程序结束和才释放。这类变的值始终存在,程序结束和才释放。这类变量的生存期为整个程序。量的生存期为整个程序。2 2 动态存储:变量存储在内存中的动态存储区,动态存储:变量存储在内存中的动态存储区,在程序运行过程中,只有当变量所在函数被在程序运行过程中,只有当变量所在函数被调用时编译系统才临时为该变量分配内存,调用时编译系统才临时为该变量分配内存,

35、函数调用结束变量空间释放。这类变量的生函数调用结束变量空间释放。这类变量的生存期为函数调用期间。存期为函数调用期间。变量的生存期是指变量值保留的期限:变量的生存期是指变量值保留的期限:46 变量的作用域是指变量的有效使用范围变量的作用域是指变量的有效使用范围 一个函数一个函数 一个文件一个文件 一个程序一个程序1 1 局部变量:在一个函数或复合语句内定义的局部变量:在一个函数或复合语句内定义的变量,局部变量仅在定义的函数或复合语句内变量,局部变量仅在定义的函数或复合语句内有效。有效。2 2 全局变量:变量在所有函数之外定义称为全全局变量:变量在所有函数之外定义称为全局变量,期作用域为从定义出开

36、始到本文件结局变量,期作用域为从定义出开始到本文件结束。全局变量一经定义,编译系统为其分配固束。全局变量一经定义,编译系统为其分配固定的内存,在程序运行过程中始终占有固定单定的内存,在程序运行过程中始终占有固定单元。元。变量的作用域变量的作用域471 1 不同函数内的局部变量可以重名,互不不同函数内的局部变量可以重名,互不影响。影响。2 2 全局变量与局部变量可以同名,在局部全局变量与局部变量可以同名,在局部变量起作用的范围内,全局变量不起作变量起作用的范围内,全局变量不起作用。用。3 3 全局变量的初始化只能有一次,是在对全局变量的初始化只能有一次,是在对全局变量说明时进行初始化。全局变量说

37、明时进行初始化。说明:说明:48int x=100;main()int x=10;f();printf(“%dt”,x);f()x+=100;printf(“%dt”,x);Output:200 1049n自动变量(自动变量(autoauto)n静态变量(静态变量(staticstatic)n外部变量(外部变量(externextern)n寄存器变量(寄存器变量(registerregister)autoauto、staticstatic、externextern和和registerregister为存贮为存贮类型说明符。类型说明符。变量说明的一般形式:变量说明的一般形式:存贮类型说明符存贮类

38、型说明符 类型说明符类型说明符 变量名称;变量名称;变量存贮类型有四种:变量存贮类型有四种:50 自动变量是最常见的一类变量自动变量是最常见的一类变量 auto auto 类型说明符类型说明符 变量名;变量名;如:如:auto auto intint a;a;auto float pi;auto float pi;说明符说明符“autoauto”可以省略。按照这种默认的可以省略。按照这种默认的规定,以前所使用的全部变量都是自动变量。规定,以前所使用的全部变量都是自动变量。自动变量自动变量511.1.说明自动变量必须在一个函数体的内部。说明自动变量必须在一个函数体的内部。2.2.函数的形参也是自

39、动变量。函数的形参也是自动变量。作用域:作用域:自动变量的作用域是在所说明的函数内部。实质自动变量的作用域是在所说明的函数内部。实质上是一个函数内部的局部变量。只有在函数被调上是一个函数内部的局部变量。只有在函数被调用时才存在,从函数中返回时即消失,它们的值用时才存在,从函数中返回时即消失,它们的值也仅限于说明它的函数,在其它的函数中不能存也仅限于说明它的函数,在其它的函数中不能存取。取。由于自动变量具有局部性,所以在两个不同的函由于自动变量具有局部性,所以在两个不同的函数中可以分别使用同名的变量而互不影响。数中可以分别使用同名的变量而互不影响。说明:说明:52main()main()inti

40、nt x=1;x=1;void f1(),f2(void f1(),f2(intint););f1();f1();f2(x);f2(x);printfprintf(x=%(x=%dndn,x);,x);void f1()void f1()intint x=3;x=3;printfprintf(x=%(x=%dtdt,x);,x);void f2(void f2(intint x)x)printfprintf(x=%(x=%dtdt,+x);,+x);53 寄存器变量与其他类型变量的区别寄存器变量与其他类型变量的区别通常的变量,是使用内存中的存贮单元。寄存通常的变量,是使用内存中的存贮单元。寄存

41、器变量是使用中央处理器器变量是使用中央处理器(CPU)CPU)的通用寄存器。的通用寄存器。计算机从寄存器中存取数据的速度要远远快于计算机从寄存器中存取数据的速度要远远快于从内存中存取数据,所以当变量使用非常频繁时,从内存中存取数据,所以当变量使用非常频繁时,将变量定义为寄存器变量可以提高程序运行速度。将变量定义为寄存器变量可以提高程序运行速度。寄存器是与机器硬件密切相关的,不同的计算寄存器是与机器硬件密切相关的,不同的计算机,寄存器的数目不一样,通常为机,寄存器的数目不一样,通常为2 2到到3 3个,若在一个,若在一个函数中说明多于个函数中说明多于2 2到到3 3个寄存器变量,编译程序会个寄存

42、器变量,编译程序会自动地将它们变为自动变量。自动地将它们变为自动变量。寄存器变量寄存器变量54 由于受硬件寄存器长度的限制,所以由于受硬件寄存器长度的限制,所以寄存器变量只能是寄存器变量只能是charchar、intint或指针型或指针型。寄存器说明符只能用于说明函数中的寄存器说明符只能用于说明函数中的变量和函数中的形式参数,外部变量或静变量和函数中的形式参数,外部变量或静态变量不能是态变量不能是registerregister。寄存器变量的定义形式:寄存器变量的定义形式:register register 类型标识符类型标识符 变量名;变量名;55 main()main()register

43、register intint x=1,y=2,z;x=1,y=2,z;intint temp,i;temp,i;z=z=x+yx+y;for(i=0;i=10000;i+)for(i=0;i=10000;i+)for(tempfor(temp=0;temp=30000;temp+);=0;temp=30000;temp+);printf(oknprintf(okn););56 main()main()register register intint temp,i;temp,i;intint x=1,y=2,z;x=1,y=2,z;z=z=x+yx+y;for(i=0;i=30000;i+)f

44、or(i=0;i=30000;i+)for(temp=0;temp=10000;temp+);for(temp=0;temp 1 时76主函数主函数 第一次调用第一次调用 第二次第二次 第三次第三次 第四次第四次 n=4 n=4 p=facto(4)p=facto(4)调用调用 n=4n=4 r=4*facto(3)r=4*facto(3)调用调用 n=3n=3 r=3*facto(2)r=3*facto(2)调用调用 n=2n=2 r=2*facto(1)r=2*facto(1)n=1 n=1 return(1)return(1)返回返回 r=2*1=2r=2*1=2 return(2)re

45、turn(2)返回返回 r=3*2=6r=3*2=6 return(6)return(6)返回返回 r=4*6=24r=4*6=24 return(24)return(24)返回返回 p=24 p=24 打印打印 24 24facto(n)facto(n)intint n;n;intint r;r;if(n=1)if(n=1)r=1;r=1;else else r=n*facto(n-1);r=n*facto(n-1);return(r);return(r);递归返回过程递归返回过程递归调用过程递归调用过程77递归调用的执行过程递归调用的执行过程递归调用的执行过程递归调用的执行过程facto(

46、facto(intint n)n)intint s;s;if(n if(n=1)1)s=1;s=1;else else s=n*facto(n-1);s=n*facto(n-1);return(s);return(s);facto(facto(facto(facto(intintintint n)n)n)n)intintintint s;s;s;s;if(n if(n if(n if(n=1)1)1)1)s=1;s=1;s=1;s=1;else else else else s=facto(n-1);s=facto(n-1);s=facto(n-1);s=facto(n-1);s=n*s;s=

47、n*s;s=n*s;s=n*s;return(s);return(s);return(s);return(s);等价于等价于等价于等价于当当 n=1 n=1 时时n!=n!=1 1当当 n 1 n 1 时时n!=n*(n-1)!n!=n*(n-1)!78main()main()intint x,n;x,n;printfprintf(x=?n=?);(x=?n=?);scanf(%d%dscanf(%d%d,&x,&n);,&x,&n);printfprintf(%d*%d=%(%d*%d=%dndn,x,n,x,n,power(x,npower(x,n););power(x,n)power(x

48、,n)intint x,n;x,n;if(n if(n=0)return(1);0)return(1);/*/*递归结束条件递归结束条件*/*/else return(x*power(x,n-1);else return(x*power(x,n-1);例例:采用递归方法计算采用递归方法计算 x x 的的 n n 次方次方x xn n=1 =1 当当 n=0 n=0 时时x xn n=x*x=x*xn-1n-1 当当 n 0 n 0 时时79 C C语言本身支持递归调用。语言本身支持递归调用。变变量量存存储储类类型型(自自动动变变量量)的的特特点点,保保证证了了在在每每层层递递归归调调用用的的过

49、过程程中中,变变量量可可以以保保持持相相对对于于各个层次的独立性,不会发生相互干扰。各个层次的独立性,不会发生相互干扰。所有的递归问题一定可以用非递归算法实现。所有的递归问题一定可以用非递归算法实现。一些问题本身已经蕴涵了递归关系且结构复一些问题本身已经蕴涵了递归关系且结构复杂,用非递归算法可能会使程序结构非常复杂,杂,用非递归算法可能会使程序结构非常复杂,采用递归算法实现,可使程序简洁,提高程序的采用递归算法实现,可使程序简洁,提高程序的可读性。递归调用会增加存储空间和执行时间上可读性。递归调用会增加存储空间和执行时间上的开销。的开销。80 1 1 1 1、下列的结论中只有一个是正确的,它是

50、、下列的结论中只有一个是正确的,它是、下列的结论中只有一个是正确的,它是、下列的结论中只有一个是正确的,它是 。A)A)A)A)所有的递归程序均可以采用非递归算法实现所有的递归程序均可以采用非递归算法实现所有的递归程序均可以采用非递归算法实现所有的递归程序均可以采用非递归算法实现 B)B)B)B)只有部分递归程序可以用非递归算法实现只有部分递归程序可以用非递归算法实现只有部分递归程序可以用非递归算法实现只有部分递归程序可以用非递归算法实现 C)C)C)C)所有的递归程序均不可以采用非递归算法实现所有的递归程序均不可以采用非递归算法实现所有的递归程序均不可以采用非递归算法实现所有的递归程序均不可

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁