有人可以解释这个 C++ program.The 结果很奇怪 :(
Can someone explain this C++ program.The result is weird :(
这是一个测试中的问题。我希望结果是 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;
}
既然可以简单地使用本地值,为什么还需要更改赋予函数的值?
int fact(int a)
{
if (a < 2)
{
return a;
}
else
{
return a * fact(a-1);
}
}
这取决于编译器。他们如何处理温度。运算符的值和优先级。
例如:在 solaris CC 上,输出是 24:1。在某些编译器上它将是 120:5 .
正确答案必须是120:1。方法如下
事实要求:5
其他部分。 a[0] : 5 return 值 = 5 * 事实 (4) = 120
事实要求:4
其他部分。 a[0] : 4 return 值 = 4*事实(3) = 4* 6 = 24
事实要求:3
其他部分。 a[0] : 3 return 值 = 3 * 事实 (2) = 3*2 = 6
事实要求:2
其他部分。 a[0] : 2 return 值 = 2*事实(1) = 2*1 = 2
事实要求:1
如果部分。 a[0] = 1 return 值 = 1
您的程序有未定义的行为。所以它无所不能。
你的"full expressions"
a[0] * fact(&(--*a));
cout << fact(a) << ":" << *a;
每个对象的访问(a[0]
& *a
)和副作用(--*a
& fact(a)
)都没有定义的评估序列.这与标准的 §1.9/15 冲突:
Except where noted,
[运算符 ?:
、&&
、||
和 ,
]
evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
和
If a side effect on a scalar object is unsequenced relative to either
(a) another side effect on the same scalar object
or
(b) a value computation using the value of the same scalar object,
the behavior is undefined.
参见 this answer 及其问题。 (我从标准中得到这句话的地方。)
可以猜测可以检测到这种违规的编译器使 fact
只是 return 1 而不会影响 *a
,因此 fact(*a)
returns 1 和 *a
returns 5。但这只是一个猜测,代码可以做任何事情。 (您可以查看汇编代码以了解发生了什么。)
具有您想要的行为的程序涉及更多的临时变量、更简单的语句、更简单的函数规范和更简单的程序结构。编写正确的代码并不难如果你知道什么不该写并检查你没有写它。为您提供帮助:
- 设置您的编译器选项以报告更多警告和错误并读取其输出(许多未定义的行为可以被编译器静态检测到)
- 当您读写时明确识别每个函数的输入和输出规范并且(子)expression/statement
- 继续明确地教育自己关于好的设计
- 继续明确地学习这门语言
这是一个测试中的问题。我希望结果是 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;
}
既然可以简单地使用本地值,为什么还需要更改赋予函数的值?
int fact(int a)
{
if (a < 2)
{
return a;
}
else
{
return a * fact(a-1);
}
}
这取决于编译器。他们如何处理温度。运算符的值和优先级。 例如:在 solaris CC 上,输出是 24:1。在某些编译器上它将是 120:5 .
正确答案必须是120:1。方法如下
事实要求:5 其他部分。 a[0] : 5 return 值 = 5 * 事实 (4) = 120
事实要求:4 其他部分。 a[0] : 4 return 值 = 4*事实(3) = 4* 6 = 24
事实要求:3 其他部分。 a[0] : 3 return 值 = 3 * 事实 (2) = 3*2 = 6
事实要求:2 其他部分。 a[0] : 2 return 值 = 2*事实(1) = 2*1 = 2
事实要求:1
如果部分。 a[0] = 1 return 值 = 1
您的程序有未定义的行为。所以它无所不能。
你的"full expressions"
a[0] * fact(&(--*a));
cout << fact(a) << ":" << *a;
每个对象的访问(a[0]
& *a
)和副作用(--*a
& fact(a)
)都没有定义的评估序列.这与标准的 §1.9/15 冲突:
Except where noted,
[运算符 ?:
、&&
、||
和 ,
]
evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
和
If a side effect on a scalar object is unsequenced relative to either
(a) another side effect on the same scalar object
or
(b) a value computation using the value of the same scalar object,
the behavior is undefined.
参见 this answer 及其问题。 (我从标准中得到这句话的地方。)
可以猜测可以检测到这种违规的编译器使 fact
只是 return 1 而不会影响 *a
,因此 fact(*a)
returns 1 和 *a
returns 5。但这只是一个猜测,代码可以做任何事情。 (您可以查看汇编代码以了解发生了什么。)
具有您想要的行为的程序涉及更多的临时变量、更简单的语句、更简单的函数规范和更简单的程序结构。编写正确的代码并不难如果你知道什么不该写并检查你没有写它。为您提供帮助:
- 设置您的编译器选项以报告更多警告和错误并读取其输出(许多未定义的行为可以被编译器静态检测到)
- 当您读写时明确识别每个函数的输入和输出规范并且(子)expression/statement
- 继续明确地教育自己关于好的设计
- 继续明确地学习这门语言