资源预览内容
第1页 / 共33页
第2页 / 共33页
第3页 / 共33页
第4页 / 共33页
第5页 / 共33页
第6页 / 共33页
第7页 / 共33页
第8页 / 共33页
第9页 / 共33页
第10页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第6章 函数 本章要求 理解模块化程序设计思想; 掌握函数的定义与调用方法; 掌握C语言的参数传递方式,尤其是数组参数的 传递特点; 掌握变量的作用域和存储方式。 本章重点 函数的定义与调用 参数传递 变量的作用域和存储方式 本章难点 参数传递 变量的作用域和存储方式已知多边形的各条边的长度,要计算多边形 的面积。 计算多边形面积,可将多边形 分解成若干个三角形。计算三角形面积的公式如下: c = 0.5 * (x + y + z); area = sqrt(c * (c - x) * (c - y) * (c - z); 多边形在面积为 : s=s1+s2+s3;abc defgS1S2 S3引例:6.1 函数概述6.1.1 模块化程序设计方法 模块是较小的、能够完成一定任务的、相 对独立的程序段,可以被看作组成一个程序 的逻辑单元。 C语言使用函数作为程序的组成单元。 一个完整的程序由一个主函数main和若干 个其它函数组成,由主函数根据需要调用其 它函数来实现相应功能,调用的关键在于函 数之间的数据传递。 对于每一个函数,它仍然由顺序、选择和 循环三种基本结构组成 。6.1.2 C函数的分类 从使用角度划分 从函数形式划分 从函数的结果划分 从函数的存储类型划分 标准函数,即库函数 自定义函数 无参函数 有参函数 无返回值函数 有返回值函数 外部函数(extern) 静态函数(static)注意:在函数 体中,形式参 数作为已知的 变量,它的值 是函数调用时 由实参传递。6.2 函数的定义 6.2.1 函数的定义形式 类型符 函数名( 形式参数) 函数体 说明: 类型符用于说明函数返回值的类型。 函数名是一个标识符。 形式参数可以是0个、一个或多个,表示该 函数被调用时所需的一些必要信息,其定义 与变量的定义形式相似。 函数体一般包括声明部分和执行部分。 6.2.2 函数返回值C语言通过return语句获得函数返回值的,其 格式如下:return 表达式; 或 return(表达式); 例: float area(float x,float y,float z) float t,s;t=0.5*(x+y+z);s=sqrt(t*(t-x)*(t-y)*(t-z);return s; 返回值类型返回计算结果注意:也有函 数无返回值。void abc() printf(“#n”);说明: 表达式的值即函数返回值,它应与所定义 的函数返回值的类型一致 一个函数可以有多条return语句,执行到 哪一条return语句,哪一条起作用 return语句的另一作用是终止执行函数 为增加程序的可读性,建议只在函数结尾 处使用一次return语句main() s1=area(a,b,c);若定义好函数area, 在main函数中就可 以调用了。6.2.3 形式参数的设计 分析函数的功能,哪个数据需要调用函数提 供,就应定义一个形式参数接收该数据。 如:计算一个三角形面积,需要知道三条边的 长度。例: float area(float x,float y,float z) float t,s;t=0.5*(x+y+z);s=sqrt(t*(t-x)*(t-y)*(t-z);return s; char getach(void) return(a+random(26); 随机产生一个 小写字母。无 需参数。6.2.4 函数原型 在使用自定义函数时,除了进行函数的定 义外,还需要在调用该函数之前对其进行原 型声明 函数原型声明和函数定义的区别 函数原型声明的作用是将函数类型告诉编 译系统,使程序在编译阶段对调用函数的合 法性进行全面的检查,避免函数调用时出现 参数的个数或类型不一致的运行错误。 函数定义部分则是函数的实际实现代码 函数原型声明的格式:类型符 函数名(形式参数);参数名可省6.3 函数调用与参数传递6.3.1 函数的调用方式 有参函数调用的格式:函数名(实际参数) 无参函数的调用格式:函数名( ) 说明: 函数总是在某个函数体中被调用; 函数调用可以在结尾处加上分号,单独作 为一条语句; 对于有返回值的函数,其调用也可以出现 在某条语句中;函数调用过程float area(float x, float y,float z) float t,s;t=0.5*(x+y+z);s=sqrt(t*(t-x)*(t-y)*(t-z);return s; void main() float a,b,c,d,e,f,g;float s1,s2,s3,s;a=9;b=11;c=18;d=13;e=14;f=7;g=8;s1=area(a,b,c);s2=area(c,d,e);s3=area(e,f,g);s=s1+s2+s3;printf(“s=%fn“,s);getch(); 库函数printf主调函数被调函数6.3.2 参数传递 函数的参数: 形式参数(形参或虚参)定义函数时的 参数,用于接受主调函数提供的值。 形参调用函数时分配内存空间,调用结束后 释放空间。 实际参数(实参)调用函数时的参数, 向被调用函数提供的一些具体信息。 可以是常量、变量或表达式,有具体的值。 若是变量,在主调函数中必须有定义。 调用有参函数时,必须要提供与形参相匹 配的实参。它们必须与形参保持个数相同, 位置与类型一一对应。函数定义:float area(float x, float y,float z) 函数调用:s1=area(a, b, c);例:设计一个求两个整数和的函数 sum,并编写main函数调用它。例:设计一个判断一个数是否为素数 的函数shusu,并编写main函数打印 100以内所有的素数。void main() int x,y;x=10; y=20; printf(“x=%d y=%dn“, x,y);swap(x,y); printf(“x=%d y=%dn“, x,y); 注意,C语言中的参数传递是一种单向的“值 传递”。void swap(int a,int b) int t;t=a;a=b;b=t; xyab1020102020106.3.3 指针变量作参数void main() int x,y;x=10; y=20; printf(“x=%d y=%dn“, x,y);swap( printf(“x=%d y=%dn“, x,y); void swap(int *a,int *b) int t;t=*a;*a=*b;*b=t; xyab1020 void root(float a,float b,float c,float *x1,float *x2) *x1=(-b+sqrt(b*b-4*a*c)/2;*x2=(-b-sqrt(b*b-4*a*c)/2; 定义形参 时要用指 针变量使用形参 时取其内 容实参为变量 的地址6.3.4 数组参数 一维数组参数的定义和使用原则 一维形参数组的定义形式为:类型名 形参数组名 不用指定元素个数,但一对方括号不可缺少, 否则无法说明该参数为一数组。 如:void sort(int a ,int n); 调用使用数组参数的函数时,与形参数组对 应的实参是一个同类型的数组名,不需要指定 元素个数,也不需要加上方括号。 如:sort(a,n); 说明: 数组参数传递的是数组的首地址,当型参 数组发生改变,实参数组也会发生改变。 如:void sort(int a ,int n); 也可以写成: void sort(int *a, int n); 通常情况下,数组做函数参数,需要再定 义一个整型形参,用于传递数组元素个数的 信息。 例:设计四个函数分别用于随机产 生20个数,排序,求最大值,每行 5个打印输出,并编写main函数调 用它。例编写一个判断一个字 符串是否为“回文”的 函数。 int huiwen(char s) char *h,*t;h=s;t=s+strlen(s)-1;while(*h=*t else return(0); A B C B A 0shthth tA B B A 0hthtt hA B B C A 0htht多维数组参数 多维形参数组的定义形式为: 类型名 形参数组名数值数值 即除了最左边的方括号可能留空外,其余都 要填写数值。 如: int max_value(int a 4,int n); 调用使用多维数组参数的函数时,与形参 数组对应的实参是一个同类型的数组名,也 不需要加上任何方括号。 如: m=max_value(x,3); 6.3.5 函数的嵌套调用 C语言允许嵌套调用函数,即在调用一个函数 的过程中,又调用另一个函数。float area(float x, float y,float z) s=sqrt(t*(t-x)*(t-y)*(t-z); void main() s1=area(a,b,c); 库函数sqrt()注意:遇到函数调用,主调函数中断,转向 被调函数执行,被调函数执行结束,回到主 调函数中断处继续执行6.3.6 函数的递归调用一个函数不仅可以调用其它函数,还可 以直接或间接调用它本身,这种调用过程被 称作递归。例:对阶乘的定义。n!=n(n-1)!(n-1)!=(n-1)(n-2)! 代码:float fact(int n) float f;if(n=0|n=1) f=1;else f = n * fact(n-1);return(f); 函数在自 身定义的 内部调用 自己。n=3 float fact(int n) float f;if(n=0|n=1)f=1;else f=n*fact(n-1);return(f); main() int x; float s;scanf(“%d“,s=fact(x);printf(“s=%f“,s); n=2 float fact(int n) float f;if(n=0|n=1)f=1;else f=n*fact(n-1);return(f); n=1 float fact(int n) float f;if(n=0|n=1)f=1;else f=n*fact(n-1);return(f); 若输入为3说明: l构成递归的条件: 能用递归形式表示,并且递归向终止条件 发展。 递归结束条件及结束时的值; l递归算法设计简单,但消耗的机时和占据 的内存空间比非递归大。例:设计递归函数计算斐波那契数 列,公式如下:f(0)=0 f(1)=1f(n)=f(n-2)+f(n-1)6.4 函数与指针 6.4.1 返回指针值的函数 定义形式为: 类型名 *函数名(形式参数) 例如:int *f(int a,int b); 注意: 返回的指针(即内存地址),必须是可用 的不被释放的地址。否则返回的地址为无意 义地址。 函数调用结束后,其形参和定义变量的内 存空间都将被释放。6.4.2 函数的指针 C程序中,函数名代表了函数存储空间的起 始地址,即函数的指针。 定义一个指针变量存放函数的入口地址,这 种指针变量被称为指向函数的指针变量,其定 义形式如下: 类型名 (*指针变量名)(参数类型); 例如:int (*p)(int,int); 指针变针变 量p,指向一个函数。
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号