缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个默认值
有什么用?
更加灵活的增加默认值,或者手动给一个初始值,解决了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;
}