为什么C++函数形参默认值从最末一个赋值?
【1】函数调用时形参的压栈顺序
1、示例代码如下(VS2010):
#include <iostream>
using namespace std; void fun(int a, int b, int c = ); void fun(int a, int b, int c) // 这种情况不可以写,因为函数声明已写
{
cout << "a :: " << a << endl;
cout << "b :: " << b << endl;
cout << "c :: " << c << endl;
} class A
{
public:
void fun1(int a, int b);
void fun2(int b, int c = );
}; void A::fun1(int a, int b = ) // 这种情况可以写
{
} void A::fun2(int b, int c) // 这种情况下不可以写,因为函数声明已写
{
} void main()
{
int n = ;
fun(n * n, n, n++); system("pause");
} // run out:
/*
a :: 121
b :: 11
c :: 10
请按任意键继续. . .
*/
分析:
从输出的结果琢磨,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、有人说还看得不太明白,云里雾里的。那么请再看如下实例分析。
代码如下:
#include <iostream>
using namespace std; class TestA
{
public:
TestA(int a = , int b = , int c = , int d = )
: m_nA(a)
, m_nB(b)
, m_nC(c)
, m_nD(d)
{} int getA() { cout << "TestA::getA() [" << m_nA << "]" << endl; return m_nA; }
int getB() { cout << "TestA::getB() [" << m_nB << "]" << endl; return m_nB; }
int getC() { cout << "TestA::getC() [" << m_nC << "]" << endl; return m_nC; }
int getD() { cout << "TestA::getD() [" << m_nD << "]" << endl; return m_nD; } private:
int m_nA;
int m_nB;
int m_nC;
int m_nD;
}; int sumFunc(int a, int b, int c, int d)
{
return (a + b + c + d);
} void main()
{
TestA aObj;
cout << "调用顺序及求和结果如下:" << endl;
cout << sumFunc(aObj.getA(), aObj.getB(), aObj.getC(), aObj.getD()) << endl;
system("pause");
} // run out:
/*
调用顺序及求和结果如下:
TestA::getD()[40]
TestA::getC()[30]
TestA::getB()[20]
TestA::getA()[10]
100
请按任意键继续. . .
*/
通过调用全局函数sumFunc,分析其形参的压栈先后顺序。
【2】为什么函数形参默认值需要从最后一个赋值?
从上一步的研究结果发现:
函数调用时,首先压栈最后一个形参,若有一个已经确定默认值或常规调用可以忽略除非在特殊情况下才考虑的形参,那么置为最末一个形参。
建议在声明函数时,最好加上默认值。定义函数时,不需要再加默认值(因为编译器会报重定义默认参数值的编译错误)。
(备注:其实,声明不加定义加也行,但是为了便于代码的阅读与维护,建议声明加定义不加。)
反证法。假设不从最后一个赋默认值,那么试想一下,编译器就会匹配不到最后一个形参的值,报编译错误。
【3】总结
压栈形参由后向前,赋默认值也应由后向前。
Good Good Study, Day Day Up.
顺序 选择 循环 总结
为什么C++函数形参默认值从最末一个赋值?的更多相关文章
- ES6学习 --函数参数默认值与解构赋值默认值
1. ES6的解构ES6中引入了解构赋值的操作,其作用是:将值从数组Array或属性从对象Object提取到不同的变量中 即分为两种情况:从数组Array中解构,以及从对象Object中解构 ①.从数 ...
- ES6函数参数默认值作用域的模拟原理实现与个人的一些推测
一.函数参数默认值中模糊的独立作用域 我在ES6入门学习函数拓展这一篇博客中有记录,当函数的参数使用默认值时,参数会在初始化过程中产生一个独立的作用域,初始化完成作用域会消失:如果不使用参数默认值,不 ...
- 函数的默认值与动态参数arguments的总结
在js函数与作用域,了解函数基本概念中,我们发现当函数的实参有一个没有上传的时候,对应的形参time展示的值就是undefined,如下代码所示: <!DOCTYPE html> < ...
- 【C#基础概念】函数参数默认值和指定传参和方法参数
函数参数默认值和指定传参 最近在编写代码时发现介绍C#参数默认值不能像PL/SQL那样直接设置default,网上也没有太多详细的资料,自己琢磨并试验后整理成果如下: C#允许在函数声明部分定义默认值 ...
- 问题:C++形参默认值为什么一定要放在最后?
问题:C++形参默认值为什么一定要放在最后? 1.会出现歧义! 2.从汇编角度看是怎么回事? 待解答!!
- Python函数参数默认值的陷阱和原理深究"
本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...
- java函数参数默认值
java函数参数默认值 今天,需要设定java函数参数的默认值,发现按照其它语言中的方法行不通 java中似乎只能通过函数的重载来实现 函数参数默认代码
- Python函数参数默认值的陷阱和原理深究(转)
add by zhj: 在Python文档中清楚的说明了默认参数是怎么工作的,如下 "Default parameter values are evaluated when the func ...
- php函数指定默认值的方法
发布:JB02 来源:脚本学堂 [大 中 小] 本文介绍下,在php编程中,指定函数的默认值的方法,分享二个例子,供大家学习参考下.本文转自:http://www.jbxue.com/ar ...
随机推荐
- 20165336 2017-2018-2 《Java程序设计》第2周学习总结
学号 2017-2018-2 20165336 <Java程序设计>第2周学习总结 教材学习内容总结 第二章 标识符第一个字符不能是数字 标识符不能是关键字 byte型变量的取值范围是-2 ...
- 不能往Windows Server 2008 R2 Server中复制文件的解决方法
目前一直直接往Windows 2008 R2 Server中复制文件(暂时还没有搭建ftp服务),突然不能复制了,于是百度找到了解决方法,特此记录(记忆). 1.在任务管理器中找到“rdpclip.e ...
- 第八节:分支开发之合并到master
流程:在客户端创建分支,修改代码,并push,然后在页面处理即可.(区别在于一个在客户端,一个在页面) 实际的开放中要记得打tag,不然到时候出问题了以后不知道从哪里开始.
- svn 部署 配置
创建目录并配置 建立版本库目录 创建一个项目名叫wy 在/data/svndata/wy mkdir -p /data/svndata/wy 建立项目版本库 创建一个新的Subversion项目wy, ...
- 前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
input标签用于接收用户输入.可以利用input 可以做登录页面 input标签是行内块标签 <input> 元素会根据不同的 type 属性,变化为多种形态. name属性:表单点击提 ...
- 20190122 loop
declare a number; v_begin date := to_date('201901013','yyyymmdd'); v_end date := to_date('20190119', ...
- Unity3D加密保护案例分享(一)
Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎.通过u ...
- vue中$set的用法
数组: this.$set(Array,index, newValue) 对象: this.$set(Object, key, value)
- PHP数组对象对比机制
$a = [1,2]; $b = [1,'2']; var_dump($a == $b); // true var_dump($a === $b); // false $c = ['ab'=>' ...
- box-shadow outline 实现双边框 阴影
文字阴影 text-shadow box-shadow 格式:text-shadow:x y blur color, … 参数 x 横向偏移 y 纵向偏移 blur ...