以下两个C#代码片段产生不同的结果(假设在递归调用之前和之后都使用变量级别).为什么?
public DoStuff(int level) { // ... DoStuff(level++); // ... }
,
public DoStuff(int level) { // ... DoStuff(level+1); // ... }
在阅读了下面的一些回复后,我认为值得发布级别++,++级别和级别+ 1的堆栈跟踪以突出显示欺骗这个问题的方式.
我已经为这篇文章简化了它们.递归调用序列以DoStuff(1)开始.
// level ++
DoStuff(int level = 1) DoStuff(int level = 2) DoStuff(int level = 2) DoStuff(int level = 2)
// ++级别
DoStuff(int level = 4) DoStuff(int level = 4) DoStuff(int level = 3) DoStuff(int level = 2)
// level + 1
DoStuff(int level = 4) DoStuff(int level = 3) DoStuff(int level = 2) DoStuff(int level = 1)
Matt.. 44
澄清所有其他答复:
+++++++++++++++++++++
DoStuff(a++);
相当于:
DoStuff(a); a = a + 1;
+++++++++++++++++++++
DoStuff(++a);
相当于:
a = a + 1; DoStuff(a);
+++++++++++++++++++++
DoStuff(a + 1);
相当于:
b = a + 1; DoStuff(b);
+++++++++++++++++++++
澄清所有其他答复:
+++++++++++++++++++++
DoStuff(a++);
相当于:
DoStuff(a); a = a + 1;
+++++++++++++++++++++
DoStuff(++a);
相当于:
a = a + 1; DoStuff(a);
+++++++++++++++++++++
DoStuff(a + 1);
相当于:
b = a + 1; DoStuff(b);
+++++++++++++++++++++
因为第一个例子实际上相当于:
public DoStuff(int level) { // ... int temp = level; level = level + 1; DoStuff(temp); // ... }
注意你也可以写++ level; 这相当于:
public DoStuff(int level) { // ... level = level + 1; DoStuff(level); // ... }
在我看来,最好不要过度使用++和 - 运算符; 它很快就会让人感到困惑和/或未定义真正发生的事情,而现代C++编译器无论如何都无法使用这些运算符生成更高效的代码.
level ++将级别传递给DoStuff,然后递增级别以在函数的其余部分中使用.这可能是一个相当讨厌的错误,因为递归将永远不会结束(从显示的内容,DoStuff始终传递相同的值).也许++级别意味着,因为这与级别++相反(递增级别并将递增的值传递给DoStuff)?
水平+ 1将通过水平+ 1到DoStuff离开水平不变的功能的其余部分.
的返回值level++
将level
与therefore
传递level
到DoStuff
.这可能是一个相当讨厌的错误,因为递归永远不会结束(从显示的DoStuff
内容始终以相同的值传递).也许++level
或level + 1
意味着呢?
level + 1
对于函数的其余部分,将level + 1
进入DoStuff
并level
保持不变.
后增量运算符(变量++)与函数完全等效
int post_increment(ref int value) { int temp = value; value = value + 1 return temp; }
而预增量运算符(++变量)恰好等同于函数
int pre_increment(ref int value) { value = value + 1; return value; }
因此,如果将运算符内联扩展到代码中,则运算符等效于:
DoStuff(a + 1) int temp = a + 1; DoStuff(temp);
DoStuff(++a) a = a + 1; DoStuff(a);
DoStuff(a++); int temp = a; a = a + 1; DoStuff(temp);
值得注意的是,后增量不等于:
DoStuff(a); a = a + 1;
此外,作为样式点,除非打算使用递增的值(规则的特定版本,"除非您打算使用该值,否则不为变量赋值",否则不应增加值) ).如果i + 1
再也不使用该值,那么首选用法应该是,DoStuff(i + 1)
而不是DoStuff(++i)
.