• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

为什么C++函数形参默认值从最末一个赋值?

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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

通过示例分析调用函数时,形参的压栈(不懂“压栈”?其实说人话即“输入”)顺序常识。

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

 1 #include <iostream>
 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 A
14 {
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 :: 121
39 b :: 11
40 c :: 10
41 请按任意键继续. . .
42 */

分析:

主观上,a如果等于10 * 10 = 100,说明是先压栈参数a。

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

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

但是客观上,还得用如上run out的运行结果说明问题:

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

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

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

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

代码如下:

 1 #include <iostream>
 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 100
47 请按任意键继续. . .
48 */

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

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

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

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

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

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

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

【3】总结

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

 

Good Good Study, Day Day Up.

顺序 选择 循环 总结


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
xutils上传文件C#http服务ashx接收发布时间:2022-07-14
下一篇:
【C语言】练习2-1发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap