第12讲 函数的嵌套调用
DESCRIPTION
第12讲 函数的嵌套调用. 一、 概述 1、 C 程序的模块化结构 2、 函数定义的一般形式 二、 函数间的数据传送 1、 形参与实参 2、 函数的返回值 3、 Void 函数. 4、 函数原型 5、 数组作为函数的参数 三、 函数的调用 1、 函数调用的一般形式 2、 函数嵌套调用. 一、 概述. 1、 C 程序的模块化结构. 结构化程序设计方法: 自顶向下,逐步细化; 模块化设计; 结构化编码。 特点: 程序结构清晰,易于维护,增加了函数的可重用性和可扩充性。. - PowerPoint PPT PresentationTRANSCRIPT
第 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形参 x , y , z 2000H 2002H 2004H
函数的返回值:当被调用函数在完成一定的功能后,可以将处理的结果返回到调用函数。
方式: 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) ); }