C++形参带有默认值函数
1. 形参默认值要从右向左给先看一个简单的示例代码#include iostream using namespace std; int sum(int a, int b) // sum函数的两个形参都没有给默认值 { return a b; } int main() { int x 10; int y 20; int ret sum(x, y); return 0; }那么我们给出默认值#include iostream using namespace std; int sum(int a 30, int b) { return a b; } int main() { int y 20; int ret sum(y); return 0; }这里的想法是把 y 传给 b a 用默认参数 30 那么此时就会报错“sum”: 缺少形参 2 的默认实参因为 C 调用函数时实参是按位置从左到右匹配形参的编译器在调用函数的时候发现 sum(y) 没有第二个参数也没有默认值所以会报错那么我们给默认值的时候就要求必须从右向左给#include iostream using namespace std; int sum(int a, int b 30) { return a b; } int main() { int x 20; int ret sum(x); return 0; }此时返回的结果就是 502. 形参在给默认值的时候不管是定义处给还是声明处给同一个形参默认值只能出现一次我们看下面的代码#include iostream using namespace std; int sum(int 10, int); //这里声明一下函数 int main() { int ret sum(); return 0; } int sum(int x, int y 20) { return x y; }但是这个代码还是会报错“sum”: 缺少形参 2 的默认实参这是因为声明处也必须遵守默认参数必须从右往左连续提供的规则、此外默认参数在调用点必须已经可见。代码从上到下执行执行到int ret sum();的时候发现声明没有给出第二个默认参数此时就会报错。默认参数不是运行时才找的而是在编译调用语句时就确定了。再看下面这个代码#include iostream using namespace std; int sum(int, int 10); int main() { int a 30; int ret sum(a); cout ret endl; return 0; } int sum(int x, int y 20) { return x y; }这个代码也会报错“sum”: 重定义默认参数 : 参数 1所以说不管是定义处还是声明处同一个形参的默认值只能给一次再看下面这个代码#include iostream using namespace std; int sum(int, int 10); int main() { int a 30; int ret sum(a); cout ret endl; return 0; } int sum(int x 20, int y) { return x y; }这个代码就不会报错其原因是默认参数可以在同一作用域的多次声明中逐步补充。函数定义本身也是一次函数声明。相当于又给第一个参数 x补了默认值 20所以两次声明合起来相当于int sum(int x 20, int y 10);但是在main里面int ret sum(a);此时编译器只看到了前面的声明还没看到后面的定义。所以在 main 这里编译器只知道第二个参数有默认值 10 。所以下面的代码时可以运行的#include iostream using namespace std; int sum(int, int 10); int sum(int 5, int); int main() { int ret sum(); cout ret endl; //15 return 0; } int sum(int x, int y) { return x y; }3.调用效率的问题 形参传入几个[变量]就有几个mov指令那么现在我们从汇编指令的角度去探索一下形参默认值的效率问题#include iostream using namespace std; //0 int sum(int x, int y) { return x y; } int main_0() { int a 10; int b 20; /* 下面这句代码的函数调用对应的汇编指令是: 008B1A44 mov eax,dword ptr [b] 008B1A47 push eax 008B1A48 mov ecx,dword ptr [a] 008B1A4B push ecx 008B1A4C call sum (08B10D2h) */ int ret sum(a, b); cout ret endl; return 0; } //1 int sum(int x, int y 10) { return x y; } int main_1() { int a 10; /* 下面这句代码的函数调用对应的汇编指令是: 008A1A3D push 0Ah 008A1A3F mov eax,dword ptr [a] 008A1A42 push eax 008A1A43 call sum (08A10D2h) */ int ret sum(a); cout ret endl; return 0; } //2 int sum(int x 5, int y 10) { return x y; } int main_2() { /* 下面这句代码的函数调用对应的汇编指令是: 00D51A36 push 0Ah 00D51A38 push 5 00D51A3A call sum (0D510D2h) */ int ret sum(a); cout ret endl; return 0; }从上面的指令可以看出传入的变量个数有几个就会相应的产生几个mov指令。那么效率就会低一些。再看下面的代码#include iostream using namespace std; int sum(int x, int y 10) { return x y; } int main() { int a 11; /* 00DA1A3D mov eax,dword ptr [a] 00DA1A40 push eax 00DA1A41 push 1Eh 00DA1A43 call sum (0DA10D2h) */ int ret sum(30, a); cout ret endl; return 0; }这里也可以体现处传入的是变量才会产生对应的mov指令否则会直接push传入的值。总结形参带默认值的函数1.给默认值的时候从右向左给 不能写成 int sum(int a 10, b)2.调用效率的问题 形参传入几个[变量]就有几个mov指令3.定义处可以给形参默认值声明也可以给形参默认值4.形参在给默认值的时候不管是定义处给还是声明处给形参默认值只能出现一次