讲授提纲第七章_函数(1)_第1页
讲授提纲第七章_函数(1)_第2页
讲授提纲第七章_函数(1)_第3页
讲授提纲第七章_函数(1)_第4页
讲授提纲第七章_函数(1)_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第七章 函数函数一、函数及其定义1函数定义的一般形式(p114)返回值类型 函数名 ( 形式参数表 )形式参数类型描述; (函数内部的)变量定义与有关说明语句部分函数的可执行语句序列函数头、函数体例7-1 求两个整数的最大值的函数定义。(或p115)int max ( x,y ) /* 定义了有两个形式参数x,y且返回int值的函数max */int x, y; /* 说明了形参x,y均为int型 */ int z; /* 定义了函数内部使用的变量z */z = x>y ? x:y; /* 将x,y中较大值送入z */return (z);/* 将z做为函数返回值,并使函数返回到被调程序

2、(父程序) */2关于函数返回值类型 允许C基本数据类型和任何有意义的用户自定义类型。 如果省略返回值类型则隐含返回int类型。 没有返回值的函数。3关于形式参数及形参说明函数参数是为在函数和父程序间传递数据而设置的。各参数在被父程序调用时才从父程序处获得真正的值,因而在定义函数时参数是“形式上”的值称形式参数,简称形参。函数被调用时形参从父程序处获得的真实值称实际参数,简称实参。实参传递给形参的过程称实形结合,加上函数处理结果返回到父程序的过程统称函数的参数传递,函数参数传递是函数技术中的重要内容。 形参之间以“,”分隔。 形参是局部性变量,只在函数内有效。 两种形参说明效果相同。无参函数的

3、()不能省略,以示位于()前面的标识符是函数名。 char GetCHAR() int k; k =getchar(); if( k>=a && k<=z) return k-32; else return 0; 4关于函数体与函数返回。 函数体是实现函数功能的程序片断,函数体的设计与通常的编程在编程思想和技术上没有任何差别。 返回语句return使函数退出运行返回到父程序继续执行,同时将函数值带回父程序。return语句共有4种形式。return(表达式);return 表达式;return; 无return语句。 return语句可以安排在函数体任何位置,也可安

4、排多条return语句。5关于多个函数的位置关系:并列关系而非嵌套关系。 6关于主函数main() 程序中有且仅有一个main()函数,程序从main()函数开始执行。 main() 函数也有形参,参数由操作系统给出,即“命令行参数”。二、函数调用1函数调用的一般形式(p115)函数名(实参表)2函数调用与函数执行过程(p116)(1) 为函数的形参分配内存空间;(2) 计算实参表达式的值,并将实参表达式的值赋给对应的形参;(3) 为函数的局部变量分配内存空间;(4) 执行函数体内的语句片段;(5) 函数体执行完毕或执行了函数体内的return语句(若return语句带表达式,则计算出该表达式

5、的值,并以此值作为函数的返回值)后,释放为这次函数调用分配的全部内存空间;(6) 将函数及返回值返回到父程序的函数调用处,继续执行父程序。例7-2 如下给出了程序中调用max函数的全过程说明。 #include <stdio.h> float max( float x, float y ) float z; z = x>y ? x : y; return z; main() float a=19.8, b=-98.8, c; c = max( a, b ); printf( "MAX(a,b)=%fn", c ); 三、函数的参数传递方式1传值方式例7-3

6、 返回阶乘的函数及其调用,函数调用时参数采用传值方式。 #include <stdio.h> float fac( int n ) int f= 1.0; while ( n >= 1 ) f = f * n; -n; return ( f ); main() int k = 6; printf( "%8.1fn", fac( k ) ); 2传地址方式例7-4 返回阶乘的函数及其调用,函数调用时采用传地址方式。 #include <stdio.h> float fac( int *n ) int f= 1.0; while ( *n >

7、= 1 ) f = f * (*n); -(*n); return ( f ); main() int k = 6; printf( "%8.1fn", fac( &k ) ); 要点 传值方式中函数对形参的处理是在函数内部变量中进行的,形参在函数内的改变不会使与之结合的实参变量发生变化,称变量直接操作。传地址方式中函数对形参的处理是在形参的所指对象单元即与形参结合的实参变量上进行的,形参在函数中的改变实质是实参变量的改变,称变量间接操作。四、函数的类型说明函数类型说明有三种方法 将函数定义放在函数调用之前。 在函数调用之前的任何位置安排一条类型说明语句,形式为:返

