1樓:孟羽然
其實遞迴呼叫就是一個「壓棧」/「彈棧」的過程。
每一次遞迴呼叫,就會把當前的現場壓棧,然後呼叫下一層;呼叫完畢後,從棧中恢復現場,繼續執行。
拿你這個遞迴函式來看,在入口和出口處分別列印了一條日誌。
入口處的日誌,一進入函式即被執行,然後進行遞迴呼叫,遞迴返回後,再列印出口的日誌。
這樣總體呼叫效果就像這樣:
1 # 第1層遞迴入口| 2 # 第2層遞迴入口| | 3 # 第3層遞迴入口| | | 4 # 第4層遞迴入口| | | 4 # 第4層遞迴出口,返回上層| | 3 # 第3層遞迴出口,返回上層| 2 # 第2層遞迴出口,返回上層1 # 第1層遞迴出口,返回上層
2樓:匿名使用者
void up_and_down(int n)那麼一步步剖析,n與指令流:
n 指令流
1 輸出,進入子過程
2 輸出,進入子過程
3 輸出,進入子過程
4 輸出,輸出
3 從子過程返回,輸出
2 從子過程返回,輸出
1 從子過程返回,輸出
注意每一個遞迴中有一前一後兩個printf哦
3樓:孫永超
**一下就知道原因了
c語言遞迴的問題,遞迴結束之後為什麼還要倒過來一遍?
4樓:匿名使用者
void函式是可以不寫return語句的,沒有return也是return。
5樓:匿名使用者
函式是否要return 一個值,是看邏輯需求的需要的
現在這個函式定義沒有返回,而是直接列印出來~
c語言遞迴練習題,用debug自己搞了一遍還是搞不懂為什麼會倒著輸出一遍,求大神給講講
6樓:匿名使用者
這個邏輯上很簡單啊,讀取一個字元,如果不是eof,就繼續遞迴,直到讀出eof,然後顯示字元,結束。
所以你的程式裡,if及下面的遞迴呼叫改一下就好。自己試試吧!
int recursive()
7樓:gta小雞
把每次呼叫recursive()的地方都用recursive的整個函式體替換一遍,就像俄羅斯套娃一樣,再來看這個程式,就懂了。
8樓:wolove書
因為是遞迴,相當於後進先出的棧。停止輸入後開始輸出,倒著來一遍 逆序了
【c語言】函式遞迴問題,題目見**,答案為什麼是d?求解!為什麼是倒著輸出的?!
9樓:蜻蜓點水
遞迴函式式自己呼叫自己,那麼那個函式會一直執行到某個特定滿足的條件的時候,才會從裡面忘外面返回啊
比如就是f(f(f(3)));
進去之後,是從最裡層的函式返回吧,那麼就是倒著瞭如果用再具體一點,就是堆疊的先進後出了,上一級的函式的東西都在底下,只有最後一層的在棧頂
10樓:帶著光圈的小雞
由於子函式呼叫在printf()語句之前,所以得到符合條件(x/2>0)為假時,才能跳過fun()呼叫,
執行printf()語句;而啥時候符合呢,請看程式執行:
第一次呼叫fun()時x=20,x/2=10>0,所以繼續呼叫fun(8);
x=8,x/2=4>0,所以繼續呼叫fun(2);
x=2,x/2=1>0,繼續呼叫fun(-1);
x=-1,x/2<0;此時if語句條件為假,執行printf() 輸出-1,
然後返回上級,仍然執行printf(),而此時x=2,輸出2然後返回上級,仍然執行printf(),而此時x=8,輸出8然後返回上級,仍然執行printf(),而此時x=20,輸出20
11樓:香山雪葉
fun(20)
printf("%d ",2);
}printf("%d ",8);
}printf("%d ",20);
}遞迴解釋起來還挺麻煩的,我把遞迴了,就如上,函式從上往下執行,就分別輸出 -1 2 8 20了
再加上花括號
12樓:匿名使用者
這就是遞迴啊。在fun(20)裡面呼叫fun(18), fun(18)不執行完,fun(20)中的printf不會執行,fun(18)裡面呼叫fun(7), fun(7)不執行完,fun(18)中的printf不會執行。以此類推。
就可以理解了
13樓:匿名使用者
這個是遞迴啊 碰到函式了 當然函式先執行 所以 輸入20->fun(8)
->fun(2)
->fun(-1) -1不滿足判斷條件
->執行 printf -1
->返回到上層 printf 2
依這種思路執行 所以倒序輸出哦
c語言的遞迴問題 為什麼會倒過來執行一次
14樓:瀟瀟小百
void up_and_down(int n)主要在這裡,當n=1的時候程式執行到
if(n<4)
up_and_down(n+1);
的時候,就會由於遞迴的原因回到void up_and_down函式開啟頭去執行n = n+1的情況了,也就是說,當n=1時,剛開始是不執行if後面那個的要等重重遞迴使得n=4的時候才執行n=4時的if後面那個printf語句的,然後再返回上一層遞迴,也就是n=3的時候,再執行n=3的時候的printf,n=2,n=1也是這樣的
15樓:匿名使用者
首先先跟你說下,你是不是忘了你的遞迴函式,首尾都要輸出。注意程式縮排,養成好習慣。
void up_and_down(int n)
以你的例子而言,首先是過程(此時n<4),在呼叫遞迴函式前先要執行第一行的輸出語句,然後呼叫遞迴語句up_and_down(1+1);進入下一層函式,依次類推,你看到了1、2、3、4。當n=4時階段結束,不再呼叫遞迴函式,但仍要依照順序執行此函式全部語句,所以要輸出4,函式執行完畢後,要返回函式呼叫處(up_and_down(3+1);的下一句),繼續按順序執行輸出語句 輸出3,同理再依次輸出2、1
所以最後看到的是1 2 3 4 4 3 2 1
up_and_down(1);
printf("1");
up_and_down(1+1);
printf("2");
up_and_down(2+1);
printf("3");
up_and_down(3+1);
printf("4");
printf("4");
printf("3");
printf("2");
printf("1");
遞迴解決問題本來就是先,直到遇到終止條件,然後再逐層返回,並不是算到最後一層,就直接返回給第一層呼叫處。以階乘為例:
rescuvie(5)}}}
}}}}}}}}}
120由於遞迴的這種特性,所以要佔據很大的空間,如果一直沒有遇到遞迴終止條件,則會一直進行下去,直到資源耗盡。階乘數大於某一程度,計算機就無法解決了。
因此與迭代相比遞迴是十分低效的演算法,不過由於遞迴有抽象的表達能力,只要有遞推關係,不必求出具體表示式就可以求解問題,所以應用還是比較廣泛的。
以上方法都被稱為線性遞迴,也可以說是傳統的遞迴。而你後面說的尾遞迴,是另一種新的方法,與傳統的線性遞迴相比,可節省資源所佔資源,避免資源耗盡的問題。
下面舉階乘尾遞迴的例子
long tailrescuvie(long n, long a)
long tailrescuvie(long n)
tailrescuvie(5)
tailrescuvie(5, 1)
tailrescuvie(4, 5)
tailrescuvie(3, 20)
tailrescuvie(2, 60)
tailrescuvie(1, 120)
1-2返回120
2-3返回120
3-4返回120
4-5返回120
tailrescuvie(5,1)返回120給tailrescuvie(5)
返回並輸出120
很容易看出,普通的線性遞迴比尾遞迴更加消耗資源,在實現上說,每次重複的過程呼叫都使得呼叫鏈條不斷加長,系統不得不使用棧進行資料儲存和恢復。而尾遞迴就不存在這樣的問題,因為他的狀態完全由n和a儲存。
就思想而言,尾遞迴其實也是一種線性遞迴,不過它把運算結果(或路徑)傳給了下一層,編譯器可以利用這一特點對語句進行優化,節省所佔資源。而且當遇到終止條件後,雖然形式上仍要返回,但計算已經結束,只要將值不斷返回即可,不必再運算,因此每次分配的記憶體不會因為遞迴而擴大。
尾遞迴適用於運算對當前遞迴路徑有依賴的問題,傳統遞迴適用於運算對更深層遞迴有依賴的問題。從效率來看兩者都差不多,不過編譯器對尾遞迴可以進行優化,大大減小尾遞迴所佔資源,而普通遞迴,編譯器的優化沒太大影響。(如果都不優化,其實所佔資源差不多)
如果你改寫下long tailrescuvie(long n, long a);使得它在頭尾輸出n(遞迴呼叫前後都輸出),你會發現輸出結果仍然是,n、n-1 ……2 1 1 2……n-1、n的過程。
不存在你說的到一半就結束了。
long tailrescuvie(long n, long a) {
cout<
16樓:匿名使用者
c語言;自頂向下,依次執行
執行完print語句後,需要返回到fun後面(因為if條件已經不滿足),所以不能再呼叫fun,而是執行相應的print語句
17樓:龍__鳳
這是因為沒執行一個up_and_down()函式都會有兩個輸出,對於你的程式,總過輸出8次,自然是先輸出1,2,3,4,然後又輸出4,3,2,1了
18樓:匿名使用者
up_and_down(n+1);這句執行完,就直接進入了遞迴, 這句還沒有執行,所以最後一層執行完之後會一次返回到上一層,因此倒著輸出了4 3 2 1
19樓:小白丶風
當然是輸出8行啦,你up_and_down方法裡邊有兩個printf,遞迴的時候,都是執行了第一句,然後判斷,遞迴呼叫,只到n=4的時候,輸出了第一個4,if判斷不在遞迴,執行了第二個print,輸出了第二個4,然後完成了這層遞迴呼叫,返回前一層n=3的遞迴,輸出第二個3完成了這層呼叫再返回前一層。。。只到輸出第二個1,遞迴才結束,只要刪掉方法裡第二個printf輸出的就是4行了
c語言問題,為什麼會輸出負數,C語言問題,輸出結果總是負數,求教
在你的switch語句最後都加一個default 看一下switch d switch u 如果出現error這行,說明你的fflush 沒有起作用,改正方法是在scanf 函式後,加一個getchar 如果沒有出現,把你的輸入資訊粘出來,即x d u都是什麼。再幫你看 這個問題有多種可能,不一而足...
為什麼快用完的煤氣罐倒過來後擰緊閥門,關掉爐灶,火還是不會滅
歐,親,光看題目還發懵呢,原因很簡單 您倒出的液化氣的液體在區域性快速蒸發,形成較高的燃燒氣體,當您點燃時,其氣態煤氣快速燃燒,自然火苗很高,至於您說的顏色那是不充分燃燒的結果。不能到這用,這樣出來的都是液體,控制不了,很危險的。快煤氣了,你可以在罐底座點熱水,能緩和一下。千萬不能到這用,危險謝謝 ...
為什麼裝滿水倒過來的杯子水不往外流呢
1 因為杯子裡面沒有空氣,所以杯子裡的大氣壓力 02 大氣壓力沒有方向,也就是說是任何方向都存在,所以杯子下面的大氣有向上的支撐力 3 此刻杯口所蓋紙所受向上的大氣壓力 大於杯子裡水的重力 故 上述實驗成立 因為有紙或玻璃片蓋住後,即使杯中的水不是滿的,只有一點空隙,只要空隙不超過大氣壓從下壓上所承...