短手是更新此程序中变量的唯一方法吗?

发布于 2025-02-10 16:03:45 字数 911 浏览 2 评论 0原文

我试图制作一个程序,以使用递归概念来找到数字数字的立方体的总和。

但是,当我尝试添加数字并更新变量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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可可 2025-02-17 16:03:45

递归的总体方法是完全错误的。

  1. 即使在最佳条件下,突变全球状态也是一个坏主意。避免在使用递归时避免这种情况尤为重要,因为它使得正确地对代码进行推理变得更加困难。

  2. 函数通常应通过返回 ing Inculation 的结果向其发出信号。这对于递归功能尤其重要。那是什么返回

  3. 在这里使用递归的目的(诚然是一个琐碎的例子)是,它已经分解并简化了每个步骤的问题:我们 use 使用递归以找到的总和。 立方体,然后为当前数字添加立方体。因此,正确的递归代码不应具有 loop


  4. 请确保您对呼叫函数的工作方式有深入的了解。编写int sumcube(int){表示函数接受参数,但不能使用使用,因为它没有名称。我们应该写一个名称:int sumcube(int num){。然后,仅在函数内部num作为参数中传递的任何内容的名称。此不必是 num 的另一个变量;它根本不必是一个变量。我们不会将变量传递给函数。我们将 value 传递给函数。


您知道,完全像pow(sumcube(num),3)时如何,3不必是变量完全,不必具有由pow函数决定的名称。 完全像如何使用pow函数时,return sa值可以在+的右侧使用该值,并且不会更改任何全局变量。


考虑到这一背景,我们可以将问题新鲜解决。这样考虑:想象一下您 其他人的函数,sumcube2,它以其他方式解决了相同的问题。我们想使用它来帮助解决问题。我们的一般方法是什么?

  1. 我们要给出sumcube2 a 比我们得到的问题(否则我们可以直接使用它)。我们已经有一个分解步骤:我们使用Division和Modulo提取最后一个数字。


  2. 我们要使用一些本地计算来调用sumcube2的结果。很容易看到如何做到这一点:我们将最后一位数字添加到函数调用中的结果中。那么我们可以返回结果。

  3. 我们需要 guard 以防止用尽空间以简化的问题。这很简单:如果我们给出了0,那么我们知道结果是0,而我们不必再做任何工作了。 (还有其他方法可以实施此步骤,但是为什么要使它更难呢?)

因此:我们需要一个函数来接受名为num的参数:

int sumCube(int num) {
    int last, rest;

我们将首先检查我们的特殊情况:

    if (!num) return 0;

否则,我们提取最后一个数字,并将其余的数字分开:

    last = num % 10;
    rest = num / 10;

我们通过使用sumcube2结果来计算和return结果:

    return sumCube2(rest) + pow(last, 3);
}

注意我们不需要修改任何全局变量,使用循环或类似的内容。

我们可以稍微凝结代码,因为我们真的不需要这些中间计算结果的名称(这是为了一次谈论逻辑一个步骤):(

int sumCube(int num) {
    if (!num) return 0;
    return sumCube2(num / 10) + pow(num % 10, 3);
}

或者我们可以使用> 而不是调用pow,您明白了。

?:有条件的表达式,或者我们可以明确使用乘法 神话sumcube2我们没有写的?

简单:sumcube是一个旨在准确执行sumcube2要做的函数。因此,我们只是称其为 - 即,在那里汇总调用。

int sumCube(int num) {
    if (!num) return 0;
    return sumCube(num / 10) + pow(num % 10, 3);
}

它之所以起作用,是因为每个 呼叫该函数具有其自己的参数和自己的本地变量,而返回 s返回到从 - 完全像调用任何其他函数。因为我们只期望递归呼吁做的作品,并且只有在有效的“有效”的工作中,我们只能递归进行递归,因此我们避免了无限的递归。

请注意,我做 在此代码中具有任何cout逻辑。这是因为sumcube perive 计算立方体的总和。 显示该结果是一个完全独立且无关的任务。这是main的责任:

int main()
{
    cout << sumCube(51) << endl;
    return 0;
}

The overall approach to the recursion is completely wrong.

  1. 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.

  2. Functions should normally signal the result of the calculation by returning it. This is especially important for recursive functions. That's what return is for.

  3. 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.

  4. 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 named num; 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), the 3 didn't have to be a variable at all, and didn't have to have a name dictated by the pow function. Exactly like how when you use the pow function, it returns 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?

  1. 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.

  2. 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 can return that result.

  3. 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 is 0, 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:

int sumCube(int num) {
    int last, rest;

We will first check our special case:

    if (!num) return 0;

Otherwise, we extract the last digit, and separate the rest of the number:

    last = num % 10;
    rest = num / 10;

We compute and return the result, by making use of the sumCube2 result:

    return sumCube2(rest) + pow(last, 3);
}

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):

int sumCube(int num) {
    if (!num) return 0;
    return sumCube2(num / 10) + pow(num % 10, 3);
}

(Or we could use a ?: conditional expression, or we could use multiplication explicitly instead of calling pow, 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 what sumCube2 was going to do. So we just call it instead - i.e., make the recursive call there.

int sumCube(int num) {
    if (!num) return 0;
    return sumCube(num / 10) + pow(num % 10, 3);
}

It works because every call to the function gets its own parameters and its own local variables, and returns 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 of sumCube is to compute the sum of the cubes. Displaying that result is a completely separate and unrelated task. It is the responsibility of main:

int main()
{
    cout << sumCube(51) << endl;
    return 0;
}
囚我心虐我身 2025-02-17 16:03:45

基本问题是在此表达式中:

sum + pow(sumCube(num), 3)

sum的值可以在调用sumcube之前读取 - 这里没有序列点,它们之间没有依赖性。由于sumcube还修改sum(这是一个全局变量),因此您获得了不确定的行为。

当您使用+=运算符时,其左操作数和右操作数(如任何分配)之间存在依赖性,因此呼叫sumcube读取sum的值的添加,因此您将始终获得sum 之后的值

The basic problem is that in this expression:

sum + pow(sumCube(num), 3)

the value of sum might be read either before or after calling sumCube -- there's no sequence point here and no dependency between them. Since sumCube also modifies sum (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 to sumCube will come before the addition which reads the value of sum, so you'll always get the value of sum after it has been modified by sumCube

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文