缺省参数-函数重载

缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个默认值

有什么用?

更加灵活的增加默认值,或者手动给一个初始值,解决了C语言#define给死一个值的缺陷,C语言无法做到缺省参数这么灵活

struct Stack
{
	int* a;
	int top;
	int capacity;
};

//void StackInit(Stack* ps)
//{
//	ps->a = (int*)malloc(sizeof(int) * 4);
//	ps->capacity = 4;
//	ps->top = 0;
//}

//如果一开始明确知道要开辟100个,那么需要扩容
//如何更灵活控制初始空间?利用缺省参数

void StackInit(Stack* ps,int DefaultCapacity = 4)
{
	ps->a = (int*)malloc(sizeof(int) * DefaultCapacity);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->capacity = DefaultCapacity;
	ps->top = 0;
}

int main()
{
	Stack st;
	StackInit(&st, 100);
	// 插入100个数据

	StackInit(&st);
	// 不知道要插入多少数据 StackInit(&st);-> StackInit(&st2, 4);
	return 0;
}

C喜欢玩的方式
#define DEFAULT_CAPACITY 100
void StackInit(struct Stack* pst)
{
pst->a = (int*)malloc(sizeof(int) * DEFAULT_CAPACITY);
if (pst->a == NULL)
{
perror(“malloc fail”);
return;
}

pst->top = 0;
pst->capacity = DEFAULT_CAPACITY;
}

使用注意

是否可以定义和声明同时出现?
否,不明确到底用哪个。

如果缺省单独出现在定义时,在编译时就会报错,编译时检查语法就会发现你少给了一个参数
在这里插入图片描述

在这里插入图片描述
所以需要再声明时给出缺省参数,定义不能给,定义不关心是否缺省
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

函数重载

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数类型类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
在这里插入图片描述

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

编译链接过程

在这里插入图片描述
反汇编发现调用函数的call和jump到对应的地址
然而编译期间 拿不到函数定义所在的地址 只有声明的地址,更像是只得到了一个承诺
链接时 符号表合并和重定位 找到定义(兑现承诺)
并且如果直接在.c文件中定义函数,那么就不需要链接步骤了,在编译阶段就可以拿到函数定义地址
在这里插入图片描述

在这里插入图片描述

两次函数地址不一样,因为调试了2次,懒得改上面的图了

在这里插入图片描述
总体流程
在这里插入图片描述

发现C++ 两个重载函数StackPush()具有不同的地址,是因为函数名修饰规则

函数名修饰规则

从g++角度看,链接时
c++的函数名修饰区分了重载函数,不论是StackPush还是func的重载都可以区分
修饰名的规则拿<_Z4funci>来看 — int func(int a)
_Z是前缀
4是函数名个数,i是int的缩写

另一个是<_Z4funcid> — int func(int a,double d)
也就是int 和 double的缩写

c++的函数名修饰把形参类型的缩写带进来了,与返回值无关
这也是为什么返回值不同不构成重载的原因

在这里插入图片描述
在这里插入图片描述

C为什么不支持

在这里插入图片描述

C比较直接,上面两个蓝框里面的名字直接用的函数名,并没有C++的函数名修饰,所以如果有2个同名函数,就不确定是哪个,无论参数是否相同。
C不支持重载,再编译时 就报错,没法写2个同名函数,所以只用gcc来看一个函数调用时用的函数名
在这里插入图片描述
可以看到直接使用func,无法区分同名函数,所以不支持重载

编译器把函数返回值也带进函数名修饰规则能否实现重载呢?

也是不行的。
在这里插入图片描述
即使更改了函数名修饰规则,带入返回值,只是解决链接时找的问题
但是在编译时无法确定Func()调用哪一个函数,返回值在调用时无法体现

是不是所有函数都要链接

如果直接在.c文件中定义函数,那么就不需要链接步骤了,在编译阶段就可以拿到函数定义地址(直接兑现)

有问题的函数重载情况

情况一

 /*1、是否构成重载 -- 构成
 2、问题。无参调用存在歧义*/
void f()
{
	cout << "f()" << endl;
}

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

int main()
{
	f(); // “f”: 对重载函数的调用不明确

	return 0;
}

情况二

在这里插入图片描述

int Func();
double Func();

int main()
{
	Func(); // 调用歧义

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值