C 价值的减少并不意味着';I don’我好像有一段时间没工作了

C 价值的减少并不意味着';I don’我好像有一段时间没工作了,c,while-loop,C,While Loop,我已经为此挣扎了几个小时 我有一个递归函数,如下所述: void fractal ( turtle_t *t, int x){ while ( x != 0){ printf("%d\n", x); turtle_walk ( t, 20*x); turtle_turn ( t, 25 ); x -= 2; fractal ( t, x ); } } 当我运行这段代码时,除了x-=2之外,其他一切似乎都正常工作。我从参数x的值10开始。打印报表给

我已经为此挣扎了几个小时

我有一个递归函数,如下所述:

void fractal ( turtle_t *t, int x){
  while ( x != 0){
    printf("%d\n", x);
    turtle_walk ( t, 20*x);
    turtle_turn ( t, 25 );
    x -= 2;
    fractal ( t, x );
  }
}
当我运行这段代码时,除了
x-=2
之外,其他一切似乎都正常工作。我从参数x的值10开始。打印报表给了我:

10, 8, 6, 4, 2, 2, 6, 4, 2, 2, etc
我错过什么了吗

我也尝试过使用

fractal ( t, x-2 );
用于递归调用,但这也不起作用。

试试这个

void fractal ( turtle_t *t, int x){
  if( x >= 0){
    printf("%d\n", x);
    turtle_walk ( t, 20*x);
    turtle_turn ( t, 25 );
    x -= 2;
    fractal ( t, x );
 }

}
当我运行这段代码时,在x-=2的情况下,一切似乎都正常

x-=2
工作正常,这就是为什么输入10时得到正确的
printf

当(x!=0)时,看看这个
。如果x为负,这将导致无限循环。

因此,将循环条件更改为
,而(x>=0)

让我们尝试用一个示例来查看此代码

void fractal ( turtle_t *t, int x){
  while ( x != 0){
    printf("%d\n", x);
    turtle_walk ( t, 20*x);
    turtle_turn ( t, 25 );
    x -= 2;
    fractal ( t, x );
  }
}
假设这个函数是通过

fractal(pTurtle, 4);
让我们将其称为第一个堆栈帧,其外观如下:

x = 4
enter the while loop since 4 != 0
print out 4
ignoring turtle_walk and turtle_turn for now
x is now 2
call the fractal function with pTurtle and 2
remember later we are not done with this function
现在它将创建第二个堆栈帧,看起来像分形的函数调用(pTurtle,2)

它将生成第三个堆栈帧,因此将调用类似分形的

fractal(pTurtle, 0)
这是毫无用处的。但我们还没有完成。现在我们回到第二个堆栈帧,也就是称为fractal(pTurtle,0)的函数,它现在的x=0。因此,它将不符合条件并被执行

现在我们回到第一个堆栈帧,它仍然有x=2。因此,它将再次查看并打印2,并执行与第二个堆栈帧相同的操作

因此,您可能从程序中获得的打印输出是:

4
2
2

您应该在函数的入口和出口添加print语句,以便查看代码的去向。它以编码方式工作-当然,当
x==0
时,函数中的
printf()
不会执行

下面是对代码的简单修改,并进行了额外的打印。它忽略turtle参数和turtle操作。它在
x0
中记录了进入时
x
的值,因此可以在退出时打印该值(为了一致性,也可以在进入时打印)

#包括
静止的
空洞分形(/*t*t,*/int x)
{
int x0=x;
printf(“-->>%d\n”,x0);
而(x!=0)
{
printf(“%d\n”,x);
/*
龟步(t,20*x);
乌龟转身(t,25);
*/
x-=2;
分形(/*t,*/x);
}

printf(“使用所有警告和调试信息(
gcc-Wall-Wextra-g
)进行编译。然后使用调试器(
gdb
)要一步一步地运行程序,请查询变量值,并了解发生了什么while循环控制递归。也许您希望
if
而不是
while
?顺便问一下,预期的输出是什么?它从10变为8是因为x-=2在工作。是的,10到8到6到4到2..但当它运行时返回2如果返回0(从而中断递归),则无需修复未中断的内容。
fractal
函数打印分形涂鸦。Warden已向您解释了循环dn递归的工作原理。(除非你对函数应该实现什么有一个清晰的想法,但是没有,也就是说,但我的印象是,
fractal
不是你自己编写的函数。)分形是我自己写的东西。我显然对递归很陌生,并试图理解这一切。我已经解释了我认为应该发生的事情,但我仍然不清楚我认为应该发生的事情为什么没有发生。@Scholarmate:“我已经解释了我认为应该发生的事情。”“没有,您没有;请再次阅读您的问题。您给出了实际输出并询问“我遗漏了什么吗?”您没有给出预期的输出。如果这应该只是一系列递减的数字,您应该只使用递归或只使用循环。但问题并不清楚。您接受的答案只使用递归。(这个答案本身不是很好,但回答者显然很善于理解你的想法。)
else-return
是多余的;到达void函数的末尾无论如何都会返回这会生成一个非常不同的数字序列。这没有错,只是它不是问题的主题-计数器,只是它已被接受为答案,尽管糟糕的
else{return;}
是完全多余的(如果
if
语句在
else
子句之后返回,就像
else
不在那里一样).是的,它是多余的。我使用return的原因很清楚,它将从那里返回。有时你会因为一整天的工作而感到疲惫。如果你查看某人的代码,即使它没有用处,它也会很清楚。我将更新并删除return。谢谢
4
2
2
#include <stdio.h>

static
void fractal(/*turtle_t *t,*/ int x)
{
    int x0 = x;
    printf("-->> %d\n", x0);
    while (x != 0)
    {
        printf("%d\n", x);
        /*
        turtle_walk ( t, 20*x);
        turtle_turn ( t, 25 );
        */
        x -= 2;
        fractal(/*t,*/ x);
    }
    printf("<<-- %d\n", x0);
}

int main(void)
{
    fractal(10);
    return 0;
}
-->> 10
10
-->> 8
8
-->> 6
6
-->> 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 6
6
-->> 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 8
8
-->> 6
6
-->> 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 6
6
-->> 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 4
4
-->> 2
2
-->> 0
<<-- 0
<<-- 2
2
-->> 0
<<-- 0
<<-- 10