第 12讲 函数的嵌套调用一,概述
1,C程序的模块化结构
2,函数定义的一般形式二,函数间的数据传送
1,形参与实参
2,函数的返回值
3,Void函数
4,函数原型
5,数组作为函数的参数三,函数的调用
1,函数调用的一般形式
2,函数嵌套调用
1,C程序的模块化结构
结构化程序设计方法:
自顶向下,逐步细化;
模块化设计;
结构化编码。
特点:
程序结构清晰,易于维护,增加了函数的可重用性和可扩充性。
一,概述格式一,
[类型符 ] 函数名称( [形参表 ] )
[形参说明 ]
{ 数据说明语句可执行语句 }
格式二,
[类型符 ] 函数名称( 类型 形参 1 [,··· ] )
{ 数据说明语句可执行语句 }
2,函数定义的一般形式函数头函数体函数头函数体函数定义的一般形式举例:
( 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)
float sum ( 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 ( float x,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 ;
}
)32(95 fc
例 编写一个自定义函数求 n!
分析:
确定形参:
求 n! 必须知道 n 的大小,设形参为 n。
确定函数:
函数的返回值即为 n! 的值,设为实型。
程序:
float jiechen( int n )
{ float x,y ;
for ( x=y=1.0; x<=n; x++ )
y *= x ;
return y ;
}
实参 (实际参数)是函数调用时调用函数传送给被调用函数参数的实际值。实参可以是常量、
变量和表达式,实参必须有确定的值。
例如,fabs( -2 );
putchar( c );
sqrt(( x*x+2) *(y+z));
二,函数间的数据传送
1,形参与实参形参 (形式参数)是函数定义时,参数表中的参数。形式参数只能是变量。在函数定义时,参数表中的形参并没有具体的值,系统也不为其分配存储单元。
例如,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 );
}
说明:
2 3 4
1000H
实参 a,b,c
1002H 1004H
传递
2 3 4形参 x,y,z
2000H 2002H 2004H
4 9 5,,
函数的返回值:当被调用函数在完成一定的功能后,可以将处理的结果返回到调用函数。
方式,return 语句
作用:将表达式的值传给调用函数,并把控制权转向调用函数实现函数的返回,即结束被调用函数的执行,并将控制返回到调用它的函数。
格式:
return [ [ ( ] 表达式 [ ) ] ];
2,函数的返回值对于不需要提供返回值的函数可以直接用
void作为函数类型定义,以表明此函数返回值为,
无类型,或,空类型,。
例,void psch( )
{ printf("Wuhan University\n"); }
main()
{ psch( ); }
3,void函数
函数原型:在定义或调用函数前,对该函数进行声明 。
作用:将函数名、函数类型及形参个数、类型、顺序等通知编译系统,当函数被调用时,可对实参、形参的类型、个数匹配情况进行检查。
格式:
类型符 函数名(参数类型 1,··· );
或:
类型符 函数名(类型符 形参 1,··· );
4,函数原型例 利用变量换数
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 );
main( )
{ int a[10],b[4][5];
···
szdy1( a[7],b[3][2]);
szdy2( b[1][2],a[4]);
·· }
szdy1( int x,int y )
{ ··
}
szdy2( int x,int y )
{ ··
}
(1)
szdy1( int x[10] ) ;
szdy2( int x[4][5] ) ;
main( )
{ int a[10],b[4][5] ;
···
szdy1 ( a );
szdy2 ( b );
·· }
szdy1( int x[10] )
{ ··
}
szdy2( int x[4][5] )
{ ··
}
(2)
数组名作函数参数时应注意:
1) 数组名作函数参数时,应在主调函数和被调函数中分别定义数组 。
2) 实参数组与形参数组的类型必须相同,但大小可以不同 。
3) 形参数组的一维下标可以省略 。
4) 数组名 表示的是 数组元素的首地址,数组名作函数参数时,传递的是 整个数组 。 实参与形参之间的数据传递是 地址传递 。
数组名作函数的参数举例:
szdy1( int x[10] ) ;
szdy2( int x[6][5] ) ;
main( )
{ int a[10],b[4][5] ;
···
szdy1 ( a );
szdy2 ( b );
·· }
szdy1( int x[6] )
{ ··
}
szdy2( int x[6][5] )
{ ··
}
例 利用数组换数
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]);
}
说明,
2000H A[0]
2002H A[1]
ab = shuzu = 2000H5
10
10
5
int ab[ 2 ] = { 5,10 } ;
huanshu2( ab,2 ) ;
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) );
}