Col*_*lor 3 c++ recursion function operator-keyword
我来自C背景,现在我正在使用C++学习OOP
以下是计算阶乘的程序.
#include <iostream>
using namespace std;
void main ()
{
char dummy;
_int16 numb;
cout << "Enter a number: ";
cin >> numb;
double facto(_int16);
cout << "factorial = " <<facto(numb);
cin >> dummy;
}
double facto( _int16 n )
{
if ( n>1 )
return ( n*facto(n-1) );
else
return 1;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常.
但是如果我替换return语句
return ( n*facto(n-1) );
Run Code Online (Sandbox Code Playgroud)
有了这个
return ( n*facto(n--) );
Run Code Online (Sandbox Code Playgroud)
那它不起作用.该N--将不会递减ñ 1.为什么呢?
我正在使用Visual Studio 2012
编辑:知道了!谢谢:)
*也,我想添加到下面的答案:使用--n将导致在n执行语句之前减少.因此,由于预先递减,表达式将成为(n-1)*facto(n-1).这就是为什么在这种情况下最好不要使用预减量*
Bat*_*eba 12
目前,通过使用n--要传递的原始,因此未修改值n到facto这是造成一个循环.
你需要n - 1改用.从表面上看,它会很有吸引力,--n因为这会减少n并评估新的(较低的)价值.但是--n会给你未定义的行为,因为你预先乘以函数返回值n,因为*它不是一个序列点,值n没有明确定义.
(顺便说一下,C中的行为是相同的).
[编辑:承认Mike Seymour关于未定义的行为点].
编辑::下面的解释只是为了阐明后期和减少前的使用,以便OP更好地理解它们.OP代码的正确答案是, n*facto(n - 1).@OP:你不应该在代码的那一部分做任何pre-drecrement,因为它会因为对序列的无序修改而调用Undefined Behavior n.
前后递减::如果要在传递值之前递减变量,则 必须使用预递减(wiki-link).另一方面,后递减在变量递减之前计算表达式:
int n = 10, x;
x = --n; // both are 9
Run Code Online (Sandbox Code Playgroud)
和
int n = 10, x;
x = n--; // x = 10, i = 9
Run Code Online (Sandbox Code Playgroud)
为什么不在你的情况下使用预先减少?:: n*facto(n--)导致UB.
为什么?
§5/ 4中的标准说
在前一个和下一个序列点之间,标量对象应通过表达式的计算最多修改其存储值一次.
和
只能访问先前值以确定要存储的值.
这意味着,在两个序列点之间,变量不能被多次修改,如果一个对象被写入一个完整的表达式,那么在同一个表达式中对它的任何和所有访问都必须直接参与值的计算.要写.