版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/low5252/article/details/94600500
下面我们来看2个案例,分析下c语言中函数参数处理顺序。
第一个:
#include "stdio.h"
void fn(int a,int b,int c)
{
printf("%d,%d,%d", a, b, c);
}
void main()
{
int a = 3;
fn(a++, a++, a++);
}
输出结果:
5,4,3
原因分析:
C函数参数作为一个整体执行的顺序是从右向左,所以会先处理最右端的参数,然后依次向左处理。所以结果为最右端的a++先被处理结果为3,然后++,接着4和5,这样就有了上面的结果。
第二个:
#include
int main(void)
{
int i = 0;
printf("%d,%d,%d,%d,%d\n", ++i, ++i, i++, ++i, i++);
}
输出结果:
5,5,2,5,0
原因分析:
和上面的一样,执行的顺序是从右向左,所以会先处理最右端的参数,然后依次向左处理。不同是出现了++i,对于i++和++i是先加与后加的区别,但是在参数处理上则对应。如果是i++那么表示符合从右向左处理的前提下,当即处理该参数。如果是++i,那么表示只是执行++i运算并不将结果作为参数结果,将参数位置压入堆栈,只有当所有参数从右向左处理完毕之后,从堆栈弹出所有因为延后操作语句而没有填入最终结果的参数位置,将最终执行的结果i,作为相应的参数值,填入进去。
现在大家回忆下,逗号运算符,逗号运算的结合性是从左至右,完毕之后整个表达式的值是最后一个表达式的值。
例子:
int a[2],x=2,y=5;
a[0]=(x+3,y++,x++);
那么最终结果是:
a[0]=2 x=3 y=6;
从上面分析可以看出,函数参数和逗号运算符的执行顺序正好相反!
注意:
但是这两个的执行顺序是不确定的。如果函数参数是普通的表达式那么他们的执行顺序是不确定的。这就是为什么我们要避免写 printf("%d%d",++i,i++);这样的垃圾代码了。
并且C++标准是没有规定的,参数压栈顺序取决于编译器的,看你用什么编译器,貌似VC同GCC的压栈顺序就是相反的,最好在外面算好了再作为参数传递
C语言函数参数默认原则
#include <iostream>
int print(int a = 1, int b = 2);
int main() {
print();
print(-1);
return 0;
}
//int print(int a = 1, int b = 2) {// 编译错
int print(int a, int b) {
std::cout << a << "," << b << std::endl;
}
结果:
1,2
-1,2
首先看上述的代码,print函数是带有默认参数的。
所以调用print(), print(-1)都可以准确的输出。
这种默认参数的情况会带来有些便利。(比如初始化一个商品对象,在99%的情况在都是正常的,那么这个商品是否正常的标记就可以默认为1,特殊的1%情况,再加上)
但是有以下三个要注意的情况。
默认参数只能放在函数声明处或者定义处,能放在声明处就放在声明处 。
上述代码把那行注释打开,默认参数在声明和定义处都有了,那么就会有编译错误。(两次默认赋值是不被允许的。)
大部分情况,别人调用你的代码只能看到函数声明,如果你写在定义处,别人根本不知道你的默认参数是什么。
如果你是在定义处写的默认参数,那么你在使用该函数前就需要把函数定义放在前面。不然编译阶段通过无默认参数的函数声明无法确定这个函数是带默认参数的。
所以,默认参数写在声明处啊。^ ^
2.如果某个参数是默认参数,那么它后面的参数必须都是默认参数
因为非默认参数的参数必须要给出具体值,而调用函数传递参数的时候是从左到右的,所以非默认参数前面的都必须要传值进来。
那么默认参数后面的当然也得都为默认参数。
3.不要重载一个带默认参数的函数
看下这个函数:
class Test
{
public:
int func(int a)
{
return a;
}
int func(int a, int b = 1)
{
return a + b;
}
} ;
你调用func(1)的时候,谁知道你想调用哪一个。
更多C++相关知识体系,请移步C++知识目录。
————————————————
版权声明:本文为CSDN博主「水无垠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/low5252/article/details/94600500