这是测试中的问题。我希望结果是1:1,但运行它并得到答案1:5,虽然我已经在Visual C ++ 2013中调试它,并看到地址的价值,这是一个' a'指向是1(最后一个' 1'在1:1中)
#include <iostream>
using namespace std;
int fact(int *a)
{
if (*a <= 1)
{
return a[0];
}
else
{
return a[0] * fact(&(--*a));
}
}
int main()
{
int *a = new int;
*a = 5;
cout << fact(a) << ":" << *a;
return 0;
}
答案 0 :(得分:3)
为什么在只使用本地值时需要更改赋值给函数的值?
int fact(int a)
{
if (a < 2)
{
return a;
}
else
{
return a * fact(a-1);
}
}
答案 1 :(得分:2)
您的程序有未定义的行为。所以它可以做任何事情。
你的“完整表达”
a[0] * fact(&(--*a));
cout << fact(a) << ":" << *a;
每个人都没有定义的对象访问权限(a[0]
&amp; *a
)和副作用(--*a
&amp; fact(a)
) 。这违反了标准的§1.9/ 15:
除非另有说明,否则
[运营商?:
,&&
,||
和,
]
对单个运算符的操作数和单个表达式的子表达式的评估是不确定的。
和
如果对标量对象的副作用相对于任何一个都没有排序 (a)对同一标量物体的另一副作用
或
(b)使用相同标量对象的值进行的值计算,
行为未定义。
请参阅this answer及其问题。 (我从标准中得到了这个引用。)
可以猜测,可以检测到此违规的编译器会使fact
返回1而不会影响*a
,以便fact(*a)
返回1而*a
返回5但这只是猜测,代码可以做任何事情。 (您可以查看汇编代码以了解正在发生的事情。)
具有您想要的行为的程序涉及更多临时,更简单的语句,更简单的功能规范和更简单的程序结构。编写正确的代码是不难的,如果你知道什么不写,并检查你没有写它。为了帮助你:
答案 2 :(得分:0)
这取决于编译器。他们如何处理临时工。运营商的价值观和先发制人。 例如:在solaris CC上,输出为24:1。在一些编译器上它将是120:5。
正确答案必须是120:1。这是如何
事实要求:5 别的一部分。 a [0]:5返回值= 5 * fact(4)= 120
事实要求:4 别的一部分。 a [0]:4返回值= 4 * fact(3)= 4 * 6 = 24
事实要求:3 别的一部分。 a [0]:3返回值= 3 * fact(2)= 3 * 2 = 6
事实要求:2 别的一部分。 a [0]:2返回值= 2 * fact(1)= 2 * 1 = 2
事实要求:1
如果是部分。 a [0] = 1返回值= 1