在C++中,函数的形参列表中的形参是可以有默认值的。有默认值的参数即为默认参数。
在函数调用时,有默认参数可以缺省。
语法:返回值类型 函数名 (参数= 默认值){函数体}
#include <iostream>
using namespace std;
int add(int x, int y, int z = 100) {
return x + y + z;
}
int main(void) {
cout << add(3, 3) << endl; //106
cout << add(3, 3, 4) << endl; //10
return 0;
}
注意事项:
#include <iostream>
using namespace std;
int add(int x, int y = 100, int z) { //error
return x + y + z;
}
int main(void) {
cout << add(3, 3) << endl;
cout << add(3, 3, 4) << endl;
return 0;
}
#include <iostream>
using namespace std;
int add(int x, int y, int z = 100);//声明这有默认值了
int main(void) {
cout << add(3, 3) << endl;
cout << add(3, 3, 4) << 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;
void swap(int &, int &) ;
int main (void) {
int x = 100;
int y = 200;
swap(&x, &y);
cout << "x : " << x << "\t" << "y : " << y << endl;
getchar();
return 0;
}
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
避免实参到形参数值复制的开销,提高传参效率
#include <iostream>
using namespace std;
struct Teacher{
char name[100];
int age;
};
void print(Teacher &st){
cout << st.name << ',' << st.age << endl;
}
int main(void) {
Teacher st = {"王钢蛋", 18};
print(st);
return 0;
}
引用型函数参数可能意外修改实参,如果不希望通过引用修改实参本身,可以将其声明为常引用(const),在提高传参效率的同时还可以接收常量型实参
#include <iostream>
using namespace std;
void add(const int &x, const int &y){
// x++; //error
cout << "x + y = " << x+y << endl;
}
int main (void) {
int x = 3, y = 5;
add(x,y);
return 0;
}
可以将函数的返回类型声明为引用型,这时函数的返回结果就是return后面数据的别名,避免了函数返回值的开销
函数中返回引用,一定要保证在函数返回以后,该引用的目标依然有效
#include <iostream>
using namespace std;
int &add(int &a, int &b) {
int temp = 0;
temp = a+b;
return temp; //风险 局部函数结束时内存空间回收
}
int main(void) {
int x = 3, y = 5;
int &t = add(x,y);
t++; //通过别名操作 已经被系统回收的内存
cout << t << endl;
return 0;
}
基本作用
同一作用域,函数名相同,但是当中的参数必须有所区分(类型、个数、顺序),将构成重载关系
#include <iostream>
using namespace std;
void swap(int *a, int *b) {
cout << "a + b = " << *a + *b << endl;
}
void swap(char *a, char *b) {
cout << "a + b = " << *a + *b << endl;
}
void swap(float *a, float *b) {
cout << "a + b = " << *a + *b << endl;
}
int main(void) {
int a = 3, b = 5;
swap(&a, &b);
char c1 = 'a', c2 = 'b';
swap(&c1, &c2);
float f1 = 3.1, f2 = 3.3;
swap(&f1, &f2);
return 0;
}
重载的实现
编译器将形参变量的类型作为最终函数名的一部分。
nm a.out
注意
? 1)形参变量名不同 不构成重载的要素
void swap(int *a, int *b);
void swap(int *sa, int *sw); //形参变量名不同
? 2)函数返回类型不同 不构成重载的要素
int swap(int *a, int *b);
void swap(float *a, float *b);//函数返回类型不同
函数匹配的优先级
当前g++编译器匹配的一般规则:
1)完全匹配 //最高
2)常量转换 //良好
3)升级转换 //一般
4)降级转换 //较差
5)省略号匹配 //最差
#include <iostream>
using namespace std;
void swap(int x) {
cout << "swap(int)" << endl;
}
void swap(int x, int y) {
cout << "swap(int, int)" << endl;
}
void bar(int c) {
cout << "bar(int)" << endl;
}
void bar(const char c) {
cout << "bar(const char)" << endl;
}
void foo(int f){
cout << "foo(int)" << endl;
}
void foo(char c) {
cout << "foo(char)" << endl;
}
void hum(int i, ...) {
cout << "hum(int...) " << endl;
}
void hum(int i, int j) {
cout << "hum(int, int)" << endl;
}
int main(void) {
int x = 10;
swap(x);
char c = 'a';
bar(c); // 常量转换 char -------> const char
short s = 10;
foo(s); // 升级转换 short --------> int
hum(2, 3.14); // 降级转换 double --------> int
return 0;
}
注意二义性问题:
默认类型转换带来的二义性
void func(unsigned int x) {
cout << "func(unsigned int)" << endl;
}
void func(double x) {
cout << "func(double)" << endl;
}
int j = 10;
//func(j); //g++ 编译器不知道调用那个函数了
func((unsigned int) j);//需要程序员自己确认需要调用那个
缺省参数带来的二义性
void tem(int x, int y, int z = 200){
cout << "tem(int, int, int)" << endl;
}
void tem(int x, int y){
cout << "tem(int, int)" << endl;
}
tem(20, 30) //error