1
C++程序
语言——V3.0
计算机学院: 张 永 鸣
Tel:82317623/7613
E-mail:zym@buaa.edu.cn
2
第三章
z 函数的定义与使用
z 函数间的参数传递
z 内联函数
z 带默认形参值的函数
z 函数重载
z 使用C++系统函数
z 函数模板(第九章介绍)
3
模块化程序设计
函数的定义与使用函数的定义与使用)模块化程序设计无论是C还是C++都是极为重要的概念。
)函数是面向对象程序设计中的基本抽象单元,是对功能的
抽象。
A
B
D
C
E F G
IH
主模块
子模块
层次分明
功能抽象
逻辑清晰 自顶向下
简化、可靠、快速、高效、可维护性简化、可靠、快速、高效、可维护性
4
程序结构函数的定义与使用
)程序结构)程序结构
void main()
{
...
fb( );
...
fc( );
...
}
fb( )
{
...
fd( );
...
fe( );
...
}
fc( )
{
...
fe( );
...
ff( );
…
fg( );
}
fd( )
{
...
fh( );
...
}
fe( )
{
...
fh( );
...
}
fh( )
{
...
...
}
ff( )
{ }
fg( )
{
fi( );
}
fi( )
{
...
...
}
函数可以
递归调用
函数可以
嵌套调用
恢复:
主调程序现场
返回地址
保存:
返回地址
当前现场
5
函数定义、函数声明和函数调用
函数的定义与使用函数的定义与使用void main()
{ double new_style( int a, double x ) ; //函数声明
double x, y;
int a;
……
y = new_style( a, x ); //函数调用
……
}
double new_style( int a, double x ) // 函数定义
{
// 函数体
}
6
定义函数
A. 在函数体中用 return 语句实现函数的返值。
B. 不允许再出现定义函数。(即函数不能嵌套定义)。
C. 缺省,为空函数。(调试程序时先调用,后补功能)
[ auto ]
register
static
extern
a.函数返回值的数据类型。
b.缺省时,隐含 int 型返值。
c.函数无返值时,可用void
表示 。
同标识符
命名
A. 被初始化的内部变量。
B. 寿命和可见性仅限于函数内部。
C. 若无参数,可写void。
函数的定义与使用函数的定义与使用
[存储类型] [数据类型] 函数名([形参表])
{
[内部数据说明 ]
[函数体]
}
7
函数的返回函数的定义与使用函数的定义与使用
return(表达式) ;
return 表达式 ;
return ;
return [ [( ] [表达式] [ )] ];
① return 语句只能把一个返值传递给调用函数。
② 若 return 语句中表达式类型与函数返回值的数据
类型不一致,则转换为函数类型。
③ 返回值可以是数值,也可以是地址。当返值是地
址时,应该用指针接受它(即函数定义为指针型函
数。
8
函数声明
函数的定义与使用函数的定义与使用
① 含类型说明的形参表
[名1], [名2 ], ..., [名n ]
② TC 2.0v 可省、C++时,不能省
调用函数:
函数名( [实参表] );
(允许嵌套调用、递归调用)
)当被调函数不可见时,调用该函数之前必须声明函数原型。
[存储类型] [数据类型] 函数名([形参表]) ;
9
例3.1 求组合数
#include
void main() // 3_1.cpp c5_2.cpp
{ int m, n, cmn( int, int );
scanf("%d,%d", &m, &n); // 输入:7,5↵ != 7 5 ↵
printf("Cmn=%d\n", cmn(m, n) );
}
cmn(int x, int y )
{ int facto( int );
if( x>=y && y>=0 )
return( facto( x) / facto( y ) / facto( x-y ) ) ;
else
return( 0 );
}
函数的定义与使用函数的定义与使用
公式: =
要求: m≥ n≥ 0 且 =1
Cnm )!(!
!
nmn
m
−
0
mC
嵌套调用
10
例3.1 求组合数(续)
// function for n!
facto (int k ) //3_1.cpp
{ int i, m=1;
if( k==0 )
return( 1 ) ;
else
{
for( i=2; i<=k; i++ )
m *= i;
return( m );
}
}
函数的定义与使用函数的定义与使用
//3_1.cpp 4,2 ↵ = = 6
7,5 ↵ = = 21
7,6 ↵ = = 7
8,7 ↵ = = -5
C24 )!24(!2
!4
−
C57 )!57(!5
!7
−
C67 )!67(!6
!7
−
C78 )!78(!7
!8
−
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11
例3.2 数制转换函数的定义与使用函数的定义与使用
例3.2 输入一个8位二进制数,将其转换为
十进制数输出。
分析:11012 = 1(23) + 1(22) + 0(21) + 1(20)
= 1310
所以,如果输入00001101,则应输出13
12
例3.2 数制转换(续)
函数的定义与使用函数的定义与使用#include //3_2.cppdouble power(double x, int n);
void main(void)
{ int i, value=0;
char ch;
cout << "Enter an 8 bit binary number:";
for(i = 7; i >= 0; i--)
{ cin >> ch;
if(ch == '1')
value += int(power(2,i));
}
cout <<"Decimal value is "<内容忠实的输出到屏幕上
方法二:递归实现。
//3_3_2.cpp recursion
#include
void main( void )
{ int c;
if((c=getchar( ) )!=EOF )
{ putchar( c );
main( );
}
}
方法二:递归实现。
//3_3_2.cpp recursion
#include
void main( void )
{ int c;
if((c=getchar( ) )!=EOF )
{ putchar( c );
main( );
}
}
函数的定义与使用方法一:非递归实现。
//3_3_1.cpp non recursion
#include
void main( void )
{ int c;
while((c=getchar( ) )!=EOF)
putchar( c );
}
方法一:非递归实现。
//3_3_1.cpp non recursion
#include
void main( void )
{ int c;
while((c=getchar( ) )!=EOF)
putchar( c );
}
//3_3_2.cpp//3_3_1.cpp
递归调用
15
例例3.4 3.4 递归函数程序。
例3.4 把输入的一篇文本文件以正向和逆向输出到屏幕上。
#include //3_4.cpp recursion
void main( void )
{ int c;
if( ( c = getchar() ) != EOF )
{ putchar( c );
main( );
putchar( c );
}
else
{ putchar( '\n' );
putchar( '\n' );
}
}
函数的定义与使用函数的定义与使用
//3_4.cpp
16
例3.5 求n!
分析:计算n!的公式如下:
是递归形式的公式,前面求组合数中n!
用非递归形式实现,现用递归函数求n!。
函数的定义与使用函数的定义与使用
⎩⎨
⎧
>−
==
)0()!1(
)0(1
!
nnn
n
n
17
例例3.5 3.5 求n!程序。
long facto(long n)
{
if (n<0)
{cout<<"n<0,data error!"<
void main( ) //3_5.cpp
{
long facto(long n);
int n;
cout<<"Enter a positive integer:";
cin >> n;
cout<
void main( ) //3_5.cpp
{
long facto(long n);
int n;
cout<<"Enter a positive integer:";
cin >> n;
cout<题
— — 古 代 印 度 布 拉 玛 庙 里 僧 侣 们 玩 的 游 戏 。
N o . 1
N o . 6 1
N o . 6 2
N o . 6 3
N o . 64
N o . 1
N o . 61
N o . 6 2
N o . 6 3
N o . 6 4
铜 板
金
盘
100万 年 (计 算 一 次 移 动 /微 秒 ) 移 动 条 件 : 一 次 移 一 个 。
5800亿 年 (计 算 一 次 移 动 /秒 ) 只 能 小 压 大 。
615,511,709,073,744,466,181264 =−
a b c
A->C
19
例例3.6 汉诺塔(2/3)
函数的定义与使用函数的定义与使用分析:
将 n 个盘子从A柱移到C柱可以分解为下面三个步骤:
①将 A 上n-1个盘子移到 B 柱上(借助C柱);
②把 A 柱上剩下的一个盘子移到 C 柱上;
③将n-1个盘子从B柱移到C柱上(借助A柱);
事实上,上面三个步骤包含两种操作:
①将多个盘子从一个柱移到另一个柱上,这是一个递归的过
程。 hanoi函数实现。
②将1个盘子从一个柱上移到另一柱上。
用move函数实现。
20
例例3.6 汉诺塔(3/3)
#include