1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Sectie 4 - Meer Comfortabele] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Harvard University] 3 00:00:04,850 --> 00:00:07,370 [Dit is CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 We hebben een quiz morgen, voor het geval jullie dat niet wist. 5 00:00:14,810 --> 00:00:20,970 Het is eigenlijk op alles wat je zou kunnen hebben gezien in de klas of had moeten zien in de klas. 6 00:00:20,970 --> 00:00:26,360 Dat geldt ook voor pointers, ook al zijn ze een zeer recente topic. 7 00:00:26,360 --> 00:00:29,860 U dient minstens begrijpen hoge hen. 8 00:00:29,860 --> 00:00:34,760 Alles wat was dan verdwenen in de klas moet je begrijpen voor de quiz. 9 00:00:34,760 --> 00:00:37,320 Dus als je vragen hebt over hen, dan kunt u nu vragen ze. 10 00:00:37,320 --> 00:00:43,280 Maar dit gaat om een ​​zeer student-geleide sessie zijn waar jullie vragen stellen, 11 00:00:43,280 --> 00:00:45,060 dus hopelijk mensen hebben vragen. 12 00:00:45,060 --> 00:00:48,020 Heeft iemand nog vragen? 13 00:00:49,770 --> 00:00:52,090 Ja. >> [Student] Kun je over pointers weer? 14 00:00:52,090 --> 00:00:54,350 Ik ga over pointers. 15 00:00:54,350 --> 00:00:59,180 Al uw variabelen behoeven te wonen in het geheugen, 16 00:00:59,180 --> 00:01:04,450 maar meestal je geen zorgen over te maken en je gewoon zeggen x + 2 en y + 3 17 00:01:04,450 --> 00:01:07,080 en de compiler zal erachter te komen waar de dingen wonen voor u. 18 00:01:07,080 --> 00:01:12,990 Zodra je te maken hebt met pointers, nu ben je expliciet het gebruik van deze geheugenadressen. 19 00:01:12,990 --> 00:01:19,800 Dus een variabele alleen maar leven op een adres op een bepaald moment. 20 00:01:19,800 --> 00:01:24,040 Willen we een pointer te verklaren, is wat het type gaat zien? 21 00:01:24,040 --> 00:01:26,210 >> Ik wil een pointer p verklaren. Hoe ziet het type eruit? 22 00:01:26,210 --> 00:01:33,530 [Student] int * p. >> Ja. Dus int * p. 23 00:01:33,530 --> 00:01:38,030 En hoe maak ik het wijzen op x? >> [Student] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Dus ampersand wordt letterlijk genoemd adres van de marktdeelnemer. 25 00:01:45,300 --> 00:01:50,460 Dus als ik zeg & x het wordt steeds het geheugen adres van de variabele x. 26 00:01:50,460 --> 00:01:56,790 Dus nu heb ik de aanwijzer p, en overal in mijn code die ik kan gebruiken * p 27 00:01:56,790 --> 00:02:02,960 of ik zou kunnen gebruiken x en het zal precies hetzelfde zijn. 28 00:02:02,960 --> 00:02:09,520 (* P). Wat is dit nou? Wat betekent die ster bedoel je? 29 00:02:09,520 --> 00:02:13,120 [Student] Het betekent een waarde op dat moment. >> Ja. 30 00:02:13,120 --> 00:02:17,590 Dus als we kijken naar het, kan het zeer nuttig zijn te trekken uit de schema's 31 00:02:17,590 --> 00:02:22,230 waar dit is een klein doosje van het geheugen voor x, wat gebeurt er met de waarde 4, 32 00:02:22,230 --> 00:02:25,980 dan hebben we een klein doosje van geheugen voor p, 33 00:02:25,980 --> 00:02:31,590 en dus p wijst naar x, dus we trekken een pijl van p naar x. 34 00:02:31,590 --> 00:02:40,270 Dus als we zeggen * p we zeggen naar het vak dat is p. 35 00:02:40,270 --> 00:02:46,480 Star is volg de pijl en dan doen wat je wilt met die doos daar. 36 00:02:46,480 --> 00:03:01,090 Dus ik kan zeggen * p = 7 en dat gaat naar het vak dat is x en verandering die tot en met 7. 37 00:03:01,090 --> 00:03:13,540 Of ik zou kunnen zeggen int z = * p * 2, dat is verwarrend, want het is ster, ster. 38 00:03:13,540 --> 00:03:19,230 Het is een ster p dereferentie, wordt de andere ster vermenigvuldigen met 2. 39 00:03:19,230 --> 00:03:26,780 Merk op dat ik zou kunnen hebben net zo goed vervangen de * p met x. 40 00:03:26,780 --> 00:03:29,430 U kunt ze gebruiken op dezelfde manier. 41 00:03:29,430 --> 00:03:38,000 En dan later op Ik kan p wijzen op een compleet nieuw ding. 42 00:03:38,000 --> 00:03:42,190 Ik kan alleen maar zeggen p = &z; 43 00:03:42,190 --> 00:03:44,940 Dus nu p niet meer verwijst naar x, het wijst op z. 44 00:03:44,940 --> 00:03:50,510 En elke keer dat ik doe * p het is hetzelfde als het doen van z. 45 00:03:50,510 --> 00:03:56,170 Dus het nuttig ding over dit is als we eenmaal beginnen met het krijgen in functies. 46 00:03:56,170 --> 00:03:59,790 >> Het is een beetje nutteloos om een ​​pointer te verklaren dat wijst op iets 47 00:03:59,790 --> 00:04:03,140 en dan ben je gewoon dereferentie het 48 00:04:03,140 --> 00:04:06,060 als je zou kunnen hebben gemaakt van de oorspronkelijke variabele te beginnen. 49 00:04:06,060 --> 00:04:18,190 Maar als je in functies - dus laten we zeggen dat we een functie, int foo, 50 00:04:18,190 --> 00:04:32,810 dat duurt een pointer en net doet * p = 6; 51 00:04:32,810 --> 00:04:39,990 Zoals we eerder zagen met swap, kunt u niet doen van een effectieve swap en een aparte functie 52 00:04:39,990 --> 00:04:45,180 door gewoon het passeren van gehele getallen omdat alles in C wordt altijd doorgeven als waarde. 53 00:04:45,180 --> 00:04:48,360 Zelfs als je pointers passeren je doorgeven als waarde. 54 00:04:48,360 --> 00:04:51,940 Het is gewoon zo gebeurt het dat deze waarden zijn geheugenadressen. 55 00:04:51,940 --> 00:05:00,770 Dus als ik zeg foo (p), ik ben het passeren van de aanwijzer in de functie foo 56 00:05:00,770 --> 00:05:03,910 en dan foo doet * p = 6; 57 00:05:03,910 --> 00:05:08,600 Zo binnen van deze functie * p nog gelijk aan x, 58 00:05:08,600 --> 00:05:12,720 maar ik kan geen gebruik maken van x binnenkant van die functie omdat het niet scoped binnen die functie. 59 00:05:12,720 --> 00:05:19,510 Dus * p = 6 is de enige manier waarop ik kan een lokale variabele van een andere functie te openen. 60 00:05:19,510 --> 00:05:23,600 Of, nou ja, pointers zijn de enige manier waarop ik kan een lokale variabele van een andere functie te openen. 61 00:05:23,600 --> 00:05:31,600 [Student] Laten we zeggen dat je wilde een pointer terug te keren. Hoe precies doe je dat? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Terug een pointer als in iets als int y = 3; return & y? >> [Student] Ja. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Oke. Je moet nooit doen. Dit is slecht. 64 00:05:48,480 --> 00:05:59,480 Ik denk dat ik zag in deze slides u begon het zien van dit hele schema van het geheugen 65 00:05:59,480 --> 00:06:02,880 waar hier heb je het geheugen adres 0 66 00:06:02,880 --> 00:06:09,550 en hier beneden heb je het geheugen adres 4 optredens of 2 om de 32. 67 00:06:09,550 --> 00:06:15,120 Dus dan heb je een aantal dingen en wat spullen en dan heb je je stack 68 00:06:15,120 --> 00:06:21,780 en je hebt je hoop, dat je gewoon begonnen met het leren over, opgroeien. 69 00:06:21,780 --> 00:06:24,390 [Student] Is niet de hoop boven de stapel? 70 00:06:24,390 --> 00:06:27,760 >> Ja. De hoop is op de top, is het niet? >> [Student] Nou, hij zet 0 op de top. 71 00:06:27,760 --> 00:06:30,320 [Student] Oh, hij zet 0 op de top. >> [Student] Oh, oke. 72 00:06:30,320 --> 00:06:36,060 Disclaimer: Overal met CS50 je gaat om het te zien op deze manier. >> [Student] Oke. 73 00:06:36,060 --> 00:06:40,290 Het is gewoon dat als je eerst zien stapels, 74 00:06:40,290 --> 00:06:45,000 zoals wanneer je denkt aan een stapel je denkt van het stapelen van dingen op de top van elkaar. 75 00:06:45,000 --> 00:06:50,810 Dus we hebben de neiging om deze flip rond, zodat de stapel groeit op als een stapel normaal zou doen 76 00:06:50,810 --> 00:06:55,940 in plaats van de stapel opknoping beneden. >> [Student] Niet hopen technisch te groeien, hoewel? 77 00:06:55,940 --> 00:07:01,100 Het hangt af van wat je bedoelt met opgroeien. 78 00:07:01,100 --> 00:07:04,010 De stack en heap groeien altijd in tegengestelde richting. 79 00:07:04,010 --> 00:07:09,420 Een stapel is altijd groeien op in de zin dat het wordt groot 80 00:07:09,420 --> 00:07:12,940 naar hogere geheugenadressen, en de hoop groeit naar beneden 81 00:07:12,940 --> 00:07:17,260 in dat het groeit in de richting van lagere geheugenadressen. 82 00:07:17,260 --> 00:07:20,250 Dus de top is 0 en de onderste is hoog geheugenadressen. 83 00:07:20,250 --> 00:07:26,390 Ze zijn zowel groeiende, alleen in tegengestelde richtingen. 84 00:07:26,390 --> 00:07:29,230 [Student] Ik bedoelde dat omdat je zei dat je stack op de bodem 85 00:07:29,230 --> 00:07:33,640 omdat het lijkt intuïtief omdat de stack te beginnen bovenaan een hoop, 86 00:07:33,640 --> 00:07:37,520 hoop is op de top van zichzelf ook, dus Dat is - >> Ja. 87 00:07:37,520 --> 00:07:44,960 U kunt ook denken aan de hoop zo opgroeien en groter, maar de stapel meer. 88 00:07:44,960 --> 00:07:50,280 Dus de stapel is degene die we soort van willen laten zien opgroeien. 89 00:07:50,280 --> 00:07:55,390 Maar overal waar je kijkt op een andere manier gaat adres 0 bovenaan verschijnen 90 00:07:55,390 --> 00:07:59,590 en de hoogste geheugenadres op de bodem, dus dit is uw gebruikelijke uitzicht op het geheugen. 91 00:07:59,590 --> 00:08:02,100 >> Heeft u een vraag? 92 00:08:02,100 --> 00:08:04,270 [Student] Kun je ons meer vertellen over de hoop? 93 00:08:04,270 --> 00:08:06,180 Ja. Ik zal dat in een seconde. 94 00:08:06,180 --> 00:08:12,220 Ten eerste, terug te gaan naar waarom terugkerende & y is een slechte zaak, 95 00:08:12,220 --> 00:08:18,470 op de stapel heb je een heleboel stack frames waarin alle functies weer te geven 96 00:08:18,470 --> 00:08:20,460 die zijn genoemd. 97 00:08:20,460 --> 00:08:27,990 Dus negeren vorige dingen, is de bovenkant van je stack altijd naar de hoofdfunctie worden 98 00:08:27,990 --> 00:08:33,090 want dat is de eerste functie dat wordt gebeld. 99 00:08:33,090 --> 00:08:37,130 En dan, als u een andere functie aan te roepen, wordt de stapel gaat naar beneden groeien. 100 00:08:37,130 --> 00:08:41,640 Dus als ik een bepaalde functie, foo, bellen en krijgt het zijn eigen stack frame, 101 00:08:41,640 --> 00:08:47,280 gevraagd kan een functie, een bar, het krijgt zijn eigen stack frame. 102 00:08:47,280 --> 00:08:49,840 En de bar zou kunnen zijn recursieve en het zou noemen zichzelf, 103 00:08:49,840 --> 00:08:54,150 en zo dat tweede gesprek bar gaat zijn eigen stack frame te krijgen. 104 00:08:54,150 --> 00:08:58,880 En zo wat er in deze stack frames zijn alle van de lokale variabelen 105 00:08:58,880 --> 00:09:03,450 en alle functies argumenten - 106 00:09:03,450 --> 00:09:08,730 Elke dingen die lokaal binnen het bereik van deze functie te gaan in deze stack frames. 107 00:09:08,730 --> 00:09:21,520 Dus dat betekent dat toen ik zei iets als bar is een functie, 108 00:09:21,520 --> 00:09:29,270 Ik ga gewoon naar een integer dan te verklaren en een pointer terug te keren naar die integer. 109 00:09:29,270 --> 00:09:33,790 Dus waar komt y wonen? 110 00:09:33,790 --> 00:09:36,900 [Student] y woont in bar. >> [Bowden] Ja. 111 00:09:36,900 --> 00:09:45,010 Ergens in een klein plein van het geheugen is een Littler plein dat y in zich heeft. 112 00:09:45,010 --> 00:09:53,370 Als ik terugkom & y, ben ik terug een pointer naar dit kleine blok van het geheugen. 113 00:09:53,370 --> 00:09:58,400 Maar toen een functie terugkeert, wordt de stack frame popped uit de stapel. 114 00:10:01,050 --> 00:10:03,530 En dat is waarom het heet stack. 115 00:10:03,530 --> 00:10:06,570 Het is net als de stapel datastructuur, als je weet wat dat is. 116 00:10:06,570 --> 00:10:11,580 Of zelfs als een stapel trays is altijd het voorbeeld, 117 00:10:11,580 --> 00:10:16,060 belangrijkste zal gaan op de bodem, dan is de eerste functie die u belt zal gaan op de top van dat, 118 00:10:16,060 --> 00:10:20,400 en je kunt niet terug naar de belangrijkste totdat u terug bent van alle functies die zijn genoemd 119 00:10:20,400 --> 00:10:22,340 die zijn geplaatst bovenop. 120 00:10:22,340 --> 00:10:28,650 >> [Student] Dus als je deed de terugkeer van de & y, die waarde is onderhevig aan wijzigingen zonder voorafgaande kennisgeving. 121 00:10:28,650 --> 00:10:31,290 Ja, het is - >> [student] Het kan worden overschreven. >> Ja. 122 00:10:31,290 --> 00:10:34,660 Het is volledig - Als u probeert en - 123 00:10:34,660 --> 00:10:38,040 Dit zou ook een int * bar omdat het terugsturen van een pointer, 124 00:10:38,040 --> 00:10:41,310 zodat de return type is int *. 125 00:10:41,310 --> 00:10:46,500 Als u probeert om de return waarde van deze functie te gebruiken, het is onbepaald gedrag 126 00:10:46,500 --> 00:10:51,770 want dat pointer wijst op slecht geheugen. >> [Student] Oke. 127 00:10:51,770 --> 00:11:01,250 Dus wat als, bijvoorbeeld, u verklaarde int * y = malloc (sizeof (int))? 128 00:11:01,250 --> 00:11:03,740 Dat is beter. Ja. 129 00:11:03,740 --> 00:11:07,730 [Student] We hadden het over hoe als we dingen sleep om onze prullenbak 130 00:11:07,730 --> 00:11:11,750 ze zijn niet echt gewist, we verliezen hun pointers. 131 00:11:11,750 --> 00:11:15,550 Dus in dit geval weten we eigenlijk wissen van de waarde of is het er nog steeds in het geheugen? 132 00:11:15,550 --> 00:11:19,130 Voor het grootste deel, het gaat om nog steeds zijn. 133 00:11:19,130 --> 00:11:24,220 Maar laten we zeggen dat we toevallig een andere functie, baz bellen. 134 00:11:24,220 --> 00:11:28,990 Baz gaat zijn eigen stack frame te krijgen hier. 135 00:11:28,990 --> 00:11:31,470 Het zal worden overschreven alle van dit spul, 136 00:11:31,470 --> 00:11:34,180 en dan als je later nog eens proberen en gebruik de pointer die je hebt voor, 137 00:11:34,180 --> 00:11:35,570 het is niet van plan om dezelfde waarde te zijn. 138 00:11:35,570 --> 00:11:38,150 Het zal net zijn veranderd omdat je de naam van de functie baz. 139 00:11:38,150 --> 00:11:43,080 [Student] Maar hadden we niet, zouden we nog steeds 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] Naar alle waarschijnlijkheid, zou je. 141 00:11:44,990 --> 00:11:49,670 Maar je kunt niet op vertrouwen. C zegt gewoon onbepaald gedrag. 142 00:11:49,670 --> 00:11:51,920 >> [Student] Oh, het doet. Oke. 143 00:11:51,920 --> 00:11:58,190 Dus als je wilt een pointer terug te keren, dit is waar malloc komt in gebruik. 144 00:12:00,930 --> 00:12:15,960 Ik ben eigenlijk schrijf gewoon terug malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 We gaan dan malloc meer in een tweede, maar het idee van malloc is al uw lokale variabelen 146 00:12:24,050 --> 00:12:26,760 altijd op de stapel. 147 00:12:26,760 --> 00:12:31,570 Alles wat is malloced gaat op de heap, en het zal voor eeuwig en altijd op de heap 148 00:12:31,570 --> 00:12:34,490 totdat u expliciet bevrijden. 149 00:12:34,490 --> 00:12:42,130 Dus dit betekent dat wanneer je malloc iets, het gaat om te overleven na de functie terugkeert. 150 00:12:42,130 --> 00:12:46,800 [Student] Zal het overleven nadat het programma stopt? >> Nee. 151 00:12:46,800 --> 00:12:53,180 Oke, dus het gaat om daar te zijn totdat het programma is helemaal klaar draait. >> Ja. 152 00:12:53,180 --> 00:12:57,510 We kunnen gaan over de details van wat er gebeurt wanneer het programma stopt. 153 00:12:57,510 --> 00:13:02,150 Mogelijk moet u me eraan te herinneren, maar dat is een apart ding helemaal. 154 00:13:02,150 --> 00:13:04,190 [Student] Dus malloc creëert een pointer? >> Ja. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [student] Ik denk dat malloc wijst een blok van het geheugen dat een pointer kan gebruiken. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Ik wil dat schema weer. >> [Student] Dus deze functie werkt, hoewel? 157 00:13:19,610 --> 00:13:26,430 [Student] Ja, malloc wijst een blok van het geheugen die u kunt gebruiken, 158 00:13:26,430 --> 00:13:30,470 en dan geeft het adres van het eerste blok van dat geheugen. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Ja. Dus als je malloc, je grijpen sommige blok van het geheugen 160 00:13:36,750 --> 00:13:38,260 dat is op dit moment in de heap. 161 00:13:38,260 --> 00:13:43,040 Als de hoop te klein is, dan is de hoop is gewoon om te groeien, en het groeit in deze richting. 162 00:13:43,040 --> 00:13:44,650 Dus laten we zeggen dat de hoop is te klein. 163 00:13:44,650 --> 00:13:49,960 Dan is het op het punt om een ​​beetje te groeien en een pointer terug te keren naar dit blok dat net groeide. 164 00:13:49,960 --> 00:13:55,130 Als je gratis spullen, je bent meer ruimte in de hoop het maken, 165 00:13:55,130 --> 00:14:00,030 dus dan een later bellen om malloc kunt hergebruiken dat het geheugen die u eerder had bevrijd. 166 00:14:00,030 --> 00:14:09,950 Het belangrijkste ding over malloc en free is dat het geeft je volledige controle 167 00:14:09,950 --> 00:14:12,700 gedurende de levensduur van deze geheugenblokken. 168 00:14:12,700 --> 00:14:15,420 Globale variabelen zijn altijd levend. 169 00:14:15,420 --> 00:14:18,500 Lokale variabelen zijn leven binnen hun bereik. 170 00:14:18,500 --> 00:14:22,140 Zodra je voorbij een accolade, de lokale variabelen zijn dood. 171 00:14:22,140 --> 00:14:28,890 Malloced geheugen leeft wanneer je wilt om te leven 172 00:14:28,890 --> 00:14:33,480 en dan wordt losgelaten wanneer u hem dat vrij te geven. 173 00:14:33,480 --> 00:14:38,420 Dat zijn eigenlijk de enige 3 soorten geheugen, echt waar. 174 00:14:38,420 --> 00:14:41,840 Er is automatische geheugenbeheer, dat is de stapel. 175 00:14:41,840 --> 00:14:43,840 Dingen gebeuren automatisch voor u. 176 00:14:43,840 --> 00:14:46,910 Wanneer u int x zeggen, is het geheugen toegewezen voor int x. 177 00:14:46,910 --> 00:14:51,630 Als x buiten het bereik valt, wordt het geheugen teruggewonnen voor x. 178 00:14:51,630 --> 00:14:54,790 Dan is er dynamisch geheugenbeheer, dat is wat malloc is, 179 00:14:54,790 --> 00:14:56,740 dat is wanneer je de controle hebt. 180 00:14:56,740 --> 00:15:01,290 Je dynamisch beslissen wanneer het geheugen wel en niet moet worden toegewezen. 181 00:15:01,290 --> 00:15:05,050 En dan is er statische is, dat betekent gewoon dat het voor altijd leeft, 182 00:15:05,050 --> 00:15:06,610 dat is wat globale variabelen zijn. 183 00:15:06,610 --> 00:15:10,240 Ze zijn gewoon altijd in het geheugen. 184 00:15:10,960 --> 00:15:12,760 >> Vragen? 185 00:15:14,490 --> 00:15:17,230 [Student] Kan je een blok te definiëren alleen door het gebruik van accolades 186 00:15:17,230 --> 00:15:21,220 maar zonder te beschikken over een if-statement of een while-opdracht of iets dergelijks? 187 00:15:21,220 --> 00:15:29,130 U kunt een blok als in een functie, maar dat heeft accolades ook. 188 00:15:29,130 --> 00:15:32,100 [Student] Dus je kunt niet alleen maar als een willekeurige paar accolades in je code 189 00:15:32,100 --> 00:15:35,680 dat de lokale variabelen? >> Ja, dat kan. 190 00:15:35,680 --> 00:15:45,900 Binnenkant van int bar konden we hebben {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 Dat zou hier zijn. 192 00:15:48,440 --> 00:15:52,450 Maar dat bepaalt volledig de omvang van int y. 193 00:15:52,450 --> 00:15:57,320 Na die tweede accolade, kan y niet meer gebruikt worden. 194 00:15:57,910 --> 00:16:00,630 Je hebt bijna nooit doen, dat wel. 195 00:16:02,940 --> 00:16:07,370 Om terug te komen wat er gebeurt als een programma eindigt, 196 00:16:07,370 --> 00:16:18,760 er is een beetje een misvatting / halve leugen dat we geven om gewoon dingen makkelijker te maken. 197 00:16:18,760 --> 00:16:24,410 Wij zeggen jullie dat als je geheugen toewijzen 198 00:16:24,410 --> 00:16:29,860 je bent toewijzing van een aantal portie RAM geheugen voor die variabele. 199 00:16:29,860 --> 00:16:34,190 Maar je bent niet echt aan te raken RAM ooit in uw programma's. 200 00:16:34,190 --> 00:16:37,490 Als je er van vindt, hoe ik trok - 201 00:16:37,490 --> 00:16:44,330 En eigenlijk, als je door in GDB zie je hetzelfde. 202 00:16:51,120 --> 00:16:57,590 Ongeacht hoe vaak u met uw programma of welk programma je draait, 203 00:16:57,590 --> 00:16:59,950 de stapel zal altijd beginnen - 204 00:16:59,950 --> 00:17:06,510 je bent altijd gaat om variabelen rond adres oxbffff iets te zien. 205 00:17:06,510 --> 00:17:09,470 Het is meestal ergens in die regio. 206 00:17:09,470 --> 00:17:18,760 Maar hoe kan 2 programma's mogelijk voor verwijzingen naar hetzelfde geheugen? 207 00:17:20,640 --> 00:17:27,650 [Student] Er is een aantal willekeurige aanduiding van waar oxbfff hoort te zijn op het RAM-geheugen 208 00:17:27,650 --> 00:17:31,320 die daadwerkelijk kan worden in verschillende plaatsen afhankelijk van wanneer de functie is aangeroepen. 209 00:17:31,320 --> 00:17:35,920 Ja. De term is virtueel geheugen. 210 00:17:35,920 --> 00:17:42,250 Het idee is dat elke proces, ieder programma dat wordt uitgevoerd op de computer 211 00:17:42,250 --> 00:17:49,450 heeft zijn eigen - laten we aannemen dat 32 bits - volledig onafhankelijk adresruimte. 212 00:17:49,450 --> 00:17:51,590 Dit is de adresruimte. 213 00:17:51,590 --> 00:17:56,220 Het heeft zijn eigen volledig onafhankelijk 4 GB te gebruiken. 214 00:17:56,220 --> 00:18:02,220 >> Dus als je 2 programma's tegelijkertijd, dit programma ziet 4 gigabyte aan zichzelf, 215 00:18:02,220 --> 00:18:04,870 dit programma ziet 4 gigabyte aan zichzelf, 216 00:18:04,870 --> 00:18:07,720 en het is onmogelijk voor dit programma te dereference een pointer 217 00:18:07,720 --> 00:18:10,920 en eindigen met het geheugen van dit programma. 218 00:18:10,920 --> 00:18:18,200 En wat virtueel geheugen is een afbeelding van een proces adresruimte 219 00:18:18,200 --> 00:18:20,470 de werkelijke dingen op RAM. 220 00:18:20,470 --> 00:18:22,940 Dus is het aan uw besturingssysteem om te weten dat, 221 00:18:22,940 --> 00:18:28,080 hey, wanneer deze kerel referentie aan pointer oxbfff, dat werkelijk betekent 222 00:18:28,080 --> 00:18:31,040 dat hij wil byte RAM 1000, 223 00:18:31,040 --> 00:18:38,150 terwijl als dit programma referentie aan oxbfff, hij wil echt RAM byte 10000. 224 00:18:38,150 --> 00:18:41,590 Ze kunnen willekeurig groot zijn. 225 00:18:41,590 --> 00:18:48,730 Dit is zelfs het geval van de dingen in een enkele processen adresruimte. 226 00:18:48,730 --> 00:18:54,770 Dus als het ziet alle 4 gigabyte aan zichzelf, maar laten we zeggen - 227 00:18:54,770 --> 00:18:57,290 [Student] Heeft elke enkel proces - 228 00:18:57,290 --> 00:19:01,350 Laten we zeggen dat u een computer met slechts 4 gigabyte aan RAM-geheugen. 229 00:19:01,350 --> 00:19:06,430 Heeft elk proces zien dat de hele 4 gigabytes? >> Ja. 230 00:19:06,430 --> 00:19:13,060 Maar de 4 gigabyte ziet is een leugen. 231 00:19:13,060 --> 00:19:20,460 Het is gewoon het denkt dat het heeft dit alles het geheugen, omdat het niet weet enig ander proces bestaat. 232 00:19:20,460 --> 00:19:28,140 Het zal alleen gebruik maken van zo veel geheugen als het daadwerkelijk nodig heeft. 233 00:19:28,140 --> 00:19:32,340 Het besturingssysteem is niet van plan om RAM te geven aan dit proces 234 00:19:32,340 --> 00:19:35,750 als het niet gebruik van een geheugen in deze hele regio. 235 00:19:35,750 --> 00:19:39,300 Het gaat niet om het geheugen voor die regio. 236 00:19:39,300 --> 00:19:54,780 Maar het idee is dat - ik probeer te bedenken - ik kan niet denken van een analogie. 237 00:19:54,780 --> 00:19:56,780 Analogieën zijn hard. 238 00:19:57,740 --> 00:20:02,700 Een van de problemen van het virtuele geheugen of een van de dingen die het is het oplossen van 239 00:20:02,700 --> 00:20:06,810 dat processen moeten volledig bewust van elkaar. 240 00:20:06,810 --> 00:20:12,140 En zo kunt u schrijven een programma dat net referentie aan elke pointer, 241 00:20:12,140 --> 00:20:19,340 graag gewoon een programma schrijven dat zegt * (ox1234), 242 00:20:19,340 --> 00:20:22,890 en dat is dereferentie geheugenadres 1234. 243 00:20:22,890 --> 00:20:28,870 >> Maar het is aan het besturingssysteem om vervolgens vertalen wat 1234 betekent. 244 00:20:28,870 --> 00:20:33,960 Dus als 1234 gebeurt er met een geldig geheugenadres zijn voor dit proces, 245 00:20:33,960 --> 00:20:38,800 alsof het op de stapel of iets, dan zal dit de terugkeer van de waarde van dat geheugenadres 246 00:20:38,800 --> 00:20:41,960 wat het proces weet. 247 00:20:41,960 --> 00:20:47,520 Maar als 1234 is geen geldig adres, zoals het gebeurt landen om 248 00:20:47,520 --> 00:20:52,910 in een klein stukje van het geheugen hier dat is buiten de stack en buiten de heap 249 00:20:52,910 --> 00:20:57,200 en je hebt niet echt gebruikt dat, dan is dat als je dingen als segfaults 250 00:20:57,200 --> 00:21:00,260 omdat je het aanraken van het geheugen dat je niet moet aanraken. 251 00:21:07,180 --> 00:21:09,340 Dit geldt ook - 252 00:21:09,340 --> 00:21:15,440 Een 32-bits systeem, 32-bits betekent dat je 32 bits om een ​​geheugenadres te definiëren. 253 00:21:15,440 --> 00:21:22,970 Het is de reden waarom pointers zijn 8 bytes, omdat 32 bits zijn 8 bytes - of 4 bytes. 254 00:21:22,970 --> 00:21:25,250 Pointers zijn 4 bytes. 255 00:21:25,250 --> 00:21:33,680 Dus als je een pointer als oxbfffff zien, dat wil zeggen - 256 00:21:33,680 --> 00:21:40,080 Binnen een bepaald programma kan je gewoon bouwen willekeurige pointer, 257 00:21:40,080 --> 00:21:46,330 overal van ox0 tot os 8 f's - ffffffff. 258 00:21:46,330 --> 00:21:49,180 [Student] Zei je niet dat ze 4 bytes? >> Ja. 259 00:21:49,180 --> 00:21:52,730 [Student] Dan elke byte zal hebben - >> [Bowden] Hexadecimaal. 260 00:21:52,730 --> 00:21:59,360 Hexadecimale - 5, 6, 7, 8. Dus pointers je gaat altijd zien in hexadecimaal. 261 00:21:59,360 --> 00:22:01,710 Het is gewoon de manier waarop we classificeren pointers. 262 00:22:01,710 --> 00:22:05,240 Elke 2 hexadecimale tekens is 1 byte. 263 00:22:05,240 --> 00:22:09,600 Dus er komt wel 8 hexadecimale cijfers voor 4 bytes. 264 00:22:09,600 --> 00:22:14,190 Dus elke aanwijzer op een 32-bits systeem gaat worden 4 bytes, 265 00:22:14,190 --> 00:22:18,550 Dit betekent dat in uw proces kunt u bouwen elke willekeurige 4 bytes 266 00:22:18,550 --> 00:22:20,550 en maak een wijzer van te maken, 267 00:22:20,550 --> 00:22:32,730 Dit betekent dat voor zover zij bekend is, kan betrekking hebben op een gehele 2 de 32 bytes van het geheugen. 268 00:22:32,730 --> 00:22:34,760 Hoewel het niet echt toegang hebben tot dat, 269 00:22:34,760 --> 00:22:40,190 zelfs als uw computer enkel 512 megabytes, hij denkt het heeft die veel geheugen. 270 00:22:40,190 --> 00:22:44,930 En het besturingssysteem is slim genoeg dat het alleen zal toewijzen wat je eigenlijk nodig hebt. 271 00:22:44,930 --> 00:22:49,630 Het is niet alleen te gaan, oh, een nieuw proces: 4 optredens. 272 00:22:49,630 --> 00:22:51,930 >> Ja. >> [Student] Wat betekent de os bedoel je? Waarom schrijf je dat? 273 00:22:51,930 --> 00:22:54,980 Het is gewoon het symbool voor hexadecimaal. 274 00:22:54,980 --> 00:22:59,590 Als u een nummer beginnen te zien met os, de opeenvolgende dingen zijn hexadecimaal. 275 00:23:01,930 --> 00:23:05,760 [Student] Je had uit te leggen over wat er gebeurt wanneer een programma eindigt. >> Ja. 276 00:23:05,760 --> 00:23:09,480 Wat gebeurt er wanneer een programma wordt beëindigd, is het besturingssysteem 277 00:23:09,480 --> 00:23:13,600 net wist de toewijzingen die het heeft voor deze adressen, en dat is het. 278 00:23:13,600 --> 00:23:17,770 Het besturingssysteem kan nu geef dat het geheugen naar een ander programma te gebruiken. 279 00:23:17,770 --> 00:23:19,490 [Student] Oke. 280 00:23:19,490 --> 00:23:24,800 Dus als je iets toe te wijzen aan de berg of de stapel of globale variabelen of wat dan ook, 281 00:23:24,800 --> 00:23:27,010 ze allemaal verdwijnen zodra het programma eindigt 282 00:23:27,010 --> 00:23:32,120 omdat het besturingssysteem is nu vrij om dat geheugen te geven aan een ander proces. 283 00:23:32,120 --> 00:23:35,150 [Student] Ook al zijn er waarschijnlijk nog waarden geschreven? >> Ja. 284 00:23:35,150 --> 00:23:37,740 De waarden zijn waarschijnlijk nog steeds. 285 00:23:37,740 --> 00:23:41,570 Het is gewoon dat het gaat om moeilijk te krijgen op hen. 286 00:23:41,570 --> 00:23:45,230 Het is veel moeilijker om bij hen dan het is om op een verwijderd bestand 287 00:23:45,230 --> 00:23:51,450 omdat het verwijderde bestand soort zit er voor een lange tijd en de harde schijf is een stuk groter. 288 00:23:51,450 --> 00:23:54,120 Dus het gaat om de verschillende delen van het geheugen te overschrijven 289 00:23:54,120 --> 00:23:58,640 voordat het gebeurt te overschrijven het stuk van het geheugen dat dat bestand gebruikt om te zijn. 290 00:23:58,640 --> 00:24:04,520 Maar het hoofdgeheugen, RAM, fietst u door een stuk sneller, 291 00:24:04,520 --> 00:24:08,040 dus het zal zeer snel worden overschreven. 292 00:24:10,300 --> 00:24:13,340 Vragen over dit of iets anders? 293 00:24:13,340 --> 00:24:16,130 [Student] Ik heb vragen over een ander onderwerp. >> Oke. 294 00:24:16,130 --> 00:24:19,060 Heeft iemand vragen over dit? 295 00:24:20,170 --> 00:24:23,120 >> Oke. Ander onderwerp. >> [Student] Oke. 296 00:24:23,120 --> 00:24:26,550 Ik ging door een aantal van de praktijk testen, 297 00:24:26,550 --> 00:24:30,480 en in een van hen had het over de sizeof 298 00:24:30,480 --> 00:24:35,630 en de waarde wordt geretourneerd of verschillende variabele types. >> Ja. 299 00:24:35,630 --> 00:24:45,060 En het zei dat zowel int en lange zowel terugkeer 4 dus, ze zijn allebei 4 bytes lang. 300 00:24:45,060 --> 00:24:48,070 Is er een verschil tussen een int en een lange, of is het hetzelfde? 301 00:24:48,070 --> 00:24:50,380 Ja, er is een verschil. 302 00:24:50,380 --> 00:24:52,960 De C standaard - 303 00:24:52,960 --> 00:24:54,950 Ik ga waarschijnlijk verpesten. 304 00:24:54,950 --> 00:24:58,800 De C standaard is net als wat C is, de officiële documentatie van C. 305 00:24:58,800 --> 00:25:00,340 Dit is wat het zegt. 306 00:25:00,340 --> 00:25:08,650 Dus de C standaard zegt alleen dat een char zal voor eeuwig en altijd 1 byte. 307 00:25:10,470 --> 00:25:19,040 Alles daarna - korte altijd precies gedefinieerd als groter dan of gelijk aan een char. 308 00:25:19,040 --> 00:25:23,010 Dit kan strikt groter is dan, maar niet positief. 309 00:25:23,010 --> 00:25:31,940 Een int net gedefinieerd als groter dan of gelijk aan een korte. 310 00:25:31,940 --> 00:25:36,210 En een lange is net gedefinieerd als groter dan of gelijk aan een int. 311 00:25:36,210 --> 00:25:41,600 En een lange lange groter is dan of gelijk is aan een lang. 312 00:25:41,600 --> 00:25:46,610 Dus het enige wat de C standaard definieert is de relatieve ordening van alles. 313 00:25:46,610 --> 00:25:54,880 De werkelijke hoeveelheid geheugen die dingen nemen is over het algemeen tot de uitvoering, 314 00:25:54,880 --> 00:25:57,640 maar het is vrij goed gedefinieerd op dit punt. >> [Student] Oke. 315 00:25:57,640 --> 00:26:02,490 Dus shorts zijn bijna altijd gaat worden 2 bytes. 316 00:26:04,920 --> 00:26:09,950 Ints zijn bijna altijd gaat worden 4 bytes. 317 00:26:12,070 --> 00:26:15,340 Lange longs zijn bijna altijd zal zijn 8 bytes. 318 00:26:17,990 --> 00:26:23,160 En verlangt, het hangt af van het feit of u een 32-bits of een 64-bit systeem. 319 00:26:23,160 --> 00:26:27,450 Zo lang zal overeenkomen met het type systeem. 320 00:26:27,450 --> 00:26:31,920 Als u een 32-bits systeem zoals de Appliance, gaat het om 4 bytes. 321 00:26:34,530 --> 00:26:42,570 Als u een 64-bits als een hoop van de recente computers, het gaat om 8 bytes. 322 00:26:42,570 --> 00:26:45,230 >> Ints zijn bijna altijd 4 bytes op dit punt. 323 00:26:45,230 --> 00:26:47,140 Lange longs zijn bijna altijd 8 bytes. 324 00:26:47,140 --> 00:26:50,300 In het verleden ints gebruikt louter 2 bytes. 325 00:26:50,300 --> 00:26:56,840 Maar let erop dat dit volledig al deze relaties van groter dan en gelijk aan voldoet. 326 00:26:56,840 --> 00:27:01,280 Zolang perfect mag dezelfde grootte als een integer is, 327 00:27:01,280 --> 00:27:04,030 en het is ook toegestaan ​​om de dezelfde grootte als een lange lang zijn. 328 00:27:04,030 --> 00:27:11,070 En toevallig zijn dat 99,999% van de systemen, zal gelijk aan 329 00:27:11,070 --> 00:27:15,800 ofwel een int of een lange lang. Het is maar net 32-bit of 64-bit. >> [Student] Oke. 330 00:27:15,800 --> 00:27:24,600 In drijvers, hoe is de decimale punt aangewezen in termen van bits? 331 00:27:24,600 --> 00:27:27,160 Zoals als binaire? >> Ja. 332 00:27:27,160 --> 00:27:30,570 U hoeft niet om te weten dat voor de CS50. 333 00:27:30,570 --> 00:27:32,960 Je hoeft niet eens te weten dat er in 61. 334 00:27:32,960 --> 00:27:37,350 Je hoeft niet die echt leren in een cursus. 335 00:27:37,350 --> 00:27:42,740 Het is gewoon een voorstelling. 336 00:27:42,740 --> 00:27:45,440 Ik vergeet de exacte beetje volkstuinen. 337 00:27:45,440 --> 00:27:53,380 Het idee van floating point is dat je een bepaald aantal bits te vertegenwoordigen wijzen - 338 00:27:53,380 --> 00:27:56,550 Kortom, alles is in wetenschappelijke notatie. 339 00:27:56,550 --> 00:28:05,600 Dus kennen een specifiek aantal bits aan het getal zelf vertegenwoordigen als 1,2345. 340 00:28:05,600 --> 00:28:10,200 Ik kan een nummer nooit vertegenwoordigen met meer cijfers dan 5. 341 00:28:12,200 --> 00:28:26,300 Dan ook kennen een specifiek aantal bits zodat het de neiging om als 342 00:28:26,300 --> 00:28:32,810 je kunt alleen oplopen tot een aantal, zoals dat is de grootste exponent kunt u, 343 00:28:32,810 --> 00:28:36,190 en je kunt alleen naar beneden naar een bepaalde exponent, 344 00:28:36,190 --> 00:28:38,770 als dat is de kleinste exponent je kunt hebben. 345 00:28:38,770 --> 00:28:44,410 >> Ik herinner me niet de exacte manier bits toegekend aan elk van deze waarden, 346 00:28:44,410 --> 00:28:47,940 maar een aantal bits gewijd aan 1,2345, 347 00:28:47,940 --> 00:28:50,930 een aantal bits gewijd aan de exponent, 348 00:28:50,930 --> 00:28:55,670 en het is alleen mogelijk om vormen een exponent van een bepaalde grootte. 349 00:28:55,670 --> 00:29:01,100 [Student] En een dubbele? Is dat als een extra lange float? >> Ja. 350 00:29:01,100 --> 00:29:07,940 Het is hetzelfde als een float, behalve nu dat u gebruikt 8 bytes in plaats van 4 bytes. 351 00:29:07,940 --> 00:29:11,960 Nu zult u in staat zijn om 9 cijfers of 10 cijfers te gebruiken, 352 00:29:11,960 --> 00:29:16,630 en deze kunnen oplopen tot 300 in plaats van 100. >> [Student] Oke. 353 00:29:16,630 --> 00:29:21,550 En drijft zijn ook 4 bytes. >> Ja. 354 00:29:21,550 --> 00:29:27,520 Nou, nogmaals, het hangt waarschijnlijk overall op algemene uitvoering, 355 00:29:27,520 --> 00:29:30,610 maar drijft zijn 4 bytes, tweepersoonskamers zijn 8. 356 00:29:30,610 --> 00:29:33,440 Doubles zijn dubbel genoemd omdat ze het dubbele van de grootte van de praalwagens. 357 00:29:33,440 --> 00:29:38,380 [Student] Oke. En zijn er verdubbelt dubbel? >> Er zijn niet. 358 00:29:38,380 --> 00:29:43,660 Ik denk dat - >> [student] Zoals lang longs? >> Ja. Ik denk het niet. Ja. 359 00:29:43,660 --> 00:29:45,950 [Student] Op-test van vorig jaar was er een vraag over de belangrijkste functie 360 00:29:45,950 --> 00:29:49,490 dat u een deel van uw programma. 361 00:29:49,490 --> 00:29:52,310 Het antwoord was dat het niet hoeft te een deel van uw programma. 362 00:29:52,310 --> 00:29:55,100 In welke situatie? Dat is wat ik zag. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Het lijkt erop - >> [student] Welke situatie? 364 00:29:59,090 --> 00:30:02,880 Heeft u het probleem? >> [Student] Ja, ik kan zeker trek het omhoog. 365 00:30:02,880 --> 00:30:07,910 Het hoeft niet zo te zijn, technisch, maar kort gezegd: het gaat worden. 366 00:30:07,910 --> 00:30:10,030 [Student] Ik zag er een op een andere jaar. 367 00:30:10,030 --> 00:30:16,220 Het was alsof Waar of niet waar: Een geldige - >> Oh, een C-bestand.? 368 00:30:16,220 --> 00:30:18,790 . [Student] Elke c bestand moet - [zowel gesproken in een keer - onverstaanbaar] 369 00:30:18,790 --> 00:30:21,120 Oke. Dus dat is een aparte. 370 00:30:21,120 --> 00:30:26,800 >> Een. C bestand moet enkel bevatten functies. 371 00:30:26,800 --> 00:30:32,400 U kunt een dossier samen in machine code, binaire, wat dan ook, 372 00:30:32,400 --> 00:30:36,620 zonder dat het uitvoerbare nog niet. 373 00:30:36,620 --> 00:30:39,420 Een geldige uitvoerbare moet een hoofdfunctie. 374 00:30:39,420 --> 00:30:45,460 U kunt schrijven 100 functies in 1 bestand, maar geen grote 375 00:30:45,460 --> 00:30:48,800 en dan die naar beneden compileren naar binair, 376 00:30:48,800 --> 00:30:54,460 dan schrijf je een ander bestand dat alleen de belangrijkste, maar het noemt een aantal van deze functies 377 00:30:54,460 --> 00:30:56,720 in deze binair bestand hier. 378 00:30:56,720 --> 00:31:01,240 En dus als je de executable maken, dat is wat de linker doet 379 00:31:01,240 --> 00:31:05,960 is het een combinatie van deze 2 binaire bestanden in een uitvoerbaar. 380 00:31:05,960 --> 00:31:11,400 Dus een. C bestand hoeft niet een hoofdfunctie te hebben. 381 00:31:11,400 --> 00:31:19,220 En op grote code bases zie je duizenden. C bestanden en 1 hoofdbestand. 382 00:31:23,960 --> 00:31:26,110 Meer vragen? 383 00:31:29,310 --> 00:31:31,940 [Student] Er was een andere vraag. 384 00:31:31,940 --> 00:31:36,710 Het zei te maken is een compiler. Waar of niet waar? 385 00:31:36,710 --> 00:31:42,030 En het antwoord was vals, en ik begreep waarom het is niet zoals Clang. 386 00:31:42,030 --> 00:31:44,770 Maar hoe noemen we maken als het niet? 387 00:31:44,770 --> 00:31:49,990 Eigenlijk te maken is gewoon - Ik kan precies zien wat het noemt. 388 00:31:49,990 --> 00:31:52,410 Maar het loopt gewoon commando's. 389 00:31:53,650 --> 00:31:55,650 Te maken. 390 00:31:58,240 --> 00:32:00,870 Ik kan trekken deze omhoog. Ja. 391 00:32:10,110 --> 00:32:13,180 Oh, ja. Zorg dat doet ook. 392 00:32:13,180 --> 00:32:17,170 Dit zegt het doel van de make werktuig is om automatisch te bepalen 393 00:32:17,170 --> 00:32:19,610 welke delen van een groot programma opnieuw gecompileerd moeten worden 394 00:32:19,610 --> 00:32:22,350 en geeft het commando's om ze opnieuw te compileren. 395 00:32:22,350 --> 00:32:27,690 U kunt maken bestanden die zijn absoluut enorm. 396 00:32:27,690 --> 00:32:33,210 Maak kijkt naar de tijdstempels van bestanden en, zoals we eerder hebben gezegd, 397 00:32:33,210 --> 00:32:36,930 kan je het compileren individuele bestanden naar beneden, en het is niet tot je bij de linker 398 00:32:36,930 --> 00:32:39,270 dat ze samengevoegd tot een uitvoerbaar. 399 00:32:39,270 --> 00:32:43,810 Dus als je 10 verschillende bestanden en u een wijziging aanbrengt in een van hen, 400 00:32:43,810 --> 00:32:47,870 dan wat merk gaat doen is gewoon opnieuw compileren dat 1 bestand 401 00:32:47,870 --> 00:32:50,640 en dan samen opnieuw koppelen alles. 402 00:32:50,640 --> 00:32:53,020 Maar het is veel dommer dan dat. 403 00:32:53,020 --> 00:32:55,690 Het is aan jou om volledig te definiëren dat dat is wat het zou moeten doen. 404 00:32:55,690 --> 00:32:59,560 Het heeft standaard de mogelijkheid om deze tijdstempel spul te herkennen, 405 00:32:59,560 --> 00:33:03,220 maar je kunt een merk-bestand om iets te doen. 406 00:33:03,220 --> 00:33:09,150 U kunt een make file, zodat wanneer u typt maken het net cd's naar een andere map. 407 00:33:09,150 --> 00:33:15,560 Ik was gefrustreerd omdat ik overstag alles binnenkant van mijn Appliance 408 00:33:15,560 --> 00:33:21,740 en dan ik de PDF van de Mac. 409 00:33:21,740 --> 00:33:30,720 >> Dus ik ga naar Finder en ik kan doen Ga, Verbind met server, 410 00:33:30,720 --> 00:33:36,950 en de server ik aansluiten op is mijn Appliance, en dan heb ik open het PDF-bestand 411 00:33:36,950 --> 00:33:40,190 dat wordt samengesteld door LaTeX. 412 00:33:40,190 --> 00:33:49,320 Maar ik was gefrustreerd omdat elke keer als ik die nodig is om de PDF te vernieuwen, 413 00:33:49,320 --> 00:33:53,900 Ik moest het kopiëren naar een specifieke directory dat het zou kunnen openen 414 00:33:53,900 --> 00:33:57,710 en het was al vervelend. 415 00:33:57,710 --> 00:34:02,650 Dus in plaats daarvan schreef ik een merk-bestand, die u moet definiëren hoe het dingen maakt. 416 00:34:02,650 --> 00:34:06,130 Hoe maak je in dit PDF-LaTeX. 417 00:34:06,130 --> 00:34:10,090 Net als elke andere merk-bestand - of Ik denk dat je nog niet het merk bestanden gezien, 418 00:34:10,090 --> 00:34:13,510 maar we hebben in de Appliance een wereldwijde merk-bestand dat gewoon zegt, 419 00:34:13,510 --> 00:34:16,679 als je het compileren van een C-bestand, gebruik Clang. 420 00:34:16,679 --> 00:34:20,960 En dus even in mijn make-bestand dat ik zeg ik, 421 00:34:20,960 --> 00:34:25,020 Dit bestand dat u gaat te willen compileren met PDF LaTeX. 422 00:34:25,020 --> 00:34:27,889 En dus is het PDF-LaTeX dat doet het compileren. 423 00:34:27,889 --> 00:34:31,880 Maak niet compileren. Het is gewoon het uitvoeren van deze commando's in de volgorde ik heb opgegeven. 424 00:34:31,880 --> 00:34:36,110 Dus het PDF LaTeX wordt uitgevoerd, kopieert deze naar de directory wil ik dat het gekopieerd moet worden, 425 00:34:36,110 --> 00:34:38,270 Het cd's naar de directory en doet andere dingen, 426 00:34:38,270 --> 00:34:42,380 maar alles wat het doet is te herkennen wanneer een bestand wordt gewijzigd, 427 00:34:42,380 --> 00:34:45,489 en als het verandert, dan zal het uitvoeren van de commando dat het zou moeten lopen 428 00:34:45,489 --> 00:34:48,760 wanneer het bestand wordt gewijzigd. >> [Student] Oke. 429 00:34:50,510 --> 00:34:54,420 Ik weet niet waar het wereldwijde merk bestanden zijn voor mij om het te controleren. 430 00:34:57,210 --> 00:35:04,290 Andere vragen? Alles wat uit het verleden quizzen? Elke pointer dingen? 431 00:35:06,200 --> 00:35:08,730 Er zijn subtiele dingen met pointers, zoals - 432 00:35:08,730 --> 00:35:10,220 Ik ga niet in staat zijn om een ​​quizvraag te vinden op het - 433 00:35:10,220 --> 00:35:16,250 maar net als dit soort dingen. 434 00:35:19,680 --> 00:35:24,060 Zorg ervoor dat je begrijpt dat als ik zeg int * x * y - 435 00:35:24,890 --> 00:35:28,130 Dit is precies niets hier, denk ik. 436 00:35:28,130 --> 00:35:32,140 Maar zoals * x * y, dat zijn 2 variabelen die op de stapel. 437 00:35:32,140 --> 00:35:37,220 Als ik zeg x = malloc (sizeof (int)), x is nog steeds een variabele op de stack, 438 00:35:37,220 --> 00:35:41,180 malloc is wat blok over in de hoop, en we hebben x wijzen op de heap. 439 00:35:41,180 --> 00:35:43,900 >> Dus iets op de stapel wijst op de heap. 440 00:35:43,900 --> 00:35:48,100 Wanneer je malloc iets, je onvermijdelijk te slaan binnenkant van een pointer. 441 00:35:48,100 --> 00:35:55,940 Zodat pointer op de stapel, de malloced blok op de heap. 442 00:35:55,940 --> 00:36:01,240 Veel mensen in de war raken en zeggen: int * x = malloc, x op de heap. 443 00:36:01,240 --> 00:36:04,100 Nee, wat x wijst naar is op de heap. 444 00:36:04,100 --> 00:36:08,540 x zelf is op de stapel, tenzij om wat voor reden je hebt x een globale variabele, 445 00:36:08,540 --> 00:36:11,960 In dat geval toevallig in een ander gebied van het geheugen. 446 00:36:13,450 --> 00:36:20,820 Dus het bijhouden, deze doos en pijl diagrammen zijn vrij normaal voor de quiz. 447 00:36:20,820 --> 00:36:25,740 Of als het niet op quiz 0, zal het op quiz 1. 448 00:36:27,570 --> 00:36:31,940 U moet weten van al deze, de stappen in het opstellen van 449 00:36:31,940 --> 00:36:35,740 omdat je moest vragen op die te beantwoorden. Ja. 450 00:36:35,740 --> 00:36:38,940 [Student] Kunnen we gaan over die stappen - >> Tuurlijk. 451 00:36:48,340 --> 00:36:58,640 Voordat stappen en samenstellen hebben we preprocessing, 452 00:36:58,640 --> 00:37:16,750 compileren, monteren, en het koppelen van. 453 00:37:16,750 --> 00:37:21,480 Preprocessing. Wat doet dat? 454 00:37:29,720 --> 00:37:32,290 Het is de gemakkelijkste stap in het - goed, niet zoals - 455 00:37:32,290 --> 00:37:35,770 dat betekent niet dat het moet duidelijk zijn, maar het is de gemakkelijkste stap. 456 00:37:35,770 --> 00:37:38,410 Jullie kunnen implementeren jezelf. Ja. 457 00:37:38,410 --> 00:37:43,410 [Student] Neem wat je hebt in je ook als deze en het kopieert en dan ook definieert. 458 00:37:43,410 --> 00:37:49,250 Het ziet er voor dingen als # include en definiëren #, 459 00:37:49,250 --> 00:37:53,800 en het gewoon kopieert en plakt wat die eigenlijk betekenen. 460 00:37:53,800 --> 00:37:59,240 Dus als je zegt dat # include cs50.h, wordt de preprocessor kopiëren en plakken cs50.h 461 00:37:59,240 --> 00:38:01,030 in die lijn. 462 00:38:01,030 --> 00:38:06,640 Als je zegt # define x te zijn 4, de preprocessor gaat door het hele programma 463 00:38:06,640 --> 00:38:10,400 en vervangt alle instanties van x met 4. 464 00:38:10,400 --> 00:38:17,530 Dus de preprocessor neemt een geldig C-bestand en voert een geldig C-bestand 465 00:38:17,530 --> 00:38:20,300 waar de dingen zijn gekopieerd en geplakt. 466 00:38:20,300 --> 00:38:24,230 Dus nu compileren. Wat doet dat? 467 00:38:25,940 --> 00:38:28,210 [Student] Het gaat van C naar binair. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] Het doet er helemaal niet naar binair. 469 00:38:30,970 --> 00:38:34,220 [Student] Voor machine-code dan? >> Het is niet machine code. 470 00:38:34,220 --> 00:38:35,700 [Student] Vergadering? >> Vergadering. 471 00:38:35,700 --> 00:38:38,890 Het gaat om Vergadering voordat het gaat helemaal naar C-code, 472 00:38:38,890 --> 00:38:45,010 en de meeste talen zoiets doen. 473 00:38:47,740 --> 00:38:50,590 Kies een willekeurige high-level taal, en als je gaat om het te compileren, 474 00:38:50,590 --> 00:38:52,390 is het waarschijnlijk te compileren in stappen. 475 00:38:52,390 --> 00:38:58,140 Eerst gaat Python compileren naar C, dan zal het naar C compileren Vergadering, 476 00:38:58,140 --> 00:39:01,600 en dan Vergadering gaat worden vertaald naar binair. 477 00:39:01,600 --> 00:39:07,800 Dus samenstellen gaat om het te brengen van C naar Assembly. 478 00:39:07,800 --> 00:39:12,130 Het woord samenstellen betekent meestal brengen het van een hoger niveau 479 00:39:12,130 --> 00:39:14,340 naar lagere programmeertaal. 480 00:39:14,340 --> 00:39:19,190 Dus dit is de enige stap in compilaties waar je begint met een high-level taal 481 00:39:19,190 --> 00:39:23,270 en eindigen in een low-level taal, en dat is de reden waarom de stap heet compileren. 482 00:39:25,280 --> 00:39:33,370 [Student] Tijdens het opstellen, laten we zeggen dat je hebt gedaan # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Zal de compiler opnieuw compileren van de cs50.h, zoals de functies die daar, 484 00:39:42,190 --> 00:39:45,280 en omgezet in Assembly code als goed, 485 00:39:45,280 --> 00:39:50,830 of zal het kopiëren en plakken iets dat is al pre-Assembly? 486 00:39:50,830 --> 00:39:56,910 cs50.h zal vrij veel nooit in Vergadering. 487 00:39:59,740 --> 00:40:03,680 Dingen als functie prototypes en dingen die er zijn voor jou om voorzichtig te zijn. 488 00:40:03,680 --> 00:40:09,270 Het garandeert dat de compiler kan dingen te controleren alsof je belfuncties 489 00:40:09,270 --> 00:40:12,910 met de juiste return typen en de juiste argumenten en dat soort dingen. 490 00:40:12,910 --> 00:40:18,350 >> Dus cs50.h worden voorbewerkt in het bestand, en dan wanneer het samenstellen van 491 00:40:18,350 --> 00:40:22,310 Het is eigenlijk weggegooid nadat het zorgt ervoor dat alles correct wordt genoemd. 492 00:40:22,310 --> 00:40:29,410 Maar de functies gedefinieerd in de CS50 bibliotheek, die gescheiden zijn van cs50.h, 493 00:40:29,410 --> 00:40:33,610 die zullen niet afzonderlijk worden opgesteld. 494 00:40:33,610 --> 00:40:37,270 Dat is eigenlijk zal naar beneden komen in de koppeling stap, dus we zullen krijgen om dat in een seconde. 495 00:40:37,270 --> 00:40:40,100 Maar eerst, wat is het monteren? 496 00:40:41,850 --> 00:40:44,500 [Student] Vergadering binaire? >> Ja. 497 00:40:46,300 --> 00:40:48,190 Montage. 498 00:40:48,190 --> 00:40:54,710 We noemen het niet compileren omdat Vergadering is vrij veel een zuivere vertaling van binaire. 499 00:40:54,710 --> 00:41:00,230 Er is heel weinig logica in gaan van Vergadering binaire. 500 00:41:00,230 --> 00:41:03,180 Het is net als kijken in een tabel, oh, hebben we deze instructie; 501 00:41:03,180 --> 00:41:06,290 die overeenkomt met binaire 01110. 502 00:41:10,200 --> 00:41:15,230 En dus de bestanden die de montage over het algemeen uitgangen zijn. O bestanden. 503 00:41:15,230 --> 00:41:19,020 En. O-bestanden zijn wat we zeiden voor, 504 00:41:19,020 --> 00:41:21,570 hoe een bestand hoeft niet een hoofdfunctie hebben. 505 00:41:21,570 --> 00:41:27,640 Elk bestand kan worden samengesteld tot een. O-bestand, zolang het is een geldige C-bestand. 506 00:41:27,640 --> 00:41:30,300 Het kan bundelen tot. O. 507 00:41:30,300 --> 00:41:43,030 Nu, het koppelen is wat eigenlijk een stelletje brengt. O bestanden en brengt ze naar een uitvoerbaar. 508 00:41:43,030 --> 00:41:51,110 En dus wat linking doet is kunt u van de CS50 bibliotheek te denken als een. O-bestand. 509 00:41:51,110 --> 00:41:56,980 Het is een reeds gecompileerd binair bestand. 510 00:41:56,980 --> 00:42:03,530 En dus als het samenstellen van je bestand, uw hello.c, waarin wordt opgeroepen GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c wordt samengesteld naar hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o is nu in binaire. 513 00:42:08,910 --> 00:42:12,830 Het maakt gebruik van GetString, dus het moet om over te gaan naar cs50.o, 514 00:42:12,830 --> 00:42:16,390 en de linker smooshes ze samen en kopieert GetString in dit bestand 515 00:42:16,390 --> 00:42:20,640 en komt met een uitvoerbaar dat alle functies die het nodig heeft. 516 00:42:20,640 --> 00:42:32,620 Dus cs50.o is niet echt een O-bestand, maar het is dichtbij genoeg dat er geen fundamenteel verschil. 517 00:42:32,620 --> 00:42:36,880 Dus koppelen net brengt een aantal bestanden bij elkaar 518 00:42:36,880 --> 00:42:41,390 die afzonderlijk alle functies bevatten moet ik gebruiken 519 00:42:41,390 --> 00:42:46,120 en creëert het uitvoerbare bestand dat daadwerkelijk wordt uitgevoerd. 520 00:42:48,420 --> 00:42:50,780 >> En dus dat is ook wat we zeiden eerder 521 00:42:50,780 --> 00:42:55,970 waar u kunt 1000 hebben. c-bestanden, kunt compileren ze allemaal. o-bestanden, 522 00:42:55,970 --> 00:43:00,040 die waarschijnlijk zal een tijdje duren, dan moet je wijzigen 1. c bestand. 523 00:43:00,040 --> 00:43:05,480 U hoeft alleen maar dat 1. C-bestand en vervolgens opnieuw koppelt alles hercompileren, 524 00:43:05,480 --> 00:43:07,690 verbinden alles weer bij elkaar. 525 00:43:09,580 --> 00:43:11,430 [Student] Als we het koppelen we schrijven lcs50? 526 00:43:11,430 --> 00:43:20,510 Ja, zo-lcs50. Die vlag signalen naar de linker dat je moet koppelen in die bibliotheek. 527 00:43:26,680 --> 00:43:28,910 Vragen? 528 00:43:41,310 --> 00:43:46,860 Hebben we gegaan over binaire, andere dan die 5 seconden in de eerste lezing? 529 00:43:50,130 --> 00:43:53,010 Ik denk het niet. 530 00:43:55,530 --> 00:43:58,820 U moet weten alle grote Os dat we gegaan, 531 00:43:58,820 --> 00:44:02,670 en je moet in staat zijn om, als we gaven je een functie, 532 00:44:02,670 --> 00:44:09,410 moet je in staat om te zeggen het is groot O ruwweg,. Of nou ja, grote O is ruw. 533 00:44:09,410 --> 00:44:15,300 Dus als je ziet geneste for-lussen een lus over hetzelfde aantal dingen, 534 00:44:15,300 --> 00:44:22,260 zoals int i, i > [student] n het kwadraat. >> Het de neiging om n kwadraat. 535 00:44:22,260 --> 00:44:25,280 Als u triple genest, het de neiging om n blokjes. 536 00:44:25,280 --> 00:44:29,330 Dus dat soort dingen moet je in staat om onmiddellijk te wijzen. 537 00:44:29,330 --> 00:44:33,890 Je moet insertion sort en bubble sort kennen en soort en al die samen te voegen. 538 00:44:33,890 --> 00:44:41,420 Het is makkelijker om te begrijpen waarom zij zijn degenen n vierkant en n log n en dat allemaal 539 00:44:41,420 --> 00:44:47,810 want ik denk dat er op een quiz een jaar wanneer we in principe je gaf 540 00:44:47,810 --> 00:44:55,050 een implementatie van bubble sort en zei: "Wat is de looptijd van deze functie?" 541 00:44:55,050 --> 00:45:01,020 Dus als je het herkent als bubble sort, dan kunt u meteen zeggen n kwadraat. 542 00:45:01,020 --> 00:45:05,470 Maar als je gewoon naar kijkt, hoeft u niet eens nodig om het een bubble sort realiseren; 543 00:45:05,470 --> 00:45:08,990 kun je gewoon zeggen dat dit dit en dit doen. Dit is n kwadraat. 544 00:45:12,350 --> 00:45:14,710 [Student] Zijn er moeilijke voorbeelden die je kan bedenken, 545 00:45:14,710 --> 00:45:20,370 als een vergelijkbaar idee van het uitzoeken? 546 00:45:20,370 --> 00:45:24,450 >> Ik denk niet dat we zouden geven u geen moeilijke voorbeelden. 547 00:45:24,450 --> 00:45:30,180 De bubble sort ding is ongeveer net zo hard als we zouden gaan, 548 00:45:30,180 --> 00:45:36,280 en zelfs dat, zolang je begrijpt dat je itereren over de array 549 00:45:36,280 --> 00:45:41,670 voor elk element in de array, wordt die gaat iets dat n kwadraat zijn. 550 00:45:45,370 --> 00:45:49,940 Er zijn algemene vragen, zoals hier hebben we - Oh. 551 00:45:55,290 --> 00:45:58,530 Alleen de andere dag, Doug beweerde, "Ik heb uitgevonden een algoritme dat een array kunnen sorteren 552 00:45:58,530 --> 00:46:01,780 "Van n getallen in O (log n) tijd!" 553 00:46:01,780 --> 00:46:04,900 Dus hoe kunnen we weten dat dat onmogelijk is? 554 00:46:04,900 --> 00:46:08,850 [Onverstaanbaar student reactie] >> Ja. 555 00:46:08,850 --> 00:46:13,710 Op zijn minst, moet u elk element te raken in de array, 556 00:46:13,710 --> 00:46:16,210 dus het is onmogelijk om te sorteren een scala aan - 557 00:46:16,210 --> 00:46:20,850 Als alles in orde ongesorteerd, dan zul je raken alles in de array, 558 00:46:20,850 --> 00:46:25,320 dus het is onmogelijk om het te doen in minder dan O van n. 559 00:46:27,430 --> 00:46:30,340 [Student] U heeft ons laten zien dat voorbeeld van de mogelijkheid om het te doen in O n 560 00:46:30,340 --> 00:46:33,920 als u veel geheugen. >> Ja. 561 00:46:33,920 --> 00:46:37,970 En Dat is - ik vergeet wat Dat is - Is het tellen sorteren? 562 00:46:47,360 --> 00:46:51,330 Hmm. Dat een geheel getal sorteeralgoritme. 563 00:46:59,850 --> 00:47:05,100 Ik was op zoek naar de speciale naam voor dit dat ik niet kon herinneren van vorige week. 564 00:47:05,100 --> 00:47:13,000 Ja. Dit zijn de soorten van soorten die dingen kunnen bereiken in grote O van n. 565 00:47:13,000 --> 00:47:18,430 Maar er zijn beperkingen, zoals je kunt alleen gebruik maken van gehele getallen tot een bepaald aantal. 566 00:47:20,870 --> 00:47:24,560 Plus als je probeert om iets te that's sorteren - 567 00:47:24,560 --> 00:47:30,750 Als uw array is 012, -12, 151, 4 miljoen, 568 00:47:30,750 --> 00:47:35,120 dan is dat enkel element gaat volledig ruïneren de hele sorteren. 569 00:47:42,060 --> 00:47:44,030 >> Vragen? 570 00:47:49,480 --> 00:47:58,870 [Student] Als je een recursieve functie en het maakt de recursieve oproepen 571 00:47:58,870 --> 00:48:02,230 binnen een return-statement, dat is de staart recursieve, 572 00:48:02,230 --> 00:48:07,360 en zo zou dat niet meer geheugen gebruiken tijdens runtime 573 00:48:07,360 --> 00:48:12,550 of het zou op z'n minst vergelijkbaar geheugen als een iteratief oplossing? 574 00:48:12,550 --> 00:48:14,530 [Bowden] Ja. 575 00:48:14,530 --> 00:48:19,840 Het zou waarschijnlijk iets trager, maar niet echt. 576 00:48:19,840 --> 00:48:23,290 Staart recursieve is vrij goed. 577 00:48:23,290 --> 00:48:32,640 Op zoek weer op stapel frames, laten we zeggen dat we de belangrijkste zijn 578 00:48:32,640 --> 00:48:42,920 en we hebben int bar (int x) of iets dergelijks. 579 00:48:42,920 --> 00:48:52,310 Dit is geen perfect recursieve functie, maar return bar (x - 1). 580 00:48:52,310 --> 00:48:57,620 Zo duidelijk, dit is onjuist. Je moet voet gevallen en dat soort dingen. 581 00:48:57,620 --> 00:49:00,360 Maar het idee hier is dat dit staart recursieve, 582 00:49:00,360 --> 00:49:06,020 wat betekent dat wanneer de belangrijkste gesprekken bar dat het gaat om de stack frame te krijgen. 583 00:49:09,550 --> 00:49:12,440 In deze stack frame er zal een kleine blok van het geheugen zijn 584 00:49:12,440 --> 00:49:17,490 dat overeenkomt met het argument x. 585 00:49:17,490 --> 00:49:25,840 En dus laten we zeggen de belangrijkste gebeurt te bellen bar (100); 586 00:49:25,840 --> 00:49:30,050 Dus x gaat beginnen als 100. 587 00:49:30,050 --> 00:49:35,660 Als de compiler erkent dat dit een staart recursieve functie, 588 00:49:35,660 --> 00:49:38,540 dan wanneer bar maakt zijn recursieve aanroep bar aan, 589 00:49:38,540 --> 00:49:45,490 plaats van een nieuwe stapel frame, dat is waar de stapel begint grotendeels groeien 590 00:49:45,490 --> 00:49:48,220 uiteindelijk zal lopen in de hoop en dan krijg je segfaults 591 00:49:48,220 --> 00:49:51,590 omdat het geheugen begint botsen. 592 00:49:51,590 --> 00:49:54,830 >> Dus in plaats van het maken van zijn eigen stack frame, kan het te realiseren, 593 00:49:54,830 --> 00:49:59,080 hey, ik heb nooit echt nodig om terug te komen op deze stapel frame, 594 00:49:59,080 --> 00:50:08,040 dus plaats ik zal gewoon vervangen dit argument met 99 en dan beginnen bar allemaal voorbij. 595 00:50:08,040 --> 00:50:11,810 En dan zal het opnieuw doen en het zal terug bar te bereiken (x - 1), 596 00:50:11,810 --> 00:50:17,320 en in plaats van het maken van een nieuwe stack frame, zal het gewoon vervangen de huidige argument met 98 597 00:50:17,320 --> 00:50:20,740 en dan terug naar het begin van bar. 598 00:50:23,860 --> 00:50:30,430 Deze activiteiten, ter vervanging van dat 1 waarde op de stack en springen terug naar het begin, 599 00:50:30,430 --> 00:50:32,430 zijn vrij efficiënt. 600 00:50:32,430 --> 00:50:41,500 Dus niet alleen is dit hetzelfde geheugengebruik als een aparte functie die wordt iteratief 601 00:50:41,500 --> 00:50:45,390 omdat je alleen met behulp van een stack frame, maar je bent niet lijden onder de nadelen 602 00:50:45,390 --> 00:50:47,240 van het moeten functies aan te roepen. 603 00:50:47,240 --> 00:50:50,240 Belfuncties kan iets duurder, omdat het te maken heeft al deze setup 604 00:50:50,240 --> 00:50:52,470 en afbouw en al deze spullen. 605 00:50:52,470 --> 00:50:58,160 Dus dit staart recursie is goed. 606 00:50:58,160 --> 00:51:01,170 [Student] Waarom staat er geen nieuwe stappen? 607 00:51:01,170 --> 00:51:02,980 Omdat het beseft dat het niet nodig is. 608 00:51:02,980 --> 00:51:07,800 De oproep tot bar is net terug van de recursieve aanroep. 609 00:51:07,800 --> 00:51:12,220 Dus het hoeft niet om iets te doen met de return waarde. 610 00:51:12,220 --> 00:51:15,120 Het zal alleen maar om onmiddellijk terug te sturen. 611 00:51:15,120 --> 00:51:20,530 Dus het gaat gewoon om zijn eigen argumenten te vervangen en opnieuw te beginnen. 612 00:51:20,530 --> 00:51:25,780 En ook, als u niet beschikt over de staart recursieve versie, 613 00:51:25,780 --> 00:51:31,460 dan krijg je al die bars waar wanneer deze balk terug 614 00:51:31,460 --> 00:51:36,010 het heeft zijn waarde terug te keren naar deze ene, dan is dat bar onmiddellijk terug 615 00:51:36,010 --> 00:51:39,620 en het de waarde terug naar deze, dan is het gewoon om onmiddellijk terug te keren 616 00:51:39,620 --> 00:51:41,350 en terug te keren zijn waarde voor deze. 617 00:51:41,350 --> 00:51:45,350 Dus je bespaart dit popping al deze dingen af ​​van de stapel 618 00:51:45,350 --> 00:51:48,730 omdat de return waarde is gewoon te worden doorgegeven helemaal back-up toch. 619 00:51:48,730 --> 00:51:55,400 Dus waarom niet gewoon ter vervanging van onze discussie met de bijgewerkte argument en opnieuw beginnen? 620 00:51:57,460 --> 00:52:01,150 Als de functie niet staart recursieve, als je zoiets doen - 621 00:52:01,150 --> 00:52:07,530 [Student] als bar (x + 1). >> Ja. 622 00:52:07,530 --> 00:52:11,770 >> Dus als je het in staat, dan ben je iets te doen met de return waarde. 623 00:52:11,770 --> 00:52:16,260 Of zelfs als je gewoon terug 2 do * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Nu bar (x - 1) moet terugkeren zodat het berekenen 2 maal deze waarde, 625 00:52:23,560 --> 00:52:26,140 dus nu is hoeft een eigen aparte stack frame, 626 00:52:26,140 --> 00:52:31,180 en nu, maakt niet uit hoe hard je ook probeert, je gaat nodig hebben om - 627 00:52:31,180 --> 00:52:34,410 Dit is niet de staart recursief. 628 00:52:34,410 --> 00:52:37,590 [Student] Zou ik proberen om een ​​recursie te brengen om te streven naar een staart recursie - 629 00:52:37,590 --> 00:52:41,450 [Bowden] In een ideale wereld, maar in CS50 u niet hoeft te doen. 630 00:52:43,780 --> 00:52:49,280 Met het oog op de staart recursie te krijgen, in het algemeen, stelt u een extra argument 631 00:52:49,280 --> 00:52:53,550 waar bar zal int x in y 632 00:52:53,550 --> 00:52:56,990 en y komt overeen met de ultieme wat je wilt om terug te keren. 633 00:52:56,990 --> 00:53:03,650 Dus dan is dit je gaat om terug te keren bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Dus dat is gewoon een high-level hoe je transformeren dingen om staart recursieve. 635 00:53:09,810 --> 00:53:13,790 Maar de extra argument - 636 00:53:13,790 --> 00:53:17,410 En dan op het einde als je je base case te bereiken, je gewoon terug y 637 00:53:17,410 --> 00:53:22,740 omdat je het verzamelen van de hele tijd dat de return waarde die u wilt. 638 00:53:22,740 --> 00:53:27,280 Je soort hebben gedaan het iteratief maar met behulp van recursieve oproepen. 639 00:53:32,510 --> 00:53:34,900 Vragen? 640 00:53:34,900 --> 00:53:39,890 [Student] Misschien over pointers, zoals bij het gebruik van strings. >> Tuurlijk. 641 00:53:39,890 --> 00:53:43,610 Pointers. 642 00:53:43,610 --> 00:53:48,440 Bij het gebruik van strings is het makkelijk omdat strings zijn char sterren, 643 00:53:48,440 --> 00:53:51,860 chars zijn voor eeuwig en altijd een enkele byte, 644 00:53:51,860 --> 00:53:57,540 en zo pointers is gelijk aan reguliere rekenen wanneer je te maken hebt met strijkers. 645 00:53:57,540 --> 00:54:08,790 Laten we zeggen dat char * s = "hello". 646 00:54:08,790 --> 00:54:11,430 Dus hebben we een blok in het geheugen. 647 00:54:19,490 --> 00:54:22,380 Het moet 6 bytes, want je moet altijd de null-terminator. 648 00:54:22,380 --> 00:54:28,620 En char * s gaat tot aan het begin van deze array. 649 00:54:28,620 --> 00:54:32,830 Dus s wijst er. 650 00:54:32,830 --> 00:54:36,710 Nu, dit is eigenlijk hoe een array werkt, 651 00:54:36,710 --> 00:54:40,780 ongeacht of het een rendement door malloc of dat het op de stapel. 652 00:54:40,780 --> 00:54:47,110 Een array is eigenlijk een pointer naar het begin van de array, 653 00:54:47,110 --> 00:54:53,640 en dan een array operatie, elke indexering, is gewoon in te gaan op die array een bepaalde offset. 654 00:54:53,640 --> 00:55:05,360 >> Dus toen ik iets als s [3] zeggen, dit gaat s en tellen 3 chars inch 655 00:55:05,360 --> 00:55:12,490 Dus s [3] Er zijn 0, 1, 2, 3, dus s [3] zal verwijzen naar dit l. 656 00:55:12,490 --> 00:55:20,460 [Student] En we konden bereiken dezelfde waarde door het doen van n + 3 en dan haakjes ster? 657 00:55:20,460 --> 00:55:22,570 Ja. 658 00:55:22,570 --> 00:55:26,010 Dit is gelijk aan * (s + 3); 659 00:55:26,010 --> 00:55:31,240 en dat is voor eeuwig en altijd gelijk maakt niet uit wat je doet. 660 00:55:31,240 --> 00:55:34,070 Je hoeft nooit aan de beugel syntax te gebruiken. 661 00:55:34,070 --> 00:55:37,770 U kunt altijd gebruik maken van de * (s + 3) syntaxis. 662 00:55:37,770 --> 00:55:40,180 Mensen hebben de neiging om de beugel syntaxis wilt, dat wel. 663 00:55:40,180 --> 00:55:43,860 [Student] Dus alle arrays zijn eigenlijk gewoon pointers. 664 00:55:43,860 --> 00:55:53,630 Er is een lichte onderscheid als ik zeg int x [4]; >> [student] Maakt dat maakt het geheugen? 665 00:55:53,630 --> 00:56:03,320 [Bowden] Dat gaat tot 4 ints te maken op de stapel, dus 16 bytes algemeen. 666 00:56:03,320 --> 00:56:05,700 Het gaat om 16 bytes te maken op de stapel. 667 00:56:05,700 --> 00:56:09,190 x nergens opgeslagen. 668 00:56:09,190 --> 00:56:13,420 Het is slechts een symbool met betrekking tot de start van het ding. 669 00:56:13,420 --> 00:56:17,680 Omdat je verklaarde de array binnenkant van deze functie, 670 00:56:17,680 --> 00:56:22,340 wat de compiler gaat doen is gewoon vervangen alle instanties van de variabele x 671 00:56:22,340 --> 00:56:26,400 met waar het is gebeurd om uit te kiezen om deze 16 bytes gezet. 672 00:56:26,400 --> 00:56:30,040 Het kan niet doen met char * s, want s is een echte pointer. 673 00:56:30,040 --> 00:56:32,380 Het is gratis te wijs andere dingen. 674 00:56:32,380 --> 00:56:36,140 x is een constante. Je kunt niet alles hebben punt naar een andere array. >> [Student] Oke. 675 00:56:36,140 --> 00:56:43,420 Maar dit idee, deze indexering, is dezelfde, ongeacht of het een traditioneel stelsel 676 00:56:43,420 --> 00:56:48,230 of als het een pointer naar iets of als het een pointer naar een malloced array. 677 00:56:48,230 --> 00:56:59,770 En in feite, het is zo gelijkwaardig dat dat ook is hetzelfde. 678 00:56:59,770 --> 00:57:05,440 Het is eigenlijk gewoon vertaalt wat er in de beugels en wat er van de beugels, 679 00:57:05,440 --> 00:57:07,970 voegt ze samen, en referentie aan. 680 00:57:07,970 --> 00:57:14,710 Dus dit is net zo geldig als * (s + 3) of s [3]. 681 00:57:16,210 --> 00:57:22,090 [Student] Kun je pointers wijzen naar 2-dimensionale arrays? 682 00:57:22,090 --> 00:57:27,380 >> Het is moeilijker. Traditioneel no. 683 00:57:27,380 --> 00:57:34,720 Een 2-dimensionale array bevindt zich op slechts een 1-dimensionale array met een aantal handige syntax 684 00:57:34,720 --> 00:57:54,110 want als ik zeg int x [3] [3], dit is echt maar 1 array met 9 waarden. 685 00:57:55,500 --> 00:58:03,000 En dus toen ik index, de compiler weet wat ik bedoel. 686 00:58:03,000 --> 00:58:13,090 Als ik zeg dat x [1] [2], weet ik wil naar de tweede rij, dus het gaat om de eerste 3 overslaan, 687 00:58:13,090 --> 00:58:17,460 en dan wil het tweede ding dat, dus het zal dit een te krijgen. 688 00:58:17,460 --> 00:58:20,480 Maar het is nog maar een single-dimensionale array. 689 00:58:20,480 --> 00:58:23,660 En dus als ik wilde een pointer toe te wijzen aan die array, 690 00:58:23,660 --> 00:58:29,770 Ik zou zeggen int * p = x; 691 00:58:29,770 --> 00:58:33,220 Het type van x is gewoon - 692 00:58:33,220 --> 00:58:38,280 Het is ruw te zeggen type x want het is gewoon een symbool en het is niet een echte variabele, 693 00:58:38,280 --> 00:58:40,140 maar het is gewoon een int *. 694 00:58:40,140 --> 00:58:44,840 x is slechts een wijzer naar het begin van deze. >> [Student] Oke. 695 00:58:44,840 --> 00:58:52,560 En dus ik zal niet in staat zijn om [1] [2] te openen. 696 00:58:52,560 --> 00:58:58,370 Ik denk dat er speciale syntax voor het declareren van een pointer, 697 00:58:58,370 --> 00:59:12,480 iets belachelijks als int (* p [-. iets absoluut belachelijk Ik weet niet eens. 698 00:59:12,480 --> 00:59:17,090 Maar er is een syntax voor de aangifte van pointers, zoals met haakjes en dingen. 699 00:59:17,090 --> 00:59:22,960 Het is misschien niet eens laten doen. 700 00:59:22,960 --> 00:59:26,640 Ik kon terug kijken naar iets dat zou me de waarheid vertellen. 701 00:59:26,640 --> 00:59:34,160 Later zullen voor, als er een syntax voor punt. Maar je zult het nooit zien. 702 00:59:34,160 --> 00:59:39,670 En zelfs de syntax zo archaïsch dat als je het gebruikt, mensen zullen verbijsterd. 703 00:59:39,670 --> 00:59:43,540 Multidimensionale arrays zijn vrij zeldzaam als het is. 704 00:59:43,540 --> 00:59:44,630 Je vrij veel - 705 00:59:44,630 --> 00:59:48,490 Nou, als je aan het doen bent matrix dingen dat het niet gaat als zeldzaam, 706 00:59:48,490 --> 00:59:56,730 maar in C je zelden gaat worden met behulp multidimensionale arrays. 707 00:59:57,630 --> 01:00:00,470 Ja. >> [Student] Laten we zeggen dat je een echt lange array. 708 01:00:00,470 --> 01:00:03,900 >> Dus in het virtuele geheugen het zou blijken te zijn alle opeenvolgende, 709 01:00:03,900 --> 01:00:05,640 als de elementen naast elkaar 710 01:00:05,640 --> 01:00:08,770 maar in het fysieke geheugen, zou het mogelijk zijn die worden opgesplitst? >> Ja. 711 01:00:08,770 --> 01:00:16,860 Hoe virtueel geheugen werkt is het scheidt gewoon - 712 01:00:19,220 --> 01:00:24,860 De eenheid van de toewijzing is een pagina, die de neiging heeft om 4 kilobytes, 713 01:00:24,860 --> 01:00:29,680 en dus als een proces zegt: hey, ik wil dit geheugen te gebruiken, 714 01:00:29,680 --> 01:00:35,970 het besturingssysteem gaat toewijzen is 4 kilobytes voor dat kleine blok van het geheugen. 715 01:00:35,970 --> 01:00:39,100 Zelfs als je alleen gebruik maken van een enkele kleine byte in het hele blok van het geheugen, 716 01:00:39,100 --> 01:00:42,850 het besturingssysteem zal geven van de volledige 4 kilobytes. 717 01:00:42,850 --> 01:00:49,410 Dus wat dit betekent is dat ik zou kunnen hebben - laten we zeggen dit is mijn stack. 718 01:00:49,410 --> 01:00:53,180 Deze stack kan worden gescheiden. Mijn stack kan megabytes en megabytes. 719 01:00:53,180 --> 01:00:55,020 Mijn stack kan enorm zijn. 720 01:00:55,020 --> 01:01:00,220 Maar de stapel zelf moet worden opgesplitst in afzonderlijke pagina's, 721 01:01:00,220 --> 01:01:09,010 die, als we kijken naar hier laten we zeggen dat dit is onze RAM, 722 01:01:09,010 --> 01:01:16,600 als ik 2 gigabyte aan RAM-geheugen, dit is de werkelijke adres 0 als de nulde byte van mijn RAM-geheugen, 723 01:01:16,600 --> 01:01:22,210 en dit is 2 gigabyte helemaal naar beneden hier. 724 01:01:22,210 --> 01:01:27,230 Dus deze pagina kan komen overeen met dit blok hier. 725 01:01:27,230 --> 01:01:29,400 Deze pagina kan overeenkomen met dit blok hier. 726 01:01:29,400 --> 01:01:31,560 Deze zou overeenkomen met deze hier. 727 01:01:31,560 --> 01:01:35,540 Dus het besturingssysteem is vrij om fysiek geheugen toe te wijzen 728 01:01:35,540 --> 01:01:39,320 aan een afzonderlijke pagina willekeurig. 729 01:01:39,320 --> 01:01:46,180 En dat betekent dat als deze grens overkomt straddle een array, 730 01:01:46,180 --> 01:01:50,070 een array toevallig links en rechts van deze van deze orde van een pagina 731 01:01:50,070 --> 01:01:54,460 dan die matrix zal worden gesplitst in het fysieke geheugen. 732 01:01:54,460 --> 01:01:59,280 En dan wanneer je stopt het programma, wanneer het proces eindigt, 733 01:01:59,280 --> 01:02:05,690 deze toewijzingen krijgen gewist en dan is het vrij om deze kleine blokken voor andere dingen gebruiken. 734 01:02:14,730 --> 01:02:17,410 Meer vragen? 735 01:02:17,410 --> 01:02:19,960 [Student] De aanwijzer rekenkunde. >> Oh ja. 736 01:02:19,960 --> 01:02:28,410 Snaren waren makkelijker, maar te kijken naar iets als ints, 737 01:02:28,410 --> 01:02:35,000 dus terug naar int x [4]; 738 01:02:35,000 --> 01:02:41,810 Of dit is een matrix of of het een pointer naar een malloced array van 4 gehele getallen, 739 01:02:41,810 --> 01:02:47,060 het gaat worden op dezelfde manier behandeld. 740 01:02:50,590 --> 01:02:53,340 [Student] Dus arrays zijn op de heap? 741 01:03:01,400 --> 01:03:05,270 [Bowden] Arrays zijn niet op de heap. >> [Student] Oh. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Dit type array meestal op de stapel 743 01:03:08,320 --> 01:03:12,220 tenzij je verklaarde dat het bij - het negeren van globale variabelen. Gebruik geen globale variabelen. 744 01:03:12,220 --> 01:03:16,280 Binnenkant van een functie zeg ik int x [4]; 745 01:03:16,280 --> 01:03:22,520 Het gaat om een ​​4-integer blok op de stapel te maken voor dit array. 746 01:03:22,520 --> 01:03:26,960 Maar dit malloc (4 * sizeof (int)); zal gaan op de heap. 747 01:03:26,960 --> 01:03:31,870 Maar na dit punt kan ik gebruik maken van x-en p in vrijwel dezelfde manier, 748 01:03:31,870 --> 01:03:36,140 anders dan de uitzonderingen die ik al eerder zei over u kunt toewijzen p. 749 01:03:36,140 --> 01:03:40,960 Technisch gezien hun grootte zijn iets anders, maar dat is volkomen irrelevant. 750 01:03:40,960 --> 01:03:43,310 Je hebt nooit daadwerkelijk gebruik maken van hun maten. 751 01:03:48,020 --> 01:03:56,810 De p Ik zou kunnen zeggen p [3] = 2; of x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 U kunt ze gebruiken op precies dezelfde manier. 753 01:03:59,680 --> 01:04:01,570 Dus pointers nu - Ja. 754 01:04:01,570 --> 01:04:07,390 [Student] Heb je niet te p * doen als je de haakjes? 755 01:04:07,390 --> 01:04:11,720 De beugels zijn een impliciete dereference. >> Oke. 756 01:04:11,720 --> 01:04:20,200 Eigenlijk, ook wat je zegt met de kunt u multidimensionale arrays 757 01:04:20,200 --> 01:05:02,650 met verwijzingen, wat je kunt doen is zoiets als, laten we zeggen, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Ik zal gewoon schrijf alles eerst uit. 759 01:05:37,880 --> 01:05:41,020 Ik wilde niet dat die ene. 760 01:05:41,020 --> 01:05:42,550 Oke. 761 01:05:42,550 --> 01:05:48,910 Wat ik heb gedaan is hier - Dat moet pp [i]. 762 01:05:48,910 --> 01:05:53,680 Dus pp is een pointer naar een pointer. 763 01:05:53,680 --> 01:06:02,420 Je mallocing pp om te wijzen op een reeks van 5 int sterren. 764 01:06:02,420 --> 01:06:10,950 Dus in het geheugen heb je op de stapel pp 765 01:06:10,950 --> 01:06:20,150 Het gaat om te wijzen op een reeks van 5 blokken die allemaal zelf pointers. 766 01:06:20,150 --> 01:06:28,210 En toen ik malloc hier beneden, ik malloc dat elk van deze individuele pointers 767 01:06:28,210 --> 01:06:32,080 moet verwijzen naar een apart blok van 4 bytes op de heap. 768 01:06:32,080 --> 01:06:35,870 Dus dit wijst op 4 bytes. 769 01:06:37,940 --> 01:06:40,660 En dit wijst op een andere 4 bytes. 770 01:06:40,660 --> 01:06:43,200 >> En allemaal punt van hun eigen 4 bytes. 771 01:06:43,200 --> 01:06:49,080 Dit geeft mij een manier van doen multidimensionale dingen. 772 01:06:49,080 --> 01:06:58,030 Ik zou kunnen zeggen pp [3] [4], maar nu is dit niet hetzelfde als multidimensionale arrays 773 01:06:58,030 --> 01:07:05,390 multidimensionale arrays omdat het vertaald [3] [4] in een verschuiving in de x array. 774 01:07:05,390 --> 01:07:14,790 Deze referentie aan p, toegang tot de derde-index, dan referentie aan dat 775 01:07:14,790 --> 01:07:20,790 en toegangen - 4 zou ongeldig zijn - de tweede index. 776 01:07:24,770 --> 01:07:31,430 Overwegende dat, wanneer we de int x [3] [4] voor als een multidimensionale array 777 01:07:31,430 --> 01:07:35,740 en wanneer u dubbelklikt beugel het is echt slechts een dereference, 778 01:07:35,740 --> 01:07:40,490 je volgt een pointer en dan een offset, 779 01:07:40,490 --> 01:07:42,850 dit is echt 2D referenties. 780 01:07:42,850 --> 01:07:45,840 Je volgt 2 aparte pointers. 781 01:07:45,840 --> 01:07:50,420 Dus dit ook technisch stelt u in staat om multidimensionale arrays 782 01:07:50,420 --> 01:07:53,550 waarbij elk array verschillende maten. 783 01:07:53,550 --> 01:07:58,000 Dus ik denk dat gekartelde multidimensionale arrays is hoe het heet 784 01:07:58,000 --> 01:08:01,870 Sinds echt het eerste wat zou kunnen wijzen op iets dat 10 elementen heeft, 785 01:08:01,870 --> 01:08:05,540 de tweede wat zou kunnen wijzen op iets dat 100 elementen heeft. 786 01:08:05,540 --> 01:08:10,790 [Student] Is er een limiet aan het aantal aanwijzingen kunt u 787 01:08:10,790 --> 01:08:14,290 verwijzen naar andere pointers? >> Nee. 788 01:08:14,290 --> 01:08:17,010 U kunt int ***** p. 789 01:08:18,050 --> 01:08:23,760 Terug naar pointers - >> [student] Oh. >> Ja. 790 01:08:23,760 --> 01:08:35,649 [Student] Als ik int *** p en dan doe ik een dereferentie en ik zeg p * gelijk is aan deze waarde, 791 01:08:35,649 --> 01:08:39,560 is het alleen maar om 1 niveau van dereferentie doen? >> Ja. 792 01:08:39,560 --> 01:08:43,340 Dus als ik wil het ding dat de laatste wijzer wijst naar toegang - 793 01:08:43,340 --> 01:08:46,210 Dan doe je *** p. >> Oke. 794 01:08:46,210 --> 01:08:54,080 Dit is dus p wijst naar een blok, verwijst naar een ander blok, wijst naar een ander blok. 795 01:08:54,080 --> 01:09:02,010 Dan als je dat doet * p = iets anders, dan bent u het wijzigen van deze 796 01:09:02,010 --> 01:09:13,640 nu verwijzen naar een ander blok. >> Oke. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] En als deze werden malloced, dan heb je nu gelekt geheugen 798 01:09:17,649 --> 01:09:20,430 tenzij je toevallig verschillende referenties van deze hebben 799 01:09:20,430 --> 01:09:25,270 want je kunt niet terug naar die degenen die je gewoon weggegooid. 800 01:09:25,270 --> 01:09:29,550 Pointers. 801 01:09:29,550 --> 01:09:36,310 int x [4], zal een array van 4 integers toewijzen 802 01:09:36,310 --> 01:09:40,670 waarbij x gaat tot aan het begin van de array. 803 01:09:40,670 --> 01:09:50,420 Dus als ik zeg iets als x [1], ik wil dat het naar de tweede geheel getal in de array gaan betekenen, 804 01:09:50,420 --> 01:09:53,319 die deze men. 805 01:09:53,319 --> 01:10:04,190 Maar echt, dat is 4 bytes in de array, omdat dit getal neemt 4 bytes. 806 01:10:04,190 --> 01:10:08,470 Dus een offset van 1 betekent echt een offset van 1 807 01:10:08,470 --> 01:10:12,030 keer zo groot, ongeacht het type van de matrix. 808 01:10:12,030 --> 01:10:17,170 Dit is een array van integers, zodat het weet te doen 1 keer groot int wanneer het wil offset. 809 01:10:17,170 --> 01:10:25,260 De andere syntax. Bedenk dat deze gelijk is aan * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Als ik zeg pointer + 1, wat dat terugkeert is het adres dat de aanwijzer wordt het opslaan van 811 01:10:35,250 --> 01:10:40,360 plus 1 maal de grootte van het type pointer. 812 01:10:40,360 --> 01:10:59,510 Dus als x = ox100, dan is x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 En je kunt misbruiken en zeggen iets als char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 en nu c gaat naar hetzelfde adres als x. 815 01:11:23,050 --> 01:11:26,040 c gaat gelijk aan ox100, 816 01:11:26,040 --> 01:11:31,490 maar c + 1 gaat gelijk aan ox101 817 01:11:31,490 --> 01:11:38,030 aangezien pointers afhankelijk van het type van de pointer die u toevoegt. 818 01:11:38,030 --> 01:11:45,390 Dus c + 1, het ziet er bij c, het is een char pointer, dus het gaat om 1 keer grootte van char toe te voegen, 819 01:11:45,390 --> 01:11:48,110 die altijd zal zijn 1, dus je krijgt 101, 820 01:11:48,110 --> 01:11:54,890 dat als ik x, die ook nog 100, x + 1 gaat worden 104. 821 01:11:56,660 --> 01:12:06,340 [Student] Kun je met c + + om de aanwijzer te bevorderen door 1? 822 01:12:06,340 --> 01:12:09,810 Ja, dat kan. 823 01:12:09,810 --> 01:12:16,180 Je kunt dat niet doen met x, want x is slechts een symbool, het is een constante, je kunt niet veranderen x. 824 01:12:16,180 --> 01:12:22,610 >> Maar c gebeurt er gewoon een pointer, dus c + + is perfect geldig en het zal verhogen met 1. 825 01:12:22,610 --> 01:12:32,440 Als c waren gewoon een int *, dan is c + + zou worden 104. 826 01:12:32,440 --> 01:12:41,250 + + Doet pointers net als c + 1 zou hebben gedaan pointers. 827 01:12:43,000 --> 01:12:48,870 Dit is eigenlijk hoe een heleboel dingen, zoals merge sort - 828 01:12:49,670 --> 01:12:55,710 In plaats van het creëren van kopieën van de dingen, kunt u in plaats daarvan gaan - 829 01:12:55,710 --> 01:13:02,400 Net als ik wilde deze helft van de array voorbij - is wis enkele van deze te laten. 830 01:13:04,770 --> 01:13:10,520 Laten we zeggen dat ik wilde deze kant van de array overgaan in een functie. 831 01:13:10,520 --> 01:13:12,700 Wat zou ik doorgeven aan die functie? 832 01:13:12,700 --> 01:13:17,050 Als ik voorbij x, ik ben het passeren van dit adres. 833 01:13:17,050 --> 01:13:23,780 Maar ik wil dit bijzondere adres passeren. Dus wat moet ik gaan? 834 01:13:23,780 --> 01:13:26,590 [Student] Pointer + 2? 835 01:13:26,590 --> 01:13:29,350 [Bowden] Dus x + 2. Ja. 836 01:13:29,350 --> 01:13:31,620 Dat gaat naar dit adres te zijn. 837 01:13:31,620 --> 01:13:42,810 U zult ook heel vaak zien als x [2] en vervolgens het adres van dat. 838 01:13:42,810 --> 01:13:47,850 Dus je moet het adres van te nemen, omdat de beugel is een impliciete dereference. 839 01:13:47,850 --> 01:13:53,250 x [2] verwijst naar de waarde die in dit vak, en dan wil je het adres van die doos, 840 01:13:53,250 --> 01:13:56,850 dus je zegt en x [2]. 841 01:13:56,850 --> 01:14:02,880 Dus dat is hoe iets in merge sort waar u de helft van de lijst door te geven aan iets 842 01:14:02,880 --> 01:14:08,790 je echt gewoon voorbij en x [2], en nu voor zover de recursieve aanroep betreft, 843 01:14:08,790 --> 01:14:12,510 mijn nieuwe array begint daar. 844 01:14:12,510 --> 01:14:15,130 Last minute vragen. 845 01:14:15,130 --> 01:14:20,050 [Student] Als we niet plaatsen een ampersand of - wat is dat genoemd? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Student] Star. >> Technisch dereference operator, maar - >> [student] dereference. 847 01:14:23,200 --> 01:14:29,310 >> Als we niet plaatsen een ster of een teken, wat gebeurt er als ik alleen maar zeggen y = x en x is een pointer? 848 01:14:29,310 --> 01:14:34,620 Wat is het type y? >> [Student] ik zal gewoon zeggen dat het wijzer 2. 849 01:14:34,620 --> 01:14:38,270 Dus als je gewoon zeggen y = x, nu x en y wijzen op hetzelfde. >> [Student] Punt op hetzelfde neer. 850 01:14:38,270 --> 01:14:45,180 En als x een int pointer? >> Het zou klagen, want je kunt niet toewijzen pointers. 851 01:14:45,180 --> 01:14:46,540 [Student] Oke. 852 01:14:46,540 --> 01:14:51,860 Vergeet niet dat pointers, ook al hebben we ze te tekenen als pijlen, 853 01:14:51,860 --> 01:15:02,010 echt alles wat ze winkel - int * x - echt alle x is het opslaan is zoiets als ox100, 854 01:15:02,010 --> 01:15:06,490 die we toevallig voor te stellen als die naar het blok opgeslagen bij 100. 855 01:15:06,490 --> 01:15:19,660 Dus als ik zeg int * y = x, ik ben gewoon het kopiëren van ox100 in y, 856 01:15:19,660 --> 01:15:24,630 die we gaan gewoon te vertegenwoordigen als y, ook wijzend naar ox100. 857 01:15:24,630 --> 01:15:39,810 En als ik zeg int i = (int) x, dan ik zal slaan ongeacht de waarde van ox100 is 858 01:15:39,810 --> 01:15:45,100 binnenkant van het, maar nu gaat worden geïnterpreteerd als een geheel getal in plaats van een pointer. 859 01:15:45,100 --> 01:15:49,310 Maar je moet de cast of anders zal klagen. 860 01:15:49,310 --> 01:15:53,300 [Student] Dus bedoel je te werpen - 861 01:15:53,300 --> 01:16:00,290 Gaat het te gieten int van x of gieten int van y? 862 01:16:00,290 --> 01:16:03,700 [Bowden] Wat? 863 01:16:03,700 --> 01:16:07,690 [Student] Oke. Na deze haakjes wordt er zullen een x of ay daar? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Ofwel. x en y zijn equivalent. >> [Student] Oke. 865 01:16:11,500 --> 01:16:14,390 Omdat ze beide pointers. >> Ja. 866 01:16:14,390 --> 01:16:21,050 [Student] Dus het zou slaan de hexadecimale 100 in getal vorm? >> [Bowden] Ja. 867 01:16:21,050 --> 01:16:23,620 Maar niet de waarde van wat het verwijst. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Ja. >> [Student] Dus gewoon het adres in integer vorm. Oke. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Als je wilde voor een aantal bizarre reden, 870 01:16:34,720 --> 01:16:38,900 je zou kunnen uitsluitend met pointers en nooit te gaan met gehele getallen 871 01:16:38,900 --> 01:16:49,240 en net zijn als int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Dan zul je echt in de war raken wanneer pointers begint gebeurt. 873 01:16:53,000 --> 01:16:56,570 Dus de nummers die ze slaan zijn zinloos. 874 01:16:56,570 --> 01:16:58,940 Het is gewoon hoe je uiteindelijk de interpretatie ervan. 875 01:16:58,940 --> 01:17:02,920 Dus ik ben vrij om te ox100 kopiëren van een int * naar een int, 876 01:17:02,920 --> 01:17:07,790 en ik ben vrij om toe te wijzen - waarschijnlijk gaat krijgen schreeuwde naar voor niet gieten Je bent - 877 01:17:07,790 --> 01:17:18,160 Ik ben vrij om iets toe te wijzen als (int *) ox1234 in deze willekeurige int *. 878 01:17:18,160 --> 01:17:25,480 Dus ox123 is net zo geldig een geheugenadres zoals & y. 879 01:17:25,480 --> 01:17:32,060 & Y gebeurt om terug te keren iets dat is vrij veel ox123. 880 01:17:32,060 --> 01:17:35,430 [Student] Zou dat echt een leuke manier om te gaan van hexadecimaal naar decimaal vorm, 881 01:17:35,430 --> 01:17:39,230 graag als je een pointer en je wierp het als een int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] U kunt eigenlijk gewoon afdrukken met als printf. 883 01:17:44,860 --> 01:17:50,300 Laten we zeggen dat ik int y = 100. 884 01:17:50,300 --> 01:18:02,700 Dus printf (% d \ n - zoals u al zou moeten weten - druk dat als een geheel getal,% x. 885 01:18:02,700 --> 01:18:05,190 We zullen gewoon af te drukken als hexadecimale. 886 01:18:05,190 --> 01:18:10,760 Dus een pointer wordt niet opgeslagen als hexadecimale, 887 01:18:10,760 --> 01:18:12,960 en een geheel getal wordt niet opgeslagen als decimale. 888 01:18:12,960 --> 01:18:14,700 Alles wordt opgeslagen als binaire. 889 01:18:14,700 --> 01:18:17,950 Het is gewoon dat we de neiging om pointers als hexadecimale tonen 890 01:18:17,950 --> 01:18:23,260 omdat we denken dat de dingen in deze 4-byte blokken, 891 01:18:23,260 --> 01:18:25,390 en geheugen adressen hebben de neiging om op de hoogte. 892 01:18:25,390 --> 01:18:28,890 We zijn net als het begint met bf, dan gebeurt het om op de stapel. 893 01:18:28,890 --> 01:18:35,560 Dus het is gewoon onze interpretatie van pointers als hexadecimale. 894 01:18:35,560 --> 01:18:39,200 Oke. Elke laatste vragen? 895 01:18:39,200 --> 01:18:41,700 >> Ik zal er zijn voor een beetje na als je iets anders. 896 01:18:41,700 --> 01:18:46,070 En dat is het einde van die. 897 01:18:46,070 --> 01:18:48,360 >> [Student] Yay! [Applaus] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]