目录
前言
1. 缺省参数
1.1 什么是缺省参数
1.2 缺省参数的分类
1.2.1 全缺省参数
1.2.2 半缺省参数
2. 函数重载
2.1 什么是函数重载
2.2 缺省参数与函数重载
2.3 函数重载的使用
3. C++支持函数重载的原因
总结
前言
在学习C语言时我们就会发现,C语言中存在的许多规则使得C语言在使用时非常的不方便,例如在函数调用时必须要传参没有默认值,函数不可以重名等等问题,C++作为C的改进版,对C语言的缺陷进行了改进,同时也兼容C的语法。在C++中上述问题都得到了解决,也就是缺省参数和函数重载,接下来我将向大家详细介绍C++的缺省参数和函数重载。
1. 缺省参数
1.1 什么是缺省参数
缺省参数是指在函数定义时为参数提供默认值,使得在调用函数时可以选择性地省略该参数。当调用函数时省略了对应的参数,函数会使用默认值来代替。
比如:
void Func(int a = 10)
{cout << "a = " << a << endl;}int main()
{Func();//没有传参时使用参数的默认值Func(2);//传参时使用的是指定参数return 0;
}
1.2 缺省参数的分类
1.2.1 全缺省参数
函数的所有参数都设置了默认值,在调用函数时可以省略所有参数。比如:
void Func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}int main()
{Func();return 0;
}
1.2.2 半缺省参数
半缺省参数是指在函数的部分参数设置了默认值,使得在调用函数时可以省略这些参数。比如:
void Func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}int main()
{Func(1,2);return 0;
}
使用注意
- 缺省参数中,半缺省缺省值只能从右往左进行缺省,且必须是连续的
比如:
int main()
{Func( ,1,2);//缺省位置从右向左,不可以中断return 0;
}
- 缺省参数声明和定义不能同时给
比如:
//定义 fun.c
void Func(int a = 10)
{cout << "a = " << a << endl;
}//声明 fun.h
void Func(int a = 2);
声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定该用那个缺省值。应该在声明中给,如果只在定义中给,那么在其他文件调用时就无法达到缺省的效果。(函数声明是告诉编译器函数的存在,不在声明中写,那么在其他接口调用时,编译器就不会认为有默认值)。
- 缺省值必须是常量或者全局变量
- C语言不支持
2. 函数重载
自然语言中,一个词可以有多重含义(一词多义),人们可以通过上下文来判断该词真实的含义,相同的名称,却有不同的作用与意义。在C++中函数重载也是如此。
2.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;
}
int main()
{Add(1, 1);Add(3.14, 3.62);return 0;
}
定义两个同名的Add函数,在进行函数调用时,编译器会根据传递的参数来选择调用哪个函数。
但如果一个传int类型,一个传double类型就会出现报错:
传进去的参数与参数列表里的参数不匹配。
2.2 缺省参数与函数重载
有缺省参数也可以构成重载,但在使用时需要注意避免造成歧义。比如:
void fun()
{cout << "fun()" << endl;
}
void fun(int a = 0)
{cout << "fun(int a)" << endl;
}
void fun(int a)
{cout << "fun(int a)" << endl;
}
在调用fun不传参时,fun()和fun(int a=0)都符合条件,这样就存在二义性,编译器在调用时不知道该调用哪一个。在结合使用时可以使用,但要避免类似这种二义性情况(尽量不要这样使用)。
2.3 函数重载的使用
函数重载可以依据参数类型不同而进行匹配,并选择调用函数,参数类型不同可分为:参数类型不同,参数个数不同,参数顺序不同。
//1.参数类型不同
int fun(int a)
{cout << "int fun(int a)" << endl;return a;
}
double fun(double b)
{cout << "double fun(double b)" << endl;return b;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void func(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void func(char b, int a)
{cout << "f(char b, int a)" << endl;
}
这些都可以构成函数重载。
但要注意:
参数相同时,返回值不参与重载的规则
比如:
int f(int a)
{return 0;
}
double f(int a)
{return 2.1;
}
如果两个函数的函数名相同、参数也相同,仅依靠返回值不同,是无法构成函数重载的(存在二义性)。
3. C++支持函数重载的原因
为什么C++支持函数重载而C语言不支持呢?
在 C/C++ 中,要运行一个程序,需要经过:编译和链接两大过程。
详细可见:程序员进阶之路:程序环境和预处理
程序大概执行流程:
C语言在编译阶段会产生一个符号表,在链接函数地址时,C语言通过符号表(函数名)去找。所以C语言不存在同名函数。
C++在编译时会通过特殊修饰产生独特的字符(地址),通过地址寻找函数,以Linux环境下为例更为直观:
Linux函数名修饰规则:
_Z 函数名字符个数 函数名 参数首字母
以 fun(int a,char b) ,fun(char b,int a) 为例,修饰后:_Z3funic、_Z3funci
我们通过VS调试也可以看到,test.s文件如下:
不同的编译器有不同的修饰规则。这也就是C++为什么可以支持函数重载。
总结
缺省参数和函数重载是C++语言中非常有用的特性,它们可以帮助我们更好地组织和管理代码。在学习和使用这两个特性时,我们需要注意一些细节,以确保代码的正确性和可读性。以上便是本期的全部内容,希望对你有所帮助。最后感谢阅读!