8、回值类型 函数名(); 在调用函数的父程序内的变量定义处,顺便说明函数返回值类型。规定 如果函数返回int, char类型可以不进行函数类型说明。§7.2 指针与函数的参数传递一、向函数中传递变量的指针例7-5 试图用swap() 函数将两实参变量的值交换。void _swap( int x, int y ) int z; z=x; x=y; y=z; main() int a=10, b=20; _swap( a,b ); printf( "a=%d, b=%dn", a, b); 结论传值方式不能将“形参的值”“传回”父程序中的实参。例7-6 用swap函数将

9、两实参变量的值交换。 #include <stdio.h> void swap( int *x, int *y ) int z; z = *x; *x = *y; *y = z; main() int a=10, b=20; swap( &a, &b ); printf( "a=%d, b=%dn", a, b); 结论传地址方式可以将“形参的值”“传回”父程序中的实参。二、通过指针向函数中传递一维数组方法 定义一个指针形参,函数调用时将实参数组的首地址赋值给指针形参,从而达到“对形参数组的处理是在实参数组上进行的”的效果。例7-7 求整型数组各

10、元素之和。int add( int *x, int n ) int sum, i; for( sum=0,i=0; i<n; i+ ) sum += *(x+i); return sum; main() int arr4 = 1,3,4,5 , s; s = add( arr, 4 ); printf( "%dn", s ); 数组的元素描述形式也可采用下标法或元素指针法。 for( sum=0,i=0; i<n; i+ ) sum += xi; /* 下标法 */ for( sum=0,i=0; i<n; i+ ) sum += x+; /* 元素指针法

11、 */ 2000 1 arr0 2002 3 arr12004 4 arr22006 5 arr32008 2000 x 2010 4 n 2012 sum 2014 i三、通过指针向函数中传递字符串方法定义一个指向字符(串)的指针变量作形参,调用时将字符串的首地址与形参变量结合使形参指针指向了实参字符串。这样在函数中对字符串的处理实质是在实参字符串上进行的。例7-8 将字符串中所有小写字母改成大写字母进行输出,小写转大写工作由自定义函数StrToUpr()完成。void StrToUpr( char *s ) while ( *s != '0' ) if ( *s>=&

12、#39;a' && *s<='z' ) *s = *s - ('a'-'A'); +s; main() char str40; gets( str ); StrToUpr( str ); puts( str ); 例7-9 用函数实现字符串的复制。 #include <stdio.h> void StrCopy( char *from, char *to ) while ( *from != '0' ) *to+ = *from+; *to = '0' main() cha

13、r str140, str240; gets( str1 ); StrCopy( str1, str2 ); puts( str2 ); 四、 通过指针向函数中传递二维数组方法传二维数组首地址以使函数中的形参指针指向二维数组,形成“对形参数组处理实质上是在实参二维数组上进行”的效果。例7-10 求二维数组中元素的最大值。程序1int Arr2Max( int a3, int m ) /* int Arr2Max(int (*a)3,int m) */ int max=-32768, i, j; for ( i=0; i<m; i+ ) for( j=0; j<3; j+ ) if(

14、 aij > max ) max = aij; return max; main() int arr23 = 1,4,7,4,18,6 ; printf( "MAX=%dn", Arr2Max(arr,2) ); 程序2 形参描述为指向一维数组的指针,函数描述改为int Arr2Max(int (*a)3,int m)。 程序3 形参描述为指向一维数组的指针,元素的处理采用游动的元素指针法。 #include <stdio.h> int Arr2Max( int (*a)3, int m ) int max=-32768, j; int (*p)3; fo

15、r ( p=a; p<a+m; p+ ) for( j=0; j<3; j+ ) if( (*p)j > max ) max = p0j; return max; main() int arr23 = 1,4,7,4,18,6 ; printf( "MAX=%dn", Arr2Max(arr,2) ); 五、返回指针的函数例7-11 某字符数组中存有两个字符串以 0做为串结束符,即字符数组中先存一个字符串以0结束,从0的下一字符位置又存有一个字符串以0结束,如下程序可以打印出第2个字符串。 #include <stdio.h> char *Se

16、condStr ( char *s ) while ( *s!='0' ) s+; return ( s+1 ); main() char str40 = "abcdef0ABCDEFGH", *str2; str2 = SecondStr( str ); puts( str2 ); §7.3 函数程序设计要点1 必须了解开发环境所能提供的系统函数。要点2 如何设计给定功能的函数,设计必须严格按如下步骤进行。(1)清楚知道函数所要完成的功能。(2)入口参量设计。要说明参数个数,传递方式,形参名,参数含义。(3)出口参量设计。要说明出口参量个数,参量

17、传递方式,参量含义。(4)写出正确的函数头描述。(5)函数体设计。要点3 如何划分函数。一、给定功能设计函数例7-12 设计函数计算n!设计过程(1)明确函数功能:求一个正整数的阶乘。(2)入口参量设计。(3)出口参量设计。(4)函数头描述:float fac (int n)(5)函数体设计。float fac ( int n ) int i; float p; for ( p=1,i=1; i<=n; i+ ) p *= i; return p; 例7-13 设计函数求一维数组中的最大值和最小值。设计过程 入口参量。 出口参量。 函数头描述。void MaxMin( a, n, max

18、, min )float a, *max, *min; / 或 float *a, *max, *min; */int n; 函数体设计。函数及调用程序 void MaxMin( a, n, max, min ) float a, *max, *min; int n; int i; *max = *min = a0; for ( i=1; i<n; i+ ) if ( ai > *max ) *max = ai; if ( ai < *min ) *min = ai; main() float a5 = 1,23,45,-9,7, c, d; MaxMin( a, 5, &a

19、mp;c, &d ); printf( "MAX=%6.1f MIN=%6.1fn", c, d ); 例7-14 编写函数将3个整数排序并求和。设计过程 参量设计。 函数头描述。int SortSum( int *x1, int *x2, int *x3 )函数设计结果 int SortSum( int *x1, int *x2, int *x3 ) int t; if( *x1 > *x2 ) t=*x1; *x1=*x2; *x2=t; if( *x1 > *x3 ) t=*x1; *x1=*x3; *x3=t; if( *x2 > *x3

20、) t=*x2; *x2=*x3; *x3=t; return ( *x1 + *x2 + *x3 ); 二、 借助函数编写程序例7-15 计算S=Cn1+Cn3+Cnk (n由键盘输入,k为不大于n的最大整数)。设计过程程序结构为: 输入n 累加器s清0 for ( i=1; i<=n;i+=2 ) 计算Cni => p è Cni = n! ( i! * (n-i)! ) s += p 输出s 设计函数 float fac (int n);#include "stdio.h" float fac( int n ) int i; float p; f

21、or( p=1,i=1; i<=n; i+ ) p *= i; return p; main( ) int n, i, sum; scanf ( "%d", &n ); for ( sum=0,i=1;i<=n;i+=2 ) sum += fac(n) / fac(i) / fac(n-i); printf ( "%dn", sum ); 例7-16 对M行N列矩阵的每行分别求和,将最小的和数输出。思考过程 函数Sum():求和及存入一维数组bM。函数Min():求数组最小值。 Sum()函数的设计 入口参量:一个M行N列的二维数组,

22、描述为int xN。出口参量:一个M个元素的一维数组,描述为int y或int *y。函数头描述:void Sum ( int x N, int y )函数:void Sum ( int xN, int y ) int i, j; for ( i=0; i<M; i+ ) yi = 0; for ( j=0; j<N; j+ ) yi += xij; Min()函数的设计 入口参量:一个M个元素的一维数组,描述为int x或int *x。出口参量:以函数返回值形式返回的x数组最大值。函数头描述:int Min ( int *x )函数:int Min( int *x ) int i

23、, min; min = x0; for ( i=1; i<M; i+ ) if ( xi < min ) min = xi; return min; 主函数main() #include <stdio.h> #define M 3 #define N 3 main() int aMN= 1,2,3, 1,2,2, 3,4,5 ; int bM; Sum ( a, b); printf( "Min=%dn", Min( b ) ); 例7-36 求一组分数之和S= ,以输入了0(分子为0或分母为0)结束输入及求和过程。#include <std

24、io.h>int gcd( int m, int n ) /* 用欧氏“辗转相除法”求m,n的最大公约数 */ /*函数体请参见例4-29 */ main() int s1, s2, a, b, k; s1 = 0; s2 = 1; scanf( "%d %d", &a, &b ); while ( a!=0 && b!=0 ) k = gcd(a,b); a /= k; b /= k; s1 = s1*b + s2*a; s2 = s2*b; k = gcd(s1,s2); s1 /= k; s2 /= k; scanf ( &quo

25、t;%d %d", &a, &b ); printf( "%d/%d=%7.2fn", s1, s2, (float)s1/s2 ); 函数嵌套调用与递归调用一、函数的嵌套调用例7-22 用函数实现起泡排序。void swap( int *x, int *y ) int t; t = *x; *x = *y; *y = t; void BubbleSort( int x, int n ) int i, j; for ( i=0; i<n-1; i+ ) for ( j=0; j<n-i-1; j+ ) if ( xj > xj+1

26、 ) swap( &xj, &xj+1 ); main() int a100, n, i; printf("input n="); scanf( "%d", &n ); for ( i=0; i<n; i+ ) scanf( "%d", &ai ); BubbleSort( a, n ); for ( i=0; i<n; i+ ) printf( "%d ", ai ); 二、函数的递归调用递归问题特征(1)细化出的子问题与原问题性质相同但比原问题简单。(2)问题有“不含

27、递归的”最简解。例7-23 用递归方法求阶乘。 #include <stdio.h> long fac( int n ) if ( n = 1 ) return 1; else return n * fac(n-1); main() printf( "%ldn", fac(4) ); 递归函数设计要点(1)递归函数中含有从原问题到子问题转换的递归调用语句。(2)递归函数有引起问题越来越简单并反映原问题与子问题性质的形参。(3)递归函数中必须有不含递归的最简情况处理语句。例7-18 菲波拉奇数列第一项是0,第二项是1,以后每一项是前2项的和。用递归函数求菲波拉奇数

28、到的第n项。int fib( int n ) if ( n = 1 ) return 0; if ( n = 2 ) return 1; return fib( n-1 ) + fib( n-2 ); main() int k=8; printf( "Fib(%d)=%dn", k, fib(k) ); 例7-19 用递归函数实现辗转相除法求最大公约数。int gcd( int m, int n ) if ( n = 0 ) return m; else return gcd( n, m%n ); main() int a, b; scanf( "%d %d&qu

29、ot;, &a, &b ); printf( "gcd(%d,%d)=%dn", a, b, gcd(a,b) ); §7.5变量的存储类型一、变量的存储性质变量的数据性质 变量的存储性质变量存储类型auto 自动变量static 静态变量extern 外部变量register 寄存器变量变量定义的完整格式 (变量存储类型标识符) 变量数据类型标识符 变量表;二、自动变量(局部变量)三、外部变量(全局变量)四、静态变量内部静态变量与局部变量的区别外部静态变量与全局变量的区别五、寄存器型变量六、再论变量初始化1静态变量的初始化2动态变量的初始化例7-

30、20 阅读下列程序并回答问题。(1)程序中定义的各个变量的存储类型是什么?分配在什么数据区?生存期、作用域是什么?(2)写出程序运行结果。 #include <stdio.h> int n = 1 ; main() static int x = 5 ; int y ; y = n; A: printf( "MAIN: x=%2d y=%2d n=%2dn", x, y, n ); B: func(); C: printf( "MAIN: x=%2d y=%2d n=%2dn", x, y, n ); D: func(); func() sta

31、tic int x = 4 ; int y = 10; x += 2; n += 10; y += n; E: printf( "FUNC: x=%2d y=%2d n=%2dn", x, y, n ); MAIN: x=5,y=1,n=1FUNC:x=6, y=21,n=11MAIN:x=5,y =1,n=11FUNC:x=8,y=31,n=21 系统函数函数的程序阅读例7-26 以下程序的运行结果是什么?sub( int x, int y, int *z ) *z = x + y; main() int a, b, c; A: sub(10, 5, &a); B

32、: sub( 7, a, &b); C: sub( a, b, &c); printf( "%d %d %dn", a, b, c); 例7-27 写出以下程序的运行结果。int a10, i; main() sub1(); sub3(a); sub2(); sub3(a); sub1() for ( ;i<10; i+ ) ai=i+i; sub2() int a10, i; for (i=0; i<10; i+ ) ai = i; sub3( int a ) int i; for ( i=0;i<10;i+ ) printf( "%d ", ai );*例7-28 阅读程序写出运行结果,并说明函数功能。int *find( int *x, int id ) while( *x != id ) if( *x>=3 &

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论