C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数

上传人:E**** 文档编号:89385418 上传时间:2019-05-24 格式:PPT 页数:40 大小:1.08MB
返回 下载 相关 举报
C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数_第1页
第1页 / 共40页
C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数_第2页
第2页 / 共40页
C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数_第3页
第3页 / 共40页
C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数_第4页
第4页 / 共40页
C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数》由会员分享,可在线阅读,更多相关《C语言程序设计(第二版)-电子教案-丁亚涛 第7章 函数(40页珍藏版)》请在金锄头文库上搜索。

1、第7章 函数,理解并掌握函数的概念、定义和调用的方法和实质 掌握有参函数的数据传递方法,区分“值传递”与“地址传递” 理解标识符作用域和生成期的概念 理解并掌握存储类型的概念 理解并学会设计简单的递归函数,引言,函数可以实现程序的模块化,使得程序设计简单、直观,提高程序的可读性和可维护性,程序员还可以将一些常用的算法编写成通用函数,以供随时调用。 无论程序的设计规模有多大、多复杂,都是划分为若干个相对独立、功能较单一的函数,通过对这些函数的调用,从而实现程序的功能。 C语言的函数分为库函数和用户自定义函数,7.1 案例:计算 (1) +(1+2)+ (1+2+3)+(1+2+3+4)+(1+2

2、+3+4+5),#include int sum(int n) int i,s=0; for( i=1 ; i = n ; i+) s = s + i; return s; void main() int s,i; for(i=1,s=0;i=5;i+) s=s+sum(i); printf(“s=%dn“,s); ,7.2 函数的定义和调用,7.2.1 函数定义 函数的定义如下: 类型 函数名(参数列表) /函数体 ,7.2.1 函数定义,类型指函数返回值的数据类型,函数名采用标识符,一对括号“()”内是参数列表,一对大括号“”内是函数体,由一组语句组成,完成函数具体功能的实现。 函数值的返

3、回通常是运行结果或状态值。返回采用return 语句,例如: return 0; return xy?x:y; return 后面跟表达式。 返回值的类型也可以是void类型,这种情况下可以写成:return;也可以省略返回语句。,参数 :,void 表示函数没有参数,通常把这种函数称为无参函数。例如: int sum(void) int i,s=0; for(i=1,s=0;i=100;i+) s = s + i; return s 函数计算并返回1到100之间的整数之和。,参数 :,参数类型1 参数名1, 参数类型2 参数名2, 函数包含一个或多个参数,每个参数都必须标注具体的数据类型。这

4、样的函数又称为有参函数。例如: int sum(int n) int i,s=0; for(i=1,s=0;i=n;i+) s = s + i; return s; 函数计算并返回1到n之间的整数之和。,7.2.2 函数调用,函数调用的形式如下: 函数名(实参列表) 例如: s = sum(100)+sum(200); s = sum(100+200); s = sum(n); 参数从调用的角度分为实际参数和形式参数,或简称为实参和形参。实参和形参是一一对应的关系,参数的个数和类型都必须一致。如果类型不一致将自动转换,不能自动转换的将在编译或运行时出错。,7.3 参考传递,实参向形参的参数传递

5、有两种形式: 值传递和地址传递。 值传递是单向的数据传递,传递完成后,对形参的任何操作都不会影响实参。 地址传递也可以说是单向的数据传递,但这种数据往往是变量、结构体、对象等的地址,对形参的操作会直接影响实参,从而使得这种形式上的“单向”数据传递变成“双向”的,7.3 参考传递,【例7-2】演示函数的参数传递,void main() int x=10,y=20; int a10 = 1,2,3,4,5,6,7,8,9,10; int i,s = 0; swap(x,y); /*值传递*/ printf(“x,y=%d(main)n“,x,y); for(i = 0 ; i 10 ; i+) s

6、 = s + ai; printf(“s=%dn“,s); s=0; change(a); /*地址传递*/ for(i = 0 ; i 10 ; i+) s = s + ai; printf(“s=%dn“,s); ,#include void swap(int a,int b) int t; t=a; a=b; b=t; printf(“a,b=%d(swap)n“,a,b); void change(int x10) int i; for(i=0 ; i10 ; i+) xi = xi+ 1; ,7.4 函数声明,函数的声明是对函数类型、名称等的说明。对函数及其函数体的建立称为函数的定义

7、。对函数的说明可以和定义一起完成,也可以只对函数的原型进行声明,这种声明通常称为引用性声明,其格式如下: (); 如: int sum(int a,int b); 和完整的函数声明不同的是,形参表可以只给出形参的类型,如: int sum(int,int ); 形参名可以省略。 另外,这种声明是一条语句,后面的分号(;)必不可少。,声明和定义的区分,变量的声明通常是对变量的类型和名称的一种说明,不一定会分配内存,而变量的定义肯定会分配内存空间。 函数的声明是对函数的类型和名称的一种说明,而函数的定义是一个模块,包括函数体部分。 声明可能也是定义,也可能不是。广义上的声明包括定义性声明和引用性声

