短手是更新此程序中变量的唯一方法吗?
我试图制作一个程序,以使用递归概念来找到数字数字的立方体的总和。
但是,当我尝试添加数字并更新变量sum
时,会发生一些奇怪的事情。 当我写
sum = sum + pow(sumcube(num),3);
时值未添加并存储在sum
中。相反,sum
中的值被覆盖,就像sum
的值每次重置为0一样。
另一方面,当我编写
sum += pow(sumcube(num),3);
时,程序似乎运行完美。这是供您参考的程序。
#include <iostream>
#include<math.h>
using namespace std;
int num = 51, dgt = 0, sum = 0;
int sumCube(int)
{
int dgt = num % 10;
while (num > 10)
{
num = num / 10;
//sum = sum + pow(sumCube(num), 3); //doesn't work properly
sum += pow(sumCube(num), 3); //works properly
}
cout << sum << endl;
return(dgt);
}
int main()
{
num = num * 10;
sumCube(num);
return 0;
}
我认为语法是引起问题的原因。但是我也查看了一些帖子,这些帖子表明语法的行为方式相同。我以前从未有这样的问题,两个版本似乎都以相同的方式工作。
任何帮助都将受到赞赏。
I was trying to make a program that finds us the sum of the cubes of the digits of a number using the concept of recursion.
But something weird happens when I try to add the numbers and update the variable sum
.
When I write
sum = sum + pow(sumCube(num), 3);
the values aren't added and stored in sum
. Instead, the values in sum
are overwritten as if the value of sum
were reset to 0 every time.
On the other hand, when I write
sum += pow(sumCube(num), 3);
the program seems to run perfectly. Here is the program for your reference.
#include <iostream>
#include<math.h>
using namespace std;
int num = 51, dgt = 0, sum = 0;
int sumCube(int)
{
int dgt = num % 10;
while (num > 10)
{
num = num / 10;
//sum = sum + pow(sumCube(num), 3); //doesn't work properly
sum += pow(sumCube(num), 3); //works properly
}
cout << sum << endl;
return(dgt);
}
int main()
{
num = num * 10;
sumCube(num);
return 0;
}
I think the syntax is what's causing the problem. But I've also viewed a few posts that say both the syntaxes behave the same way. I never had such a problem before, both the versions seemed to work the same way.
Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
递归的总体方法是完全错误的。
即使在最佳条件下,突变全球状态也是一个坏主意。避免在使用递归时避免这种情况尤为重要,因为它使得正确地对代码进行推理变得更加困难。
函数通常应通过
返回
ing Inculation 的结果向其发出信号。这对于递归功能尤其重要。那是什么返回
是。在这里使用递归的目的(诚然是一个琐碎的例子)是,它已经分解并简化了每个步骤的问题:我们 use 使用递归以找到的总和。 立方体,然后为当前数字添加立方体。因此,正确的递归代码不应具有
loop 。
请确保您对呼叫函数的工作方式有深入的了解。编写
int sumcube(int){
表示函数接受参数,但不能使用使用,因为它没有名称。我们应该写一个名称:int sumcube(int num){
。然后,仅在函数内部,num
是作为参数中传递的任何内容的名称。此不必是 num 的另一个变量;它根本不必是一个变量。我们不会将变量传递给函数。我们将 value 传递给函数。您知道,完全像写
pow(sumcube(num),3)
时如何,3
不必是变量完全,不必具有由pow
函数决定的名称。 完全像如何使用pow
函数时,return
sa值可以在+的右侧使用该值
,并且不会更改任何全局变量。考虑到这一背景,我们可以将问题新鲜解决。这样考虑:想象一下您 其他人的函数,
sumcube2
,它以其他方式解决了相同的问题。我们想使用它来帮助解决问题。我们的一般方法是什么?我们要给出
sumcube2
a 比我们得到的问题(否则我们可以直接使用它)。我们已经有一个分解步骤:我们使用Division和Modulo提取最后一个数字。我们要使用一些本地计算来调用
sumcube2
的结果。很容易看到如何做到这一点:我们将最后一位数字添加到函数调用中的结果中。那么我们可以返回
结果。我们需要 guard 以防止用尽空间以简化的问题。这很简单:如果我们给出了
0
,那么我们知道结果是0
,而我们不必再做任何工作了。 (还有其他方法可以实施此步骤,但是为什么要使它更难呢?)因此:我们需要一个函数来接受名为
num
的参数:我们将首先检查我们的特殊情况:
否则,我们提取最后一个数字,并将其余的数字分开:
我们通过使用
sumcube2
结果来计算和return
结果:注意我们不需要修改任何全局变量,使用
时
循环或类似的内容。我们可以稍微凝结代码,因为我们真的不需要这些中间计算结果的名称(这是为了一次谈论逻辑一个步骤):(
或者我们可以使用
> 而不是调用
pow
,您明白了。?:有条件的表达式,或者我们可以明确使用乘法 神话
sumcube2
我们没有写的?简单:
sumcube
是一个旨在准确执行sumcube2
要做的函数。因此,我们只是称其为 - 即,在那里汇总调用。它之所以起作用,是因为每个 呼叫该函数具有其自己的参数和自己的本地变量,而
返回
s返回到从 - 完全像调用任何其他函数。因为我们只期望递归呼吁做的作品,并且只有在有效的“有效”的工作中,我们只能递归进行递归,因此我们避免了无限的递归。请注意,我做 在此代码中具有任何
cout
逻辑。这是因为sumcube
的 perive 是计算立方体的总和。 显示该结果是一个完全独立且无关的任务。这是main
的责任:The overall approach to the recursion is completely wrong.
Mutating global state is a bad idea even in the best conditions. It's especially important to avoid that when using recursion, because it makes it much harder to reason about the code correctly.
Functions should normally signal the result of the calculation by
return
ing it. This is especially important for recursive functions. That's whatreturn
is for.The point of using recursion here (admittedly a trivial example) is that it already decomposes and simplifies the problem at each step: we use the recursion to find the sum of all the other cubes, and then add the cube for the current digit. Therefore, the correct recursive code should not have a
while
loop.Please make sure you have a solid understanding of how calling a function works. Writing
int sumCube(int) {
means that the function accepts a parameter, but can't use it because there is no name for it. We should write a name:int sumCube(int num) {
. Then, only inside the function,num
is a name for whatever was passed in as an argument. This does not have to be another variable namednum
; it does not have to be a variable at all. We do not pass variables to functions. We pass values to functions.You know, exactly like how when you write
pow(sumCube(num), 3)
, the3
didn't have to be a variable at all, and didn't have to have a name dictated by thepow
function. Exactly like how when you use thepow
function, itreturn
s a value that you can use on the right-hand side of+
, and doesn't change any global variable.With that background in mind, we can approach the problem fresh. Think about it this way: imagine that you had someone else's function,
sumCube2
, which solves the same problem in some other way. We want to use it to help solve the problem. What is our general approach?We want to give
sumCube2
a simpler problem than the one that we got (or else we could have just used it directly). We have a decomposition step already: we use division and modulo to extract the last digit.We want to combine the result from calling
sumCube2
, with some local calculation. It's easy to see how to do this: we cube the last digit, and add the result from the function call to that cubed value. Then we canreturn
that result.We need to guard against the problem of running out of room for simplification. This is simple: if we're given
0
, then we know the result is0
, and we don't have to do any more work. (There are other ways to implement this step, but why make it any harder?)So: We need a function that accepts a parameter named
num
:We will first check our special case:
Otherwise, we extract the last digit, and separate the rest of the number:
We compute and
return
the result, by making use of thesumCube2
result:Notice that we don't need to modify any global variables, use a
while
loop, or anything like that.We can condense the code a little bit, since we don't really need names for those intermediate calculation results (that was just to be able to talk about the logic one step at a time):
(Or we could use a
?:
conditional expression, or we could use multiplication explicitly instead of callingpow
, you get the idea.)Now, how do we make this use recursion, and not have to depend on the mythical
sumCube2
that we didn't write?Simple:
sumCube
is a function that is intended to do exactly whatsumCube2
was going to do. So we just call it instead - i.e., make the recursive call there.It works because every call to the function gets its own parameters and its own local variables, and
return
s back to where it was called from - exactly like calling any other function. Because we only expect the recursive call to do part of the work, and because we only recurse when there is a valid "part of" the work to do recursively, we avoid infinite recursion.Notice that I do not have any
cout
logic in this code. That is because the purpose ofsumCube
is to compute the sum of the cubes. Displaying that result is a completely separate and unrelated task. It is the responsibility ofmain
:基本问题是在此表达式中:
sum
的值可以在调用sumcube
之前读取 - 这里没有序列点,它们之间没有依赖性。由于sumcube
还修改sum
(这是一个全局变量),因此您获得了不确定的行为。当您使用
+=
运算符时,其左操作数和右操作数(如任何分配)之间存在依赖性,因此呼叫sumcube
读取sum
的值的添加,因此您将始终获得sum
之后的值The basic problem is that in this expression:
the value of
sum
might be read either before or after callingsumCube
-- there's no sequence point here and no dependency between them. SincesumCube
also modifiessum
(it's a global variable), you get indeterminate behavior.When you use the
+=
operator, there's a dependency between its left operand and its right operand (as there is with any assignment), so the call tosumCube
will come before the addition which reads the value ofsum
, so you'll always get the value ofsum
after it has been modified bysumCube