320 likes | 524 Views
第12讲 函数的嵌套调用. 一、 概述 1、 C 程序的模块化结构 2、 函数定义的一般形式 二、 函数间的数据传送 1、 形参与实参 2、 函数的返回值 3、 Void 函数. 4、 函数原型 5、 数组作为函数的参数 三、 函数的调用 1、 函数调用的一般形式 2、 函数嵌套调用. 一、 概述. 1、 C 程序的模块化结构. 结构化程序设计方法: 自顶向下,逐步细化; 模块化设计; 结构化编码。 特点: 程序结构清晰,易于维护,增加了函数的可重用性和可扩充性。.
E N D
第12讲函数的嵌套调用 • 一、概述 • 1、 C程序的模块化结构 • 2、 函数定义的一般形式 • 二、函数间的数据传送 • 1、 形参与实参 • 2、 函数的返回值 • 3、 Void函数
4、 函数原型 • 5、 数组作为函数的参数 • 三、函数的调用 • 1、 函数调用的一般形式 • 2、 函数嵌套调用
一、概述 1、 C程序的模块化结构 • 结构化程序设计方法: • 自顶向下,逐步细化; • 模块化设计; • 结构化编码。 • 特点: • 程序结构清晰,易于维护,增加了函数的可重用性和可扩充性。
函数头 函数头 函数体 函数体 2、 函数定义的一般形式 • 格式一 : • [类型符] 函数名称( [形参表] ) • [形参说明] • { 数据说明语句 • 可执行语句 } • 格式二 : • [类型符] 函数名称( 类型 形参1 [ ,··· ] ) • { 数据说明语句 • 可执行语句 }
函数定义的一般形式举例: (1) float sum ( x , y ) float x , y ; { int z ; z = x + y ; return z ; } (2) float sum (float x, float y ) { int z ; z = x + y ; return z ; }
函数定义的一般形式说明: (1) floatsum ( x , y ) float x , y ; { int z ; z = x + y ; return z ; } 类型说明符: 指明函数的类型,函数的类型是指函数的返回值的类型,函数返回值所具有的数据类型的种类与变量相同。省略时则默认为int型。若明确表示函数 "不带回值",可以用 " void " 作类型符,称"无类型"或称"空类型"。
float sum (x , y) float x , y ; { int z ; z = x + y ; return z ; } 函数名: 通常是一个标识符,在一个程序中除了主函数外其余函数的名字可以任意取,但应有意义。 "()" 函数标志。
参数表( 形参表 ): • 函数定义时的参数称为形式参数,形式参数彼此间用逗号分隔。 • 形式参数省略时称无参函数,但此时函数名后的圆括号不能省。 • 形参说明是用来指明各个形式参数的类型,它随形参的存在而存在。 float sum ( floatx , float y ) { …… } float sum ( x , y ) float x , y ; { int z ; z = x + y ; return z ; }
函数体: 函数中最外层一对花括弧"{ ······· }"括起来的内容,它由若干个数据说明语句和可执行语句组成,决定函数要实现的功能、完成的任务。 函数体内若无任何语句时,为空函数。 float sum ( x , y ) float x , y ; { int z ; z = x + y ; return z ; }
例 编写自定义函数计算: • 分析: • 确定形参:求 c 必须知道 f 的大小,设形参为temp。 • 确定函数:函数的返回值即为 c 的值,设为实型。 程序:float ftoc( temp ) float temp ; { float c ; c =(5./9.)*( temp – 32 ); return c ; }
例 编写一个自定义函数求 n! • 分析: • 确定形参: • 求 n!必须知道 n 的大小,设形参为 n。 • 确定函数: • 函数的返回值即为 n!的值,设为实型。 程序: float jiechen( int n ) { float x, y ; for ( x=y=1.0; x<=n; x++ ) y *= x ; return y ; }
二、函数间的数据传送 1、 形参与实参 • 实参(实际参数)是函数调用时调用函数传送给被调用函数参数的实际值。实参可以是常量、变量和表达式,实参必须有确定的值。 • 例如: fabs( -2 ); • putchar( c ); • sqrt((x*x+2)*(y+z));
形参(形式参数)是函数定义时,参数表中的参数。形式参数只能是变量。在函数定义时,参数表中的形参并没有具体的值,系统也不为其分配存储单元。形参(形式参数)是函数定义时,参数表中的参数。形式参数只能是变量。在函数定义时,参数表中的形参并没有具体的值,系统也不为其分配存储单元。 • 例如:max( float x, float y ) • { ··· } • float ftoc( float temp ) • { ··· }
例 形参和实参的运用 • try( int x, int y, int z ) • { printf( "2) x=%d, y=%d, z=%d\n", x, y, z); • z = x + y ; x = x * x ; y = y * y ; • printf( "3) x=%d, y=%d, z=%d\n", x, y, z); • } • main( ) • { int a=2, b =3, c=4 ; • printf( "1) a=%d, b=%d, c=%d\n", a, b, c ); • try( a, b, c ) ; • printf( "4) a=%d, b=%d, c=%d\n", a, b, c ); • }
1000H 1002H 1004H 实参 a ,b ,c 2 3 4 传递 2 4 3 9 4 5 形参 x ,y ,z 形参 x ,y ,z 2000H 2000H 2002H 2002H 2004H 2004H 说明:
2、 函数的返回值 • 函数的返回值:当被调用函数在完成一定的功能后,可以将处理的结果返回到调用函数。 • 方式:return 语句 • 作用:将表达式的值传给调用函数,并把控制权转向调用函数实现函数的返回,即结束被调用函数的执行,并将控制返回到调用它的函数。 • 格式: • return [ [ ( ] 表达式 [ ) ] ];
3、 void函数 • 对于不需要提供返回值的函数可以直接用void作为函数类型定义,以表明此函数返回值为”无类型”或”空类型”。 例:voidpsch( ) { printf("Wuhan University\n"); } main() { psch( ); }
4、 函数原型 • 函数原型:在定义或调用函数前,对该函数进行声明。 • 作用:将函数名、函数类型及形参个数、类型、顺序等通知编译系统,当函数被调用时,可对实参、形参的类型、个数匹配情况进行检查。 • 格式: • 类型符 函数名(参数类型1,··· ); • 或: • 类型符 函数名(类型符 形参1,··· );
例 利用变量换数 • void huanshu1( int x, int y ); /* 函数原型声明*/ • main( ) /* 主函数 */ • { int a=5,b=10; • printf(" 1)a = %d,b = %d\n",a ,b); • huanshu1( a , b ) ; • printf(" 4)a = %d,b = %d\n",a ,b);} • void huanshu1( int x, int y ) /* 利用变量换数 */ • { int t ; • printf(" 2)x = %d ,y = %d\n",x ,y ); • t = x ; x = y ; y = t ; • printf(" 3)x = %d ,y = %d\n",x ,y ); }
例 判定素数。 • #include "math.h" • int isprime( int ); /* 函数原型声明*/ • main( ) • { int x=35; • if ( isprime(x)) printf("%d 是素数。\n", x ); • else printf("%d 不是素数。\n", x ); • } • isprime( int a ) • { int i; • for ( i=2 ; i<=sqrt((double)a); i++ ) • if ( a%i == 0) return 0 ; • return 1 ; }
5、 数组作为函数的参数 • 数组元素做函数实参,遵循”值传送”特性,此时形参为变量。 • 数组名可做实参和形参,传送的是整个数组。 • 在用数组名做函数参数时,实参和形参都应该用数组(或指针变量)。
szdy1( int x,int y ) { ··· } szdy2( int x,int y ) { ··· } szdy1( int x,int y ); szdy2( int x,int y ); main( ) { int a[10], b[4][5]; ··· szdy1( a[7],b[3][2]); szdy2( b[1][2],a[4]); ··· } 数组元素作为函数参数举例: (1)
szdy1( int x[10] ) { ··· } szdy2( int x[4][5] ) { ··· } szdy1( int x[10] ) ; szdy2( int x[4][5] ) ; main( ) { int a[10], b[4][5] ; ··· szdy1 ( a ); szdy2 ( b ); ··· } (2)
数组名作函数参数时应注意: • 1)数组名作函数参数时,应在主调函数和被调函数中分别定义数组。 • 2)实参数组与形参数组的类型必须相同,但大小可以不同。 • 3)形参数组的一维下标可以省略。 • 4)数组名表示的是数组元素的首地址,数组名作函数参数时,传递的是整个数组。实参与形参之间的数据传递是地址传递。
数组名作函数的参数举例: szdy1( int x[6] ) { ··· } szdy2( int x[6][5] ) { ··· } szdy1( int x[10] ) ; szdy2( int x[6][5] ) ; main( ) { int a[10], b[4][5] ; ··· szdy1 ( a ); szdy2 ( b ); ··· }
例 利用数组换数 void huanshu2(int shuzu[ ],int n); main( ) /* 主函数 */ { int ab[2]={ 5 , 10 }, i; for (i=0;i<2;i++) printf("1)ab[%d]=%2d ",i,ab[i]); huanshu2( ab, 2 ); printf("\n"); for (i=0;i<2;i++) printf("4)ab[%d]=%2d ",i,ab[i]); }
void huanshu2(int shuzu[ ], int n ) { int t, i; printf("\n"); for (i=0;i<n;i++) printf("2)shuzu[%d]=%2d ",i,shuzu[i]); for (i=0;i<n-1;i++) { t=shuzu[i]; shuzu[i]=shuzu[i+1]; shuzu[i+1]=t; } printf("\n"); for ( i=0; i<n; i++ ) printf("3)shuzu[%d]=%2d ",i,shuzu[i]); }
说明: 5 10 10 5 int ab[ 2 ] = { 5 , 10 } ; huanshu2( ab , 2 ) ; shuzu = 2000H ab = for ( i=0; i<n-1; i++) { k = shuzu[i]; shuzu[i]=shuzu[i+1]; shuzu[ i+1 ]=k ; }
三、函数的调用 1、 函数调用的一般形式 • 格式: • 函数名( [ 实参列表 ] ); • 说明: • 实参与形参的个数相等、类型相同、顺序一致,呈一一对应的关系。 • 实参的求值顺序不确定,与所用系统有关。 • 实参应有确定的值。
方式 • 1)函数语句: • 例printf(”·····”); • 2)函数表达式: • 例c=2*pow (3.5 ,6); • 3)函数参数: • 例c=2*pow (pow (3.5,6),6); • 例printf(”%f\n”,pow (3.5,6));
例:说出下列程序的功能 • fun2( int a, int b ) • { int c ; c=a*b%3 ; return c ; • } • fun1( int a, int b ) • { int c ; a+=a ; b+=b ; • c = fun2( a, b ) ; return c*c ; • } • main ( ) • { int x=11, y=19 ; • printf("%d\n", fun1( x, y) ); • }