我正在编写一个程序,该程序可以递归打印出前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
我不知道为什么第一个输出是错误的。我需要一些帮助。
答案 0 :(得分:1)
num - 1
创建一个新的临时int
,作为num
的副本,并从该临时int
中减去1。
--num
从num
本身减去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