1 00:00:00,000 --> 00:00:05,587 2 00:00:05,587 --> 00:00:07,670 DOUG LLOYD: Pokud jste viděli video na rekurze, 3 00:00:07,670 --> 00:00:10,170 Celý proces může mít Zdálo se trochu kouzelné. 4 00:00:10,170 --> 00:00:10,930 Jak to funguje? 5 00:00:10,930 --> 00:00:15,010 Jak se funkce, vědí, že muset čekat a čekat na jinou hodnotu 6 00:00:15,010 --> 00:00:19,150 až se vrátí ze jinou funkci zavolat, aby si výsledek chceme? 7 00:00:19,150 --> 00:00:22,550 >> No, důvod, proč to funguje, je to, že něčeho známého jako zásobníku volání. 8 00:00:22,550 --> 00:00:26,360 Při volání funkci, Systém vyčleňuje místo v paměti 9 00:00:26,360 --> 00:00:28,120 pro tuto funkci dělat svou práci. 10 00:00:28,120 --> 00:00:31,720 A my nazýváme tyto kousky paměti, která jsou vyčleněny pro každou funkci 11 00:00:31,720 --> 00:00:35,670 volejte rám zásobníku nebo funkci rámce. 12 00:00:35,670 --> 00:00:38,290 A jak se dalo očekávat, Tyto zásobník rámy 13 00:00:38,290 --> 00:00:41,000 žijí na zásobníku část paměti. 14 00:00:41,000 --> 00:00:43,960 15 00:00:43,960 --> 00:00:47,540 >> Více než jedna funkce stack frame může existovat v paměti v daném čase. 16 00:00:47,540 --> 00:00:51,240 Pokud hlavní volá funkci tah, a žádá, aby pohyb směrem, 17 00:00:51,240 --> 00:00:54,460 všechny tři funkce mají otevřené rámy. 18 00:00:54,460 --> 00:00:57,350 Ale ne všichni mají aktivní rámy. 19 00:00:57,350 --> 00:00:59,410 Tyto rámy jsou uspořádány v zásobníku. 20 00:00:59,410 --> 00:01:01,820 A rám z naposledy volal 21 00:01:01,820 --> 00:01:04,390 funkce je vždy v horní části zásobníku. 22 00:01:04,390 --> 00:01:07,150 A to je vždy aktivní rámeček. 23 00:01:07,150 --> 00:01:10,420 Je tu jen opravdu vždy jednou Funkce, která je aktivní vždy. 24 00:01:10,420 --> 00:01:12,420 Je to jeden na vrcholu zásobníku. 25 00:01:12,420 --> 00:01:17,620 >> Když se funkce volá další funkce, to nějak lisy pauzu. 26 00:01:17,620 --> 00:01:20,590 Tak nějak je v pořadí, a čekal. 27 00:01:20,590 --> 00:01:24,050 A další stack frame je tlačena do zásobníku na vrcholu toho. 28 00:01:24,050 --> 00:01:26,150 A to se stane aktivní rámeček. 29 00:01:26,150 --> 00:01:28,600 A snímek bezprostředně Níže je třeba čekat 30 00:01:28,600 --> 00:01:33,560 dokud není opět aktivní frame před tím, než může pokračovat v jeho práci. 31 00:01:33,560 --> 00:01:35,870 Pokud je funkce kompletní a je to hotovo, 32 00:01:35,870 --> 00:01:37,720 jeho rám je vyskočila z hromádky. 33 00:01:37,720 --> 00:01:38,950 To je terminologie. 34 00:01:38,950 --> 00:01:41,110 A snímek bezprostředně pod ní, jak jsem právě řekl, 35 00:01:41,110 --> 00:01:42,880 se stane novým aktivním rámu. 36 00:01:42,880 --> 00:01:45,960 >> A pokud to volá jinou funkci, že to bude zase pauzu. 37 00:01:45,960 --> 00:01:49,290 Ta nová funkce stack frame bude nasunout na vrcholu zásobníku. 38 00:01:49,290 --> 00:01:50,650 To bude dělat svou práci. 39 00:01:50,650 --> 00:01:52,100 Mohlo by to pop zpátky. 40 00:01:52,100 --> 00:01:55,630 A další funkce pod ní může pokračovat znovu. 41 00:01:55,630 --> 00:02:00,080 >> Takže pojďme přes to ještě jednou, hledá při představě, že funkce faktoriálu 42 00:02:00,080 --> 00:02:03,070 že definovány v rekurze video vidět 43 00:02:03,070 --> 00:02:07,770 přesně tak, jak kouzlo za tím rekurzivní proces probíhá. 44 00:02:07,770 --> 00:02:09,870 Takže to je celý náš soubor, že jo? 45 00:02:09,870 --> 00:02:14,000 Definovali jsme dva functions-- hlavní a fakt. 46 00:02:14,000 --> 00:02:15,980 A jak bychom mohli očekávat, jakýkoli program v jazyce C se děje 47 00:02:15,980 --> 00:02:18,470 začít na prvním řádku hlavní. 48 00:02:18,470 --> 00:02:21,660 >> Tak jsme vytvořit nový rámec pro hlavní zásobníku. 49 00:02:21,660 --> 00:02:23,320 A bude to začít zobrazovat. 50 00:02:23,320 --> 00:02:25,270 Hlavní volání printf. 51 00:02:25,270 --> 00:02:29,390 A printf bude vytisknout faktoriál 5. 52 00:02:29,390 --> 00:02:31,440 No, to neví co faktoriál 5 je, 53 00:02:31,440 --> 00:02:35,620 a tak tento hovor je již v závislosti na jiném volání funkce. 54 00:02:35,620 --> 00:02:37,270 Takže hlavní bude pozastavit právě tam. 55 00:02:37,270 --> 00:02:39,103 Nechám své šipka vpravo tam, barva 56 00:02:39,103 --> 00:02:41,360 to stejné barvy jako stack frame na pravé straně, 57 00:02:41,360 --> 00:02:47,720 což znamená, že hlavní bude zmrazit tady, zatímco faktoriál 5 se nazývá. 58 00:02:47,720 --> 00:02:49,300 >> Takže faktoriál 5 se nazývá. 59 00:02:49,300 --> 00:02:53,160 A bude to začít u velmi začátek faktoriálové funkce. 60 00:02:53,160 --> 00:02:55,440 To klade otázku mám činit až 1? 61 00:02:55,440 --> 00:02:56,810 Je 5 rovno 1? 62 00:02:56,810 --> 00:02:57,410 No, no. 63 00:02:57,410 --> 00:03:01,110 Tak to bude, aby šel do else část, návrat n krát 64 00:03:01,110 --> 00:03:02,990 faktoriál n minus 1. 65 00:03:02,990 --> 00:03:03,490 No dobře. 66 00:03:03,490 --> 00:03:07,070 >> Takže teď, faktoriál 5 je V závislosti na dalším hovoru 67 00:03:07,070 --> 00:03:09,740 na faktoriál, předávání ve 4 jako parametr. 68 00:03:09,740 --> 00:03:14,210 A tak se faktoriál 5 rám, který červeným rámečkem, 69 00:03:14,210 --> 00:03:17,160 se chystá zmrazit právě tam v tomto řádku jsem uveden 70 00:03:17,160 --> 00:03:21,914 a čekat na faktoriálem 4 až do konce co je třeba to udělat tak, že pak ji 71 00:03:21,914 --> 00:03:23,330 se může stát opět aktivní rámeček. 72 00:03:23,330 --> 00:03:26,890 >> Takže faktoriál 4 začíná na začátek faktoriál. 73 00:03:26,890 --> 00:03:28,556 4 je rovno 1? 74 00:03:28,556 --> 00:03:30,180 Ne, tak to bude dělat totéž. 75 00:03:30,180 --> 00:03:31,590 Bude to jít dolů jiného větev. 76 00:03:31,590 --> 00:03:33,240 Bude se dostat na tento řádek kódu. 77 00:03:33,240 --> 00:03:35,710 OK, budu se vrátit čtyřikrát. 78 00:03:35,710 --> 00:03:41,270 Oh, faktoriál 3-- tak faktoriálu 4 závisí na faktoriálem 3 úprav. 79 00:03:41,270 --> 00:03:43,055 >> A tak je potřeba volat faktoriál 3. 80 00:03:43,055 --> 00:03:45,180 A to bude projít opět stejný proces. 81 00:03:45,180 --> 00:03:48,200 Začíná to přes, se sem dostane. 82 00:03:48,200 --> 00:03:50,980 Faktoriál ze dne 3. závisí o faktoriálem 1. 83 00:03:50,980 --> 00:03:53,750 Takže faktoriál 2 startů, se sem dostane. 84 00:03:53,750 --> 00:03:56,310 Záleží na tom, faktoriálem 1. 85 00:03:56,310 --> 00:03:57,430 Faktoriál z 1 startů. 86 00:03:57,430 --> 00:03:57,650 >> DOBŘE. 87 00:03:57,650 --> 00:03:59,775 Takže teď, se dostáváme nějakém zajímavém místě, že jo? 88 00:03:59,775 --> 00:04:02,190 Nyní tedy, 1 je roven 1. 89 00:04:02,190 --> 00:04:05,130 A tak se vracíme 1. 90 00:04:05,130 --> 00:04:06,770 V tomto bodě, se vracíme. 91 00:04:06,770 --> 00:04:07,880 Funkce se stalo. 92 00:04:07,880 --> 00:04:11,140 Je to chování je-- je tu nic jiného pro to dělat, 93 00:04:11,140 --> 00:04:17,006 a tak rámec fronty pro faktoriál 1 objeví off. 94 00:04:17,006 --> 00:04:17,589 Je konec. 95 00:04:17,589 --> 00:04:19,480 To se vrátil 1. 96 00:04:19,480 --> 00:04:23,370 A teď, faktoriál 2, který byl rám bezprostředně pod ním 97 00:04:23,370 --> 00:04:26,160 ve stohu, se stane aktivní rámeček. 98 00:04:26,160 --> 00:04:29,030 >> A to může vyzvednout přesně tam, kde přestali. 99 00:04:29,030 --> 00:04:32,240 Bylo to čekání na faktoriál 1. dokončit svou práci. 100 00:04:32,240 --> 00:04:33,610 Nyní bylo dokončeno. 101 00:04:33,610 --> 00:04:35,510 A tak jsme tady. 102 00:04:35,510 --> 00:04:38,080 >> Faktoriál ze dne 1. vrátila hodnotu 1. 103 00:04:38,080 --> 00:04:42,430 Takže faktoriál 2 může řekněme vrátit 2 krát 1. 104 00:04:42,430 --> 00:04:43,680 Jeho práce je nyní hotovo. 105 00:04:43,680 --> 00:04:49,110 Je to vrátil do 2 faktoriál ze dne 3., který čekal na něj. 106 00:04:49,110 --> 00:04:53,370 Faktoriál ze 3 je nyní horní rám, aktivní rám ve stohu. 107 00:04:53,370 --> 00:04:58,617 A tak říká, OK, dobře, jdu Pro návrat 3x 2, což je 6. 108 00:04:58,617 --> 00:05:00,700 A já dám, že hodnotu zpět faktoriál 109 00:05:00,700 --> 00:05:03,430 4, který byl na mě čeká. 110 00:05:03,430 --> 00:05:04,500 Jsem hotov. 111 00:05:04,500 --> 00:05:09,410 Faktoriál ze dne 3. objeví mimo zásobníku, a faktoriál 4 je nyní aktivní rámeček. 112 00:05:09,410 --> 00:05:13,510 >> 4 říká, OK, budu se vrátit 4 krát faktoriál 3, což bylo šest. 113 00:05:13,510 --> 00:05:15,980 To byla hodnota, která faktoriál 3 vrátil. 114 00:05:15,980 --> 00:05:19,010 A tak 4 krát 6 je 24. 115 00:05:19,010 --> 00:05:20,990 A já jdu projít že zpět do faktoriál 116 00:05:20,990 --> 00:05:23,160 5, který byl na mě čeká. 117 00:05:23,160 --> 00:05:25,270 Faktoriál 5 je nyní aktivní rámeček. 118 00:05:25,270 --> 00:05:30,700 Bude to návrat 5x faktoriál 4-- 5 krát 24, nebo 120-- 119 00:05:30,700 --> 00:05:32,722 a dát tuto hodnotu zpět na hlavní, která má 120 00:05:32,722 --> 00:05:35,680 Čekal velmi trpělivě dlouho ve spodní části zásobníku. 121 00:05:35,680 --> 00:05:36,640 >> To je místo, kde to začalo. 122 00:05:36,640 --> 00:05:37,670 To dělalo toto volání. 123 00:05:37,670 --> 00:05:39,400 Několik snímků převzal na vrcholu. 124 00:05:39,400 --> 00:05:41,890 To je nyní zpět v horní části zásobníku. 125 00:05:41,890 --> 00:05:43,450 Je to aktivní rámeček. 126 00:05:43,450 --> 00:05:47,810 Takže hlavní dostal hodnotu 120 zpět z faktoriálem 5. 127 00:05:47,810 --> 00:05:50,750 Je to už čeká na vytisknout tuto hodnotu. 128 00:05:50,750 --> 00:05:51,657 A pak se to dělá. 129 00:05:51,657 --> 00:05:53,240 Neexistuje žádné další řádky kódu v hlavní. 130 00:05:53,240 --> 00:05:56,800 Takže hlavní je rám objeví off zásobníku, a my jsme udělali. 131 00:05:56,800 --> 00:05:58,992 >> A to je to, jak funguje rekurze. 132 00:05:58,992 --> 00:06:00,200 To je, jak stack snímků pracovat. 133 00:06:00,200 --> 00:06:03,120 Tyto volání funkcí že se stalo předtím 134 00:06:03,120 --> 00:06:06,620 jsou jen na pauze, čekání pro následných výzev 135 00:06:06,620 --> 00:06:12,050 až do konce, takže se může stát aktivním rám a dokončit to, co je třeba udělat. 136 00:06:12,050 --> 00:06:13,060 >> Jsem Doug Lloyd. 137 00:06:13,060 --> 00:06:14,880 To je CS50. 138 00:06:14,880 --> 00:06:16,580