C++ 缺省参数及函数重载分析

发布于:2022-12-15 ⋅ 阅读:(842) ⋅ 点赞:(0)

目录

1.缺省参数

1.1 缺省参数定义

1.2 缺省参数分类

1.2.1全缺省参数

 1.2.2 半缺省参数

2. 函数重载


1.缺省参数

1.1 缺省参数定义

定义:缺省参数是声明或定义函数时,为函数的参数指定一个默认值。在调用函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。

举个例子,你晚上准备一个人吃水煮肉片(默认),如果有人约你吃饭,你就马上会去吃他安排的(指定的实参),如果没人约,还是吃默认的水煮肉片。

#include<iostream>
using namespace std;

void test(int x = 1)
{
	cout << x << endl;
}

int main()
{
	test();
	test(30);
	return 0;
}

在没有指定的实参时,打印默认值,1 在指定实参后 ,打印 30.

1.2 缺省参数分类

1.2.1全缺省参数

即函数的所有参数都是缺省参数

void test1(int a = 1, int b = 2, int c = 3)
{
	cout << a<< endl;
	cout << b << endl;
	cout << c << endl;
}

 test1 函数的所有参数都是缺省参数,这理解起来没有困难。

但是我们需要注意的是,在对全缺省参数指定实参时,只能按照从左到右依次,做不到指定位置。

void test1(int a = 1, int b = 2, int c = 3)
{
	cout << a<< endl;
	cout << b << endl;
	cout << c << endl;
}

int main()
{
	test1(20);
	cout << endl;
	test1(20, 30);
	cout << endl;
	test1(10, 20, 30);
	cout << endl;

	return 0;
}

 当我们尝试指定位置时,会报错,C++并不支持这种功能。

 1.2.2 半缺省参数

半缺省参数 实际上指的是 部分缺省参数。即函数的有一部分参数为缺省参数。

缺省参数必须从右往左,且连续,不满足其中的任一条件都会报错。

void test2(int a, int b = 1)
{
	cout << a << endl;
	cout << b << endl;
}

int main()
{

	test2(20);
	cout << endl;
	test2(20, 40);
	return 0;
}

 我们还需要注意的点

缺省参数不能在函数的声明和定义中同时初现    (推荐在声明时使用缺省参数,更直观)

缺省值必须是常量,或者全局变量

2. 函数重载

2.1 函数重载概念

函数重载是函数的一种特殊情况,C++ 允许在同一作用域中,声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或顺序)必须不同。

例如


int Add(int x, int y)
{
	return x + y;
}

double Add(double x, double y)
{
	return x + y;
}

long Add(long x, long y)
{
	return x + y;
}

int main()
{
	cout<<Add(5, 10)<<endl;
	//cout << Add(1.1, 1.2)<<endl;  cout标准输出时,自动识别数据类型,不利于我们判断
	printf("%lf", Add(1.1, 1.2));
	cout << endl;
	//cout << Add(10L, 20L) << endl;
	printf("%ld", Add(10L, 20L));
}

 这个例子就很好的展示的函数重载,但是可能有细心的读者也发现了上述几个函数的返回值类型不同,注意,返回值类型不是判断函数重载与否的标准  , 判断的标准从来只有 参数类型,个数,顺序 三个方面。

2.2 名字修饰

C++支持函数重载,为什么C语言不支持?

我们需要更深层次的理解

在C/C++中,一个程序的运行过程需要经历 :预处理   编译   汇编   链接

(26条消息) C语言提高篇——程序环境和预处理_杨斯文。的博客-CSDN博客

简单回顾一下编译器编译程序的过程 

1.预处理 -> 头文件展开 ,宏替换,条件编译,去掉注释

2.编译 -> 检查语法 ,生成汇编代码  ,语法,词法,语义分析,符号汇总

3.汇编 -> 汇编代码转换二进制机器码 ,形成符号表

4.链接

在C语言中,编译时,由于C语言是直接通过函数名标识和查找,两个重载函数,函数名相同,在形成符号表时,就会存在歧义和冲突,其次在链接时,也存在歧义和冲突。

C++的目标文件符号表不是直接用函数名来标识和查找函数,有自己的函数名修饰规则,不同的编译器有不同的规则。g++ 的修饰函数名规则 : _Z + 函数名长度 +函数名 +参数首字母

因为修饰规则的存在,只要参数不同,那么在符号表中的重载函数就不存在歧义和冲突了。

实际我们的项目通常由多个头文件和源文件构成,在一个文件中,如果文件有函数的定义,编译时,直接填上地址,如果当前文件只有函数的声明,那么定义就在其他的源文件中,此时只能链接时去其他的文件的符号表中根据函数的修饰名称去找,这也是链接的重要工作。

总结 : C语言直接使用函数名来标识和查找函数,它无法区分同名函数,不支持重载。C++ 是通过函数修饰规则来区分,只要参数有不同,就可以区分同名函数,实现重载。