2016-02-29 82 views
-1

我一直在掙扎着這個小時。減少價值似乎並沒有在一個時間循環

我有一個遞歸函數,詳情如下:

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

的遞歸調用嘗試,但將不能工作。

+1

編譯所有的警告和調試信息('GCC -Wall -Wextra -g')。然後**使用調試器**('gdb')一步一步地運行程序,查詢變量的值,並瞭解發生了什麼 –

+0

while循環控制遞歸。 – Scholarmate

+0

也許你想'if'而不是'while'?順便說一下,預期的產量是多少? –

回答

0

試試這個

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); 
} 

} 
+0

這確實修復了它,但while循環應該可以工作。 – Scholarmate

+0

同時嘗試x> 0 – Grv

+2

'else return'是多餘的;到達無效函數的末尾無論如何返回 –

1

當我運行此代碼,一切似乎execpt的X工作 - = 2。

x -=2運行正常的,爲什麼你得到正確printf當你進入10

看這個while (x != 0)。如果x變爲負值,則會導致無限循環。 因此將您的環路條件更改爲while (x >= 0)

2

讓我們試着用一個例子來看這段代碼。

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)

x = 2 
enter the while loop since 2 != 0 
print out 2 
ignoring turtle_walk and turtle_turn for now 
x is now 0 
call the fractal function with pTurtle and 0 

而且它會產生第三堆棧幀,所以會有形的調用,比如

fractal(pTurtle, 0) 

這將無能爲力。但我們還沒有完成。現在我們回到第二個堆棧框架,即稱爲分形(pTurtle,0)的函數,它現在具有x = 0。因此,它將失敗條件並完成。

現在我們返回到第一個堆棧幀,它仍然有x = 2。所以它會再次查看並打印2並執行與第二個堆棧幀相同的操作。

所以你可能在你的程序與打印件的輸出是:

4 
2 
2 
+0

好的如何解決它呢? – Scholarmate

+1

沒有必要修復沒有損壞的東西。 「分形」功能打印分形塗鴉。監獄長已經給你解釋循環如何遞歸工作。 (除非你清楚知道函數應該達到什麼,但不是,但是我的印象是'分形'不是你自己寫的函數。) –

+0

分形是我寫的東西我。我顯然是新的遞歸,並試圖理解這一切。我已經解釋了我認爲應該發生的事情,而且我還不清楚爲什麼我認爲應該發生,沒有發生。 – Scholarmate

3

您應該進入和退出功能添加打印語句,所以你可以看到那裏的代碼去。它作爲編碼工作 - printf()在功能不被執行時,當然x == 0

下面是您的代碼的簡單改編,以及額外的打印。它忽略了烏龜參數和烏龜操作。它記錄x的值x0,因此它可以在退出時打印(也可以在輸入時打印,以保持一致性)。

#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