#include <stdio.h>
main()
{
int i=5;
if(--i)
{
main();
printf("%d ",i);
}
請注意,如果我們將int i
設置爲static
那麼答案將是0000
。爲什麼這個程序成功編譯但運行失敗?
#include <stdio.h>
main()
{
int i=5;
if(--i)
{
main();
printf("%d ",i);
}
請注意,如果我們將int i
設置爲static
那麼答案將是0000
。爲什麼這個程序成功編譯但運行失敗?
變量i
具有輸入功能main()
價值每一次(每次調用main()
擁有該變量的堆棧上自己的副本)。沒有遞歸終止,因爲遞歸終止的條件從未滿足(即:--i
從不計算爲零)。 因此,遞歸調用main()
,直到堆棧中沒有更多位置。
但是,如果您將i
聲明爲static
,則所有對main()
的調用都有一個共享副本變量i
。當--i
評估爲零時滿足遞歸終止條件。
它運行的空間(堆棧),因爲它正在爲main()的indefinetely
代碼本身是正確的,該程序將編譯沒有任何問題的呼叫。問題是條件if (--i)
將始終評估爲真,因爲每次遞歸調用main
時,會創建一個新的本地i
變量,並且總是值得5
。隨着堆疊越來越多的調用,當堆棧無法再增長時,程序將由SIGSEGV終止。爲什麼程序輸出0000
在聲明i
爲static
變量是因爲i
不是在每一個main
呼叫重新聲明
==10972== Memcheck, a memory error detector
==10972== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==10972== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==10972== Command: ./a.out
==10972==
==10972== Stack overflow in thread #1: can't grow stack to 0xffe801000
==10972==
==10972== Process terminating with default action of signal 11 (SIGSEGV)
理由是:你可以用Valgrind的觀察此。所以基本main
遞歸調用,直到i
值得0
。然後,所有堆疊的printf
被執行,但是在這些堆棧調用中,每個堆棧調用中i
的值爲0
,您將看到0000
。 static
關鍵字使所有main
調用實際上引用相同的i
變量而不是副本。
什麼是你不明白?遞歸或靜態變量? –
通過添加靜態我得到0000,這是可以理解的,但問題是在循環中,終止條件不存在,現在我明白了。 – user8332164
您可以在這裏查看我的答案,以瞭解當我們進行無限遞歸調用時會發生什麼情況:https://stackoverflow.com/questions/45427160/why-am-i-getting-segmentation-fault-in-this/45429726#45429726 – babon