参数缺省和函数重载讲解

简介: 参数缺省和函数重载讲解

1.参数缺省的概念

       一般情况下,函数调用时的实参个数应与形参相同,但为了更方便地使用函数,C++也允许定义具有缺省参数的函数,这种函数调用时,实参个数可以与形参不相同。

      缺省参数指在定义函数时为形参指定缺省值(默认值)。

      这样的函数在调用时,对于缺省参数,可以给出实参值,也可以不给出参数值。如果给出实参,将实参传递给形参进行调用,如果不给出实参,则按缺省值进行调用。

      缺省参数的函数调用:缺省实参并不一定是常量表达式,可以是任意表达式,甚至可以通过函数调用给出。如果缺省实参是任意表达式,则函数每次被调用时该表达式被重新求值。但表达式必须有意义。


2.参数缺省的用法

以下图为例:


3.缺省参数分类

3.1.全缺省参数

全缺省就是所有参数都给了缺省值


3.2.半缺省参数

半缺省并不是缺省一半的参数,而是缺省部分参数

半缺省规定:必须从右往左缺省 ,如下面的实例:

 缺省一个参数的调用方式:


缺省二个参数的调用方式:


4.函数重载的概念

函数重在是指在同一个作用域内,有多个函数名相同,但是形参列表不同(参数类型不同,参数个数不同,参数顺序不同),返回值无关,我们将这种叫做重载函数。重载的函数是通过形参列表区分的,和其他无关。一句话来说“一个接口,多种实现”。


例如:如果要实现一个加法运算,加法函数可以是整型也可以是浮点型,就可以使用函数重载实现


5.函数重载的用法

如果要实现一个加法运算,加法函数可以是整型也可以是浮点型,就可以使用函数重载实现。

例如:

int Add(int a, int b)
{
  return a + b;
}
float Add(int a,float b)
{
  return a + b;
}
float Add(float a, int b)
{
  return a + b;
}
float Add(float a, float b)
{
  return a + b;
}


5.1参数类型不同

int add(int left, int right)
{
  cout << "int add(int left, int right)" << endl;
  return left + right;
}
double add(double left, double right)
{
  cout << "double add(double left, double right)" << endl;
  return left + right;
}

5.2参数个数不同

void f()
{
  cout << "f()" << endl;
}
void f(int a)
{
  cout << "f(int a)" << endl;
}

5.3参数顺序不同

void f(int a, char b)
{
  cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
  cout << "f(char b, int a)" << endl;
}


注意:返回值不同,不能构成重载 ,因为调用的时候不能区分


6.函数重载的原理

(前言:这部分我了解的也还不是非常深入,因此写的不是那么详细,也撮合着看吧~~)


大家有没有想过,为什么C语言不支持函数重载,而C++支持函数重载?C++又是如何支持的呢?


演示函数重载的原理用VS编译器不方便演示,需要用到Linux操作系统


在Linux系统下创建一个C语言的工程:


func.h 里面放的时函数的声明,func.c 里面放的时函数的定义,test.c 里面包含主函数

我们对这个工程进行编译:

此时会出现错误提示:

只有注释掉一个f()函数,才能编译成功,下图是注释无参f()函数后的执行结果:

这里就验证了C语言不能支持函数重载。

下面用C++ 对上述代码进行编译运行:

这里验证的是C++支持重载。

下一步,我们要探究的是为什么C语言不支持函数重载,而C++支持函数重载 ?C++是如何支持的?重点来了哈(敲黑板!!)

让我们来回顾一下编译链接的过程:

其中C语言不支持函数重载和C++支持函数重载就是链接这里的原因。

我们观察一下函数调用在汇编代码中是怎样实现的:

C语言不支持函数重载,因为编译的时候,两个重载函数函数名相同,在Func.o符号表中存在歧义和冲突,其次链接的时候也存在歧义和冲突,因为他们都是直接使用函数名去标识和查找,而重载函数,函数名相同


C++支持函数重载,因为C++的目标文件符号表中不是直接用函数名来标识和查找函数,C++引用了一个函数名修饰规则但不同的编译器下修饰规则有所不同, 有了函数名修饰规则,只要参数不同,func.o的符号标里面就不存在二义性和冲突了。链接的时候,test:o的main的函数里面去调用两个重载函数查找地址是也是明确的。


文章到这里就结束啦~~

目录
相关文章
|
5月前
|
C++
C++函数的默认参数、占位符、重载
C++函数的默认参数、占位符、重载
|
5月前
|
编译器 C++
C++对C的改进和拓展\域解析符、形参默认值、函数重载
C++对C的改进和拓展\域解析符、形参默认值、函数重载
25 0
|
6月前
|
存储 C#
C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析
方法是一段代码,只有在调用时才会运行。 您可以将数据(称为参数)传递给方法。 方法用于执行某些操作,也被称为函数。 为什么使用方法?为了重用代码:定义一次代码,然后多次使用。
98 0
|
弹性计算 JavaScript 编译器
函数类型-3:函数重载
本实验将介绍TypeScript中的函数重载
函数类型-3:函数重载
|
存储 编译器 C++
C++中类的几个默认成员函数
C++中类的几个默认成员函数
函数重载&函数默认参数
函数重载&函数默认参数
38 0
|
JavaScript
TypeScript 函数的详细使用(默认参数、可选参数、剩余参数、重载声明)
TypeScript 函数的详细使用(默认参数、可选参数、剩余参数、重载声明)
221 0
函数高级 — 默认参数、占位参数、函数重载
函数高级 — 默认参数、占位参数、函数重载
139 0
函数高级 — 默认参数、占位参数、函数重载