1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Oddíl 4 - Více Komfortní] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Harvard University] 3 00:00:04,850 --> 00:00:07,370 [To je CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 Máme kvíz zítra, v případě, že vy nevěděl, že. 5 00:00:14,810 --> 00:00:20,970 Je to v podstatě na vše, co jste mohli vidět ve třídě nebo měli vidět ve třídě. 6 00:00:20,970 --> 00:00:26,360 To zahrnuje ukazatele, i když jsou velmi nedávné téma. 7 00:00:26,360 --> 00:00:29,860 Měli byste alespoň pochopit vysoké úrovně z nich. 8 00:00:29,860 --> 00:00:34,760 Cokoliv, co byl pryč přes ve třídě, měli byste pochopit, pro kvíz. 9 00:00:34,760 --> 00:00:37,320 Takže pokud máte nějaké dotazy na nich, můžete požádat je teď. 10 00:00:37,320 --> 00:00:43,280 Ale to bude velmi student-vedl zasedání, kde jste klást otázky, 11 00:00:43,280 --> 00:00:45,060 takže doufejme, že lidé mají otázky. 12 00:00:45,060 --> 00:00:48,020 Má někdo nějaké dotazy? 13 00:00:49,770 --> 00:00:52,090 Ano. >> [Student] Můžeš jít přes ukazatelů znovu? 14 00:00:52,090 --> 00:00:54,350 Půjdu přes ukazatelů. 15 00:00:54,350 --> 00:00:59,180 Všechny vaše proměnných nutně žít v paměti, 16 00:00:59,180 --> 00:01:04,450 ale obvykle nemusíte bát, že a stačí říct x + 2 a y + 3 17 00:01:04,450 --> 00:01:07,080 a kompilátor bude zjistit, kde věci jsou živé na vás. 18 00:01:07,080 --> 00:01:12,990 Jakmile máte co do činění s ukazateli, teď jsi explicitně pomocí těchto adresy paměti. 19 00:01:12,990 --> 00:01:19,800 Takže jediné proměnné pouze někdy žít v jednom adresu v daném okamžiku. 20 00:01:19,800 --> 00:01:24,040 Pokud chceme deklarovat ukazatel, jaký je typ bude vypadat? 21 00:01:24,040 --> 00:01:26,210 >> Chci vyhlásit ukazatel p. Co je typ vypadat? 22 00:01:26,210 --> 00:01:33,530 [Student] int * p. Jo >>. Takže int * p. 23 00:01:33,530 --> 00:01:38,030 A jak mám udělat to poukázat na x? >> [Student] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Tak ampersand je doslova nazývá adresa provozovatele. 25 00:01:45,300 --> 00:01:50,460 Takže když říkám, a x je to čím dál paměti adresu proměnné x. 26 00:01:50,460 --> 00:01:56,790 Takže teď mám ukazatel p, a kdekoli v mém kódu mohu použít * p 27 00:01:56,790 --> 00:02:02,960 nebo bych mohl použít x a bude to přesně to samé. 28 00:02:02,960 --> 00:02:09,520 (* P). Co je to děláš? Co, že hvězda znamená? 29 00:02:09,520 --> 00:02:13,120 [Student] To znamená, že hodnota v tomto bodě. Jo >>. 30 00:02:13,120 --> 00:02:17,590 Takže když se podíváme na to, může to být velmi užitečné upozornit na diagramy 31 00:02:17,590 --> 00:02:22,230 je-li to krabička paměti pro x, který se stane, že má hodnotu 4, 32 00:02:22,230 --> 00:02:25,980 pak máme malou krabičku paměti pro p, 33 00:02:25,980 --> 00:02:31,590 a tak p ukazuje na x, takže jsme nakreslit šipku z bodu P do x. 34 00:02:31,590 --> 00:02:40,270 Takže když říkáme, * p říkáme jít do pole, které je p. 35 00:02:40,270 --> 00:02:46,480 Hvězda je sledovat šipku a pak dělat, co chcete s tímto box tady. 36 00:02:46,480 --> 00:03:01,090 Takže můžu říct, * p = 7, a že půjde na pole, které je x, a změny, které se 7. 37 00:03:01,090 --> 00:03:13,540 Nebo bych mohl říct, int z = * p * 2; To matoucí, protože je to hvězda, hvězda. 38 00:03:13,540 --> 00:03:19,230 Ten hvězda dereferencing p, druhá hvězda je vynásobí 2. 39 00:03:19,230 --> 00:03:26,780 Všimněte si, bych mohl mít stejně dobře nahradil * p s x. 40 00:03:26,780 --> 00:03:29,430 Můžete je použít stejným způsobem. 41 00:03:29,430 --> 00:03:38,000 A pak o něco později I může mít p bod na zcela novou věc. 42 00:03:38,000 --> 00:03:42,190 Mohu jen říct, p = &z; 43 00:03:42,190 --> 00:03:44,940 Takže teď p již neodkazuje na x, ale poukazuje na z.. 44 00:03:44,940 --> 00:03:50,510 A kdykoliv jsem to * p je to stejné, jako dělá z. 45 00:03:50,510 --> 00:03:56,170 Takže užitečná věc na tom je, jakmile začneme dostat do funkcí. 46 00:03:56,170 --> 00:03:59,790 >> Je to trochu zbytečné deklarovat ukazatel, který ukazuje na něco, co 47 00:03:59,790 --> 00:04:03,140 a pak jste jen dereferencing to 48 00:04:03,140 --> 00:04:06,060 když jste mohl použít původní proměnnou začít. 49 00:04:06,060 --> 00:04:18,190 Ale když se dostanete do funkcí - tak řekněme, že máme nějakou funkci, int foo, 50 00:04:18,190 --> 00:04:32,810 který bere ukazatel a jen dělá * P = 6; 51 00:04:32,810 --> 00:04:39,990 Stejně jako jsme viděli předtím, než se swapu, můžete to udělat efektivní swap a samostatnou funkci 52 00:04:39,990 --> 00:04:45,180 tím, že jen kolem celých čísel, protože vše v C je vždy kolem hodnoty. 53 00:04:45,180 --> 00:04:48,360 I když jste kolem ukazatele jste kolem hodnoty. 54 00:04:48,360 --> 00:04:51,940 To jen tak se stane, že tyto hodnoty jsou adresy paměti. 55 00:04:51,940 --> 00:05:00,770 Takže když říkám foo (p), jsem kolem ukazatel do funkce foo 56 00:05:00,770 --> 00:05:03,910 a potom foo dělá * p = 6; 57 00:05:03,910 --> 00:05:08,600 Takže uvnitř této funkce, * p je stále odpovídá x, 58 00:05:08,600 --> 00:05:12,720 ale nemohu použít x uvnitř této funkce, protože to není rozsahem v této funkci. 59 00:05:12,720 --> 00:05:19,510 Takže * p = 6 je jediný způsob, jak mohu získat přístup k místní proměnné z jiné funkce. 60 00:05:19,510 --> 00:05:23,600 Nebo, no, ukazatele jsou jediný způsob, jak mohu získat přístup k místní proměnné z jiné funkce. 61 00:05:23,600 --> 00:05:31,600 [Student] Řekněme, že byste chtěli vrátit ukazatel. Jak přesně to děláte, že? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Vrací ukazatel jako v něco jako int y = 3; return & y? >> [Student] Jo. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Dobře. Nikdy byste neměli udělat. To je špatné. 64 00:05:48,480 --> 00:05:59,480 Myslím, že jsem viděl v těchto přednáškových snímků jsi začal vidět celý tento diagram paměti 65 00:05:59,480 --> 00:06:02,880 kde tady máte paměťovou adresu 0 66 00:06:02,880 --> 00:06:09,550 a tady máte adresu v paměti 4 koncerty nebo 2 na 32. 67 00:06:09,550 --> 00:06:15,120 Takže máš nějaké věci a nějaké věci a pak se budete muset váš stack 68 00:06:15,120 --> 00:06:21,780 a máte svůj haldy, které jste právě začal poznávat, roste. 69 00:06:21,780 --> 00:06:24,390 [Student] Není haldy nad zásobníku? 70 00:06:24,390 --> 00:06:27,760 >> Jo. Halda je na vrcholu, je to tak? >> [Student] No, dal 0 na vrcholu. 71 00:06:27,760 --> 00:06:30,320 [Student] Oh, dal 0 na vrcholu. >> [Student] Oh, dobře. 72 00:06:30,320 --> 00:06:36,060 Upozornění: Kdekoliv s CS50 budete vidět to takhle. >> [Student] Dobře. 73 00:06:36,060 --> 00:06:40,290 Je to jen, že když jste nejprve vidět stohy, 74 00:06:40,290 --> 00:06:45,000 jako když si myslíte, že stoh si myslíte, že stohování věci na vrcholu jednoho jiný. 75 00:06:45,000 --> 00:06:50,810 Takže máme tendenci otočit to asi tak stack roste jako stack normálně 76 00:06:50,810 --> 00:06:55,940 místo zásobníku visí dolů. >> [Student] Ještě ne hromady technicky rostou až příliš, i když? 77 00:06:55,940 --> 00:07:01,100 Záleží na tom, co máte na mysli tím, vyrůstat. 78 00:07:01,100 --> 00:07:04,010 Zásobník a haldy vždy rostou v opačných směrech. 79 00:07:04,010 --> 00:07:09,420 Zásobník je vždy vyrůstá v tom smyslu, že je to roste 80 00:07:09,420 --> 00:07:12,940 k vyšší paměťové adresy, a haldy roste dolů 81 00:07:12,940 --> 00:07:17,260 v tom, že je to stále k nižším adresy paměti. 82 00:07:17,260 --> 00:07:20,250 Tak, aby horní je 0 a dolní část je vysoká adresy paměti. 83 00:07:20,250 --> 00:07:26,390 Jsou oba roste, jen v protilehlých směrech. 84 00:07:26,390 --> 00:07:29,230 [Student] Jen jsem myslel, že proto, že jste řekl, že jste dal hromadu na dně 85 00:07:29,230 --> 00:07:33,640 protože se zdá více intuitivní, protože pro zásobník začít na vrcholu haldy, 86 00:07:33,640 --> 00:07:37,520 haldy je na vrcholu sebe taky, takže to je - >> Jo. 87 00:07:37,520 --> 00:07:44,960 Můžete také myslet na hromadu jako vyrůstat a větší, ale zásobník víc. 88 00:07:44,960 --> 00:07:50,280 Takže stack je ten, že jsme trochu chtít ukázat roste. 89 00:07:50,280 --> 00:07:55,390 Ale všude, kam se podíváte jinak se chystá ukázat adresu 0 nahoře 90 00:07:55,390 --> 00:07:59,590 a nejvyšší adresa paměti v dolní části, takže to je váš obvyklý pohled na paměti. 91 00:07:59,590 --> 00:08:02,100 >> Máte dotaz? 92 00:08:02,100 --> 00:08:04,270 [Student] Můžete nám říci více o hromadu? 93 00:08:04,270 --> 00:08:06,180 Jo. I k tomu se dostaneme za chvíli. 94 00:08:06,180 --> 00:08:12,220 Za prvé, jít zpátky, proč vracet & Y je špatná věc, 95 00:08:12,220 --> 00:08:18,470 na zásobníku budete mít spoustu zásobníku snímků, které reprezentují všechny funkce 96 00:08:18,470 --> 00:08:20,460 které byli povoláni. 97 00:08:20,460 --> 00:08:27,990 Takže ignorovat předchozí věci, horní část zásobníku je vždy bude hlavní funkce 98 00:08:27,990 --> 00:08:33,090 protože to je to první funkce, která je volána. 99 00:08:33,090 --> 00:08:37,130 A pak, když budete volat jinou funkci, zásobník bude růst dolů. 100 00:08:37,130 --> 00:08:41,640 Takže když ti budu říkat nějakou funkci, foo, a to má svůj vlastní zásobník rám, 101 00:08:41,640 --> 00:08:47,280 může volat nějakou funkci, bar, to dostane jeho vlastní zásobníku rám. 102 00:08:47,280 --> 00:08:49,840 A bar může být rekurzivní, a to mohl zavolat sám, 103 00:08:49,840 --> 00:08:54,150 a tak, aby druhý hovor do baru bude mít své vlastní zásobníku rám. 104 00:08:54,150 --> 00:08:58,880 A tak, co se děje v těchto stack rámy jsou všechny lokální proměnné 105 00:08:58,880 --> 00:09:03,450 a všechny argumenty funkce, které - 106 00:09:03,450 --> 00:09:08,730 Všechny věci, které jsou místně rozsahem této funkci pokračovat v těchto zásobníku rámů. 107 00:09:08,730 --> 00:09:21,520 Takže to znamená, že když jsem řekl něco jako bar je funkce, 108 00:09:21,520 --> 00:09:29,270 Jdu jen prohlásit celé číslo a vrátí ukazatel na tento integer. 109 00:09:29,270 --> 00:09:33,790 Tak kde y žijí? 110 00:09:33,790 --> 00:09:36,900 [Student] y žije v baru. >> [Bowden] Jo. 111 00:09:36,900 --> 00:09:45,010 Někde v tomto malém náměstí paměti je čtverec littler, který má y v něm. 112 00:09:45,010 --> 00:09:53,370 Když jsem se vrátit a y, vracím ukazatel na tento malý blok paměti. 113 00:09:53,370 --> 00:09:58,400 Ale pak, když funkce vrací, jeho stack frame dostane vyskočila ze zásobníku. 114 00:10:01,050 --> 00:10:03,530 A to je důvod, proč se tomu říká stack. 115 00:10:03,530 --> 00:10:06,570 Je to jako struktury zásobníku dat, pokud víte, co to je. 116 00:10:06,570 --> 00:10:11,580 Nebo dokonce jako hromada zásobníků je vždy příklad, 117 00:10:11,580 --> 00:10:16,060 Hlavní je jít na dně, pak první funkce voláte se jít na vrcholu, že 118 00:10:16,060 --> 00:10:20,400 a můžete se dostat zpět do hlavního, až se vrátíte ze všech funkcí, které byly tzv. 119 00:10:20,400 --> 00:10:22,340 , které byly umístěny na vrcholu toho. 120 00:10:22,340 --> 00:10:28,650 >> [Student] Takže pokud jste to vrátit a y, že hodnota se mohou změnit bez předchozího upozornění. 121 00:10:28,650 --> 00:10:31,290 Ano, to - >> [Student] Mohlo by to být přepsána. Jo >>. 122 00:10:31,290 --> 00:10:34,660 Je to úplně - Pokusíte-li se - 123 00:10:34,660 --> 00:10:38,040 To by také int * bar, protože se vrací ukazatel, 124 00:10:38,040 --> 00:10:41,310 tak jeho návratový typ je int *. 125 00:10:41,310 --> 00:10:46,500 Pokud se pokusíte použít návratovou hodnotu této funkce, je to nedefinované chování 126 00:10:46,500 --> 00:10:51,770 proto, že ukazatel ukazuje na špatnou vzpomínkou. >> [Student] Dobře. 127 00:10:51,770 --> 00:11:01,250 Takže co když, například, jste prohlásil int * y = malloc (sizeof (int))? 128 00:11:01,250 --> 00:11:03,740 To je lepší. Ano. 129 00:11:03,740 --> 00:11:07,730 [Student] Mluvili jsme o tom, jak když jsme přetáhnout věci do našeho koše 130 00:11:07,730 --> 00:11:11,750 oni nejsou ve skutečnosti odstraněny, jsme jen ztratit jejich ukazatele. 131 00:11:11,750 --> 00:11:15,550 Takže v tomto případě se budeme vlastně vymazat hodnotu, nebo je tam ještě v paměti? 132 00:11:15,550 --> 00:11:19,130 Z větší části, bude to ještě bude. 133 00:11:19,130 --> 00:11:24,220 Ale řekněme, že náhodou zavolat nějakou jinou funkci, Baz. 134 00:11:24,220 --> 00:11:28,990 Baz dostane svůj vlastní zásobník rám tady. 135 00:11:28,990 --> 00:11:31,470 Je to bude přepsání všech těchto věcí, 136 00:11:31,470 --> 00:11:34,180 a pak, pokud se později vyzkoušet a používat ukazatel, který jste dostali dříve, 137 00:11:34,180 --> 00:11:35,570 to nebude mít stejnou hodnotu. 138 00:11:35,570 --> 00:11:38,150 Bude to změnilo jen proto, že jste volal funkci Baz. 139 00:11:38,150 --> 00:11:43,080 [Student] Ale už nejsme, stále bychom si 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] S největší pravděpodobností, že ne. 141 00:11:44,990 --> 00:11:49,670 Ale nemůžete spolehnout na to. C jen říká, nedefinované chování. 142 00:11:49,670 --> 00:11:51,920 >> [Student] Oh, to dělá. Dobře. 143 00:11:51,920 --> 00:11:58,190 Takže když se chcete vrátit ukazatel, to je místo, kde malloc přichází v provozu. 144 00:12:00,930 --> 00:12:15,960 Píšu vlastně jen návrat malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Půjdeme přes malloc více sekundu, ale představa, že malloc je všechno vaše lokálních proměnných 146 00:12:24,050 --> 00:12:26,760 vždy jít na stack. 147 00:12:26,760 --> 00:12:31,570 Cokoliv, co se malloced pokračuje na haldě, a to navždy a vždy na haldě 148 00:12:31,570 --> 00:12:34,490 dokud je výslovně uvolnit ji. 149 00:12:34,490 --> 00:12:42,130 Takže to znamená, že když malloc něco, bude to přežít po funkce vrátí. 150 00:12:42,130 --> 00:12:46,800 [Student] Bude to přežít poté, co program se zastaví? >> Ne 151 00:12:46,800 --> 00:12:53,180 Dobře, takže to tam bude, dokud program je úplně hotový chodu. Ano >>. 152 00:12:53,180 --> 00:12:57,510 Můžeme jít přes detaily o tom, co se stane, když se program zastaví. 153 00:12:57,510 --> 00:13:02,150 Možná budete muset připomínat mě, ale to je samostatná věc úplně. 154 00:13:02,150 --> 00:13:04,190 [Student] Tak malloc vytváří ukazatel? Jo >>. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [Student] Myslím, že malloc označuje blok paměti, že ukazatel může použít. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Chci, aby diagram znovu. >> [Student] Takže tato funkce funguje, i když? 157 00:13:19,610 --> 00:13:26,430 [Student] Jo, malloc označuje blok paměti, které můžete použít, 158 00:13:26,430 --> 00:13:30,470 a pak vrátí adresu prvního bloku této paměti. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Jo. Takže, když malloc, jste chytil nějaký blok paměti 160 00:13:36,750 --> 00:13:38,260 že je v současné době v haldě. 161 00:13:38,260 --> 00:13:43,040 Pokud Halda je příliš malý, pak haldy je jen poroste, a to roste v tomto směru. 162 00:13:43,040 --> 00:13:44,650 Takže řekněme, že haldy je příliš malý. 163 00:13:44,650 --> 00:13:49,960 Pak je to o růst trochu a vrátí ukazatel na tento blok, který právě vyrostl. 164 00:13:49,960 --> 00:13:55,130 Když věci zdarma, děláš větší prostor v haldě, 165 00:13:55,130 --> 00:14:00,030 takže pak později nazvali malloc můžete znovu použít, že paměť, kterou předtím uvolněn. 166 00:14:00,030 --> 00:14:09,950 Důležité informace o malloc a free je, že vám dává úplnou kontrolu 167 00:14:09,950 --> 00:14:12,700 po celou dobu životnosti těchto paměťových bloků. 168 00:14:12,700 --> 00:14:15,420 Globální proměnné jsou vždy živý. 169 00:14:15,420 --> 00:14:18,500 Lokální proměnné jsou naživu do jejich působnosti. 170 00:14:18,500 --> 00:14:22,140 Jakmile jdete kolem ortézy kudrnaté, místní proměnné jsou mrtví. 171 00:14:22,140 --> 00:14:28,890 Malloced paměť je naživu, když chcete, aby to bylo naživu 172 00:14:28,890 --> 00:14:33,480 a pak se uvolní, když řeknete, že mohou být propuštěn. 173 00:14:33,480 --> 00:14:38,420 To jsou vlastně jen 3 druhy paměti, opravdu. 174 00:14:38,420 --> 00:14:41,840 Tam je automatická správa paměti, což je zásobník. 175 00:14:41,840 --> 00:14:43,840 Věci se dějí za vás automaticky. 176 00:14:43,840 --> 00:14:46,910 Když se řekne int x, je paměť přidělená pro int x. 177 00:14:46,910 --> 00:14:51,630 Když x dostane mimo rozsah, je paměť kultivovaný pro x. 178 00:14:51,630 --> 00:14:54,790 Pak je tu dynamická správa paměti, která je co malloc je, 179 00:14:54,790 --> 00:14:56,740 což je, když máte kontrolu. 180 00:14:56,740 --> 00:15:01,290 Můžete dynamicky rozhodnout, kdy by měly paměť a neměly by být přiděleny. 181 00:15:01,290 --> 00:15:05,050 A pak je tu statická, což prostě znamená, že to žije věčně, 182 00:15:05,050 --> 00:15:06,610 což je to, co globální proměnné. 183 00:15:06,610 --> 00:15:10,240 Jsou to jen vždy v paměti. 184 00:15:10,960 --> 00:15:12,760 >> Otázky? 185 00:15:14,490 --> 00:15:17,230 [Student] Můžete definovat blok jen pomocí složené závorky 186 00:15:17,230 --> 00:15:21,220 ale neměl by mít v případě ztráty nebo while nebo něco takového? 187 00:15:21,220 --> 00:15:29,130 Můžete definovat blok jako ve funkci, ale že má složené závorky taky. 188 00:15:29,130 --> 00:15:32,100 [Student] Takže nemůžete prostě jako náhodné dvojice složených závorek v kódu 189 00:15:32,100 --> 00:15:35,680 které mají lokální proměnné? >> Ano, můžete. 190 00:15:35,680 --> 00:15:45,900 Uvnitř int baru bychom mohli mít {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 Že to má být tady. 192 00:15:48,440 --> 00:15:52,450 Ale to kompletně definuje rozsah int y. 193 00:15:52,450 --> 00:15:57,320 Po tomto druhém rovnátka kudrnaté, můžete y nesmí být nadále používána. 194 00:15:57,910 --> 00:16:00,630 Málem jsi to nikdy neudělal, ačkoli. 195 00:16:02,940 --> 00:16:07,370 Dostat se zpátky na to, co se stane, když program skončí, 196 00:16:07,370 --> 00:16:18,760 je to něco jako rozšířený omyl / polovina lži, že dáváme, aby se jen dělat věci lépe. 197 00:16:18,760 --> 00:16:24,410 Řekneme vám, že když se alokovat paměť 198 00:16:24,410 --> 00:16:29,860 jste vyčleňují kus RAM pro dané proměnné. 199 00:16:29,860 --> 00:16:34,190 Ale ty jsi opravdu přímo dotýkat RAM někdy ve svých programech. 200 00:16:34,190 --> 00:16:37,490 Pokud si myslíte, že o tom, jak jsem kreslil - 201 00:16:37,490 --> 00:16:44,330 A skutečně, pokud si projít v GDB uvidíte to samé. 202 00:16:51,120 --> 00:16:57,590 Bez ohledu na to, kolikrát jsi spustit program nebo jaký program používáte, 203 00:16:57,590 --> 00:16:59,950 zásobník je vždycky začít - 204 00:16:59,950 --> 00:17:06,510 jste vždy uvidí proměnné kolem něčeho adresu oxbffff. 205 00:17:06,510 --> 00:17:09,470 Je to obvykle někde v této oblasti. 206 00:17:09,470 --> 00:17:18,760 Ale jak může 2 programy mohl mít ukazatele na stejné paměti? 207 00:17:20,640 --> 00:17:27,650 [Student] Tam je nějaký libovolný určení, kde je oxbfff měl být na RAM 208 00:17:27,650 --> 00:17:31,320 , které mohou být ve skutečnosti v různých místech v závislosti na tom, kdy byla volána funkce. 209 00:17:31,320 --> 00:17:35,920 Jo. Termín je virtuální paměť. 210 00:17:35,920 --> 00:17:42,250 Myšlenka je, že každý jednotlivý proces, každý program, který je spuštěn na počítači 211 00:17:42,250 --> 00:17:49,450 má vlastní - předpokládejme, že 32 bitů - zcela nezávislý adresový prostor. 212 00:17:49,450 --> 00:17:51,590 To je adresový prostor. 213 00:17:51,590 --> 00:17:56,220 Má své vlastní zcela nezávislé 4 GB k použití. 214 00:17:56,220 --> 00:18:02,220 >> Takže, pokud se dostanete 2 programy současně, tento program vidí 4 GB k sobě, 215 00:18:02,220 --> 00:18:04,870 tento program vidí 4 GB k sobě, 216 00:18:04,870 --> 00:18:07,720 a to je nemožné pro tento program dereference ukazatele 217 00:18:07,720 --> 00:18:10,920 a skončit s pamětí z tohoto programu. 218 00:18:10,920 --> 00:18:18,200 A co virtuální paměť je mapování z procesů adresového prostoru 219 00:18:18,200 --> 00:18:20,470 skutečných věcí na RAM. 220 00:18:20,470 --> 00:18:22,940 Takže je to pro váš operační systém, aby věděli, 221 00:18:22,940 --> 00:18:28,080 hej, když ten chlap dereferences ukazatel oxbfff, že ve skutečnosti znamená 222 00:18:28,080 --> 00:18:31,040 že chce RAM byte 1000, 223 00:18:31,040 --> 00:18:38,150 vzhledem k tomu, pokud tento program dereferences oxbfff, že opravdu chce RAM byte 10000. 224 00:18:38,150 --> 00:18:41,590 Mohou být libovolně daleko od sebe. 225 00:18:41,590 --> 00:18:48,730 To platí dokonce i věcí v rámci jednoho procesů adresního prostoru. 226 00:18:48,730 --> 00:18:54,770 Tak jako to vidí všechny 4 GB k sobě, ale řekněme, že - 227 00:18:54,770 --> 00:18:57,290 [Student] Má každý proces - 228 00:18:57,290 --> 00:19:01,350 Řekněme, že máte počítač pouze s 4 GB paměti RAM. 229 00:19:01,350 --> 00:19:06,430 Má každý proces vidět celé 4 GB? Ano >>. 230 00:19:06,430 --> 00:19:13,060 Ale 4 GB to vidí je lež. 231 00:19:13,060 --> 00:19:20,460 Je to prostě, že si myslí, že má všechny tyto paměti, protože neví, jiný proces existuje. 232 00:19:20,460 --> 00:19:28,140 To bude používat pouze tolik paměti, jak to vlastně potřebuje. 233 00:19:28,140 --> 00:19:32,340 Operační systém se nebude dát RAM do tohoto procesu 234 00:19:32,340 --> 00:19:35,750 jestli to nebyl použit žádný paměť celého tohoto regionu. 235 00:19:35,750 --> 00:19:39,300 Nebude to, aby to paměť pro tuto oblast. 236 00:19:39,300 --> 00:19:54,780 Ale nápad je to - já se snažím myslet na - já si nemyslím, že analogie. 237 00:19:54,780 --> 00:19:56,780 Analogie jsou tvrdé. 238 00:19:57,740 --> 00:20:02,700 Jednou z otázek, virtuální paměti nebo jedna z věcí, je to řešení 239 00:20:02,700 --> 00:20:06,810 je to, že proces by měl být zcela vědomi sebe. 240 00:20:06,810 --> 00:20:12,140 A tak si můžete zapsat libovolný program, který jen dereferences žádný ukazatel, 241 00:20:12,140 --> 00:20:19,340 Líbí stačí napsat program, který říká, že * (ox1234), 242 00:20:19,340 --> 00:20:22,890 a to je to, dereferencing adresa paměti 1234. 243 00:20:22,890 --> 00:20:28,870 >> Ale je to až do operačního systému a pak přeložit, co znamená 1234. 244 00:20:28,870 --> 00:20:33,960 Takže pokud 1234 se stane, že platné adresa paměti pro tento proces, 245 00:20:33,960 --> 00:20:38,800 jako je to na frontě, nebo tak něco, pak to vrátí hodnotu této paměťové adresy 246 00:20:38,800 --> 00:20:41,960 pokud jde o proces ví. 247 00:20:41,960 --> 00:20:47,520 Ale pokud 1234 není platná adresa, stejně jako se to stane přistát 248 00:20:47,520 --> 00:20:52,910 v nějakém malém kousku paměti zde, který je mimo zásobníku a za hromadu 249 00:20:52,910 --> 00:20:57,200 a vy jste opravdu používat, pak to je, když se dostanete věci, jako segfault chyb 250 00:20:57,200 --> 00:21:00,260 proto, že jste se dotknete paměti, že byste neměli dotýkat. 251 00:21:07,180 --> 00:21:09,340 To je také pravda - 252 00:21:09,340 --> 00:21:15,440 32-bit systém, 32 bitů znamená, že máte 32 bitů při definování adresu paměti. 253 00:21:15,440 --> 00:21:22,970 Je to důvod, proč ukazatele jsou 8 bytů, protože 32 bitů je 8 bajtů - nebo 4 bajty. 254 00:21:22,970 --> 00:21:25,250 Ukazatele jsou 4 byty. 255 00:21:25,250 --> 00:21:33,680 Takže když vidíte ukazatel, jako oxbfffff, že je - 256 00:21:33,680 --> 00:21:40,080 V jakémkoli programu stačí postavit libovolnou ukazatel, 257 00:21:40,080 --> 00:21:46,330 kdekoli od ox0 to vůl 8 f's - FFFFFFFF. 258 00:21:46,330 --> 00:21:49,180 [Student] Neříkal jsi, že jsou 4 byty? Jo >>. 259 00:21:49,180 --> 00:21:52,730 [Student] Pak každý byte bude mít - >> [Bowden] Hexadecimální. 260 00:21:52,730 --> 00:21:59,360 Hexadecimální - 5, 6, 7, 8. Takže ukazateli budete vždy vidět v šestnáctkové soustavě. 261 00:21:59,360 --> 00:22:01,710 Je to jen, jak dělíme ukazatele. 262 00:22:01,710 --> 00:22:05,240 Každé 2 číslice šestnáctkové je 1 byte. 263 00:22:05,240 --> 00:22:09,600 Takže tam to bude 8 hexadecimálních číslic pro 4 byty. 264 00:22:09,600 --> 00:22:14,190 Takže každý ukazatel na 32-bitovém systému bude 4 byty, 265 00:22:14,190 --> 00:22:18,550 což znamená, že ve vašem procesu si můžete postavit libovolného 4 bajty 266 00:22:18,550 --> 00:22:20,550 a aby ukazatel z toho, 267 00:22:20,550 --> 00:22:32,730 , což znamená, že pokud je to známo, může to řešit celý 2 až 32 bajtů paměti. 268 00:22:32,730 --> 00:22:34,760 I když to opravdu není mít přístup k, že 269 00:22:34,760 --> 00:22:40,190 i když je počítač má pouze 512 MB, si myslí, že má tolik paměti. 270 00:22:40,190 --> 00:22:44,930 A operační systém je dost chytrý na to, že to bude jen přidělí to, co skutečně potřebujete. 271 00:22:44,930 --> 00:22:49,630 To není jen tak, oh, nový proces: 4 koncerty. 272 00:22:49,630 --> 00:22:51,930 >> Jo. >> [Student] Co vůl znamená? Proč jsi to napsal? 273 00:22:51,930 --> 00:22:54,980 Je to jen symbol na hexadecimální. 274 00:22:54,980 --> 00:22:59,590 Když vidíte číslo začátek s volem, postupné věci jsou hexadecimální. 275 00:23:01,930 --> 00:23:05,760 [Student] jsi vysvětloval, co se stane, když program skončí. Ano >>. 276 00:23:05,760 --> 00:23:09,480 Co se stane, když program skončí, je operační systém 277 00:23:09,480 --> 00:23:13,600 jen vymaže mapování, že má pro tyto adresy, a to je to. 278 00:23:13,600 --> 00:23:17,770 Operační systém může nyní jen dát tu vzpomínku na jiný program používat. 279 00:23:17,770 --> 00:23:19,490 [Student] Dobře. 280 00:23:19,490 --> 00:23:24,800 Takže když budete přidělovat něco na haldě nebo zásobníku nebo globální proměnné nebo něco, 281 00:23:24,800 --> 00:23:27,010 všichni jen tak zmizet, jakmile program skončí 282 00:23:27,010 --> 00:23:32,120 protože operační systém je nyní zdarma, aby se paměť jiných procesů. 283 00:23:32,120 --> 00:23:35,150 [Student] I když tam jsou pravděpodobně stále hodnoty psané v? Jo >>. 284 00:23:35,150 --> 00:23:37,740 Hodnoty jsou pravděpodobně stále existují. 285 00:23:37,740 --> 00:23:41,570 Je to prostě, že to bude těžké dostat se na ně. 286 00:23:41,570 --> 00:23:45,230 Je to mnohem těžší dostat se na ně, než je dostat se na smazaného souboru 287 00:23:45,230 --> 00:23:51,450 protože smazaný soubor druh sedí tam po dlouhou dobu, a pevný disk je mnohem větší. 288 00:23:51,450 --> 00:23:54,120 Takže to bude přepsat různé části paměti 289 00:23:54,120 --> 00:23:58,640 před tím, než se stane přepsat kus paměti, že soubor používá k být. 290 00:23:58,640 --> 00:24:04,520 Ale hlavní paměti, RAM, můžete procházet mnohem rychleji, 291 00:24:04,520 --> 00:24:08,040 takže to bude velmi rychle být přepsány. 292 00:24:10,300 --> 00:24:13,340 Otázky týkající se této nebo cokoliv jiného? 293 00:24:13,340 --> 00:24:16,130 [Student] Mám otázky týkající se jiného tématu. Dobře >>. 294 00:24:16,130 --> 00:24:19,060 Má někdo nějaké dotazy na toto téma? 295 00:24:20,170 --> 00:24:23,120 >> Dobře. Jiné téma. >> [Student] Dobře. 296 00:24:23,120 --> 00:24:26,550 Chtěl jsem přes některé z praktických testů, 297 00:24:26,550 --> 00:24:30,480 a v jednom z nich se mluvilo o sizeof 298 00:24:30,480 --> 00:24:35,630 a hodnota, která se vrací, nebo různé typy proměnných. Ano >>. 299 00:24:35,630 --> 00:24:45,060 A řekl, že oba int a dlouho obě vrátit 4, takže oba jsou délce 4 bajty. 300 00:24:45,060 --> 00:24:48,070 Je nějaký rozdíl mezi int a dlouhé, nebo je to totéž? 301 00:24:48,070 --> 00:24:50,380 Ano, tam je rozdíl. 302 00:24:50,380 --> 00:24:52,960 C standard - 303 00:24:52,960 --> 00:24:54,950 Já jsem asi jít zkazit. 304 00:24:54,950 --> 00:24:58,800 C Norma je přesně to, co C je oficiální dokumentace C. 305 00:24:58,800 --> 00:25:00,340 To je to, co říká. 306 00:25:00,340 --> 00:25:08,650 Takže C standard jen říká, že char bude navždy a vždy 1 bajt. 307 00:25:10,470 --> 00:25:19,040 Všechno po tom - krátký, je vždy jen definován jako větší než nebo rovno znak. 308 00:25:19,040 --> 00:25:23,010 Toto by mohlo být přísně větší než, ale není pozitivní. 309 00:25:23,010 --> 00:25:31,940 Int je právě definována jako větší než nebo rovno krátký. 310 00:25:31,940 --> 00:25:36,210 A dlouhá je právě definoval jako větší nebo rovna int. 311 00:25:36,210 --> 00:25:41,600 A long long je větší než nebo rovno dlouho. 312 00:25:41,600 --> 00:25:46,610 Takže jediné, co C standard definuje je relativní uspořádání všeho. 313 00:25:46,610 --> 00:25:54,880 Skutečná velikost paměti, že věci zabírají je obecně až po realizaci, 314 00:25:54,880 --> 00:25:57,640 ale je to docela dobře definována v tomto bodě. >> [Student] Dobře. 315 00:25:57,640 --> 00:26:02,490 Takže šortky jsou téměř vždy bude 2 bytů. 316 00:26:04,920 --> 00:26:09,950 Ints jsou téměř vždy bude 4 byty. 317 00:26:12,070 --> 00:26:15,340 Dlouhé dlouhé výrobky jsou téměř vždy bude 8 bytů. 318 00:26:17,990 --> 00:26:23,160 A touží, to záleží na tom, zda používáte 32-bit nebo 64-bit systém. 319 00:26:23,160 --> 00:26:27,450 Tak dlouho bude odpovídat typu systému. 320 00:26:27,450 --> 00:26:31,920 Pokud používáte 32-bitový systém jako Appliance, že to bude 4 byty. 321 00:26:34,530 --> 00:26:42,570 Pokud používáte 64-bit jako hodně novějších počítačích, to bude 8 bytů. 322 00:26:42,570 --> 00:26:45,230 >> Ints jsou téměř vždy 4 bytů v tomto bodě. 323 00:26:45,230 --> 00:26:47,140 Dlouhé dlouhé výrobky jsou téměř vždy 8 bytů. 324 00:26:47,140 --> 00:26:50,300 V minulosti, ints používán pouze 2 byty. 325 00:26:50,300 --> 00:26:56,840 Ale si všimnout, že tato zcela splňuje všechny tyto vztahů větší než a rovno. 326 00:26:56,840 --> 00:27:01,280 Tak dlouho se dokonale dovoleno mít stejnou velikost jako celé číslo, 327 00:27:01,280 --> 00:27:04,030 a je to také mohli být stejné velikosti jako long long. 328 00:27:04,030 --> 00:27:11,070 A to jen tak náhodou, že v 99,999% systémů, se bude rovnat 329 00:27:11,070 --> 00:27:15,800 buď int nebo long long. Záleží jen na 32-bit nebo 64-bit. >> [Student] Dobře. 330 00:27:15,800 --> 00:27:24,600 V plave, jak je desetinné místo určené v podmínkách kousků? 331 00:27:24,600 --> 00:27:27,160 Stejně jako jako binární? Jo >>. 332 00:27:27,160 --> 00:27:30,570 Nemusíte vědět, že pro CS50. 333 00:27:30,570 --> 00:27:32,960 Nemusíte ani dozvědět, že v 61. 334 00:27:32,960 --> 00:27:37,350 Nemáte naučit, že skutečně v každém předmětu. 335 00:27:37,350 --> 00:27:42,740 Je to jen charakter. 336 00:27:42,740 --> 00:27:45,440 Zapomněl jsem přesně bit příděly. 337 00:27:45,440 --> 00:27:53,380 Myšlenka s plovoucí desetinnou čárkou, je, že můžete alokovat určitý počet bitů reprezentovat - 338 00:27:53,380 --> 00:27:56,550 V podstatě vše, co je ve vědecké notaci. 339 00:27:56,550 --> 00:28:05,600 Takže si přidělit určitý počet bitů k reprezentaci čísla sám, jako 1,2345. 340 00:28:05,600 --> 00:28:10,200 Nikdy představovat číslo s více číslicemi, než 5. 341 00:28:12,200 --> 00:28:26,300 Pak se také přidělit určitý počet bitů, takže má tendenci být jako 342 00:28:26,300 --> 00:28:32,810 můžete jít jen do určité číslo, tak je největší exponent můžete mít, 343 00:28:32,810 --> 00:28:36,190 a můžete jít jen do určité exponentem, 344 00:28:36,190 --> 00:28:38,770 rád, že je to nejmenší exponent můžete mít. 345 00:28:38,770 --> 00:28:44,410 >> Nevzpomínám si přesně způsob, jakým bity jsou určeny pro všechny z těchto hodnot, 346 00:28:44,410 --> 00:28:47,940 ale určitý počet bitů jsou věnovány 1,2345, 347 00:28:47,940 --> 00:28:50,930 další určitý počet bitů jsou určeny pro exponent, 348 00:28:50,930 --> 00:28:55,670 a je to jen možné reprezentovat exponentu o určité velikosti. 349 00:28:55,670 --> 00:29:01,100 [Student] A double? Je to jako extra dlouhou plováku? Jo >>. 350 00:29:01,100 --> 00:29:07,940 Je to totéž jako float, s výjimkou teď používáte 8 bajtů místo 4 bajty. 351 00:29:07,940 --> 00:29:11,960 Nyní budete moci používat 9 číslic nebo 10 číslic, 352 00:29:11,960 --> 00:29:16,630 a to bude moci jít do 300 místo 100. >> [Student] Dobře. 353 00:29:16,630 --> 00:29:21,550 A plováky jsou také 4 byty. Ano >>. 354 00:29:21,550 --> 00:29:27,520 No, opět, pravděpodobně záleží celkově o obecné provádění, 355 00:29:27,520 --> 00:29:30,610 ale plováky jsou 4 byty, dvoulůžkové jsou 8. 356 00:29:30,610 --> 00:29:33,440 Zdvojnásobí se nazývají dvojitá, protože jsou dvakrát velikost plováky. 357 00:29:33,440 --> 00:29:38,380 [Student] Dobře. A jsou tam double čtyřhře? >> Nejsou. 358 00:29:38,380 --> 00:29:43,660 Myslím, že - >> [Student] Jako dlouhých touží? Jo >>. To si nemyslím. Ano. 359 00:29:43,660 --> 00:29:45,950 [Student] Na loňské testu byla otázka o hlavní funkci 360 00:29:45,950 --> 00:29:49,490 musel být součástí vašeho programu. 361 00:29:49,490 --> 00:29:52,310 Odpověď byla, že to nemusí být součástí vašeho programu. 362 00:29:52,310 --> 00:29:55,100 V jaké situaci? To je to, co jsem viděl. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Zdá se, že - >> [Student] Jakou situaci? 364 00:29:59,090 --> 00:30:02,880 Máte problém? >> [Student] Jo, můžu rozhodně vytáhněte ji. 365 00:30:02,880 --> 00:30:07,910 To nemusí být, technicky, ale v podstatě to bude. 366 00:30:07,910 --> 00:30:10,030 [Student] Viděl jsem jeden na jiné roce. 367 00:30:10,030 --> 00:30:16,220 Bylo to jako True nebo False: platná - >> Oh, c soubor.? 368 00:30:16,220 --> 00:30:18,790 . [Student] Každý c soubor musí mít - [jak řečeno najednou - nesrozumitelný] 369 00:30:18,790 --> 00:30:21,120 Dobře. Tak to je samostatná. 370 00:30:21,120 --> 00:30:26,800 >> . C soubor pouze musí obsahovat funkce. 371 00:30:26,800 --> 00:30:32,400 Můžete sestavit soubor do strojového kódu, binární, bez ohledu, 372 00:30:32,400 --> 00:30:36,620 aniž by bylo spustitelný ještě. 373 00:30:36,620 --> 00:30:39,420 Platný spustitelný, musí mít hlavní funkci. 374 00:30:39,420 --> 00:30:45,460 Můžete napsat 100 funkce v 1 souboru, ale ne hlavní 375 00:30:45,460 --> 00:30:48,800 a pak zkompilovat, které se na binární, 376 00:30:48,800 --> 00:30:54,460 pak můžete napsat jiný soubor, který má pouze hlavní, ale to vyžaduje spoustu z těchto funkcí 377 00:30:54,460 --> 00:30:56,720 v tomto binární soubor sem. 378 00:30:56,720 --> 00:31:01,240 A tak, když děláš spustitelný soubor, který je co linker dělá 379 00:31:01,240 --> 00:31:05,960 je to kombinuje tyto 2 binární soubory do spustitelného. 380 00:31:05,960 --> 00:31:11,400 Tak. C soubor nemusí mít hlavní funkci vůbec. 381 00:31:11,400 --> 00:31:19,220 A na velké bází kódu uvidíte tisíce. Soubory C a 1 hlavního souboru. 382 00:31:23,960 --> 00:31:26,110 Další otázky? 383 00:31:29,310 --> 00:31:31,940 [Student] Tam byl další otázka. 384 00:31:31,940 --> 00:31:36,710 To řekl, aby je kompilátor. Pravda nebo lež? 385 00:31:36,710 --> 00:31:42,030 A odpověď byla falešná, a pochopil jsem, proč to není jako Clang. 386 00:31:42,030 --> 00:31:44,770 Ale co říkáme, aby, pokud to není? 387 00:31:44,770 --> 00:31:49,990 Udělejte je v podstatě jen - vidím přesně to, co říká. 388 00:31:49,990 --> 00:31:52,410 Ale to jen spouští příkazy. 389 00:31:53,650 --> 00:31:55,650 Udělejte. 390 00:31:58,240 --> 00:32:00,870 Mohu vytáhnout toto nahoru. Jo. 391 00:32:10,110 --> 00:32:13,180 Oh, yeah. Zkontrolujte také to dělá. 392 00:32:13,180 --> 00:32:17,170 To říká, že účelem utilitou make je určit automaticky 393 00:32:17,170 --> 00:32:19,610 které části velkého programu se musí prekompilovat 394 00:32:19,610 --> 00:32:22,350 a vydávat příkazy k překompilovat. 395 00:32:22,350 --> 00:32:27,690 Můžete provést make soubory, které jsou naprosto obrovská. 396 00:32:27,690 --> 00:32:33,210 Udělejte dívá na časová razítka souborů a jak jsme řekli dříve, 397 00:32:33,210 --> 00:32:36,930 můžete sestavit jednotlivé soubory dolů, a není to až se dostanete do linker 398 00:32:36,930 --> 00:32:39,270 že jsou dohromady do spustitelného souboru. 399 00:32:39,270 --> 00:32:43,810 Takže pokud máte 10 různých souborů a provést změnu na 1 z nich, 400 00:32:43,810 --> 00:32:47,870 pak to, co udělat, je dělat, je jen překompilovat, že 1 soubor 401 00:32:47,870 --> 00:32:50,640 a potom znovu všechno dohromady. 402 00:32:50,640 --> 00:32:53,020 Ale je to mnohem hloupější než to. 403 00:32:53,020 --> 00:32:55,690 Je na vás, abyste kompletně definovat, že je to to, co by měla dělat. 404 00:32:55,690 --> 00:32:59,560 Je standardně má schopnost rozpoznat toto časové razítko věci, 405 00:32:59,560 --> 00:33:03,220 ale můžete napsat make soubor nic dělat. 406 00:33:03,220 --> 00:33:09,150 Můžete napsat, aby soubor tak, že když zadáte, aby to jen cd do jiného adresáře. 407 00:33:09,150 --> 00:33:15,560 Byla jsem frustrovaná, protože jsem připínáček vše uvnitř mého spotřebiče 408 00:33:15,560 --> 00:33:21,740 a pak jsem zobrazit PDF z Mac. 409 00:33:21,740 --> 00:33:30,720 >> Tak jsem jít do Finder a můžu si jít, Připojit k serveru, 410 00:33:30,720 --> 00:33:36,950 a server se připojit k je můj spotřebiče, a pak jsem otevřít PDF 411 00:33:36,950 --> 00:33:40,190 , který se sestavuje LaTeXu. 412 00:33:40,190 --> 00:33:49,320 Ale já jsem začínal být frustrovaný, protože pokaždé jsem potřeboval obnovit PDF, 413 00:33:49,320 --> 00:33:53,900 Musel jsem zkopírovat jej do konkrétního adresáře, který by mohl získat přístup 414 00:33:53,900 --> 00:33:57,710 a to bylo stále nepříjemné. 415 00:33:57,710 --> 00:34:02,650 Takže místo toho jsem napsal make soubor, který budete muset definovat, jak to dělá věci. 416 00:34:02,650 --> 00:34:06,130 Jak uděláte v tomto je PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Stejně jako jakoukoliv jinou značku souboru - nebo jsem asi jste neviděli Make soubory, 418 00:34:10,090 --> 00:34:13,510 ale máme v Appliance globální make soubor, který právě říká, 419 00:34:13,510 --> 00:34:16,679 Pokud se kompilace soubor C, použijte řinčet. 420 00:34:16,679 --> 00:34:20,960 A tak tady v mém souboru, který na značku dělám já říkám, 421 00:34:20,960 --> 00:34:25,020 Tento soubor budete chtít kompilovat PDF LaTeXu. 422 00:34:25,020 --> 00:34:27,889 A tak je to PDF LaTeX, že to dělá kompilace. 423 00:34:27,889 --> 00:34:31,880 Udělejte není kompilace. Je to prostě běží tyto příkazy v pořadí jsem uvedl. 424 00:34:31,880 --> 00:34:36,110 Tak to běží PDF LaTeX, zkopíruje ho do adresáře chci to být zkopírovány, 425 00:34:36,110 --> 00:34:38,270 to cd do adresáře a dělá jiné věci, 426 00:34:38,270 --> 00:34:42,380 ale vše, co dělá, je uznat, když soubor změn, 427 00:34:42,380 --> 00:34:45,489 a pokud změní, pak to bude spusťte příkazy, které to má spustit 428 00:34:45,489 --> 00:34:48,760 když se soubor změní. >> [Student] Dobře. 429 00:34:50,510 --> 00:34:54,420 Já nevím, kde se globální Udělejte soubory jsou pro mě podívat se na to. 430 00:34:57,210 --> 00:35:04,290 Další otázky? Něco z minulosti kvízy? Jakékoliv ukazatel věci? 431 00:35:06,200 --> 00:35:08,730 Existují jemné věci, s ukazateli, jako je - 432 00:35:08,730 --> 00:35:10,220 Nebudu mít možnost najít kvízovou otázku na to - 433 00:35:10,220 --> 00:35:16,250 ale stejně jako tyhle věci. 434 00:35:19,680 --> 00:35:24,060 Ujistěte se, že jste pochopili, že když řeknu, int * x * y - 435 00:35:24,890 --> 00:35:28,130 To není zrovna nic tady, myslím. 436 00:35:28,130 --> 00:35:32,140 Ale jako * x * y, které jsou 2 proměnné, které jsou ve frontě. 437 00:35:32,140 --> 00:35:37,220 Když řeknu, že x = malloc (sizeof (int)), x je stále variabilní na zásobníku, 438 00:35:37,220 --> 00:35:41,180 malloc je nějaký blok nad v haldě, a my máme x bod do haldy. 439 00:35:41,180 --> 00:35:43,900 >> Takže něco na zásobníku ukazuje na hromadu. 440 00:35:43,900 --> 00:35:48,100 Kdykoli budete malloc něco, jste nevyhnutelně uložením uvnitř ukazatel. 441 00:35:48,100 --> 00:35:55,940 Tak to je ukazatel na zásobníku, je malloced blok na haldě. 442 00:35:55,940 --> 00:36:01,240 Mnoho lidí si zmatený a říci int * x = malloc, x je na hromadu. 443 00:36:01,240 --> 00:36:04,100 Ne, co x poukazuje, je na haldě. 444 00:36:04,100 --> 00:36:08,540 x sám je na stacku, pokud z nějakého důvodu jste x být globální proměnná, 445 00:36:08,540 --> 00:36:11,960 v takovém případě se stane, že je v jiném regionu paměti. 446 00:36:13,450 --> 00:36:20,820 Takže sledování, tyto krabice a šipka diagramy jsou docela běžné, že kvíz. 447 00:36:20,820 --> 00:36:25,740 Nebo, pokud to není na kvíz 0, bude na testu 1. 448 00:36:27,570 --> 00:36:31,940 Měli byste vědět, všechny z nich, podle kroků v sestavování 449 00:36:31,940 --> 00:36:35,740 protože jste museli odpovídat na otázky týkající se těch. Ano. 450 00:36:35,740 --> 00:36:38,940 [Student] Mohli bychom vyrazit přes tyto kroky - >> Jasně. 451 00:36:48,340 --> 00:36:58,640 Před kroků a sestavování jsme předzpracování, 452 00:36:58,640 --> 00:37:16,750 sestavování, montáž a propojení. 453 00:37:16,750 --> 00:37:21,480 Předzpracování. Co to má dělat? 454 00:37:29,720 --> 00:37:32,290 Je to nejjednodušší krok - dobře, ne jako - 455 00:37:32,290 --> 00:37:35,770 to neznamená, že by mělo být zřejmé, ale je to nejjednodušší krok. 456 00:37:35,770 --> 00:37:38,410 Vy mohly provádět to sami. Jo. 457 00:37:38,410 --> 00:37:43,410 [Student] Vezmi si, co máte ve vaší zahrnuje takhle, a to kopíruje a pak také definuje. 458 00:37:43,410 --> 00:37:49,250 Vypadá to na věci jako # include a # define, 459 00:37:49,250 --> 00:37:53,800 a to jen kopie a pasty, co skutečně znamenají. 460 00:37:53,800 --> 00:37:59,240 Takže když říkáte # include cs50.h, preprocesor je kopírování a vkládání cs50.h 461 00:37:59,240 --> 00:38:01,030 do tohoto řádku. 462 00:38:01,030 --> 00:38:06,640 Když se řekne # define x za 4, preprocesor prochází celý program 463 00:38:06,640 --> 00:38:10,400 a nahrazuje všechny výskyty x s 4. 464 00:38:10,400 --> 00:38:17,530 Takže preprocesor má platnou C soubor a výstupy platný C soubor 465 00:38:17,530 --> 00:38:20,300 kde věci byly zkopírovat a vložit. 466 00:38:20,300 --> 00:38:24,230 Takže teď kompilaci. Co to má dělat? 467 00:38:25,940 --> 00:38:28,210 [Student] To jde z C na binární. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] To není jet celou cestu na binární. 469 00:38:30,970 --> 00:38:34,220 [Student] do strojového kódu a pak? >> To není strojový kód. 470 00:38:34,220 --> 00:38:35,700 [Student] shromáždění? >> Shromáždění. 471 00:38:35,700 --> 00:38:38,890 Jde to shromáždění, než přejde celou cestu ke kódu C, 472 00:38:38,890 --> 00:38:45,010 a většina jazyků něco takového. 473 00:38:47,740 --> 00:38:50,590 Vybrat jakýkoliv vysoké úrovni jazyka, a pokud budete kompilovat, 474 00:38:50,590 --> 00:38:52,390 je pravděpodobné, sestavit v krocích. 475 00:38:52,390 --> 00:38:58,140 Nejprve to bude kompilovat Python do C, pak to bude kompilovat C do shromáždění, 476 00:38:58,140 --> 00:39:01,600 a pak shromáždění se chystá přeloženy do binární. 477 00:39:01,600 --> 00:39:07,800 Takže kompilace bude, aby ji z C na shromáždění. 478 00:39:07,800 --> 00:39:12,130 Slovo sestavování obvykle znamená uvést jej na vyšší úrovni 479 00:39:12,130 --> 00:39:14,340 na nižší úrovni programovacího jazyka. 480 00:39:14,340 --> 00:39:19,190 Tak to je jen krok při sestavování, kde můžete začít s high-úrovni jazyka 481 00:39:19,190 --> 00:39:23,270 a skončí v low-level jazyk, a to je důvod, proč je krok nazývá kompilace. 482 00:39:25,280 --> 00:39:33,370 [Student] Během sestavování, řekněme, že jste udělali # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Bude kompilátor překompilovat cs50.h, stejně jako funkcí, které jsou tam, 484 00:39:42,190 --> 00:39:45,280 a převést do assembleru stejně, 485 00:39:45,280 --> 00:39:50,830 nebo to bude zkopírovat a vložit něco, co bylo pre-shromáždění? 486 00:39:50,830 --> 00:39:56,910 cs50.h bude do značné míry nikdy skončit ve shromáždění. 487 00:39:59,740 --> 00:40:03,680 Věci jako funkce prototypů a věci jsou jen pro vás být opatrní. 488 00:40:03,680 --> 00:40:09,270 To zaručuje, že kompilátor můžete zkontrolovat věci, jako jste volání funkcí 489 00:40:09,270 --> 00:40:12,910 s právem návratové typy a správné argumenty a tak. 490 00:40:12,910 --> 00:40:18,350 >> Takže cs50.h bude předzpracovány do souboru, a pak, když je to kompilaci 491 00:40:18,350 --> 00:40:22,310 je to v podstatě vyhodit po dbá na to, aby vše, co je nazýváno správně. 492 00:40:22,310 --> 00:40:29,410 Ale funkce definované v CS50 knihovně, které jsou oddělené od cs50.h, 493 00:40:29,410 --> 00:40:33,610 ti nebudou samostatně sestaven. 494 00:40:33,610 --> 00:40:37,270 To bude skutečně sestoupí v propojení kroku, takže k tomu se dostaneme za chvíli. 495 00:40:37,270 --> 00:40:40,100 Ale nejprve, co je montáž? 496 00:40:41,850 --> 00:40:44,500 [Student] Montáž na binární? Jo >>. 497 00:40:46,300 --> 00:40:48,190 Sestavení. 498 00:40:48,190 --> 00:40:54,710 Nechceme říkat, že sestavování, protože shromáždění je do značné míry čisté překlad binární. 499 00:40:54,710 --> 00:41:00,230 Tam je velmi málo logiku jít od shromáždění na binární. 500 00:41:00,230 --> 00:41:03,180 Je to jako hledat v tabulce, oh, máme tento návod; 501 00:41:03,180 --> 00:41:06,290 která odpovídá binární 01110. 502 00:41:10,200 --> 00:41:15,230 A tak se soubory, které montáž obecně výstupy jsou. O soubory. 503 00:41:15,230 --> 00:41:19,020 A o. Soubory jsou to, co jsme říkali dříve, 504 00:41:19,020 --> 00:41:21,570 Jak soubor nemusí mít hlavní funkci. 505 00:41:21,570 --> 00:41:27,640 Každý soubor může být sestaven až do. Souboru ° tak dlouho, jak je to platný C souboru. 506 00:41:27,640 --> 00:41:30,300 To může být sestaven do. O.. 507 00:41:30,300 --> 00:41:43,030 Nyní, propojení je, co vlastně přináší spoustu. O soubory a přináší jim spustitelný. 508 00:41:43,030 --> 00:41:51,110 A tak to, co dělá, je linkování můžete myslet na CS50 knihovny jako. Soubor °. 509 00:41:51,110 --> 00:41:56,980 Je to již zkompilovaný binární soubor. 510 00:41:56,980 --> 00:42:03,530 A tak při kompilaci souboru, váš hello.c, který volá GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c dostane sestavují do hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o je nyní v binárním formátu. 513 00:42:08,910 --> 00:42:12,830 Používá GetString, takže je třeba přejít na cs50.o, 514 00:42:12,830 --> 00:42:16,390 a linker smooshes dohromady a zkopíruje GetString do tohoto souboru 515 00:42:16,390 --> 00:42:20,640 a přichází s spustitelný soubor, který má všechny funkce, které potřebuje. 516 00:42:20,640 --> 00:42:32,620 Takže cs50.o není vlastně O soubor, ale je to dost blízko, že není žádný podstatný rozdíl. 517 00:42:32,620 --> 00:42:36,880 Takže propojení právě přináší spoustu souborů dohromady 518 00:42:36,880 --> 00:42:41,390 že samostatně obsahují všechny funkce je potřeba použít 519 00:42:41,390 --> 00:42:46,120 a vytváří spustitelný soubor, který bude skutečně spustit. 520 00:42:48,420 --> 00:42:50,780 >> A tak to také to, co jsme říkali před 521 00:42:50,780 --> 00:42:55,970 kde můžete mít 1000. c soubory, kompilovat je všechny. o soubory, 522 00:42:55,970 --> 00:43:00,040 která bude pravděpodobně chvíli trvat, pak změníte 1. c. souboru. 523 00:43:00,040 --> 00:43:05,480 Jediné, co potřebujete překompilovat, že 1. C soubor a potom znovu všechno ostatní, 524 00:43:05,480 --> 00:43:07,690 odkaz všechno dohromady. 525 00:43:09,580 --> 00:43:11,430 [Student] Když jsme propojování píšeme lcs50? 526 00:43:11,430 --> 00:43:20,510 Jo, tak lcs50. Ta vlajka signály linker, který by měl být spojující v této knihovně. 527 00:43:26,680 --> 00:43:28,910 Otázky? 528 00:43:41,310 --> 00:43:46,860 Už jsme přešli binární jiné než ty, které 5 sekund na první přednášce? 529 00:43:50,130 --> 00:43:53,010 To si nemyslím. 530 00:43:55,530 --> 00:43:58,820 Měli byste vědět, všechny velké Os, že jsme pryč přes, 531 00:43:58,820 --> 00:44:02,670 a vy byste měli být schopni, kdybychom vám dal funkci, 532 00:44:02,670 --> 00:44:09,410 měli byste být schopni říct, že je to velký O, zhruba. Nebo dobře, velký O je drsný. 533 00:44:09,410 --> 00:44:15,300 Takže pokud jste vidět vnořené cykly for smyčkování přes stejný počet věcí, 534 00:44:15,300 --> 00:44:22,260 jako int i, i > [Student] n na druhou. >> To bývá n na druhou. 535 00:44:22,260 --> 00:44:25,280 Pokud jste triple vnořené, to inklinuje být n cubed. 536 00:44:25,280 --> 00:44:29,330 Takže tyhle věci byste měli být schopni poukázat okamžitě. 537 00:44:29,330 --> 00:44:33,890 Musíte vědět, vložení druh bubliny a řazení a sloučit druh a všechny z nich. 538 00:44:33,890 --> 00:44:41,420 Je to snazší pochopit, proč jsou ty, n na druhou a n log n a všechny, které 539 00:44:41,420 --> 00:44:47,810 protože si myslím, že byl na testu jeden rok, pokud jsme v podstatě vám dal 540 00:44:47,810 --> 00:44:55,050 provádění bublinkové druhu a řekl: "Co je doba chodu této funkce?" 541 00:44:55,050 --> 00:45:01,020 Takže pokud jste uznat, že jako bubliny řadit, pak můžete okamžitě říci, n na druhou. 542 00:45:01,020 --> 00:45:05,470 Ale pokud jste na něj jen podívají, vy ani nemusíte uvědomit, že je to bublina druhu; 543 00:45:05,470 --> 00:45:08,990 stačí říct, je to dělá tohle a tohle. Toto je n na druhou. 544 00:45:12,350 --> 00:45:14,710 [Student] Existují nějaké těžké příklady můžete přijít s, 545 00:45:14,710 --> 00:45:20,370 jako podobné myšlenky přijít? 546 00:45:20,370 --> 00:45:24,450 >> Nemyslím si, že bychom vám žádné nepříjemné příklady. 547 00:45:24,450 --> 00:45:30,180 Bublina sort věc je asi tak těžké, jak bychom jít, 548 00:45:30,180 --> 00:45:36,280 a dokonce i to, že tak dlouho, jak jste pochopili, že jste iterace pole 549 00:45:36,280 --> 00:45:41,670 pro každý prvek v poli, který se bude něco, co se n na druhou. 550 00:45:45,370 --> 00:45:49,940 Existují obecné otázky, jako tady máme - Oh. 551 00:45:55,290 --> 00:45:58,530 Jen druhý den, Doug tvrdil, "jsem vymyslel algoritmus, který je možné třídit pole 552 00:45:58,530 --> 00:46:01,780 "Zn čísel v O (log n) čas!" 553 00:46:01,780 --> 00:46:04,900 Tak jak můžeme vědět, že to není možné? 554 00:46:04,900 --> 00:46:08,850 [Neslyšitelné Student odpověď] >> Jo. 555 00:46:08,850 --> 00:46:13,710 Přinejmenším, budete muset dotknout každý prvek v poli, 556 00:46:13,710 --> 00:46:16,210 takže je možné třídit pole - 557 00:46:16,210 --> 00:46:20,850 Pokud je vše v pořádku netříděného, ​​pak budete dotýkat všechno v poli, 558 00:46:20,850 --> 00:46:25,320 takže je možné to udělat za méně než O n. 559 00:46:27,430 --> 00:46:30,340 [Student] Ukázal jsi nám, že příklad, že jsou schopni to udělat v O n 560 00:46:30,340 --> 00:46:33,920 pokud používáte velké množství paměti. Jo >>. 561 00:46:33,920 --> 00:46:37,970 A to je - já zapomněl, co to je - je to počítání druh? 562 00:46:47,360 --> 00:46:51,330 Hmm. To je celé číslo třídění algoritmus. 563 00:46:59,850 --> 00:47:05,100 Hledal jsem zvláštní jména pro to, že jsem si nemohl vzpomenout minulý týden. 564 00:47:05,100 --> 00:47:13,000 Jo. Jedná se o typy druhů, které mohou docílit věci ve velkém O n. 565 00:47:13,000 --> 00:47:18,430 Ale existují omezení, jako je možné použít pouze celá čísla do určité číslo. 566 00:47:20,870 --> 00:47:24,560 Plus, pokud se snažíte vyřešit něco to je - 567 00:47:24,560 --> 00:47:30,750 Pokud váš pole je 012, -12, 151, 4000000, 568 00:47:30,750 --> 00:47:35,120 pak, že jeden prvek bude zcela zničit celý třídění. 569 00:47:42,060 --> 00:47:44,030 >> Otázky? 570 00:47:49,480 --> 00:47:58,870 [Student] Pokud máte rekurzivní funkci, a to jen dělá rekurzivní volání 571 00:47:58,870 --> 00:48:02,230 v rámci return, to je ocas rekurzivní, 572 00:48:02,230 --> 00:48:07,360 a tak by nebylo využívají více paměti za běhu 573 00:48:07,360 --> 00:48:12,550 , nebo by alespoň používat srovnatelné paměti jako opakující se řešení? 574 00:48:12,550 --> 00:48:14,530 [Bowden] Ano. 575 00:48:14,530 --> 00:48:19,840 Bylo by pravděpodobně poněkud pomalejší, ale ne tak docela. 576 00:48:19,840 --> 00:48:23,290 Ocas rekurzivní je docela dobrý. 577 00:48:23,290 --> 00:48:32,640 Se znovu podíváme stack snímků, řekněme, že máme hlavní 578 00:48:32,640 --> 00:48:42,920 a máme int bar (int x), nebo tak něco. 579 00:48:42,920 --> 00:48:52,310 To není dokonalý rekurzivní funkce, ale návrat bar (x - 1). 580 00:48:52,310 --> 00:48:57,620 Tak samozřejmě, tohle je vadný. Musíte základní případy a tak. 581 00:48:57,620 --> 00:49:00,360 Ale myšlenka je, že toto je ocas rekurzivní, 582 00:49:00,360 --> 00:49:06,020 což znamená, že když hlavní hovory bar to dostane jeho stack frame. 583 00:49:09,550 --> 00:49:12,440 V tomto zásobníku rámu to bude málo blok paměti 584 00:49:12,440 --> 00:49:17,490 která odpovídá jeho argument x. 585 00:49:17,490 --> 00:49:25,840 A tak řekněme, že hlavní stane volat bar (100); 586 00:49:25,840 --> 00:49:30,050 Takže x bude začít jako 100. 587 00:49:30,050 --> 00:49:35,660 Pokud kompilátor uznává, že je to ocas rekurzivní funkce, 588 00:49:35,660 --> 00:49:38,540 pak, když bar dělá jeho rekurzivní volání bar, 589 00:49:38,540 --> 00:49:45,490 namísto toho, aby nový zásobník rám, který je místo, kde zásobník začne růst do značné míry, 590 00:49:45,490 --> 00:49:48,220 nakonec to bude probíhat do haldy a pak dostanete segfault chyb 591 00:49:48,220 --> 00:49:51,590 protože paměť začíná srážet. 592 00:49:51,590 --> 00:49:54,830 >> Takže místo toho, aby svůj vlastní zásobník rám, může si uvědomit, 593 00:49:54,830 --> 00:49:59,080 hej, já nikdy muset vrátit k tomuto rámce fronty, 594 00:49:59,080 --> 00:50:08,040 takže místo toho jsem si jen vyměnit tento argument s 99 a pak začít bar po celém těle. 595 00:50:08,040 --> 00:50:11,810 A pak to bude dělat to znovu a dosáhnou návratu bar (x - 1), 596 00:50:11,810 --> 00:50:17,320 a namísto toho, aby nový rámec fronty, bude to jen nahrazení současné argument s 98 597 00:50:17,320 --> 00:50:20,740 a pak skočit zpět na začátku baru. 598 00:50:23,860 --> 00:50:30,430 Tyto operace, které je nahradí hodnotu 1 na zásobníku a skákání zpět na začátek, 599 00:50:30,430 --> 00:50:32,430 jsou docela účinné. 600 00:50:32,430 --> 00:50:41,500 Takže je nejen to samé využití paměti jako samostatná funkce, která je interaktivní 601 00:50:41,500 --> 00:50:45,390 proto, že jste pouze pomocí 1 zásobníku frame, ale nejste utrpení nevýhody 602 00:50:45,390 --> 00:50:47,240 mít volání funkcí. 603 00:50:47,240 --> 00:50:50,240 Volání funkce může být poněkud drahé, protože má tohle všechno nastavení 604 00:50:50,240 --> 00:50:52,470 a teardown a všechny tyhle věci. 605 00:50:52,470 --> 00:50:58,160 Tak tohle ocas rekurze je dobrá. 606 00:50:58,160 --> 00:51:01,170 [Student] Proč to nevytváří nové kroky? 607 00:51:01,170 --> 00:51:02,980 Vzhledem k tomu, že si uvědomuje, že není třeba. 608 00:51:02,980 --> 00:51:07,800 Výzva k baru je jen vrací rekurzivního volání. 609 00:51:07,800 --> 00:51:12,220 Takže to nemusí dělat nic s návratovou hodnotou. 610 00:51:12,220 --> 00:51:15,120 Je to jen tak, aby okamžitě vrátit. 611 00:51:15,120 --> 00:51:20,530 Tak to jen tak nahradit jeho vlastní argumentaci a začít znovu. 612 00:51:20,530 --> 00:51:25,780 A také, pokud nemáte ocas rekurzivní verzi, 613 00:51:25,780 --> 00:51:31,460 pak dostanete všechny tyto bary, kde, kdy tento ukazatel vrací 614 00:51:31,460 --> 00:51:36,010 má vrátit jeho hodnotu na tento jeden, a pak, že bar se okamžitě vrátí 615 00:51:36,010 --> 00:51:39,620 a vrátí jeho hodnotu na tento jeden, pak je to jen tak aby se okamžitě vrátil 616 00:51:39,620 --> 00:51:41,350 a vrátí jeho hodnotu na tento jeden. 617 00:51:41,350 --> 00:51:45,350 Takže šetříte to objevovat všechny tyto věci pryč zásobníku 618 00:51:45,350 --> 00:51:48,730 protože vrácená hodnota je jen tak, aby byla přenesena celou cestu zpět stejně. 619 00:51:48,730 --> 00:51:55,400 Tak proč ne jen vyměnit náš argument s aktualizovaným argumentu a začít znovu? 620 00:51:57,460 --> 00:52:01,150 Pokud funkce není ocas rekurzivní, pokud děláte něco jako - 621 00:52:01,150 --> 00:52:07,530 [Student], pokud bar (x + 1). Jo >>. 622 00:52:07,530 --> 00:52:11,770 >> Takže pokud jste to ve stavu, pak děláte něco s návratovou hodnotou. 623 00:52:11,770 --> 00:52:16,260 Nebo i když jste právě udělat návrat 2 * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Takže teď bar (x - 1) musí vrátit, aby se pro výpočet 2 krát, že hodnoty, 625 00:52:23,560 --> 00:52:26,140 takže teď to potřebují svůj samostatný zásobník rám, 626 00:52:26,140 --> 00:52:31,180 a nyní, bez ohledu na to, jak moc se snažíš, budete muset - 627 00:52:31,180 --> 00:52:34,410 To není ocas rekurzivní. 628 00:52:34,410 --> 00:52:37,590 [Student] Chtěl jsem zkusit přivést rekurzi usilovat o koncové rekurze - 629 00:52:37,590 --> 00:52:41,450 [Bowden] V ideálním světě, ale v CS50 nemusíte se. 630 00:52:43,780 --> 00:52:49,280 S cílem získat rekurze ocasu, obecně, můžete nastavit další argument 631 00:52:49,280 --> 00:52:53,550 kde bar bude mít int x do y 632 00:52:53,550 --> 00:52:56,990 a y odpovídá konečnému věc, kterou chcete vrátit. 633 00:52:56,990 --> 00:53:03,650 Takže pak budete vracet bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Takže je to jen na vysoké úrovni, jak transformovat věci byly ocas rekurzivní. 635 00:53:09,810 --> 00:53:13,790 Ale navíc argument - 636 00:53:13,790 --> 00:53:17,410 A pak na konci, když se dostanete na základní případ, stačí se vrátit y 637 00:53:17,410 --> 00:53:22,740 protože jste se hromadí po celou dobu návratovou hodnotu, kterou chcete. 638 00:53:22,740 --> 00:53:27,280 Tak nějak si to dělám iterativně, ale pomocí rekurzivní volání. 639 00:53:32,510 --> 00:53:34,900 Otázky? 640 00:53:34,900 --> 00:53:39,890 [Student] Možná o ukazatel aritmetický, stejně jako při použití řetězce. Jistě >>. 641 00:53:39,890 --> 00:53:43,610 Ukazatel aritmetika. 642 00:53:43,610 --> 00:53:48,440 Při použití řetězců je to snadné, protože řetězce jsou char hvězdy, 643 00:53:48,440 --> 00:53:51,860 znaky jsou navždy a vždy jeden byte, 644 00:53:51,860 --> 00:53:57,540 a tak ukazatel aritmetické je ekvivalentní k pravidelnému aritmetiky, když máte co do činění s řetězci. 645 00:53:57,540 --> 00:54:08,790 Řekněme, že char * s = "hello". 646 00:54:08,790 --> 00:54:11,430 Takže máme blok v paměti. 647 00:54:19,490 --> 00:54:22,380 Je třeba 6 bajtů, protože se vždy potřebujete null terminátor. 648 00:54:22,380 --> 00:54:28,620 A char * s se bude poukázat na začátku tohoto pole. 649 00:54:28,620 --> 00:54:32,830 Takže s body tam. 650 00:54:32,830 --> 00:54:36,710 Nyní, to je v podstatě, jak každý pole funguje, 651 00:54:36,710 --> 00:54:40,780 bez ohledu na to, zda byl návrat do malloc nebo zda je to na zásobníku. 652 00:54:40,780 --> 00:54:47,110 Každá řada je v podstatě ukazatel na začátek pole, 653 00:54:47,110 --> 00:54:53,640 a pak každý pole operace, jakékoliv indexování, je jen tak do tohoto pole určité vyrovnání. 654 00:54:53,640 --> 00:55:05,360 >> Takže když jsem řekl něco jako s [3], což bude s a počítání 3 znaky a. 655 00:55:05,360 --> 00:55:12,490 Tak s [3], máme 0, 1, 2, 3, takže s [3] se bude ve vztahu k tomuto l. 656 00:55:12,490 --> 00:55:20,460 [Student] A tak bychom mohli dosáhnout stejnou hodnotu tím, že dělá S + 3 a pak závorky star? 657 00:55:20,460 --> 00:55:22,570 Ano. 658 00:55:22,570 --> 00:55:26,010 To je ekvivalentní * (s + 3); 659 00:55:26,010 --> 00:55:31,240 a že je navždy a vždy ekvivalentní bez ohledu na to, co děláte. 660 00:55:31,240 --> 00:55:34,070 Už nikdy nebudete muset použít držák syntaxi. 661 00:55:34,070 --> 00:55:37,770 Můžete vždy použít * (y + 3) syntax. 662 00:55:37,770 --> 00:55:40,180 Lidé mají tendenci rád držáku syntaxi, ačkoli. 663 00:55:40,180 --> 00:55:43,860 [Student] Takže všechny pole jsou vlastně jen ukazatele. 664 00:55:43,860 --> 00:55:53,630 Tam je nepatrný rozdíl, když řeknu, int x [4]; >> [Student] Znamená to, že vytvořit paměť? 665 00:55:53,630 --> 00:56:03,320 [Bowden] To bude vytvářet 4 ints ve frontě, tak 16 bytů celkově. 666 00:56:03,320 --> 00:56:05,700 Bude to vytvořit 16 bajtů na zásobníku. 667 00:56:05,700 --> 00:56:09,190 x není uloženo kdekoliv. 668 00:56:09,190 --> 00:56:13,420 Je to jen symbol odkazuje na začátku věc. 669 00:56:13,420 --> 00:56:17,680 Protože jste prohlásila, pole uvnitř této funkce, 670 00:56:17,680 --> 00:56:22,340 co kompilátor udělá je jen nahradit všechny výskyty proměnné x 671 00:56:22,340 --> 00:56:26,400 tam, kde se to stalo zvolit, aby těchto 16 bajtů. 672 00:56:26,400 --> 00:56:30,040 Je možné to udělat s char * s, protože s je skutečný ukazatel. 673 00:56:30,040 --> 00:56:32,380 Je zdarma ke přejděte na jiné věci. 674 00:56:32,380 --> 00:56:36,140 x je konstantní. Nelze mít místo na jiném poli. >> [Student] Dobře. 675 00:56:36,140 --> 00:56:43,420 Ale tato myšlenka, toto indexování, je stejná bez ohledu na to, zda je to tradiční pole 676 00:56:43,420 --> 00:56:48,230 nebo jestli je to ukazatel na něco nebo jestli je to ukazatel na malloced pole. 677 00:56:48,230 --> 00:56:59,770 A ve skutečnosti, že je tak ekvivalentní, že je rovněž jedno a totéž. 678 00:56:59,770 --> 00:57:05,440 Je to vlastně jen znamená, co je uvnitř hranatých závorek a to, co zbylo z držáků, 679 00:57:05,440 --> 00:57:07,970 je sečte, a dereferences. 680 00:57:07,970 --> 00:57:14,710 Tak tohle je stejně platný jako * (y + 3), nebo s [3]. 681 00:57:16,210 --> 00:57:22,090 [Student] Můžete mít odkazy směřující na 2-rozměrné pole? 682 00:57:22,090 --> 00:57:27,380 >> Je to těžší. Tradičně, no. 683 00:57:27,380 --> 00:57:34,720 2-rozměrné pole je jen 1-rozměrné pole s nějakou pohodlnou syntaxi 684 00:57:34,720 --> 00:57:54,110 protože když řeknu, int x [3] [3], je to opravdu jen 1 pole s 9 hodnotami. 685 00:57:55,500 --> 00:58:03,000 A tak když jsem index, kompilátor ví, co mám na mysli. 686 00:58:03,000 --> 00:58:13,090 Když řeknu, že x [1] [2], že ví, že chci jít do druhé řady, takže to bude přeskočit první 3, 687 00:58:13,090 --> 00:58:17,460 a pak to chce druhý věc, takže to bude stáhni jeden. 688 00:58:17,460 --> 00:58:20,480 Ale je to stále jen jedno-rozměrné pole. 689 00:58:20,480 --> 00:58:23,660 A tak když jsem chtěl přiřadit ukazatel na daném poli, 690 00:58:23,660 --> 00:58:29,770 Řekl bych, že int * p = x; 691 00:58:29,770 --> 00:58:33,220 Typ x je jen - 692 00:58:33,220 --> 00:58:38,280 Je to drsné říkat typ x, protože je to jen symbol, a to není skutečné proměnné, 693 00:58:38,280 --> 00:58:40,140 ale je to jen int *. 694 00:58:40,140 --> 00:58:44,840 x je jen ukazatel na začátek tohoto. >> [Student] Dobře. 695 00:58:44,840 --> 00:58:52,560 A tak nebudu mít přístup [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Myslím, že je zvláštní Syntaxe pro deklarování ukazatele, 697 00:58:58,370 --> 00:59:12,480 něco směšné jako int (* p [-. něco naprosto směšné Já ani nevím. 698 00:59:12,480 --> 00:59:17,090 Ale je tu Syntaxe pro deklarování ukazatele, jako se závorkami a věcí. 699 00:59:17,090 --> 00:59:22,960 Dokonce se ani nemusí nechat udělat. 700 00:59:22,960 --> 00:59:26,640 Jsem se mohl podívat zpět na něco, co by mi pravdu. 701 00:59:26,640 --> 00:59:34,160 Podívám se na to později, pokud je syntaxe pro bod. Ale nikdy nebudete vidět. 702 00:59:34,160 --> 00:59:39,670 A dokonce i syntaxe je tak archaický, že pokud budete používat, budou lidé zmateně. 703 00:59:39,670 --> 00:59:43,540 Vícerozměrné pole jsou velmi vzácné, jak to je. 704 00:59:43,540 --> 00:59:44,630 Jste docela hodně - 705 00:59:44,630 --> 00:59:48,490 No, pokud děláte věci, matice to nebude vzácné, 706 00:59:48,490 --> 00:59:56,730 ale v C budete jen zřídka bude používat vícerozměrná pole. 707 00:59:57,630 --> 01:00:00,470 Jo. >> [Student] Řekněme, že máte opravdu dlouhou pole. 708 01:00:00,470 --> 01:00:03,900 >> Takže ve virtuální paměti, že se zdá být vše po sobě jdoucích, 709 01:00:03,900 --> 01:00:05,640 jako prvky přímo vedle sebe, 710 01:00:05,640 --> 01:00:08,770 ale ve fyzickém paměti, že by bylo možné, že se rozešli? Ano >>. 711 01:00:08,770 --> 01:00:16,860 Jak virtuální paměť funguje, je to jen odděluje - 712 01:00:19,220 --> 01:00:24,860 Jednotka přidělení je stránka, která má tendenci být 4 KB, 713 01:00:24,860 --> 01:00:29,680 a tak když proces říká, hej, já chci použít tuto paměť, 714 01:00:29,680 --> 01:00:35,970 operační systém bude přidělí mu 4 KB pro toho malého bloku paměti. 715 01:00:35,970 --> 01:00:39,100 Dokonce i když si jen použít jeden malý byte v celém bloku paměti, 716 01:00:39,100 --> 01:00:42,850 operační systém se bude dát mu plné 4 KB. 717 01:00:42,850 --> 01:00:49,410 Takže to, co to znamená, je, že jsem mohl mít - řekněme, že to je moje stack. 718 01:00:49,410 --> 01:00:53,180 Tento zásobník může být oddělen. Můj stack může být megabajtů a megabyty. 719 01:00:53,180 --> 01:00:55,020 Můj stack může být obrovský. 720 01:00:55,020 --> 01:01:00,220 Ale stack sám má být rozdělen do jednotlivých stránek, 721 01:01:00,220 --> 01:01:09,010 která, pokud se podíváme na tady řekněme, že to je naše RAM, 722 01:01:09,010 --> 01:01:16,600 když mám 2 GB paměti RAM, je to skutečná adresa 0 jako 0. byte mého RAM, 723 01:01:16,600 --> 01:01:22,210 a to je 2 GB všechny tady dole. 724 01:01:22,210 --> 01:01:27,230 Takže tato stránka může odpovídat tomuto bloku sem. 725 01:01:27,230 --> 01:01:29,400 Tato stránka může odpovídat tomuto bloku sem. 726 01:01:29,400 --> 01:01:31,560 To by se dalo odpovídat tenhle sem. 727 01:01:31,560 --> 01:01:35,540 Takže operační systém je zdarma přiřadit fyzické paměti 728 01:01:35,540 --> 01:01:39,320 na jednotlivou stránku libovolně. 729 01:01:39,320 --> 01:01:46,180 A to znamená, že pokud se tato hranice se stane rozkročit pole, 730 01:01:46,180 --> 01:01:50,070 pole se stane být opuštěno to a právo tohoto pořadí stránky, 731 01:01:50,070 --> 01:01:54,460 pak toto pole se bude rozdělena do fyzické paměti. 732 01:01:54,460 --> 01:01:59,280 A pak se po ukončení programu, kdy proces skončí, 733 01:01:59,280 --> 01:02:05,690 Tyto mapování se vymažou a pak je to zdarma využívat tyto malé bloky pro ostatní věci. 734 01:02:14,730 --> 01:02:17,410 Další otázky? 735 01:02:17,410 --> 01:02:19,960 [Student] Ukazatel aritmetika. >> Ach jo. 736 01:02:19,960 --> 01:02:28,410 Řetězce bylo jednodušší, ale při pohledu na něco jako ints, 737 01:02:28,410 --> 01:02:35,000 tak zpět do int x [4]; 738 01:02:35,000 --> 01:02:41,810 Ať už je to pole, nebo zda je to ukazatel na malloced pole celých čísel 4, 739 01:02:41,810 --> 01:02:47,060 to bude zacházeno stejným způsobem. 740 01:02:50,590 --> 01:02:53,340 [Student] Tak pole jsou na haldě? 741 01:03:01,400 --> 01:03:05,270 [Bowden] Pole nejsou na haldě. >> [Student] Oh. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Tento typ pole má tendenci být na zásobníku 743 01:03:08,320 --> 01:03:12,220 pokud jste prohlásil ji za - ignoruje globální proměnné. Nepoužívejte globální proměnné. 744 01:03:12,220 --> 01:03:16,280 Uvnitř funkce říkám int x [4]; 745 01:03:16,280 --> 01:03:22,520 Bude to vytvořit 4-celé číslo bloku na zásobníku pro toto pole. 746 01:03:22,520 --> 01:03:26,960 Ale to malloc (4 * sizeof (int)); se chystá jít na haldě. 747 01:03:26,960 --> 01:03:31,870 Ale po tomto bodě mohu použít X a P v téměř stejným způsobem, 748 01:03:31,870 --> 01:03:36,140 jiné než výjimek, které jsem řekl dříve, než o tom můžete přiřadit ks. 749 01:03:36,140 --> 01:03:40,960 Technicky, jejich velikosti jsou poněkud odlišné, ale to je zcela irelevantní. 750 01:03:40,960 --> 01:03:43,310 Nikdy jste vlastně používají své velikosti. 751 01:03:48,020 --> 01:03:56,810 P Mohl bych říct, p [3] = 2, nebo x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 Můžete je použít v přesně stejným způsobem. 753 01:03:59,680 --> 01:04:01,570 Takže ukazatel aritmetika nyní - Ano. 754 01:04:01,570 --> 01:04:07,390 [Student] Líbí se vám nemusel dělat p * pokud máte držáky? 755 01:04:07,390 --> 01:04:11,720 Konzole jsou implicitní dereference. Dobře >>. 756 01:04:11,720 --> 01:04:20,200 Vlastně, i to, co říkáte, se můžete dostat vícerozměrných polí 757 01:04:20,200 --> 01:05:02,650 s ukazateli, co můžete udělat, je něco jako, řekněme, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Já si jen napsat to všechno jako první. 759 01:05:37,880 --> 01:05:41,020 Nechtěla jsem, že jeden. 760 01:05:41,020 --> 01:05:42,550 Dobře. 761 01:05:42,550 --> 01:05:48,910 Co jsem udělal, je zde - To by mělo být pp [i]. 762 01:05:48,910 --> 01:05:53,680 Takže pp je ukazatel na ukazatel. 763 01:05:53,680 --> 01:06:02,420 Jste mallocing pb poukázat na pole 5 hvězdiček int. 764 01:06:02,420 --> 01:06:10,950 Takže v paměti máte na zásobníku pp 765 01:06:10,950 --> 01:06:20,150 Bude to poukázat na pole 5 bloků, které jsou všechno sami ukazatele. 766 01:06:20,150 --> 01:06:28,210 A pak, když jsem malloc tady dole, jsem malloc, že ​​každý z těchto jednotlivých ukazatelů 767 01:06:28,210 --> 01:06:32,080 by měla směřovat na samostatném bloku na 4 bajty na haldy. 768 01:06:32,080 --> 01:06:35,870 Takže tento poukazuje na 4 bajty. 769 01:06:37,940 --> 01:06:40,660 A tenhle ukazuje na odlišný 4 bajty. 770 01:06:40,660 --> 01:06:43,200 >> A všechny z nich poukázat na jejich vlastní 4 bajty. 771 01:06:43,200 --> 01:06:49,080 To mi dává způsob, jak dělat multidimenzionální věci. 772 01:06:49,080 --> 01:06:58,030 Mohl bych říct, pp [3] [4], ale teď to není totéž jako multidimenzionální pole 773 01:06:58,030 --> 01:07:05,390 protože vícerozměrné pole je přeložena [3] [4] do jediné posun do pole x. 774 01:07:05,390 --> 01:07:14,790 Tento dereferences p, přistupuje třetí index, pak dereferences, že 775 01:07:14,790 --> 01:07:20,790 a přístupy - 4 by neplatné - druhý index. 776 01:07:24,770 --> 01:07:31,430 Vzhledem k tomu, kdy jsme měli int x [3] [4] jak před, tak vícerozměrné pole 777 01:07:31,430 --> 01:07:35,740 a při poklepání držák je to opravdu jen jeden dereference, 778 01:07:35,740 --> 01:07:40,490 jste po jediné ukazatel a pak offset, 779 01:07:40,490 --> 01:07:42,850 je to opravdu 2D odkazy. 780 01:07:42,850 --> 01:07:45,840 Můžete sledovat 2 samostatné ukazatele. 781 01:07:45,840 --> 01:07:50,420 Tak to také technicky umožňuje mít multidimenzionální pole 782 01:07:50,420 --> 01:07:53,550 kde každý jednotlivec je pole různé velikosti. 783 01:07:53,550 --> 01:07:58,000 Takže si myslím, zubaté vícerozměrných polí je to, co se jmenuje 784 01:07:58,000 --> 01:08:01,870 protože opravdu první věc, kterou by mohl směřovat k něčemu, co má 10 prvků, 785 01:08:01,870 --> 01:08:05,540 Druhá věc by mohl směřovat k něčemu, co má 100 prvků. 786 01:08:05,540 --> 01:08:10,790 [Student] Je nějaký limit na počet ukazatelů můžete mít 787 01:08:10,790 --> 01:08:14,290 ukázal na jiné ukazatele? >> Ne 788 01:08:14,290 --> 01:08:17,010 Můžete mít int ***** věst. 789 01:08:18,050 --> 01:08:23,760 Zpět na ukazatel aritmetiky - >> [studentka] Oh. Jo >>. 790 01:08:23,760 --> 01:08:35,649 [Student] Pokud mám int *** p a pak jsem udělat dereferencing a říkám p * je rovna této hodnotě, 791 01:08:35,649 --> 01:08:39,560 je to jen bude dělat 1 úroveň dereferencing? Ano >>. 792 01:08:39,560 --> 01:08:43,340 Takže když chci získat přístup k věci, že poslední ukazatel ukazuje na - 793 01:08:43,340 --> 01:08:46,210 Pak si udělat *** p. Dobře >>. 794 01:08:46,210 --> 01:08:54,080 Tak tohle je p poukazuje na 1 blok, poukazuje na jiného bloku, poukazuje na jiného bloku. 795 01:08:54,080 --> 01:09:02,010 Pak, pokud to uděláte * p = něco jiného, ​​pak měníte to 796 01:09:02,010 --> 01:09:13,640 Dosud poukázat na jiný blok. Dobře >>. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] A pokud byly malloced, pak jste nyní unikly paměti 798 01:09:17,649 --> 01:09:20,430 pokud se stalo, že mají různé odkazy na tyto 799 01:09:20,430 --> 01:09:25,270 protože se nemůžete dostat zpět k těm ty, které jste právě zahodil. 800 01:09:25,270 --> 01:09:29,550 Ukazatel aritmetika. 801 01:09:29,550 --> 01:09:36,310 int x [4], se bude alokovat pole celých čísel 4 802 01:09:36,310 --> 01:09:40,670 kde x bude poukázat na začátku pole. 803 01:09:40,670 --> 01:09:50,420 Takže když jsem řekl něco jako x [1], já chci, aby to znamená jít do druhé celé číslo v poli, 804 01:09:50,420 --> 01:09:53,319 který by byl tento. 805 01:09:53,319 --> 01:10:04,190 Ale opravdu, to je 4 bytů do pole, protože to číslo zabírá 4 bajty. 806 01:10:04,190 --> 01:10:08,470 Takže posun 1 opravdu znamená posun 1 807 01:10:08,470 --> 01:10:12,030 krát větší než bez ohledu na typ pole je. 808 01:10:12,030 --> 01:10:17,170 To je pole celých čísel, takže ví, jak udělat 1 krát velikost int, když chce kompenzovat. 809 01:10:17,170 --> 01:10:25,260 Druhý syntaxe. Pamatujte si, že to je ekvivalentní * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Když řeknu, že kurzoru + 1, co to vrací je adresa, na kterou je ukazatel ukládání 811 01:10:35,250 --> 01:10:40,360 plus 1 krát větší typu ukazatel. 812 01:10:40,360 --> 01:10:59,510 Takže pokud x = ox100, pak x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 A můžete zneužívají a řekne něco jako char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 a nyní c bude stejná adresa jako x. 815 01:11:23,050 --> 01:11:26,040 c bude rovna ox100, 816 01:11:26,040 --> 01:11:31,490 ale c + 1 bude rovna ox101 817 01:11:31,490 --> 01:11:38,030 od ukazatel aritmetický závisí na typu ukazatele, které jsou přidány k. 818 01:11:38,030 --> 01:11:45,390 Takže c + 1, to vypadá na c, je to char ukazatel, takže to bude přidat 1 krát velikost char, 819 01:11:45,390 --> 01:11:48,110 , která se vždy bude 1, takže budete mít 101, 820 01:11:48,110 --> 01:11:54,890 vzhledem k tomu, když to udělám x, která je také stále 100, x + 1 bude 104. 821 01:11:56,660 --> 01:12:06,340 [Student] Můžete použít c + +, aby se pokročilo ukazatel o 1? 822 01:12:06,340 --> 01:12:09,810 Ano, můžete. 823 01:12:09,810 --> 01:12:16,180 Můžete to udělat s x, protože x je jen symbol, je to konstanta, nemůžete změnit x. 824 01:12:16,180 --> 01:12:22,610 >> Ale c stane být jen ukazatel, takže c + + je dokonale platné, a to bude zvyšovat o 1. 825 01:12:22,610 --> 01:12:32,440 Je-li c bylo jen int *, pak c + + by se 104. 826 01:12:32,440 --> 01:12:41,250 + + Se ukazatel aritmetický stejně jako c + 1 by měl udělat ukazatel aritmetiku. 827 01:12:43,000 --> 01:12:48,870 To je vlastně, jak hodně věcí, jako je druh korespondence - 828 01:12:49,670 --> 01:12:55,710 Namísto vytváření kopií věcí, můžete místo toho projít - 829 01:12:55,710 --> 01:13:02,400 Stejně jako když jsem chtěl, aby tuto polovinu pole - nechte se vymazat něco z toho. 830 01:13:04,770 --> 01:13:10,520 Řekněme, že jsem chtěl, aby tuto stranu pole do funkce. 831 01:13:10,520 --> 01:13:12,700 Co bych předat této funkci? 832 01:13:12,700 --> 01:13:17,050 Pokud projdu x, jsem absolvování adresu. 833 01:13:17,050 --> 01:13:23,780 Ale já chci, aby tuto konkrétní adresu. Tak co bych měl projít? 834 01:13:23,780 --> 01:13:26,590 [Student] Pointer + 2? 835 01:13:26,590 --> 01:13:29,350 [Bowden] Tak x + 2. Ano. 836 01:13:29,350 --> 01:13:31,620 To je bude tato adresa. 837 01:13:31,620 --> 01:13:42,810 Budete také velmi často vidí to jako x [2], a pak adresu toho. 838 01:13:42,810 --> 01:13:47,850 Takže musíte mít adresu, protože držák je implicitní dereference. 839 01:13:47,850 --> 01:13:53,250 x [2] se vztahuje na hodnotu, která je v tomto poli, a pak se má adresu tohoto pole, 840 01:13:53,250 --> 01:13:56,850 takže říkáte & x [2]. 841 01:13:56,850 --> 01:14:02,880 Tak to je, jak se něco v druhu korespondence, kde chcete předat polovinu seznamu k něčemu 842 01:14:02,880 --> 01:14:08,790 opravdu jen projít a x [2], a nyní pokud jde o rekurzivní volání se týká, 843 01:14:08,790 --> 01:14:12,510 moje nové pole začíná tam. 844 01:14:12,510 --> 01:14:15,130 Last minute otázky. 845 01:14:15,130 --> 01:14:20,050 [Student] Pokud se nám nepodaří dát ampersand nebo - co je to jmenuje? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Student] Star. Technicky >>, dereference operátor, ale - >> [studentka] dereference. 847 01:14:23,200 --> 01:14:29,310 >> Pokud nemáme dát hvězdu nebo ampersand, co se stane, když jsem jen říct, y = x, a x je ukazatel? 848 01:14:29,310 --> 01:14:34,620 Jaký je typ y? >> [Student] Já si jen říct, že je ukazatel 2. 849 01:14:34,620 --> 01:14:38,270 Takže pokud jste právě řekl y = x, x a y nyní ukazují na stejnou věc. >> [Student] Bod na stejnou věc. 850 01:14:38,270 --> 01:14:45,180 A je-li x int ukazatel? >> To by si stěžovat, že není možné přiřadit ukazatele. 851 01:14:45,180 --> 01:14:46,540 [Student] Dobře. 852 01:14:46,540 --> 01:14:51,860 Pamatujte si, že ukazatele, i když jsme kreslit jako šípy, 853 01:14:51,860 --> 01:15:02,010 Opravdu vše, co store - int * x - opravdu vše x je ukládání je něco jako ox100, 854 01:15:02,010 --> 01:15:06,490 které jsme náhodou reprezentovat jako cílení na bloku uloženého v 100. 855 01:15:06,490 --> 01:15:19,660 Takže když říkám int * y = x; jsem jen kopírování ox100 do y, 856 01:15:19,660 --> 01:15:24,630 které jsme právě bude reprezentovat jako y, také ukázal na ox100. 857 01:15:24,630 --> 01:15:39,810 A když řeknu, int i = (int) x, pak i se chystá uložit bez ohledu na hodnotu ox100 je 858 01:15:39,810 --> 01:15:45,100 uvnitř ní, ale teď to bude vykládat jako celé číslo namísto ukazatele. 859 01:15:45,100 --> 01:15:49,310 Ale budete potřebovat sádru, nebo jinde to bude stěžovat. 860 01:15:49,310 --> 01:15:53,300 [Student] Tak to jste na mysli cast - 861 01:15:53,300 --> 01:16:00,290 Je to bude obsazení int X i lití int na y? 862 01:16:00,290 --> 01:16:03,700 [Bowden] Co? 863 01:16:03,700 --> 01:16:07,690 [Student] Dobře. Po těchto závorkách je tam bude x, nebo ay tam? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Buď. x a y jsou rovnocenné. >> [Student] Dobře. 865 01:16:11,500 --> 01:16:14,390 Vzhledem k tomu, že jsou oba ukazatele. Jo >>. 866 01:16:14,390 --> 01:16:21,050 [Student] Tak to by uložit hexadecimální 100 v celé číslo formě? >> [Bowden] Jo. 867 01:16:21,050 --> 01:16:23,620 Ale ne hodnota bez ohledu na to odkazuje. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Jo. >> [Student] Takže jen adresa ve formě celého čísla. Dobře. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Pokud byste chtěli z nějakého důvodu bizarní, 870 01:16:34,720 --> 01:16:38,900 můžete zabývat výhradně s ukazateli a nikdy řešit s celými čísly 871 01:16:38,900 --> 01:16:49,240 a prostě být jako int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Pak budete si opravdu zmatený, jakmile ukazatel aritmetický začne děje. 873 01:16:53,000 --> 01:16:56,570 Takže čísla, která ukládají, jsou nesmyslné. 874 01:16:56,570 --> 01:16:58,940 Je to jen, jak jste skončili jejich výklad. 875 01:16:58,940 --> 01:17:02,920 Takže jsem volně kopírovat ox100 z int * na int, 876 01:17:02,920 --> 01:17:07,790 a já jsem volný přiřadit - Jsi pravděpodobně bude dostat křičel na dobu odlévání - 877 01:17:07,790 --> 01:17:18,160 Jsem volná přiřadit něco jako (int *) ox1234 do této svévolné int *. 878 01:17:18,160 --> 01:17:25,480 Takže ox123 je stejně platná adresa paměti, jak je & y. 879 01:17:25,480 --> 01:17:32,060 A y se stane vrátit něco, co je docela hodně ox123. 880 01:17:32,060 --> 01:17:35,430 [Student] Bylo by to opravdu cool způsob, jak jít z šestnáctkové do desítkové podobě, 881 01:17:35,430 --> 01:17:39,230 jako když máte ukazatel a obsadil ji jako int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] Můžete opravdu jen tisknout pomocí jako printf. 883 01:17:44,860 --> 01:17:50,300 Řekněme, že mám int y = 100. 884 01:17:50,300 --> 01:18:02,700 Takže printf (% d \ n - jako byste měli již víte - tisk, že jako celočíselné,% x. 885 01:18:02,700 --> 01:18:05,190 Budeme jen vytisknout ji jako hexadecimální. 886 01:18:05,190 --> 01:18:10,760 Takže ukazatel není uložena jako hexadecimální, 887 01:18:10,760 --> 01:18:12,960 a číslo není uloženo jako desetinné. 888 01:18:12,960 --> 01:18:14,700 Vše je uloženo jako binární. 889 01:18:14,700 --> 01:18:17,950 Je to jen, že máme tendenci ukázat ukazatele jako hexadecimální 890 01:18:17,950 --> 01:18:23,260 protože si myslíme, že věci v těchto 4-byte blocích, 891 01:18:23,260 --> 01:18:25,390 a paměťové adresy mají tendenci, aby se seznámili. 892 01:18:25,390 --> 01:18:28,890 My jsme jako, když začne s bf, pak se stane, že je v zásobníku. 893 01:18:28,890 --> 01:18:35,560 Takže je to jen naše interpretace ukazatelů jako hexadecimální. 894 01:18:35,560 --> 01:18:39,200 Dobře. Nějaká poslední otázky? 895 01:18:39,200 --> 01:18:41,700 >> Budu tady na chvíli po, pokud máte něco jiného. 896 01:18:41,700 --> 01:18:46,070 A to je konec, že. 897 01:18:46,070 --> 01:18:48,360 >> [Student] Yay! [Potlesk] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]