为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

C与C++第三章:函数

2011-08-25 46页 pdf 5MB 18阅读

用户头像

is_265013

暂无简介

举报
C与C++第三章:函数 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...
C与C++第三章:函数
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 //3_6_1.cpp void hanoi( int n, char a, char b, char c ) { if( n>0 ) { hanoi(n-1, a, c, b) ; cout <<"Move disc "<> n; hanoi( n, 'a', 'b', 'c' ); } 函数的定义与使用函数的定义与使用 //3_6_1.cpp 21 函数的参数传递 函数的定义与使用函数的定义与使用…………函数名函数名( )( ) {{ funcfunc((实参表实参表);); }} …………funcfunc((形参表形参表)) {{ ………… }} 1. 实参与形参的个数、顺序、数据类型必须一致。 2. 在函数被调用时才分配形参的存储单元。 3. 实参可以是常量、变量或表达式(是形参的初值)。 4. 传递时是传递参数值,即复制传递。 5. 使用地址作为参数,即地址传递(可返处理结果)。 6. 数组作为参数时的情况: – 数组元素作实参,与单个变量一样。 – 数组名作参数,传送的是数组首地址(可回带结果)。 7. 形参以引用接收实参,即地址传递(可返处理结果)。 * 使用全局变量传递数据 22 例:复制与地址方式传递数据 函数的定义与使用函数的定义与使用 例3.8 引用地址接收 #include //3_8.cpp void main() { int a=2, b=5; void swp1( int &, int & ); cout << a << " " << b << endl; swp1( a, b ); cout << a << ", "<< b << endl; } void swp1( int &x, int &y ) { int r; r = x; x = y; y = r; cout << x << "; "<< y << endl; } 例3.8 引用地址接收 #include //3_8.cpp void main() { int a=2, b=5; void swp1( int &, int & ); cout << a << " " << b << endl; swp1( a, b ); cout << a << ", "<< b << endl; } void swp1( int &x, int &y ) { int r; r = x; x = y; y = r; cout << x << "; "<< y << endl; } 例3.7 复制数据传递 #include //3_7.cpp void main() { int a=2, b=5; void swp1( int , int ); cout << a << " " << b << endl; swp1( a, b ); cout << a << ", " << b << endl; } void swp1( int x, int y ) { int r; r = x; x = y; y = r; cout << x << "; "<< y << endl; } 例3.7 复制数据传递 #include //3_7.cpp void main() { int a=2, b=5; void swp1( int , int ); cout << a << " " << b << endl; swp1( a, b ); cout << a << ", " << b << endl; } void swp1( int x, int y ) { int r; r = x; x = y; y = r; cout << x << "; "<< y << endl; } //3_8.cpp//3_7.cpp 23 例3.9 数组名和数组元素传递数据。 #include void main(void) { int a[2], b[2], c; int func1( int x[], int s, int t ); a[0]=a[1]=b[0]=b[1]=1; cout<<"-1-"< //3_10.cpp inline double CalArea(double radius) { return 3.14*radius*radius; } void main( ) { double r(3.0); //for VC 6.0 //double r=3.0; //for VC 6.0 and TC 3.0 double area; area=CalArea(r); cout << area << endl; } //3_10.cpp 28 缺省形参值的作用 带缺省参数的函数带缺省参数的函数void void funcfunc((intint a,a, intint b= b= --1);1); 调用调用funcfunc函数的方法:函数的方法:funcfunc(1, 2); (1, 2); 或或 funcfunc(1); (1); 例例3.113.11 int add(int x=5, int y=6) { return x+y; }int add(int x=5, int y=6) { return x+y; } #include //3_11.cpp void main(void) { cout << add(10, 20) << endl; //30=10+20 cout << add(10) << endl; //16=10+6 cout << add( ) << endl; //11=5+6 } #include //3_11.cpp void main(void) { cout << add(10, 20) << endl; //30=10+20 cout << add(10) << endl; //16=10+6 cout << add( ) << endl; //11=5+6 } //3_11.cpp 29 参数缺省值的位置和应用参数缺省值的位置和应用 带缺省参数的函数带缺省参数的函数)) 一般在函数原型中指定参数缺省值,且只有参数列表一般在函数原型中指定参数缺省值,且只有参数列表 的后部参数才可以是缺省的。的后部参数才可以是缺省的。 void f(void f(intint a,a, intint b= b= --1,1, intint c=10); //c=10); //正确正确 void f(void f(intint a,a, intint b= b= --1,1, intint c); //c); //错误错误 void f(void f(intint a,a, intint c,c, intint b= b= --1); //1); //正确正确 )) 一旦使用某个缺省参数值,则这个参数后面的所有缺一旦使用某个缺省参数值,则这个参数后面的所有缺 省值都被使用。省值都被使用。 f(2, 4, 6); f(2, 4, 6); 或或 f(2); f(2); 或或 f(2, 4); //f(2, 4); //正确正确 f(2, ,4); //f(2, ,4); //错误错误 30 参数缺省值和添加及占位符参数缺省值和添加及占位符 带缺省参数的函数带缺省参数的函数)) 一般参数缺省值也可以是全局变量、全局常量,甚至 是一个函数调用。 int d= -10; void f2(int a, int b= -1, int c=d); //正确 int setclock( time_t start_time = time(NULL) ); )) 在函数声明中,一旦定义了缺省值,就不能再定义它, 但可以添加一个或多个缺省值。 void f3(int a, int b, int c=0); void f3(int a, int b=1, int c); //正确添加b的缺省值 void f3(int a, int b=1, int c=0); //错误,重定义b、c )) 缺省参数可以让声明的参数没有标识符。 void func(int x, int =0, float f=1.1); void func(int x, int, float f) { /*…可用x,f…*/} 用func函数:func(1); 或func(1, 2, 3.0); 占位符(placeholder) //3_12.cpp 31 参数个数不定应用参数个数不定应用 带缺省参数的函数带缺省参数的函数)) 有些函数有时不能明确参数类型和参数个数,此时可有些函数有时不能明确参数类型和参数个数,此时可 利用利用......符,它表示符,它表示参数个数不定参数个数不定。。 (在(在stdargstdarg.h.h头文件提供了一系列处理头文件提供了一系列处理……参数例程)参数例程) 例3.13 输出错误信息 void error( int severity …) { …... } …... error(0, "system", "error"); error(1, "can't", "open" , "printer" ); error(2, "error"); …... //3_13.cpp 32 重载函数 ))一词多义,一词多义,从上下文中理解其含义。从上下文中理解其含义。 playplay the piano(basketballthe piano(basketball、、footballfootball、、…………)) )) C++C++允许功能相近的函数在同作用域内定义同名函数,允许功能相近的函数在同作用域内定义同名函数, 从而形成重载。方便使用,便于记忆。从而形成重载。方便使用,便于记忆。 int abs(int i); long labs(long l); double dabs(double d); …… // in C abs(-10); labs(-100000); dabs(-12.34); int abs(int i); long labs(long l); double dabs(double d); …… // in C abs(-10); labs(-100000); dabs(-12.34); int abs(int i); long abs(long l); double abs(double d); … // in C++(内用名字变异) abs(-10); abs(-100000); abs(-12.34); int abs(int i); long abs(long l); double abs(double d); … // in C++(内用名字变异) abs(-10); abs(-100000); abs(-12.34); 重载函数的要求:同名函数至少在参数个数 或参数类型上有所不同。 33 使用重载函数时一些限制 ))编译程序将根据实参和形参的类型及个数的最佳匹配来 选择调用哪一个函数。 )选择使用哪一个重载函数的过程,与C++处理其它的模 糊问题一样。 abs('A'); abs(12.45F); 找不到相应的函数声明,就调用最便于进行 类型转换的那个函数。 函函 数数 重重 载载 int add(int x, int y); int add(int a, int b); 编译器不以形参名来区分 int add(int x, int y); int add(int a, int b); 编译器不以形参名来区分 int add(int x, int y); void add(int x, int y); 编译器不以返回值来区分 int add(int x, int y); void add(int x, int y); 编译器不以返回值来区分 typedef INT int; void func(int i); void func(INT i); 参数的类型实际相同 typedef INT int; void func(int i); void func(INT i); 参数的类型实际相同 34 形参中的限定符const ))const 以及函数中引用的指针可以通过使用const 限定符来区分。 void func(char *ch); void func(const char *ch); …… void main( ) { const char c1 = 'a'; char c2 = 'b'; func(&c1); //calls void func(const char *ch); func(&c2); //calls void func(char *ch); } //3_14.cpp 函函 数数 重重 载载 35 坏的编程风格 ))让重载函数执行不同的功能是非常坏的编程风格, 同名函数应该具有相同的功能。 int add(int x,int y) { return x+y; } int add(int x,int y) { return x+y; } float add(float x,float y) { return x-y; } float add(float x,float y) { return x-y; } )不要同时使用重载函数和缺省参数的函数,因为 当调用函数时少写一个参数,系统无法判定是利用 重载函数还是利用缺省参数的函数,会发生错误。 函函 数数 重重 载载 36 例3.15 重载函数应用举例 编写三个名为add的重载函数,分别实现两整数相 加、两实数相加和两个复数相加的功能。 #include //3_15.cpp struct complex { double real; double imaginary; }; //3_15.cpp 函函 数数 重重 载载 37 例3.15 重载函数应用举例 void main(void) { int m, n; double x, y; complex c1, c2, c3; int add(int m, int n); double add(double x, double y); complex add(complex c1, complex c2); cout<<"Enter two integer: "; cin>>m>>n; cout<<"integer "<>x>>y; cout<<"real number "<>c1.real>>c1.imaginary; cout<<"Enter the second complex number: "; cin>>c2.real>>c2.imaginary; c3=add(c1,c2); cout<<"complex number (" << c1.real << ',' << c1.imaginary <<")+(" << c2.real << ',' << c2.imaginary <<")=(" << c3.real << ',' << c3.imaginary <<")\n"; } //3_15.cpp 函函 数数 重重 载载 38 例3.15 重载函数应用举例 int add(int m, int n) { return m+n; } double add(double x, double y) { return x+y; } complex add(complex c1, complex c2) { complex c; c.real=c1.real+c2.real; c.imaginary=c1.imaginary+c2.imaginary; return c; } 运行结果: Enter two integer: 3 5# integer 3+5=8 Enter two real number: 2.3 5.8# real number 2.3+5.8= 8.1 Enter the first complex number: 12.3 45.6# Enter the second complex number: 56.7 67.8# complex number (12.3,45.6)+(56.7,67.8)= (69,113.4) //3_15.cpp 重载的重要应用是 构造函数 重载的重要应用是重载的重要应用是 构造函数构造函数 函函 数数 重重 载载 39 函数模板的声明 函函 数数 模模 板板 ))函数模板可以用来创建一个通用功能的函 数,以支持多种不同形参,进一步简化重 载函数的函数体设计。 ))声明方法: template 函数定义 40 例3.16 求绝对值函数的模板 #include template T abs(T x) { return x<0 ? –x : x;} void main( )//3_16.cpp { int n= -5; double d= -5.5; cout< 42 例3.17 系统函数应用举例使用使用 C ++ C ++ 系统函数系统函数 )题目: 从键盘输入一个角度值,求出该角度的正弦值、 余弦值和正切值。 )分析: 系统函数中提供了求正弦值、余弦值和正切值 的函数:sin( )、cos( )、tan( ),函数的说明 在头文件math.h中。 43 例3.17 举例程序 #include #include const double pi(3.14159265); void main(void) //3_17.cpp { double a,b; cout << "Enter a number "; cin >> a; b=a*pi/180; cout<<"sin("<
/
本文档为【C与C++第三章:函数】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
热门搜索

历史搜索

    清空历史搜索