ch5-3 函数重载和默认参数.ppt_第1页
ch5-3 函数重载和默认参数.ppt_第2页
ch5-3 函数重载和默认参数.ppt_第3页
ch5-3 函数重载和默认参数.ppt_第4页
ch5-3 函数重载和默认参数.ppt_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1,五、函数重载function overloading 六、默认参数default argument values,第8章 函 数,2,五、函数重载function overloading (C+特有) 1.重载函数与名称细分 函数重载是C+新引进的。 在同一作用范围中为多个函数定义(其功能通常是相近 的)指定一个共同的函数名,委托编译器根据每一个单独函 数的形参个数、类型和位置的差异在幕后进行名称细分并选 择合适的函数调用匹配的现象称为函数重载。 重载函数是函数名相同入口参数类型、位置或个数有所 不同的多个函数或其中的一个函数。,3,函数是有类型的,函数的类型不单单指函数的返回类 型,函数

2、的形参列表构成的入口类型是函数重载意义上更重 要的类型, 编译器根据函数的入口类型细分重载函数并由 此确定每一个函数定义代码段入口地址的唯一性。 系统不根据函数的返回类型确定函数重载的调用匹配, 也无法区别引用形参和数值形参在重载意义上的差异。 实际上对于单独调用的同名函数,程序员自身也难以区 别调用的是哪个函数版本。,4,例如:如下两个函数版本: int f (int k) return k; /int型的数值入口,int型的数值返回 int* f (int /函数调用是模糊的 /编译器无法鉴别函数调用f(n)匹配上面函数中的哪个 版本。对于上面两个重载函数f只有定义没有调用并不出现 amb

3、iguous call to overloaded function提示,也就是说引 用形参和数值形参可以用于名称细分,但不足以解决调用点 处的模糊性。,5,typedef 声明并未引进新的数据类型,只是为已经存在 的类型提供一个类名同义词,因此不构成名称细分的独立条 件。 例如: typedef float real; float funct (real x) return x+1 ; real funct (float y) return y -1; 编译器不对上面的funct函数进行名称细分,两者拥有 相同的类型参量。,6,例 参数类型和位置不同的重载函数 #include long ,

4、7,long min (long l,short s) printf (min(long,short);); return sl?s:l; void main(void) long l=l; long L=L; short s=s; double d= d; double D=D; max(L,l)-; max(D,d)+; printf (min=%cn, min(s,l); printf (min=%cn, min(L,s); ,8,说明:上面定义了两对函数: 一对函数是返回引用形参两者极大值之一的引用的函 数; 另一对函数是返回数值形参中两者极小值的函数,函数 原型分别为 long mi

5、n (short ,long); 和 long min (long ,short );, 这一对函数完成相同的功能不同的只是将两个形参的位置互 换。在函数调用min (s,l)匹配的是函数min (short ,long )。 函数 max (long 后其值减少一个单位,因此在函 数min (s,l)表达式的结果为min=k。,9,2.函数虚实结合类型匹配 在同一作用范围中函数void vf (int a,int* p) p+; 与 函数void vf (int b,int* q) b+; 视为相同的函数,两者具 有同样的参量类型列表void vf (int ,int*)。 函数重载时,编译

6、器根据函数的入口参数类型对同名函 数进行名称细分, 重载函数的名称细分之后依存在具体函 数代码选取的问题,选择原则是根据调用函数的实参的数据 类型对当前范围中的函数进行形参的最佳匹配。 如果找到一个恰当的函数匹配,就启动该函数的入口地 址。重载函数必须在形参类型、个数或参数位置顺序上有所 区分。,10,函数在调用时本身就存在强制的或隐含的类型转换即从 实参类型到形参类型的转换,重载函数也不例外。编译器幕 后为重载函数的参量建立一个备用函数集,备用函数是在某 个位置实参可以转换为形参类型的函数。 如果备用函数集的交集不是唯一的,则函数重载就是有 二义的,从而函数调用就导致错误。 函数调用过程中参

7、数匹配和转换的次序分为下面五个阶 段或步骤: a. 精确匹配:实参的数据类型与形参的类型一对一的严 格匹配属于精确匹配,例如long型形参匹配long型实参;long 型的数值形参与long void f (short * p) printf (%dt,*p); void f (int /输出: 10 20 30,13,说明: 算术型的数值形参存在隐含的类型转换规则,当源操作 数(实参)的类型和目标操作数(形参)的类型不一致时可以不 提供显式类型转换,当长精度数据转换为短精度数据时会提 出警告。 而指针和引用的入口形参当源操作数(实参)的类型和目 标操作数(形参)的类型不一致时须提供显式类型转

8、换,返回 的时候也是这样。,14,例 函数重载时的参量提升匹配和精确匹配 #include void f (long v) printf (long %d;,v); void f(unsigned long n) printf (unsigned long %d;,n); void f (double d) printf (double %3.1f;,d); void f(char* v) printf(char*%s;,v); void f(const char * p) printf(const char*%st,p); void main() f (1L); f (2Lu); f (3.

9、0f); f (4.0) ; char* p=aa; f (p); const char* r=bb; f (r); /输出:long 1;unsigned long 2;double 3.0; double 4.0 ; char*aa ;const char* bb,15,函数f(char*)不匹配只读指针实参,而函数f(const char*) 可安全地匹配char*型的实参,char*型的实参优先启动 f (char*),如果f (char*)不存在,则启动f (const char *)函数. long型数据和unsigned long型数据混合算术类型上 是平级的,float型数据则

10、高其一个级别。float型实参从低进 度数据类型提升到double类型的高精度形参数据类型,因此 f (3.0f)启动 f (double)函数。 表达式1L是long型数据,2Lu是unsigned long型表达式; f (1L)严格匹配f (long) f (2Lu)严格匹配f (unsigned long) 函数调用f(1*c)中的实参1*c为int型。int型数据可 以提升到long型也可以提升到double型,因此函数调用 f (1*c)导致歧义。,16,3.连接C语言中的程序模块 extern关键字另一个用法是沿用根据C语言规则编写的 程序。这个特点使得C语言的模块不必进行改写就

11、可直接索 引。以下例子给出了具有C连接名称的声明方法: extern C int printf (const char *format,.); /声明printf具有C连接 extern C #include /头文件cfile.h中的所有内容具有C连接 /声明具有C连接的两个函数ShowMoney和GetMoney extern C int ShowMoney (int count); float GetMoney (void); ,17,/定义具有C连接的函数max extern C long max (long x, long y) return xy? x:y ; /声明一个具有C连接

12、的全局变量errorflag:extern C int errorflag; /C连接不涉及重载时函数名称的细分,下面的说明导致错误: extern C int f (void); / C连接的函数名简单地就是f extern C int f (int); / error:second C linkage of overloaded function f not allowed,18,将第一个C划去改为: extern int f (void); / C+连接对于这个函数进行名称细分,可认为f初步处理为f_v extern C int f (int); /C连接的函数名简单地就是f则编译通过。

13、因此将双引号括 /起来的C划去可回归到C+语言的连接约定。 C连接最大的特点是函数名在编码时不根据形参列表中 的类名进行名称细分。,19,六、默认参数default argument values 1. 默认参数的函数 默认参数也称为缺省参量,函数调用时常需提供一组默 认的参数值,作为程序的原始出发点供软件的用户使用。 函数定义中的每一个参数都可以拥有一个默认值,如果 在函数调用中没有为对应默认值的参量提供实参数据,系统 就直接使用默认值。默认值是形参列表中设置的初始值,格 式为: int f (int x,long x=10,const double y=20); 这样就可以采用几种等价地调

14、用形式: f (3); f (3,10); f (3,10,20);,20,例 默认参数值的函数 #include int d; int f3 (int n=3) return n; / 默认值为3 void f (int i=1,long l=2,int f = f3() d=i+l+f; void main (void) f (); printf (f() sets d=%dn,d); f (2); printf (f(2) sets d=%dn,d); f (2,3); printf (f(2,3) sets d=%dn,d); f (2,3,4); printf (f(2,3,4) s

15、ets d=%dn,d); ,21,无默认值的参量需要实参匹配。 例如函数定义: void funct (int i, long l=2, float f=3) d=i+l+f; 是正确的但函数调用funct ()导致: error: funct : function does not take 0 parameters 默认值可以使用常数、全局变量或函数调用,默认值必 须编译时静态确定。 默认参数不影响函数的虚实结合的匹配转换规则。,22,使用默认参数受到如下的限制: 1) 默认参量的位置必须从形参列表的最右边依次从右 到左排放,其数量不限。 默认值不能在形参列表的中间遗失。如函数定义 vo

16、id f (int i=1,long l,float f=3)d=i+l+f; 导致: error: f : missing default parameter for parameter 2 2) 默认值或在函数原型中提供或在函数定义的标题头 中指定,当既有原型又存在定义时仅在函数原型中设置默认 值。,23,2. 默认参数与函数重载 默认参数不是函数形参的类型抽象,因此不用于细分重 载的函数。 系统根据形参类型进行名称细分,然后由实参的类型在 细分的重载函数备用集中选择恰当的函数。 下面的例子是重载函数中使用默认参数时模糊引起的语 法错误。 例 默认参数导致的语法模糊 #include double d; void funct (int i, long =2,float f=3); /函数原型中默认值可省去形参名 void funct (int i, long l) d=i+l; ,24,void main (void) funct(2); /调用void funct(int i,long =2,float f=3); funct(2,3); / error take place here

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论