8、明,我们通常所说的声明指的是后者。,7.5 作用域,作用域就是作用范围,不同作用域允许相同的标识符出现,同一作用域标识符不能重复,嵌套的作用域标识符由内向外屏蔽。,7.5 作用域,标识符a共出现了3次。大圆A中的int a作用范围是整个程序;小圆B、D中的int a分属B、D范围,而且都屏蔽了大圆A中的a,小圆C可以直接访问大圆中的int a; 小圆B不能访问小圆D中char d,同样,小圆D不能访问小圆B中的char b。 B、C、D都能访问大圆A中的char c、int sum(int n); 小圆B、C、D可以理解成是3个函数或复合语句。在有些教材中用“块”来表示一段相对独立的代码。,【

9、例7-3】作用域演示,int a=10; static int add(int a, int b) return a+b; main() int a,b,c;int i,s = 0;int sub(int,int);extern int d;a=20;c=10; int a; int c=20; b=10; a = add(b,c);n printf(“a = %d,b = %d,c = %dn“,a,b,c); for(i=1; i=100; i+) s = s + i; for(i=1; i=100; i+) s = sub(s, i); printf(“s = %dn“,s); prin

10、tf(“d = %dn“ ,d); extern int sub(int a, int b) return a-b; int d = 888; int e = 999;,7.6 存储类型,从分配内存到被回收,变量的使用具有时效性,这就是变量的生存期。在整个程序运行过程中,不同存储类型的变量生存期也各有差异。 一个程序在内存中占用的存储空间分为两个部分:程序区和数据区,数据区也可以分成静态数据区和动态数据区。 生存期和作用域是不同的概念,分别从时间上和空间上对变量的使用进行界定,相互关联又不完全一致,例如,静态变量的生存期贯穿整个程序,但作用域是从声明位置开始到文件结束。,7.6 存储类型,一个

11、程序在内存中占用的存储空间分为两个部分:程序区和数据区,数据区也可以分成静态数据区和动态数据区,7.6 存储类型,变量的存储类型包括: 自动(auto) 寄存器(register) 静态(static) 外部(extern),7.6.1 自动(auto)类型,auto用于局部变量的存储类型声明,可以省略,系统默认局部变量为auto类型。 auto类型变量是动态变量,声明时系统不会自动初始化,其值是随机的,所以必须在使用前初始化或赋值。下面的用法是错误的: int add(int a,int b) int c; c = c + a + b; /*错误:c没有初始化*/ return c; aut

12、o int a; /*错误:外部变量不能声明为auto*/,7.6.2 寄存器(register)类型,register用于局部变量的存储类型声明,表示请求编译器尽可能直接分配使用CPU的寄存器,在寄存器满的情况下才分配内存。这种类型的变量主要用于循环变量,可以大大提高对这种变量的存取速度,从而提高程序效率。 能实际实现为register类型的变量很少,主要是寄存器数量有限。,7.6.3 静态(static)类型,static类型变量称为静态变量,存放在静态存储区。 全局变量和局部变量都可以声明为static类型,但意义不同。 全局变量总是静态存储,默认值为0。全局变量前加上static表示该

13、变量只能在本程序文件内使用,其他文件无使用权限。对于全局变量,static关键字主要用于在程序包含多个文件时限制变量的使用范围,对于只有一个文件的程序有无static都是一样。 局部变量声明为static类型,则要求系统对该变量采用静态存储的内存分配方式。值得注意的是,对这种static类型的局部变量,系统初始化只进行一次,多次遇到该声明语句,将不再被执行。,【例7-5】演示静态变量,int s; static int t; /*其他文件不能使用*/ main() int sum(int); int i; for(i=3 ; i = 5 ; i+) s = sum(i);t = t + s;

14、/*t自动初始化为0 */ printf(“1+2+3+4+5 = %dn“,s); printf(“(1+2+3)+(1+2+3+4)+(1+2+3+4+5) = %dn“,t); int sum(int n) static int s=0; /*该行语句只执行一次*/ int i; for( i = 1; i = n ; i+) s = s + i; return s; ,【程序分析】,sum函数计算1+2+3+n。主函数中利用for循环3次调用sum函数,分别计算sum(3)、sum(4)、sum(5) sum(3) = 1+2+3 = 6 s 等于6 sum(4) = 6+(1+2+3

15、+4) = 6+10 = 16 s 等于16 sum(5) =16+(1+2+3+4+5) = 16+15 = 31 s 等于31 t = 6 + 16 + 31 = 53,7.6.4 外部(extern)类型,extern 关键字用于声明外部的联接。对于全局变量,以下定义形式没什么区别: extern int a; int a; 默认情况下,在文件域中声明的变量和函数都是外部的。但对于作用域范围之外的变量和函数,需要extern来进行引用性声明。,7.7 案例:递归计算s=1+2+3+100,#include int f(int n) if(n = 1) return 1; else ret

16、urn n*f(n-1); int s(int n) if(n = 1) return 1; else return n + s(n-1); void main() printf(“5! = %dn“,f(5); printf(“1+2+3+.+100 = %dn“,s(100); ,7.7 递归函数,函数不能嵌套定义,但可以嵌套调用。函数A可以调用B,函数B也可以调用C,这种调用称为嵌套调用。 函数直接或间接调用自身,则称为递归调用,该函数则称为递归函数。,7.9 案例:函数参数处理次序的案例,void f(int a,int b) printf(“a=%d,b=%dn“,a,b); void main() int i,j; i=j=1; f(i,+i); i=j=1; f(i,

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

当前位置:首页 > 高等教育 > 大学课件

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