博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么C++函数形参默认值从最末一个赋值?
阅读量:4625 次
发布时间:2019-06-09

本文共 2403 字,大约阅读时间需要 8 分钟。

【1】函数调用时形参的压栈顺序

1、示例代码如下(VS2010):

1 #include 
2 using namespace std; 3 4 void fun(int a, int b, int c = 100); 5 6 void fun(int a, int b, int c) // 这种情况不可以写,因为函数声明已写 7 { 8 cout << "a :: " << a << endl; 9 cout << "b :: " << b << endl;10 cout << "c :: " << c << endl;11 }12 13 class A14 {15 public:16 void fun1(int a, int b);17 void fun2(int b, int c = 100);18 };19 20 void A::fun1(int a, int b = 100) // 这种情况可以写21 {22 }23 24 void A::fun2(int b, int c) // 这种情况下不可以写,因为函数声明已写25 {26 }27 28 void main()29 {30 int n = 10;31 fun(n * n, n, n++);32 33 system("pause");34 }35 36 // run out:37 /*38 a :: 12139 b :: 1140 c :: 1041 请按任意键继续. . .42 */

分析:

从输出的结果琢磨,a如果等于10 * 10 = 100,说明是先压栈参数a。

然后,再压栈参数b,b = n, 那么b等于10。

最后,再压栈参数c,c = n++,即c等于10。而n最终等于11。

但是,还得用客观事实说明问题:

首先,压栈形参c,c = n++,即c等于10。而n执行完后等于11。

然后,压栈形参b,b = n,即b等于11。

最后,再压栈形参a,a = n * n, 即a等于121。

2、有人说还看得不太明白,云里雾里的。那么请再看如下实例分析。

代码如下:

1 #include 
2 using namespace std; 3 4 class TestA 5 { 6 public: 7 TestA(int a = 10, int b = 20, int c = 30, int d = 40) 8 : m_nA(a) 9 , m_nB(b)10 , m_nC(c)11 , m_nD(d)12 {}13 14 int getA() { cout << "TestA::getA() [" << m_nA << "]" << endl; return m_nA; }15 int getB() { cout << "TestA::getB() [" << m_nB << "]" << endl; return m_nB; }16 int getC() { cout << "TestA::getC() [" << m_nC << "]" << endl; return m_nC; }17 int getD() { cout << "TestA::getD() [" << m_nD << "]" << endl; return m_nD; }18 19 private:20 int m_nA;21 int m_nB;22 int m_nC;23 int m_nD;24 };25 26 int sumFunc(int a, int b, int c, int d)27 {28 return (a + b + c + d);29 }30 31 void main()32 {33 TestA aObj;34 cout << "调用顺序及求和结果如下:" << endl;35 cout << sumFunc(aObj.getA(), aObj.getB(), aObj.getC(), aObj.getD()) << endl;36 system("pause");37 }38 39 // run out:40 /*41 调用顺序及求和结果如下:42 TestA::getD()[40]43 TestA::getC()[30]44 TestA::getB()[20]45 TestA::getA()[10]46 10047 请按任意键继续. . .48 */

 通过调用全局函数sumFunc,分析其形参的压栈先后顺序。

【2】为什么函数形参默认值需要从最后一个赋值?

从上一步的研究结果发现:

函数调用时,首先压栈最后一个形参,若有一个已经确定默认值或常规调用可以忽略除非在特殊情况下才考虑的形参,那么置为最末一个形参。

建议在声明函数时,最好加上默认值。定义函数时,不需要再加默认值(因为编译器会报重定义默认参数值的编译错误)。

(备注:其实,声明不加定义加也行,但是为了便于代码的阅读与维护,建议声明加定义不加。)

反证法。假设不从最后一个赋默认值,那么试想一下,编译器就会匹配不到最后一个形参的值,报编译错误。

【3】总结

压栈形参由后向前,赋默认值也应由后向前。

 

Good Good Study, Day Day Up.

顺序 选择 循环 总结

转载于:https://www.cnblogs.com/Braveliu/p/6616853.html

你可能感兴趣的文章
线程局部存储TLS(thread local storage)
查看>>
洛谷 P1066 2^k进制数
查看>>
Python之list和tuple
查看>>
安装jar包到maven仓库
查看>>
从程序员的“劣根性”发散开去
查看>>
数据库1
查看>>
再再发Gif动画处理类库 - 315版
查看>>
vector的内存分配与释放
查看>>
iPhone:constrainedToSize获取字符串的宽高
查看>>
59.贪心练习: 1044 拦截导弹
查看>>
【bzoj2034】 2009国家集训队—最大收益
查看>>
java编译器不匹配问题(java compiler level does not match the version of the installed java project facet)...
查看>>
mysqldump导出数据出现问题
查看>>
学习PHP函数:preg_match_all
查看>>
python之浅谈数据类型
查看>>
论文检测网站
查看>>
[转]如何选购塑料水杯(塑料口杯、茶杯)
查看>>
CF838D Airplane Arrangement
查看>>
固定表格头跟第一列
查看>>
IP数据报首部校验和算法 详细 非代码
查看>>