C中的参数--i和i-1有什么区别?

时间:2019-07-07 17:08:44

标签: c++ c recursion operators parameter-passing

我正在编写一个程序,该程序可以递归打印出前10个自然数。首先,我将参数“ --num”

int natural_numbers(int num) {
    if (num > 1) // Base case
        natural_numbers(--num);
    printf("%d ", num);
}
Input: 10
Output: 1 1 2 3 4 5 6 7 8 9

然后我将参数更改为“ num-1”,并打印出我期望的结果。

int natural_numbers(int num) {
    if (num > 1) // Base case
        natural_numbers(num - 1);
    printf("%d ", num);
}
Input: 10
Output: 1 2 3 4 5 6 7 8 9 10

我不知道为什么第一个输出是错误的。我需要一些帮助。

4 个答案:

答案 0 :(得分:1)

num - 1创建一个新的临时int,作为num的副本,并从该临时int中减去1。

--numnum本身减去1。

此外,请注意,您的函数natural_numbers应该是void。现在它显示为int,但是您不返回任何内容,因此您的程序确实具有Undefined Behaviour

您可以使用调试器并逐步执行程序,以查看何时出现问题,或添加一些调试记录。这是您的原始程序,在递归调用之前在之前之后进行打印。为了使算法起作用,前后的数字应该相同,而您将会看到,它们不是相同的。

#include <iostream>
#include <string>

void natural_numbers(int num) {
    static size_t indent = 0;
    std::cout << std::string(indent, ' ') << "num before: " << num << "\n";
    if(num > 1) { // Base case
        ++indent;
        natural_numbers(--num);
        --indent;
    }
    std::cout << std::string(indent, ' ') << "num after: " << num << "\n";
}

int main() {
    natural_numbers(10);
}

答案 1 :(得分:1)

在第一部分中,您使用递减--运算符来更改num值。您的第二个代码不会更改num值(它将临时num - 1值传递给函数调用)。

因此,如果您下一个printf num的值是不同的。在第一部分中,它递减一,在第二部分中,它是原始的num值。

如果您最初用natural_numbers调用num == 10,则可以在下面跟踪其值在下一行中如何更改/不更改。

                                  //      num (its value)
int natural_numbers(int num) {    //       10
    if (num > 1) // Base case     //       10
        natural_numbers(--num);   //       10 / and 9 (after execution)
    printf("%d ", num);           //        9
}

int natural_numbers(int num) {    //       10
    if (num > 1) // Base case     //       10
        natural_numbers(num - 1); //       10
    printf("%d ", num);           //       10
}

答案 2 :(得分:0)

如果您想将num - 1传递给一个函数(实际上就是在这里做的那样),那么只需调用natural_numbers(num - 1)即可。不需要花哨的东西。这不是巧合,这是行之有效的方式。

C的特殊++--运算符比仅仅加或减1做更多的事情-显着更多。它们加或减1,并存储增加或减少的变量移至原始位置。因此,--num不仅从num中减去1,还将值num - 1存储回num中。但这不是您想要的。您不想修改num,因为在每个递归调用中,您都希望打印出您开始使用的num的值,而不是不是递减的版本进入递归。

答案 3 :(得分:-1)

您认为我们希望在第3号之前调用该函数

当您使用--num时,就像您在natural_function中更改输入的数字一样

当调用natural_numbers(3)时的本地堆栈看起来像

// =========call natural_number(3)

natural_number(2) // --num (change num itself. its like num = num - 1 then pass it)

// But here in this local stack  block "num" becomes 2 

print 2 // <== here it prints 2 on the backward step

// ========= call natural_number(2)

natural_number(1) // --num (change num itself. its like num = num - 1 then pass it)

// But here in this local stack  block "num" becomes 1

print 1 // <== Here it prints 1 on the backward step

// ========= call natural_number(1)

print 1 // Here we go out of stack by printing 1  

Result: 1 1 2

现在,如果我们用(num-1)调用该函数 这意味着您不想更改在自己的本地堆栈块中输入的“ num”变量。

(num-1)的本地堆栈如下所示:

// ========= call natural_number(3)

natural_number(2) // (num - 1) (num wont change. its like temp = num - 1 then pass temp to it)

print 3 // Here it prints 3 on the backward step

// ========= call natural_number(2)

natural_number(1) // (num - 1) (num wont change. its like temp = num - 1 then pass temp to it)

print 2 // <== Here it prints 2 on the backward step

// ========= call natural_number(1)

print 1 // Here we go out of stack by returning 1  

Result: 1 2 3
相关问题