c++中的递减运算符
Decrement Operator in C++
我是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;
}
以上代码运行正常。
但是如果我替换返回语句
return ( n*facto(n-1) );
with this
return ( n*facto(n--) );
则不起作用。 n——不会递减 n 1。为什么?
我使用的是Visual Studio 2012
编辑:知道了!谢谢:)
*也,我想添加到下面的答案:使用——n将导致n
在语句执行之前递减。由于预减量,表达式变成了(n-1)*facto(n-1)
。这就是为什么在这种情况下最好不要使用预减量*
目前,通过使用n--
,您将n
的原始且因此未修改的值传递给facto
,这会导致循环。
你需要用n - 1
代替。从表面上看,使用--n
是诱人的,因为这会减少n
并计算为新的(较低的)值。但是--n
将给您未定义的行为,因为您是将函数返回值预先乘以n
,并且由于*
不是序列点,因此n
的值没有定义。
(顺便说一下,C中的行为是相同的)。
[编辑:感谢Mike Seymour关于未定义行为的观点].
EDIT::下面的解释只是为了让OP更好地理解Post和pre -递减的用法。 OP代码的正确答案是, n*facto(n - 1)
。@OP:你不应该在那部分代码中做任何预求,因为它会调用未定义行为,因为变量n
的未排序修改。
前后减量::如果希望在传递值之前对变量进行减量,则必须使用预减量(wiki-link)。另一方面,后减量在变量被减量之前计算表达式:
int n = 10, x;
x = --n; // both are 9
和
int n = 10, x;
x = n--; // x = 10, i = 9
为什么不使用预减量呢?:: n*facto(n--)
导致UB。为什么?
§5/4中的标准说
在前一个和下一个序列点之间,标量对象应它的存储值是否最多被一次修改表达式。
和
只有在确定要访问的值时才能访问先验值存储。
这意味着,在两个序列点之间,一个变量不能被修改超过一次,如果在一个完整表达式中写入一个对象,那么在同一表达式中对该对象的任何和所有访问都必须直接涉及到要写入的值的计算。
return ( n*facto(n--) );
您正在使用后减量运算符。发生的事情是,您将n
的值传递给函数,然后对其进行减量。这不会影响已经传递给函数
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 如何防止clang格式在流运算符调用之间添加换行符<<