在C++中,函数的形参列表中是可以有默认值的。有默认值的参数即位默认参数。
在函数调用时,有默认参数可以缺省
语法:返回值类型 函数名 (参数=默认值){函数体}
#include <iostream>
using namespace std;
int add (int x,int y,int z = 100);
int main() {
int a;
a = add(100,200);
cout << a << endl;
return 0;
}
int add(int x,int y,int z) {
return x + y + z;
}
//运行结果为400,只能在定义函数的地方有默认值,实现函数不能有默认值
注意事项:靠右原则,即如果某个参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值;例如:
#include <iostream>
using namespace std;
int add(int x, int y = 1, z = 2) {
return x + y + z;
}
int main(){
int a;
a = add(1);
cout << a << endl;
return 0;
}
//运行结果为4;
函数声明和函数实现(即函数定义),只允许有一个默认值,即如果函数声明有默认值,则函数实现的时候就不能有缺省参数;
#include <iostream>
using namespace std;
int add(int x, int y = 1, int z =12);
int main(int argc, const char *argv[])
{
int a;
a = add(1);
cout << a << endl;
return 0;
}
int add(int x, int y, int z) {
return x + y + z;
}
只有类型而没有变量名的参数称为“哑元”
int func(int a, int) {
...
}
使用哑元的场景:
void func(int i, int j) { ... } == 升级 void func(int i) {...}//升级之后,前面调用的函数需要修改传参
void func(int i, int j) { ... } == 升级 void func(int i,int) {...}//升级之后,前面调用的函数不需要修改传参
#include <iostream>
using namespace std;
int swap(const int &a, const int &b);
int main(int argc, const char *argv[])
{
int c;
c = swap(1,2);
cout << c << endl;
return 0;
}
int swap(const int &a, const int &b) {
return a + b;
}
避免实参到形参值复制的开销,提高传参效率
#include <iostream>
using namespace std;
struct teacher{
char name[100];
int age;
};
void print(const teacher &t) {
cout << t.name << " " << t.age << endl;
}
int main(int argc, const char *argv[])
{
const teacher t = {"zhangsan", 28};
print(t);
return 0;
}
引用型函数参数可能意外修改实参,如果不希望通过引用修改实参本身,可以将其声明为常引用,在提高传参效率的同事还可以接收常量型实参。
int add(const int &a, const int &b) {
return a + b;
}
int main(void) {
add(3,5);
return 0;
}
可以将函数的返回类型声明为引用型,这时函数的返回结果就是return后面数据的别名,避免了函数返回值的开销。
函数中返回引用,一定要保证在函数返回之后,该引用的目标依然有效。
#include <iostream>
using namespace std;
int & add(int &a, int &b) {
static int temp = a + b;
return temp;
}
int main(int argc, const char *argv[])
{
int a = 10;
int b = 20;
int x = add(a,b);
cout << x << endl;
return 0;
}
//temp变量必须加static或者设置成全局变量,不然调用完函数之后,temp变量的地址已经被系统回收
函数重载:同一作用域,函数名相同,但是参数表必须有所区分(类型、个数、顺序),将构成重载关系。例如:
#include <iostream>
using namespace std;
void swap(int *a, int *b) {
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void swap(char *a, char *b) {
char tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void swap(bool *a, bool *b) {
bool tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main(int argc, const char *argv[])
{
int x = 10, y = 20;
char a = 'a', b = 'b';
bool m = true, n = false;
swap(&x, &y);
swap(&a, &b);
swap(&m, &n);
cout << x << " " << y << endl;
cout << a << " " << b << endl;
cout << m << " " << n << endl;
return 0;
}
注释:三个函数名相同,但是参数数据类型不同,叫做函数重载
注意:形参变量名不同,不构成重载的要素
? ? ? ? ? ?函数返回类型不同,不构成重载要素。
函数重载的实现:编译器将形参变量的类型作为最终函数名的一部分
函数匹配的优先级:
当前g++编译器匹配的一般规则:
#include <iostream>
using namespace std;
void swap(int a, int b) {
int tmp;
tmp = a;
a = b;
b = tmp;
cout << a << " " << b << endl;
}
void con(const int a) {
cout << "con(const int a)" <<endl;
}
void foo(char a) {
cout << "foo(char)" << endl;
}
void foo(int a) {
cout << "foo(int)" << endl;
}
void hun(short a) {
cout << "hun(short)" << endl;
}
void hum(int x, int y) {
cout << "hum(int,int)" << endl;
}
void hum(int x, ...) {
cout << "hum(int, ...)" << endl;
}
int main(int argc, const char *argv[])
{
int x = 10, y = 20;
short a = 12.12;
swap(x,y);//完全匹配
con(x);//常量转换
foo(a);//升级转换short转int
hun(a);//降级转换int 转 short
hum(x,a);//最低级的是省略转换
return 0;
}
注意二义性问题:
int func(unsigned int a) {
return a;
}
int func(double a) {
return a;
}
int n = 12;
func(n);//erro
void func(int x, int y, int z = 100) {
cout << "func(int,int,int)" << endl;
}
void func(int x, int y) {
cout << "func(int,int)" << endl;
}
int x = 10, y = 20;
func(x,y);//erro