【全面认识C++——缺省参数 && 函数重载】

————————————————————————————————————————————

前言

无论使用什么语言,函数都是代码段中必不可少的部分,因此我们有必要深入认识一下C++中函数的两种特殊用法——缺省参数,函数重载。

缺省参数

以前你在C语言中所看到的函数形式是不是这样的

void Func(int a)

但是进入C++以后,你会看到函数变成了这样的:

void Func(int a=0)

是不是很神奇?下面我们就将逐一介绍。

一、缺省参数的三种形式

所谓缺省参数,就是指在函数的声明时给形参一个初始值。

1.全缺省参数:顾名思义,也就是所有参数均有初始值。

void Func(int a=0,int b=0,int c=100)

传参方法:
全缺省传参时,可传可不传
如果传参,那么该变量将采用传入的参数值;
如果不传参,那么该变量则采用指定的初始值

但是在缺省的情况下传参时,必须从左向右传参,不能跳过!!!
eg:

	Func();// 不传参:a=0,b=0,c=100
	Func(1, 2, 3);//传参:a=1,b=2,c=3
	Func(1, 2); //部分传参:a=1,b=2,c=100

而, **Func(, 2, 3); **大错特错(妄图跳过左边的变量给右边的变量传参)!

2.半缺省参数:**(部分缺省)**也就是说有一部分参数缺省

void Func(int a,int b=0,int c=100)

dang dang 敲黑板:半缺省参数只能从右向左缺省,不能跳过
比如说:
void Func(int a,int b=0,int c)
这样跳过c,直接让b缺省的方式就大no特no了

传参方法:
至少要给左边未缺省的部分传参,至于右边缺省部分,可穿可不传

Func(1);//至少要给a传参 a=1,b=0,c=100
Func(1, 2, 3);//右边缺省部分可穿可不传(但同时也要注意:从左向右传参,不能跳过)

二、缺省参数的用处

在实现静态顺序表和栈时,由于未知大小,我们只能是先假定一个数组大小,空间不足时进行扩容。可是这样做不仅会造成程序效率的降低,也会导致内存碎片的产生。这时,缺省参数就有大用处了。
我们先看看原先的实现方式:

void Init_Contact(Contact* Con)
{
	assert(Con);
	Con->count = 0;
	struct Peo* tmp=(struct Peo*)calloc(1000, sizeof(struct Peo));
	if (tmp == NULL)
	{
		printf("Init_Contact::%s\n", strerror(errno));
		return;
	}
	Con->data = tmp;

}

而现在,我们可以使用半缺省参数解决之前的不足

void Init_Contact(Contact* Con,int num=1000)
{
	assert(Con);
	Con->count = 0;
	struct Peo* tmp=(struct Peo*)calloc(num, sizeof(struct Peo));
	if (tmp == NULL)
	{
		printf("Init_Contact::%s\n", strerror(errno));
		return;
	}
	Con->data = tmp;

}

如此一来,当我们未知大小时,就不传参,系统自动使用初始值。
当我们已知大小时,就将确定的大小穿进去
eg:

Init_Contact(&Con)//未知大小
Init_Contact(&Con,100000)//已知大小

三、使用缺省参数的注意事项

1.为了避免出现初始化值不同引起的冲突,在函数声明和函数定义中,我们通常只选择一个地方进行缺省(函数声明,这有益于使用者使用)。
2.缺省值必须是全局变量或常量
3.C语言不支持缺省

函数重载

首先我们来看C语言中:

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

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

调用函数时,会报出这样的警告:
在这里插入图片描述

也就是说,在C语言中,函数名不能重复。可如果我们要对于不同数据类型的数据采用同样的处理方法,难道我们要为每一种数据类型写一个函数吗?这好麻烦,于是C++作为一门更加智能的语言,就提出了函数重载,来解决这个问题。

一、函数重载的定义

通俗的来讲,就是一词多义
也就是说,当多个函数的名称相同而参数类型不同时,它们之间就构成了重载关系
举个栗子:

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

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

int main()
{
	float tmp = Add(5.1f, 2.3f);
	cout << Add(5, 2) << endl;
	return 0;
}

在这里插入图片描述

二、函数重载的进一步解释(impotant)

1.函数重载时,要求参数不同,主要是从以下三方面讲的:
参数个数不同
参数类型不同
参数顺序不同
——这里的参数顺序是指不同类型参数的顺序(假如相同类型的参数顺序不同,不构成函数重载)
eg:
int charchar int
int a int bint b int a ×

2.函数重载表面上调用的是同一个函数,但编译器内部会自动识别参数类型后匹配不同的函数
ps:我们前面提到的cin,cout的智能识别性,其背后实现就是函数重载后封装而成的。

三、函数重载的实现

为什么C语言不支持函数重载,而C++却支持函数重载呢?难道它有魔法??
这里,我们就不得不用到一点程序运行背后的知识了(如果各位有需要可以留言)

在文件编译期间,将汇编代码转换为二进制指令时会生成一个叫做符号表的东西(这可是个寻宝图,它是后续链接阶段跨文件寻找符号的地图)。
在C语言符号表中是这样的,
函数名:地址
Func:0x00123456
正是因为这样,当多个函数的名称重复时,编译器就傻了,我该用那个地址呢?

而在C++的符号表中,则多了一个函数名修饰规则——它是通过函数的参数类型对函数名称进行修饰的,在参数不同时,修饰出的名称不同(具体规则由编译器决定)
即:
_Addi:0x11558879
_Addc:0x44779922

当缺省参数遇上函数重载

今天我们学习了缺省参数和函数重载两个内容,有些好奇心中的朋友可能会想把他们组合在一起,看看会有什么样的火花。那我要说:很遗憾,beng~,出事了

void func()
{
	return;
}

void func(int a = 0, int b = 0)
{
	return;
}

此时,如果你这样调用,到还好


	func(1, 2);
	func(1);

可是,一旦你这样写:

func();

编译器又傻了…你到底想让我用谁??
所以,千万千万不要这样混用!!!!!!

小彩蛋

最后送大家一道面试题,
为什么返回值不同时不能构成函数重载?是因为函数名修饰规则中没有返回值吗?
(不要偷看答案哦~~)
————————————————————————————————————————————
NONO,当然不是!
`在这里插入图片描述
即使函数名修饰规则加上返回值,依然不能通过返回值来判断调用哪个函数。
原因在于:无论返回值是什么,在函数调用时并无法指定返回值类型,由此引发了歧义(二义性),当然也就无法用返回值作为判断依据啦

	int ret=func(1, 2);
	char ret=fun(1, 2);

结语:

1.缺省参数只能从右往左缺省,不能跳过。
2.缺省参数传参只能从左往右传参,不能跳过。
3.缺省参数使传参形式变得更加灵活,而函数重载对于参数格式要求非常严格,
因此二者不能混用!

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值