1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Afsnit 4 - Mere behagelig] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Harvard University] 3 00:00:04,850 --> 00:00:07,370 [Dette er CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 Vi har en quiz i morgen, hvis du fyre ikke vide det. 5 00:00:14,810 --> 00:00:20,970 Det er dybest set på alt hvad du kunne have set i klassen eller skulle have set i klassen. 6 00:00:20,970 --> 00:00:26,360 Det omfatter pegepinde, selvom de er en meget nylige emne. 7 00:00:26,360 --> 00:00:29,860 Du bør i det mindste forstå de høje niveauer af dem. 8 00:00:29,860 --> 00:00:34,760 Alt, hvad der var gået over i klassen, bør du forstå for quizzen. 9 00:00:34,760 --> 00:00:37,320 Så hvis du har spørgsmål om dem, kan du bede dem nu. 10 00:00:37,320 --> 00:00:43,280 Men det vil være en meget elev-ledede session, hvor du fyre stille spørgsmål, 11 00:00:43,280 --> 00:00:45,060 så forhåbentlig folk har spørgsmål. 12 00:00:45,060 --> 00:00:48,020 Er der nogen der har spørgsmål? 13 00:00:49,770 --> 00:00:52,090 Ja. >> [Studerende] Kan du gå over pointers igen? 14 00:00:52,090 --> 00:00:54,350 Jeg vil gå over pegepinde. 15 00:00:54,350 --> 00:00:59,180 Alle dine variabler nødvendigvis bor i hukommelsen, 16 00:00:59,180 --> 00:01:04,450 men normalt behøver du ikke bekymre dig om det, og du bare sige x + 2 og y + 3 17 00:01:04,450 --> 00:01:07,080 og compileren vil regne ud, hvor tingene lever for dig. 18 00:01:07,080 --> 00:01:12,990 Når du har at gøre med pointere, nu er du eksplicit vha. disse hukommelse adresser. 19 00:01:12,990 --> 00:01:19,800 Så en enkelt variabel vil kun nogensinde bo på en enkelt adresse på et givet tidspunkt. 20 00:01:19,800 --> 00:01:24,040 Hvis vi ønsker at erklære en pegepind, hvad den type kommer til at se ud? 21 00:01:24,040 --> 00:01:26,210 >> Jeg vil gerne erklære en pointer p. Hvad betyder den type ud? 22 00:01:26,210 --> 00:01:33,530 [Studerende] int * p. >> Yeah. Så int * p. 23 00:01:33,530 --> 00:01:38,030 Og hvordan gør jeg det peger på x? >> [Studerende] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] So-tegn er bogstaveligt talt kaldes adresse operatør. 25 00:01:45,300 --> 00:01:50,460 Så når jeg siger & x det bliver lageradressen af ​​den variable x. 26 00:01:50,460 --> 00:01:56,790 Så nu har jeg markøren p, og hvor som helst i min kode jeg kan bruge * p 27 00:01:56,790 --> 00:02:02,960 eller jeg kunne bruge x, og det vil være præcis de samme ting. 28 00:02:02,960 --> 00:02:09,520 (* P). Hvad er dette gør? Hvad betyder det stjerne betyde? 29 00:02:09,520 --> 00:02:13,120 [Studerende] Det betyder en værdi på det tidspunkt. >> Yeah. 30 00:02:13,120 --> 00:02:17,590 Så hvis vi ser på det, kan det være meget nyttigt at trække de diagrammer 31 00:02:17,590 --> 00:02:22,230 hvor dette er en lille kasse med hukommelse for x, som tilfældigvis har værdien 4, 32 00:02:22,230 --> 00:02:25,980 så har vi en lille kasse med hukommelse for p, 33 00:02:25,980 --> 00:02:31,590 og så p peger på x, så trækker vi en pil fra p til x. 34 00:02:31,590 --> 00:02:40,270 Så når vi siger * p vi siger gå til den boks, der er p. 35 00:02:40,270 --> 00:02:46,480 Star er følg pilen, og derefter gøre hvad du vil med denne boks lige der. 36 00:02:46,480 --> 00:03:01,090 Så jeg kan sige * p = 7, og som vil gå til den boks, der er x og forandring, til 7. 37 00:03:01,090 --> 00:03:13,540 Eller jeg kunne sige int z = * p * 2, det er forvirrende, fordi det er stjerne, stjerne. 38 00:03:13,540 --> 00:03:19,230 Den ene stjerne er dereferere p, er den anden stjerne gange med 2. 39 00:03:19,230 --> 00:03:26,780 Bemærk, at jeg kunne have lige så godt erstattet * p med x. 40 00:03:26,780 --> 00:03:29,430 Du kan bruge dem på samme måde. 41 00:03:29,430 --> 00:03:38,000 Og så senere jeg kan få p peger på en helt ny ting. 42 00:03:38,000 --> 00:03:42,190 Jeg kan bare sige p = &z; 43 00:03:42,190 --> 00:03:44,940 Så nu P ikke længere peger på x, og det peger på z. 44 00:03:44,940 --> 00:03:50,510 Og helst jeg gør * p det er det samme som at gøre z. 45 00:03:50,510 --> 00:03:56,170 Så det nyttige ting om dette er, når vi begynder at komme ind i funktioner. 46 00:03:56,170 --> 00:03:59,790 >> Det er lidt nytteløst at erklære en pegepind, der peger på noget 47 00:03:59,790 --> 00:04:03,140 og så er du bare dereferere det 48 00:04:03,140 --> 00:04:06,060 når du kunne have brugt den oprindelige variabel til at begynde med. 49 00:04:06,060 --> 00:04:18,190 Men når du kommer ind i funktioner - så lad os sige, at vi har nogle funktion, int foo, 50 00:04:18,190 --> 00:04:32,810 der tager en pointer og bare gør * p = 6; 51 00:04:32,810 --> 00:04:39,990 Ligesom vi så før med swap, kan du ikke gøre en effektiv swap og en særskilt funktion 52 00:04:39,990 --> 00:04:45,180 ved blot passerer heltal fordi alt i C altid er forbi værdi. 53 00:04:45,180 --> 00:04:48,360 Selv når du passerer pointers du passerer i værdi. 54 00:04:48,360 --> 00:04:51,940 Det er bare sådan, at disse værdier er hukommelse adresser. 55 00:04:51,940 --> 00:05:00,770 Så når jeg siger foo (p), jeg passerer markøren ind i funktionen Foo 56 00:05:00,770 --> 00:05:03,910 og derefter Foo gør * p = 6; 57 00:05:03,910 --> 00:05:08,600 Så indersiden af ​​denne funktion, er * p stadig svarer til x, 58 00:05:08,600 --> 00:05:12,720 men jeg kan ikke bruge x indersiden af ​​denne funktion, da det ikke er scoped inden for denne funktion. 59 00:05:12,720 --> 00:05:19,510 Så * p = 6 er den eneste måde jeg kan få adgang til en lokal variabel fra en anden funktion. 60 00:05:19,510 --> 00:05:23,600 Eller, ja, pointers er den eneste måde jeg kan få adgang til en lokal variabel fra en anden funktion. 61 00:05:23,600 --> 00:05:31,600 [Studerende] Lad os sige at du ville returnere en pegepind. Hvordan præcist gør man det? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Returner en pointer som i noget lignende int y = 3; afkast & y? >> [Studerende] Yeah. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Okay. Du bør aldrig gøre det. Det er skidt. 64 00:05:48,480 --> 00:05:59,480 Jeg tror jeg så i disse forelæsninger dias du begyndte at se hele denne diagram af hukommelse 65 00:05:59,480 --> 00:06:02,880 hvor op her du har fået hukommelse adresse 0 66 00:06:02,880 --> 00:06:09,550 og hernede har du hukommelsesadressekonstanter 4 gigs eller 2 til 32. 67 00:06:09,550 --> 00:06:15,120 Så du har fået nogle ting og nogle ting og så har du din stack 68 00:06:15,120 --> 00:06:21,780 og du har fået din bunke, som du lige er begyndt at lære om, at vokse op. 69 00:06:21,780 --> 00:06:24,390 [Studerende] Er ikke den bunke oven i stakken? 70 00:06:24,390 --> 00:06:27,760 >> Yeah. Den bunke er på toppen, er det ikke? >> [Studerende] Nå, han lagde 0 på toppen. 71 00:06:27,760 --> 00:06:30,320 [Studerende] Åh, han satte 0 på toppen. >> [Studerende] Åh, okay. 72 00:06:30,320 --> 00:06:36,060 Disclaimer: Anywhere med CS50 du kommer til at se det på denne måde. >> [Studerende] Okay. 73 00:06:36,060 --> 00:06:40,290 Det er bare, at når du først ser stakke, 74 00:06:40,290 --> 00:06:45,000 ligesom når du tænker på en stak du tænker på at stable ting oven på hinanden. 75 00:06:45,000 --> 00:06:50,810 Så vi har en tendens til at vende dette rundt, så stakken vokser op som en stak normalt ville 76 00:06:50,810 --> 00:06:55,940 stedet for stablen hænger ned. >> [Studerende] ikke dynger teknisk vokse op for, selvom? 77 00:06:55,940 --> 00:07:01,100 Det afhænger af hvad du mener med at vokse op. 78 00:07:01,100 --> 00:07:04,010 Stakken og heap altid vokse i modsatte retninger. 79 00:07:04,010 --> 00:07:09,420 En stak er altid vokser op i den forstand, at det vokser op 80 00:07:09,420 --> 00:07:12,940 mod højere hukommelse adresser, og bunke vokser ned 81 00:07:12,940 --> 00:07:17,260 i at det vokser i retning af lavere hukommelse adresser. 82 00:07:17,260 --> 00:07:20,250 Så toppen er 0, og bunden er høj hukommelse adresser. 83 00:07:20,250 --> 00:07:26,390 De er begge stadig, bare i modsatte retninger. 84 00:07:26,390 --> 00:07:29,230 [Studerende] Jeg mente bare, at fordi du sagde, du lægger stakken på bunden 85 00:07:29,230 --> 00:07:33,640 fordi det forekommer mere intuitivt grund for stakken at starte på toppen af ​​en bunke, 86 00:07:33,640 --> 00:07:37,520 bunke er oven på sig selv også, så that's - >> Yeah. 87 00:07:37,520 --> 00:07:44,960 Du kan også tænke på bunke som vokser op og større, men stakken mere så. 88 00:07:44,960 --> 00:07:50,280 Så stakken er den, vi slags ønsker at vise vokse op. 89 00:07:50,280 --> 00:07:55,390 Men overalt du ser ellers vil vise adresse 0 øverst 90 00:07:55,390 --> 00:07:59,590 og den højeste hukommelse adressen nederst, så dette er din sædvanlige billede af hukommelsen. 91 00:07:59,590 --> 00:08:02,100 >> Har du et spørgsmål? 92 00:08:02,100 --> 00:08:04,270 [Studerende] Kan du fortælle os mere om bunke? 93 00:08:04,270 --> 00:08:06,180 Yeah. Jeg kommer til om et øjeblik. 94 00:08:06,180 --> 00:08:12,220 Først går tilbage til hvorfor returnering & y er en dårlig ting, 95 00:08:12,220 --> 00:08:18,470 på stakken du har en masse stakrammer, som repræsenterer alle de funktioner 96 00:08:18,470 --> 00:08:20,460 der er blevet kaldt. 97 00:08:20,460 --> 00:08:27,990 Så ignorerer tidligere ting er toppen af ​​din stack altid vil være den primære funktion 98 00:08:27,990 --> 00:08:33,090 da det er den første funktion, der bliver kaldt. 99 00:08:33,090 --> 00:08:37,130 Og så når du kalder en anden funktion, er stakken vil vokse ned. 100 00:08:37,130 --> 00:08:41,640 Så hvis jeg kalder en funktion, foo, og det får sin egen stakramme, 101 00:08:41,640 --> 00:08:47,280 den kan kalde en funktion, bar, det får sin egen stakramme. 102 00:08:47,280 --> 00:08:49,840 Og bar kunne være rekursiv, og det kunne kalde sig, 103 00:08:49,840 --> 00:08:54,150 og således at andet opkald til bar vil få sin egen stakramme. 104 00:08:54,150 --> 00:08:58,880 Og så hvad der går i disse stakrammer er alle de lokale variable 105 00:08:58,880 --> 00:09:03,450 og alle de funktionsargumenter at - 106 00:09:03,450 --> 00:09:08,730 Eventuelle ting, der er lokalt scoped til denne funktion gå i disse stakrammer. 107 00:09:08,730 --> 00:09:21,520 Så det betyder, når jeg sagde noget i retning bar er en funktion, 108 00:09:21,520 --> 00:09:29,270 Jeg skal bare til at erklære et heltal og derefter returnere en pegepind til denne heltal. 109 00:09:29,270 --> 00:09:33,790 Så hvor kommer y bor? 110 00:09:33,790 --> 00:09:36,900 [Studerende] y bor i bar. >> [Bowden] Yeah. 111 00:09:36,900 --> 00:09:45,010 Et sted i denne lille firkant af hukommelse er en littler firkant, der har y i det. 112 00:09:45,010 --> 00:09:53,370 Når jeg vender tilbage & Y, jeg returnerer en pointer til denne lille blok af hukommelse. 113 00:09:53,370 --> 00:09:58,400 Men så når en funktionen returnerer, bliver dens stakramme poppet fra stakken. 114 00:10:01,050 --> 00:10:03,530 Og det er derfor, det hedder stakken. 115 00:10:03,530 --> 00:10:06,570 Det er ligesom stakken datastruktur, hvis du ved hvad det er. 116 00:10:06,570 --> 00:10:11,580 Eller endda som en stak af bakker er altid eksempel, 117 00:10:11,580 --> 00:10:16,060 main kommer til at gå på bunden, så den første funktion du kalder kommer til at gå på toppen af ​​det, 118 00:10:16,060 --> 00:10:20,400 og du kan ikke komme tilbage til main indtil du vender tilbage fra alle funktioner, der er blevet kaldt 119 00:10:20,400 --> 00:10:22,340 som er blevet anbragt oven på den. 120 00:10:22,340 --> 00:10:28,650 >> [Studerende] Så hvis du gjorde gøre returnere & y, at værdien kan ændres uden varsel. 121 00:10:28,650 --> 00:10:31,290 Ja, det er - >> [studerende] Det kunne være overskrevet. >> Yeah. 122 00:10:31,290 --> 00:10:34,660 Det er helt - Hvis du prøver og - 123 00:10:34,660 --> 00:10:38,040 Dette ville også være en int * bar fordi det returnerer en pointer, 124 00:10:38,040 --> 00:10:41,310 så dens returtype er int *. 125 00:10:41,310 --> 00:10:46,500 Hvis du forsøger at bruge returværdien af ​​denne funktion, er det udefineret adfærd 126 00:10:46,500 --> 00:10:51,770 fordi denne pegepind peger på dårlig hukommelse. >> [Studerende] Okay. 127 00:10:51,770 --> 00:11:01,250 Så hvad nu hvis, for eksempel, erklærede du int * y = malloc (sizeof (int))? 128 00:11:01,250 --> 00:11:03,740 Det er bedre. Ja. 129 00:11:03,740 --> 00:11:07,730 [Studerende] Vi talte om, hvordan når vi trækker ting til vores papirkurven 130 00:11:07,730 --> 00:11:11,750 de er faktisk ikke slettet, vi skal bare miste deres pointers. 131 00:11:11,750 --> 00:11:15,550 Så i dette tilfælde har vi faktisk slette værdien, eller er det stadig i hukommelsen? 132 00:11:15,550 --> 00:11:19,130 For det meste, det vil stadig være der. 133 00:11:19,130 --> 00:11:24,220 Men lad os sige, at vi tilfældigvis kalde en anden funktion, baz. 134 00:11:24,220 --> 00:11:28,990 Baz kommer til at få sin egen stakramme på her. 135 00:11:28,990 --> 00:11:31,470 Det kommer til at blive overskrive alle disse ting, 136 00:11:31,470 --> 00:11:34,180 og derefter, hvis du senere forsøge at bruge markøren som du fik før, 137 00:11:34,180 --> 00:11:35,570 det kommer ikke til at være den samme værdi. 138 00:11:35,570 --> 00:11:38,150 Det kommer til at have ændret sig, bare fordi du kaldte funktionen Baz. 139 00:11:38,150 --> 00:11:43,080 [Studerende] Men havde vi ikke, ville vi stadig få 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] Efter al sandsynlighed ville du. 141 00:11:44,990 --> 00:11:49,670 Men du kan ikke stole på det. C bare siger udefineret adfærd. 142 00:11:49,670 --> 00:11:51,920 >> [Studerende] Åh, det gør. Okay. 143 00:11:51,920 --> 00:11:58,190 Så når du ønsker at returnere en pegepind, er det her malloc kommer i brug. 144 00:12:00,930 --> 00:12:15,960 Jeg skriver faktisk bare returnere malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Vi vil gå over malloc mere i en anden, men tanken om malloc er alle dine lokale variable 146 00:12:24,050 --> 00:12:26,760 altid gå på stakken. 147 00:12:26,760 --> 00:12:31,570 Alt, hvad der er malloced går på bunke, og det vil for evigt og altid være på heapen 148 00:12:31,570 --> 00:12:34,490 indtil du eksplicit frigøre det. 149 00:12:34,490 --> 00:12:42,130 Så det betyder, at når du malloc noget, det kommer til at overleve efter funktionen returnerer. 150 00:12:42,130 --> 00:12:46,800 [Studerende] Vil det overleve, når programmet stopper? >> Nej. 151 00:12:46,800 --> 00:12:53,180 Okay, så det kommer til at være der, indtil programmet er helt færdig kører. >> Ja. 152 00:12:53,180 --> 00:12:57,510 Vi kan gå over oplysninger om, hvad der sker, når programmet stopper. 153 00:12:57,510 --> 00:13:02,150 Du skal muligvis til at minde mig, men det er en særskilt ting helt. 154 00:13:02,150 --> 00:13:04,190 [Studerende] So malloc skaber en pointer? >> Yeah. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [studerende] Jeg tror malloc betegner en blok af hukommelse, en pegepind kan bruge. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Jeg ønsker at diagrammet igen. >> [Studerende] Så denne funktion virker, selvom? 157 00:13:19,610 --> 00:13:26,430 [Studerende] Yeah, malloc betegner en blok af hukommelse, som du kan bruge, 158 00:13:26,430 --> 00:13:30,470 og derefter returnerer adressen på den første blok i denne hukommelse. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Yeah. Så når du malloc, du snuppe nogle blok af hukommelse 160 00:13:36,750 --> 00:13:38,260 Det er i øjeblikket i bunke. 161 00:13:38,260 --> 00:13:43,040 Hvis bunke er for lille, så den bunke er bare at vokse, og den vokser i denne retning. 162 00:13:43,040 --> 00:13:44,650 Så lad os sige den bunke er for lille. 163 00:13:44,650 --> 00:13:49,960 Så det handler om at vokse en lille smule og returnere en pegepind til denne blok, der bare voksede. 164 00:13:49,960 --> 00:13:55,130 Når du gratis ting, du gør mere plads i bunke, 165 00:13:55,130 --> 00:14:00,030 så derefter en senere kald til malloc kan genbruge denne hukommelse, som du tidligere havde befriet. 166 00:14:00,030 --> 00:14:09,950 Det vigtige ved malloc og gratis er, at det giver dig fuld kontrol 167 00:14:09,950 --> 00:14:12,700 over levetiden for disse hukommelsesblokke. 168 00:14:12,700 --> 00:14:15,420 Globale variabler er altid i live. 169 00:14:15,420 --> 00:14:18,500 Lokale variabler er i live inden for deres rækkevidde. 170 00:14:18,500 --> 00:14:22,140 Så snart du går forbi en klammeparentes, de lokale variable er døde. 171 00:14:22,140 --> 00:14:28,890 Malloced hukommelse er i live, når du ønsker det at være i live 172 00:14:28,890 --> 00:14:33,480 og derefter frigives, når du fortæller det til at blive frigivet. 173 00:14:33,480 --> 00:14:38,420 Det er faktisk de eneste 3 typer af hukommelse, virkelig. 174 00:14:38,420 --> 00:14:41,840 Der er automatisk hukommelse forvaltning, hvilket er stakken. 175 00:14:41,840 --> 00:14:43,840 Tingene sker automatisk for dig. 176 00:14:43,840 --> 00:14:46,910 Når du siger int x, hukommelse afsat til int x. 177 00:14:46,910 --> 00:14:51,630 Når x går ud af rækkevidde, er hukommelsen regenereret for x. 178 00:14:51,630 --> 00:14:54,790 Så er der dynamisk hukommelse ledelse, hvilket er hvad malloc er, 179 00:14:54,790 --> 00:14:56,740 der er, når du har kontrol. 180 00:14:56,740 --> 00:15:01,290 Du dynamisk beslutte, hvornår hukommelsen bør og ikke bør tildeles. 181 00:15:01,290 --> 00:15:05,050 Og så er der statisk, hvilket betyder blot, at den lever for evigt, 182 00:15:05,050 --> 00:15:06,610 hvilket er, hvad globale variabler. 183 00:15:06,610 --> 00:15:10,240 De er bare altid i hukommelsen. 184 00:15:10,960 --> 00:15:12,760 >> Spørgsmål? 185 00:15:14,490 --> 00:15:17,230 [Studerende] Kan du definere en blok blot ved hjælp af krøllede parenteser 186 00:15:17,230 --> 00:15:21,220 men ikke behøver at have en if-sætning eller et stykke erklæring eller noget i den retning? 187 00:15:21,220 --> 00:15:29,130 Du kan definere en blok som i en funktion, men som har krøllede parenteser også. 188 00:15:29,130 --> 00:15:32,100 [Studerende] Så du kan ikke bare have som en tilfældig par krøllede parenteser i din kode 189 00:15:32,100 --> 00:15:35,680 der har lokale variabler? >> Ja, du kan. 190 00:15:35,680 --> 00:15:45,900 Inside of int bar vi kunne have {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 Det er meningen at være lige her. 192 00:15:48,440 --> 00:15:52,450 Men det er helt definerer omfanget af int y. 193 00:15:52,450 --> 00:15:57,320 Efter denne anden klammeparentes, kan y ikke bruges længere. 194 00:15:57,910 --> 00:16:00,630 Du næsten aldrig gøre det, selv om. 195 00:16:02,940 --> 00:16:07,370 Kom tilbage til, hvad der sker, når et program slutter, 196 00:16:07,370 --> 00:16:18,760 Der er lidt af en misforståelse / halv løgn, at vi giver, for at bare gøre tingene lettere. 197 00:16:18,760 --> 00:16:24,410 Vi fortæller dig, at når du allokere hukommelse 198 00:16:24,410 --> 00:16:29,860 du afsætte nogle bid af RAM for denne variabel. 199 00:16:29,860 --> 00:16:34,190 Men du er ikke rigtig direkte berøring RAM nogensinde i dine programmer. 200 00:16:34,190 --> 00:16:37,490 Hvis du tænker over det, hvordan jeg gjorde - 201 00:16:37,490 --> 00:16:44,330 Og faktisk, hvis du går gennem i GDB du vil se det samme. 202 00:16:51,120 --> 00:16:57,590 Uanset hvor mange gange du kører dit program eller hvilket program, du kører, 203 00:16:57,590 --> 00:16:59,950 stakken vil altid starte - 204 00:16:59,950 --> 00:17:06,510 du altid kommer til at se variabler omkring adresse oxbffff noget. 205 00:17:06,510 --> 00:17:09,470 Det er normalt et sted i denne region. 206 00:17:09,470 --> 00:17:18,760 Men hvordan kan 2 programmer muligvis have henvisninger til den samme hukommelse? 207 00:17:20,640 --> 00:17:27,650 [Studerende] Der er nogle vilkårlige udpegning af hvor oxbfff formodes at være på RAM 208 00:17:27,650 --> 00:17:31,320 der rent faktisk kan være forskellige steder afhængigt af, når funktionen blev kaldt. 209 00:17:31,320 --> 00:17:35,920 Yeah. Udtrykket er virtuel hukommelse. 210 00:17:35,920 --> 00:17:42,250 Ideen er, at hver enkelt proces, hver eneste program, der kører på din computer 211 00:17:42,250 --> 00:17:49,450 har sin egen - lad os antage 32 bit - helt uafhængig adresse plads. 212 00:17:49,450 --> 00:17:51,590 Dette er den adresse rummet. 213 00:17:51,590 --> 00:17:56,220 Det har sine egne helt uafhængige 4 gigabyte til at bruge. 214 00:17:56,220 --> 00:18:02,220 >> Så hvis du kører 2 programmer samtidigt, dette program ser 4 gigabyte til sig selv, 215 00:18:02,220 --> 00:18:04,870 dette program ser 4 gigabyte til sig selv, 216 00:18:04,870 --> 00:18:07,720 og det er umuligt for dette program at dereference en pegepind 217 00:18:07,720 --> 00:18:10,920 og ender med hukommelse fra dette program. 218 00:18:10,920 --> 00:18:18,200 Og hvad virtuel hukommelse er er en kortlægning fra et processer adresse rum 219 00:18:18,200 --> 00:18:20,470 til de faktiske ting på RAM. 220 00:18:20,470 --> 00:18:22,940 Så det er op til dit operativsystem for at vide, 221 00:18:22,940 --> 00:18:28,080 hey, når denne fyr dereferences pointer oxbfff, der virkelig betyder 222 00:18:28,080 --> 00:18:31,040 at han ønsker RAM byte 1000, 223 00:18:31,040 --> 00:18:38,150 hvorimod hvis dette program dereferences oxbfff, han virkelig ønsker RAM byte 10000. 224 00:18:38,150 --> 00:18:41,590 De kan være vilkårligt langt fra hinanden. 225 00:18:41,590 --> 00:18:48,730 Dette er endda tilfældet med tingene inden for en enkelt processer adresse rummet. 226 00:18:48,730 --> 00:18:54,770 Så ligesom det ser alle 4 gigabyte til sig selv, men lad os sige - 227 00:18:54,770 --> 00:18:57,290 [Studerende] Har hver enkelt proces - 228 00:18:57,290 --> 00:19:01,350 Lad os sige du har en computer med kun 4 GB RAM. 229 00:19:01,350 --> 00:19:06,430 Har hver enkelt proces se hele 4 gigabyte? >> Ja. 230 00:19:06,430 --> 00:19:13,060 Men de 4 gigabyte den ser er en løgn. 231 00:19:13,060 --> 00:19:20,460 Det er bare det mener, at det har alt dette hukommelsen, fordi den ikke kender nogen anden proces eksisterer. 232 00:19:20,460 --> 00:19:28,140 Det vil kun bruge så meget hukommelse, som den faktisk har brug for. 233 00:19:28,140 --> 00:19:32,340 Operativsystemet er ikke vil give RAM til denne proces 234 00:19:32,340 --> 00:19:35,750 hvis det ikke bruger nogen hukommelse i hele denne region. 235 00:19:35,750 --> 00:19:39,300 Det kommer ikke til at give det hukommelsen for denne region. 236 00:19:39,300 --> 00:19:54,780 Men ideen er, at - Jeg forsøger at tænke på - jeg kan ikke tænke på en analogi. 237 00:19:54,780 --> 00:19:56,780 Analogier er hårdt. 238 00:19:57,740 --> 00:20:02,700 Et af de spørgsmål virtuel hukommelse eller en af ​​de ting det er at løse 239 00:20:02,700 --> 00:20:06,810 er, at processer bør være helt klar over hinanden. 240 00:20:06,810 --> 00:20:12,140 Og så du kan skrive et program, der bare dereferences nogen pointer, 241 00:20:12,140 --> 00:20:19,340 gerne bare skrive et program, der siger * (ox1234), 242 00:20:19,340 --> 00:20:22,890 og det er dereferere hukommelse adresse 1234. 243 00:20:22,890 --> 00:20:28,870 >> Men det er op til det operativsystem, der derefter oversætte hvad 1234 betyder. 244 00:20:28,870 --> 00:20:33,960 Så hvis 1234 sker for at være en gyldig hukommelse adresse til denne proces, 245 00:20:33,960 --> 00:20:38,800 ligesom det er på stakken eller noget, så vil dette returnere værdien af ​​at hukommelsen adresse 246 00:20:38,800 --> 00:20:41,960 for så vidt angår fremgangsmåden, ved. 247 00:20:41,960 --> 00:20:47,520 Men hvis 1234 er ikke en gyldig adresse, ligesom det sker at lande 248 00:20:47,520 --> 00:20:52,910 i nogle lille stykke af hukommelse, som ligger hinsides stakken og ud over dyngen 249 00:20:52,910 --> 00:20:57,200 og du har ikke rigtig brugt det, så det er når du får ting som segfault'er 250 00:20:57,200 --> 00:21:00,260 fordi du rører hukommelse, som du ikke bør røre. 251 00:21:07,180 --> 00:21:09,340 Det er også sandt - 252 00:21:09,340 --> 00:21:15,440 En 32-bit system, 32 bit betyder, at du har 32 bits til at definere en hukommelse adresse. 253 00:21:15,440 --> 00:21:22,970 Det er derfor, pegepinde er 8 bytes, fordi 32 bit er 8 bytes - eller 4 bytes. 254 00:21:22,970 --> 00:21:25,250 Pointers er 4 bytes. 255 00:21:25,250 --> 00:21:33,680 Så når du ser en pegepind som oxbfffff, der er - 256 00:21:33,680 --> 00:21:40,080 Inden et givent program kan du bare konstruere en vilkårlig pointer, 257 00:21:40,080 --> 00:21:46,330 hvor som helst fra ox0 til ox 8 f's - FFFFFFFF. 258 00:21:46,330 --> 00:21:49,180 [Studerende] Sagde du ikke, de er 4 byte? >> Yeah. 259 00:21:49,180 --> 00:21:52,730 [Studerende] Så hver byte vil have - >> [Bowden] Hexadecimal. 260 00:21:52,730 --> 00:21:59,360 Hexadecimal - 5, 6, 7, 8. Så pointers du vil altid se i hexadecimal. 261 00:21:59,360 --> 00:22:01,710 Det er bare hvordan vi klassificerer pointers. 262 00:22:01,710 --> 00:22:05,240 Hver 2 cifre af hexadecimal er 1 byte. 263 00:22:05,240 --> 00:22:09,600 Så der kommer til at være 8 hexadecimale cifre til 4 bytes. 264 00:22:09,600 --> 00:22:14,190 Så hver eneste markør på en 32-bit system vil være 4 byte, 265 00:22:14,190 --> 00:22:18,550 hvilket betyder, at din proces kan du konstruere vilkårlige 4 byte 266 00:22:18,550 --> 00:22:20,550 og lave en pointer ud af det, 267 00:22:20,550 --> 00:22:32,730 hvilket betyder, at så vidt det er bekendt, kan den afgive en hel 2 til 32 bytes hukommelse. 268 00:22:32,730 --> 00:22:34,760 Selvom det ikke rigtig har adgang til det, 269 00:22:34,760 --> 00:22:40,190 selvom din computer kun har 512 megabyte, men mener, det har så meget hukommelse. 270 00:22:40,190 --> 00:22:44,930 Og operativsystemet er smart nok, at det kun vil tildele hvad du rent faktisk har brug for. 271 00:22:44,930 --> 00:22:49,630 Det er ikke bare gå, åh, en ny proces: 4 gigs. 272 00:22:49,630 --> 00:22:51,930 >> Yeah. >> [Studerende] Hvad betyder okse betyde? Hvorfor skriver du det? 273 00:22:51,930 --> 00:22:54,980 Det er bare et symbol for hexadecimal. 274 00:22:54,980 --> 00:22:59,590 Når du ser et nummer starter med okse, de successive ting er hexadecimal. 275 00:23:01,930 --> 00:23:05,760 [Studerende] Du var forklare om, hvad der sker, når et program slutter. >> Ja. 276 00:23:05,760 --> 00:23:09,480 Hvad sker der, når et program slutter, er operativsystemet 277 00:23:09,480 --> 00:23:13,600 bare sletter kortlægninger, at det har for disse adresser, og det er det. 278 00:23:13,600 --> 00:23:17,770 Operativsystemet kan nu nøjes med at give denne hukommelse til et andet program til at bruge. 279 00:23:17,770 --> 00:23:19,490 [Elev] Okay. 280 00:23:19,490 --> 00:23:24,800 Så når du allokere noget på heapen eller de stak eller globale variabler eller noget, 281 00:23:24,800 --> 00:23:27,010 de alle bare forsvinde, så snart programmet slutter 282 00:23:27,010 --> 00:23:32,120 da operativsystemet er nu fri til at give denne hukommelse til enhver anden proces. 283 00:23:32,120 --> 00:23:35,150 [Studerende] Selvom der er sandsynligvis stadig værdier skrevet i? >> Yeah. 284 00:23:35,150 --> 00:23:37,740 Værdierne er sandsynligvis stadig. 285 00:23:37,740 --> 00:23:41,570 Det er bare det vil være vanskeligt at få ram på dem. 286 00:23:41,570 --> 00:23:45,230 Det er meget sværere at få ram på dem, end det er at komme på en slettet fil 287 00:23:45,230 --> 00:23:51,450 fordi den slettede fil slags sidder der i lang tid, og harddisken er en meget større. 288 00:23:51,450 --> 00:23:54,120 Så det kommer til at overskrive forskellige dele af hukommelsen 289 00:23:54,120 --> 00:23:58,640 før det sker at overskrive bid af hukommelse, denne fil bruges til at være på. 290 00:23:58,640 --> 00:24:04,520 Men hovedlager, RAM, du bladre gennem en hel del hurtigere, 291 00:24:04,520 --> 00:24:08,040 så det kommer til at meget hurtigt blive overskrevet. 292 00:24:10,300 --> 00:24:13,340 Spørgsmål til dette eller noget andet? 293 00:24:13,340 --> 00:24:16,130 [Studerende] Jeg har spørgsmål om et andet emne. >> Okay. 294 00:24:16,130 --> 00:24:19,060 Er der nogen der har spørgsmål om dette? 295 00:24:20,170 --> 00:24:23,120 >> Okay. Andet emne. >> [Studerende] Okay. 296 00:24:23,120 --> 00:24:26,550 Jeg gik gennem nogle af de praksis tests, 297 00:24:26,550 --> 00:24:30,480 og i en af ​​dem det talte om sizeof 298 00:24:30,480 --> 00:24:35,630 og den værdi, den returnerer eller forskellige variable typer. >> Ja. 299 00:24:35,630 --> 00:24:45,060 Og det siges, at både int og lang både tilbagevenden 4, så de er begge 4 byte lang. 300 00:24:45,060 --> 00:24:48,070 Er der nogen forskel mellem en int og en lang, eller er det det samme? 301 00:24:48,070 --> 00:24:50,380 Ja, der er en forskel. 302 00:24:50,380 --> 00:24:52,960 The C standard - 303 00:24:52,960 --> 00:24:54,950 Jeg er nok kommer til at rod op. 304 00:24:54,950 --> 00:24:58,800 C-standard er ligesom hvad C er den officielle dokumentation C. 305 00:24:58,800 --> 00:25:00,340 Dette er, hvad det siger. 306 00:25:00,340 --> 00:25:08,650 Så C standard bare siger, at en char vil for evigt og altid være 1 byte. 307 00:25:10,470 --> 00:25:19,040 Alt efter, at - en kort er altid lige defineres som værende større end eller lig med en char. 308 00:25:19,040 --> 00:25:23,010 Dette kan være strengt større end, men ikke positiv. 309 00:25:23,010 --> 00:25:31,940 En int er lige defineres som værende større end eller lig med en kort. 310 00:25:31,940 --> 00:25:36,210 Og et langt er netop defineret som værende større end eller lig med en int. 311 00:25:36,210 --> 00:25:41,600 Og en lang lang er større end eller lig med lang. 312 00:25:41,600 --> 00:25:46,610 Så det eneste, C standarden definerer, er den relative rækkefølge af alt. 313 00:25:46,610 --> 00:25:54,880 Den faktiske mængde hukommelse, ting tager op er almindeligvis op til gennemførelsen, 314 00:25:54,880 --> 00:25:57,640 men det er temmelig godt defineret på dette punkt. >> [Studerende] Okay. 315 00:25:57,640 --> 00:26:02,490 Så shorts er næsten altid vil være 2 byte. 316 00:26:04,920 --> 00:26:09,950 Ints er næsten altid vil være 4 byte. 317 00:26:12,070 --> 00:26:15,340 Lange længes næsten altid vil være 8 byte. 318 00:26:17,990 --> 00:26:23,160 Og længes, det afhænger af, om du bruger en 32-bit eller en 64-bit system. 319 00:26:23,160 --> 00:26:27,450 Så længe vil svare til den type system. 320 00:26:27,450 --> 00:26:31,920 Hvis du bruger en 32-bit system som Appliance, går det at være 4 byte. 321 00:26:34,530 --> 00:26:42,570 Hvis du bruger en 64-bit som en masse af de seneste computere, går det at være 8 bytes. 322 00:26:42,570 --> 00:26:45,230 >> Ints er næsten altid 4 byte på dette punkt. 323 00:26:45,230 --> 00:26:47,140 Lange længes er næsten altid 8 bytes. 324 00:26:47,140 --> 00:26:50,300 I fortiden, brugte int'er kun være 2 bytes. 325 00:26:50,300 --> 00:26:56,840 Men bemærk, at denne helt opfylder alle disse relationer er større end og lig med. 326 00:26:56,840 --> 00:27:01,280 Så længe er perfekt lov til at være samme størrelse som et helt tal, 327 00:27:01,280 --> 00:27:04,030 og det er også tilladt at være den samme størrelse som en lang lang. 328 00:27:04,030 --> 00:27:11,070 Og det bare så sker for at være, at der i 99,999% af systemerne, er det vil være lig med 329 00:27:11,070 --> 00:27:15,800 enten en int eller en lang lang. Det bare afhænger af 32-bit eller 64-bit. >> [Studerende] Okay. 330 00:27:15,800 --> 00:27:24,600 I flåd, er, hvordan decimaltegnet udpeget i form af bits? 331 00:27:24,600 --> 00:27:27,160 Ligesom som binær? >> Yeah. 332 00:27:27,160 --> 00:27:30,570 Du behøver ikke at vide, at for CS50. 333 00:27:30,570 --> 00:27:32,960 Du behøver ikke engang lære, at i 61. 334 00:27:32,960 --> 00:27:37,350 Du behøver ikke lære at virkelig i ethvert kursus. 335 00:27:37,350 --> 00:27:42,740 Det er bare en repræsentation. 336 00:27:42,740 --> 00:27:45,440 Jeg glemmer de eksakte bit kolonihaver. 337 00:27:45,440 --> 00:27:53,380 Ideen med flydende punkt er, at man afsætter et bestemt antal bit til at repræsentere - 338 00:27:53,380 --> 00:27:56,550 Dybest set, alt er i videnskabelig notation. 339 00:27:56,550 --> 00:28:05,600 Så du tildele et bestemt antal bits til at repræsentere selve nummeret, ligesom 1,2345. 340 00:28:05,600 --> 00:28:10,200 Jeg kan aldrig repræsentere et tal med flere cifre end 5. 341 00:28:12,200 --> 00:28:26,300 Så kan du også tildele et bestemt antal bits, så det har en tendens til at være ligesom 342 00:28:26,300 --> 00:28:32,810 du kan kun gå op til et vist antal, ligesom det er den største eksponent du kan have, 343 00:28:32,810 --> 00:28:36,190 og du kan kun gå ned til en vis eksponent, 344 00:28:36,190 --> 00:28:38,770 gerne, der er den mindste eksponent du kan have. 345 00:28:38,770 --> 00:28:44,410 >> Jeg kan ikke huske den præcise måde bits er tildelt til alle disse værdier, 346 00:28:44,410 --> 00:28:47,940 men et vist antal bit er dedikeret til 1,2345, 347 00:28:47,940 --> 00:28:50,930 andet bestemt antal bits er dedikeret til eksponent, 348 00:28:50,930 --> 00:28:55,670 og det er kun muligt at repræsentere en eksponent for en vis størrelse. 349 00:28:55,670 --> 00:29:01,100 [Studerende] Og en dobbelt? Er det ligesom en ekstra lang float? >> Yeah. 350 00:29:01,100 --> 00:29:07,940 Det er det samme som en float undtagen nu du bruger 8 bytes i stedet for 4 byte. 351 00:29:07,940 --> 00:29:11,960 Nu vil du være i stand til at bruge 9 cifre eller 10 cifre, 352 00:29:11,960 --> 00:29:16,630 og dette vil være i stand til at gå op til 300 i stedet for 100. >> [Studerende] Okay. 353 00:29:16,630 --> 00:29:21,550 Og flåd er også 4 bytes. >> Ja. 354 00:29:21,550 --> 00:29:27,520 Nå, igen, det afhænger nok overall den generelle gennemførelse, 355 00:29:27,520 --> 00:29:30,610 men flåd er 4 bytes, doubler er 8. 356 00:29:30,610 --> 00:29:33,440 Doubles kaldes dobbelt, fordi de er dobbelt størrelse af flåd. 357 00:29:33,440 --> 00:29:38,380 [Elev] Okay. Og er der dobbelt fordobler? >> Der er ikke. 358 00:29:38,380 --> 00:29:43,660 Jeg tror - >> [studerende] Kan du lide lange længes? >> Yeah. Det tror jeg ikke. Ja. 359 00:29:43,660 --> 00:29:45,950 [Studerende] Den sidste års test var der et spørgsmål om den primære funktion 360 00:29:45,950 --> 00:29:49,490 skulle være en del af dit program. 361 00:29:49,490 --> 00:29:52,310 Svaret var, at det ikke behøver at være en del af dit program. 362 00:29:52,310 --> 00:29:55,100 I hvilken situation? Det er, hvad jeg så. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Det synes - >> [studerende] Hvad situation? 364 00:29:59,090 --> 00:30:02,880 Har du problemet? >> [Studerende] Ja, jeg kan helt sikkert trække det op. 365 00:30:02,880 --> 00:30:07,910 Det behøver ikke at være teknisk, men dybest set er det kommer til at være. 366 00:30:07,910 --> 00:30:10,030 [Studerende] Jeg så en på et andet år. 367 00:30:10,030 --> 00:30:16,220 Det var ligesom Sandt eller falsk: Et gyldigt - >> Åh, en c-fil.? 368 00:30:16,220 --> 00:30:18,790 . [Studerende] Enhver c-filen skal have - [både taler på én gang - uforståelig] 369 00:30:18,790 --> 00:30:21,120 Okay. Så det er adskilt. 370 00:30:21,120 --> 00:30:26,800 >> A. C. fil bare nødt til at indeholde funktioner. 371 00:30:26,800 --> 00:30:32,400 Du kan udarbejde en fil til maskinkode, binær, uanset, 372 00:30:32,400 --> 00:30:36,620 uden at det er eksekverbar endnu. 373 00:30:36,620 --> 00:30:39,420 En gyldig eksekverbar skal have en hovedfunktion. 374 00:30:39,420 --> 00:30:45,460 Du kan skrive 100 funktioner i 1 fil, men ingen vigtigste 375 00:30:45,460 --> 00:30:48,800 og derefter kompilere at ned til binær, 376 00:30:48,800 --> 00:30:54,460 så skriver du en anden fil, der kun har main men det kræver en masse af disse funktioner 377 00:30:54,460 --> 00:30:56,720 i denne binære fil herovre. 378 00:30:56,720 --> 00:31:01,240 Og så når du laver den eksekverbare, det er hvad linkeren gør 379 00:31:01,240 --> 00:31:05,960 er det kombinerer disse 2 binære filer til en eksekverbar. 380 00:31:05,960 --> 00:31:11,400 Så en. C. fil behøver ikke at have en hovedfunktion på alle. 381 00:31:11,400 --> 00:31:19,220 Og på store kodebaser du vil se tusindvis af. C-filer og 1 vigtigste fil. 382 00:31:23,960 --> 00:31:26,110 Flere spørgsmål? 383 00:31:29,310 --> 00:31:31,940 [Studerende] Der var et andet spørgsmål. 384 00:31:31,940 --> 00:31:36,710 Det sagde gøre er en compiler. Sandt eller falsk? 385 00:31:36,710 --> 00:31:42,030 Og svaret var forkert, og jeg forstod, hvorfor det er ikke ligesom Dunk. 386 00:31:42,030 --> 00:31:44,770 Men hvad gør vi kalder gøre, hvis det ikke er? 387 00:31:44,770 --> 00:31:49,990 Gør er dybest set bare - jeg kan se præcis, hvad den kalder det. 388 00:31:49,990 --> 00:31:52,410 Men det bare kører kommandoer. 389 00:31:53,650 --> 00:31:55,650 Gør. 390 00:31:58,240 --> 00:32:00,870 Jeg kan trække det op. Yeah. 391 00:32:10,110 --> 00:32:13,180 Oh, yeah. Gør også gør det. 392 00:32:13,180 --> 00:32:17,170 Det siger formålet med make nytte er automatisk at afgøre 393 00:32:17,170 --> 00:32:19,610 hvilke dele af et stort program som behøver at blive genoversat 394 00:32:19,610 --> 00:32:22,350 og udstede kommandoer til at genoversætte dem. 395 00:32:22,350 --> 00:32:27,690 Du kan gøre lave filer, der er absolut enorm. 396 00:32:27,690 --> 00:32:33,210 Gør ser på tidsstempler af filer, og ligesom vi sagde før, 397 00:32:33,210 --> 00:32:36,930 du kan kompilere individuelle filer ned, og det er ikke før du kommer til linkeren 398 00:32:36,930 --> 00:32:39,270 at de er sat sammen til en eksekverbar. 399 00:32:39,270 --> 00:32:43,810 Så hvis du har 10 forskellige filer, og du foretager en ændring til 1 af dem, 400 00:32:43,810 --> 00:32:47,870 så hvad gør vil gøre er bare rekompilere at 1 fil 401 00:32:47,870 --> 00:32:50,640 og derefter sammenlænke alt sammen. 402 00:32:50,640 --> 00:32:53,020 Men det er meget dummere end det. 403 00:32:53,020 --> 00:32:55,690 Det er op til dig at helt definere, at det er, hvad det skal gøre. 404 00:32:55,690 --> 00:32:59,560 Det som standard har evnen til at genkende denne tidsstempel stuff, 405 00:32:59,560 --> 00:33:03,220 men du kan skrive en make-fil til at gøre noget. 406 00:33:03,220 --> 00:33:09,150 Du kan skrive en make fil, så når du skriver at gøre det bare cd'er til en anden mappe. 407 00:33:09,150 --> 00:33:15,560 Jeg var ved at blive frustreret, fordi jeg tack alt inde i mit Appliance 408 00:33:15,560 --> 00:33:21,740 og så vil jeg se PDF fra Mac. 409 00:33:21,740 --> 00:33:30,720 >> Så jeg går til Finder og jeg kan gøre Go, forbindelse til server, 410 00:33:30,720 --> 00:33:36,950 og serveren jeg forbindelse til, er min Appliance, og så åbner jeg op for PDF 411 00:33:36,950 --> 00:33:40,190 der bliver udarbejdet af LaTeX. 412 00:33:40,190 --> 00:33:49,320 Men jeg var ved at blive frustreret, fordi hver eneste gang jeg havde brug for at opdatere PDF, 413 00:33:49,320 --> 00:33:53,900 Jeg var nødt til at kopiere det til en bestemt mappe, at det kunne få adgang til 414 00:33:53,900 --> 00:33:57,710 og det var at få irriterende. 415 00:33:57,710 --> 00:34:02,650 Så i stedet skrev jeg en make-fil, som du er nødt til at definere, hvordan det gør tingene. 416 00:34:02,650 --> 00:34:06,130 Hvordan du gør i dette er PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Ligesom enhver anden make-fil - eller jeg gætte, du ikke har set de gøre filer, 418 00:34:10,090 --> 00:34:13,510 men vi har i Appliance en global make-fil, der bare siger, 419 00:34:13,510 --> 00:34:16,679 hvis du kompilerer en C-fil, skal du bruge Dunk. 420 00:34:16,679 --> 00:34:20,960 Og så her i min make-fil, som jeg gør jeg siger, 421 00:34:20,960 --> 00:34:25,020 denne fil, du vil ønsker at kompilere med PDF LaTeX. 422 00:34:25,020 --> 00:34:27,889 Og så det er PDF LaTeX, der laver den kompilering. 423 00:34:27,889 --> 00:34:31,880 Gør ikke kompilering. Det er bare at køre disse kommandoer i rækkefølge jeg angav. 424 00:34:31,880 --> 00:34:36,110 Så det kører PDF LaTeX, det kopierer det til den mappe jeg vil have det skal kopieres til, 425 00:34:36,110 --> 00:34:38,270 det cd'er til mappen og gør andre ting, 426 00:34:38,270 --> 00:34:42,380 men alt det gør, er at anerkende Når en fil ændringer, 427 00:34:42,380 --> 00:34:45,489 og hvis det ændrer, så vil det køre de kommandoer, det er meningen at løbe 428 00:34:45,489 --> 00:34:48,760 når filen ændres. >> [Studerende] Okay. 429 00:34:50,510 --> 00:34:54,420 Jeg ved ikke, hvor de globale gøre filer er for mig at tjekke det ud. 430 00:34:57,210 --> 00:35:04,290 Andre spørgsmål? Alt fra fortiden quizzer? Eventuelle pointer ting? 431 00:35:06,200 --> 00:35:08,730 Der er subtile ting med pegepinde som - 432 00:35:08,730 --> 00:35:10,220 Jeg har ikke tænkt mig at være i stand til at finde en quiz spørgsmål på det - 433 00:35:10,220 --> 00:35:16,250 men ligesom denne slags ting. 434 00:35:19,680 --> 00:35:24,060 Sørg for at du forstår, at når jeg siger int * x * y - 435 00:35:24,890 --> 00:35:28,130 Det er ikke ligefrem noget her, tror jeg. 436 00:35:28,130 --> 00:35:32,140 Men ligesom * x * y, de er 2 variabler, der er på stakken. 437 00:35:32,140 --> 00:35:37,220 Når jeg siger x = malloc (sizeof (int)), x er stadig en variabel på stakken, 438 00:35:37,220 --> 00:35:41,180 malloc er nogle blok over i den bunke, og vi har x pege på den bunke. 439 00:35:41,180 --> 00:35:43,900 >> Så noget på stakken peger på bunke. 440 00:35:43,900 --> 00:35:48,100 Når du malloc noget, du uundgåeligt gemme det inde i en pegepind. 441 00:35:48,100 --> 00:35:55,940 Så det pointer er på stakken, den malloced blok er på heapen. 442 00:35:55,940 --> 00:36:01,240 En masse mennesker bliver forvirrede og siger int * x = malloc, x er på heapen. 443 00:36:01,240 --> 00:36:04,100 Nej Hvad x peger på, er på heapen. 444 00:36:04,100 --> 00:36:08,540 x selv er på stakken, medmindre uanset af hvilken grund, du har x være en global variabel, 445 00:36:08,540 --> 00:36:11,960 i hvilket tilfælde det sker for at være i et andet område af hukommelsen. 446 00:36:13,450 --> 00:36:20,820 Så at holde styr, er disse box og pil diagrammer temmelig almindeligt for quizzen. 447 00:36:20,820 --> 00:36:25,740 Eller hvis det ikke er på quiz 0, vil det være på quiz 1. 448 00:36:27,570 --> 00:36:31,940 Du skal vide alle disse, trinene i kompilering 449 00:36:31,940 --> 00:36:35,740 siden du var nødt til at svare på spørgsmål om dem. Ja. 450 00:36:35,740 --> 00:36:38,940 [Studerende] Kunne vi gå over disse skridt - >> Sure. 451 00:36:48,340 --> 00:36:58,640 Før trin og udarbejdelse vi har forbehandling, 452 00:36:58,640 --> 00:37:16,750 kompilering, montage, og sammenkædning. 453 00:37:16,750 --> 00:37:21,480 Forbehandling. Hvad betyder det så? 454 00:37:29,720 --> 00:37:32,290 Det er den nemmeste skridt i - ja, ikke som - 455 00:37:32,290 --> 00:37:35,770 det betyder ikke, det bør være indlysende, men det er den nemmeste skridt. 456 00:37:35,770 --> 00:37:38,410 I gutter kunne gennemføre det selv. Yeah. 457 00:37:38,410 --> 00:37:43,410 [Studerende] Tag hvad du har i din omfatter som denne, og det kopierer og derefter definerer også. 458 00:37:43,410 --> 00:37:49,250 Det ser for ting som # include og # define, 459 00:37:49,250 --> 00:37:53,800 og det bare kopier og pastaer, hvad de rent faktisk betyder. 460 00:37:53,800 --> 00:37:59,240 Så når du siger # include cs50.h er præprocessoren kopiere og indsætte cs50.h 461 00:37:59,240 --> 00:38:01,030 i denne linje. 462 00:38:01,030 --> 00:38:06,640 Når du siger # define x at være 4, præprocessoren går igennem hele programmet 463 00:38:06,640 --> 00:38:10,400 og erstatter alle forekomster af x med 4. 464 00:38:10,400 --> 00:38:17,530 Så præprocessoren tager en gyldig C-fil og udsender en gyldig C-fil 465 00:38:17,530 --> 00:38:20,300 hvor tingene er blevet kopieret og indsat. 466 00:38:20,300 --> 00:38:24,230 Så nu kompilering. Hvad betyder det så? 467 00:38:25,940 --> 00:38:28,210 [Studerende] Det går fra C til binær. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] Det går ikke hele vejen til binær. 469 00:38:30,970 --> 00:38:34,220 [Studerende] Til maskinkode så? >> Det er ikke maskine kode. 470 00:38:34,220 --> 00:38:35,700 [Studerende] Assembly? >> Forsamling. 471 00:38:35,700 --> 00:38:38,890 Det går til forsamlingen, før den går hele vejen til C-kode, 472 00:38:38,890 --> 00:38:45,010 og de fleste sprog gøre noget som dette. 473 00:38:47,740 --> 00:38:50,590 Pick enhver højniveausprog, og hvis du kommer til at kompilere det, 474 00:38:50,590 --> 00:38:52,390 det er sandsynligt, at kompilere i trin. 475 00:38:52,390 --> 00:38:58,140 Først det kommer til at kompilere Python til C, så det kommer til at kompilere C til Assembly, 476 00:38:58,140 --> 00:39:01,600 og derefter forsamlingen vil blive oversat til binær. 477 00:39:01,600 --> 00:39:07,800 Så kompilering vil bringe det fra C til forsamling. 478 00:39:07,800 --> 00:39:12,130 Ordet samle betyder normalt at bringe det fra et højere niveau 479 00:39:12,130 --> 00:39:14,340 til et lavere niveau programmeringssprog. 480 00:39:14,340 --> 00:39:19,190 Så dette er den eneste trin i udarbejdelse, hvor du starter med et højniveausprog 481 00:39:19,190 --> 00:39:23,270 og ender i en lav-niveau sprog, og det er grunden til, at trin kaldes kompilering. 482 00:39:25,280 --> 00:39:33,370 [Studerende] Under kompilering, lad os sige, at du har gjort # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Vil compiler rekompilere det cs50.h, ligesom de funktioner, der er derinde, 484 00:39:42,190 --> 00:39:45,280 og omsætte det til Assembly kode så godt, 485 00:39:45,280 --> 00:39:50,830 eller vil den kopiere og indsætte noget, der har været præ-forsamlingen? 486 00:39:50,830 --> 00:39:56,910 cs50.h vil stort set aldrig ender i forsamlingen. 487 00:39:59,740 --> 00:40:03,680 Ting som funktion prototyper og ting er bare for dig at være forsigtig. 488 00:40:03,680 --> 00:40:09,270 Det garanterer, at compileren kan kontrollere ting som du ringer funktioner 489 00:40:09,270 --> 00:40:12,910 med de rigtige tilbagevenden typer og de rigtige argumenter og kram. 490 00:40:12,910 --> 00:40:18,350 >> Så cs50.h vil blive forbehandles i filen, og derefter når det er kompilering 491 00:40:18,350 --> 00:40:22,310 Det er dybest set smidt væk efter det gør sikker på, at alt bliver kaldt korrekt. 492 00:40:22,310 --> 00:40:29,410 Men de funktioner der er defineret i CS50 biblioteket, som er adskilt fra cs50.h, 493 00:40:29,410 --> 00:40:33,610 de vil ikke blive særskilt udarbejdet. 494 00:40:33,610 --> 00:40:37,270 Det vil faktisk komme ned i sammenkædningen trin, så vi vil komme til at i et sekund. 495 00:40:37,270 --> 00:40:40,100 Men først, hvad samling? 496 00:40:41,850 --> 00:40:44,500 [Studerende] forsamlingen til binær? >> Yeah. 497 00:40:46,300 --> 00:40:48,190 Samling. 498 00:40:48,190 --> 00:40:54,710 Vi kalder det ikke kompilere fordi forsamlingen er temmelig meget en ren oversættelse af binær. 499 00:40:54,710 --> 00:41:00,230 Der er meget lidt logik i at gå fra forsamlingen til binær. 500 00:41:00,230 --> 00:41:03,180 Det er ligesom at slå op i en tabel, åh, har vi denne instruktion; 501 00:41:03,180 --> 00:41:06,290 der svarer til binært 01110. 502 00:41:10,200 --> 00:41:15,230 Og så de filer, samle generelt udgange er. O-filer. 503 00:41:15,230 --> 00:41:19,020 Og. O-filer er, hvad vi sagde før, 504 00:41:19,020 --> 00:41:21,570 hvordan en fil ikke behøver at have en hovedfunktion. 505 00:41:21,570 --> 00:41:27,640 Enhver fil kan opgøres ned til en. O fil, så længe det er en gyldig C-fil. 506 00:41:27,640 --> 00:41:30,300 Det kan udarbejdes ned. O.. 507 00:41:30,300 --> 00:41:43,030 Nu forbinder er hvad der rent faktisk bringer en masse. O-filer og bringer dem til en eksekverbar. 508 00:41:43,030 --> 00:41:51,110 Og så hvad linking gør, er du kan tænke på det CS50 biblioteket som en. O-fil. 509 00:41:51,110 --> 00:41:56,980 Det er en allerede kompileret binær fil. 510 00:41:56,980 --> 00:42:03,530 Og så når du kompilere din fil, din hello.c, som opfordrer GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c bliver kompileret ned til hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o er nu i binær. 513 00:42:08,910 --> 00:42:12,830 Det bruger GetString, så det skal gå over til cs50.o, 514 00:42:12,830 --> 00:42:16,390 og linkeren smooshes dem sammen og kopierer GetString ind i denne fil 515 00:42:16,390 --> 00:42:20,640 og kommer ud med en eksekverbar fil, der har alle funktioner, den har brug for. 516 00:42:20,640 --> 00:42:32,620 Så cs50.o er faktisk ikke en O-fil, men det er tæt nok, at der ikke er nogen fundamental forskel. 517 00:42:32,620 --> 00:42:36,880 Så forbinder bare bringer en masse filer sammen 518 00:42:36,880 --> 00:42:41,390 der hver for sig indeholder alle de funktioner, jeg skal bruge 519 00:42:41,390 --> 00:42:46,120 og skaber den eksekverbare, der rent faktisk kører. 520 00:42:48,420 --> 00:42:50,780 >> Og så det er også, hvad vi sagde før 521 00:42:50,780 --> 00:42:55,970 hvor du kan have 1000. c-filer, du samle dem alle til. o-filer, 522 00:42:55,970 --> 00:43:00,040 som formentlig vil tage et stykke tid, så du ændre 1. c. fil. 523 00:43:00,040 --> 00:43:05,480 Du behøver kun at kompilere at 1. C. fil og derefter sammenkæde alt andet, 524 00:43:05,480 --> 00:43:07,690 linke det hele sammen igen. 525 00:43:09,580 --> 00:43:11,430 [Studerende] Når vi forbinder vi skriver lcs50? 526 00:43:11,430 --> 00:43:20,510 Ja, så-lcs50. Det flag signaler til linkeren at du bør forbinder i biblioteket. 527 00:43:26,680 --> 00:43:28,910 Spørgsmål? 528 00:43:41,310 --> 00:43:46,860 Har vi gået over binær andet end at 5 sekunder i den første forelæsning? 529 00:43:50,130 --> 00:43:53,010 Det tror jeg ikke. 530 00:43:55,530 --> 00:43:58,820 Du skal kende alle de store Os at vi har været igennem, 531 00:43:58,820 --> 00:44:02,670 og du bør være i stand til, hvis vi gav dig en funktion, 532 00:44:02,670 --> 00:44:09,410 du bør være i stand til at sige, det er big O, groft. Eller godt, big O er ru. 533 00:44:09,410 --> 00:44:15,300 Så hvis du ser indlejret for-løkker looping over det samme antal ting, 534 00:44:15,300 --> 00:44:22,260 ligesom int i, i > [studerende] n potens. >> Det plejer at være n potens. 535 00:44:22,260 --> 00:44:25,280 Hvis du tredobbelt har indlejret, det har en tendens til at være n kubik. 536 00:44:25,280 --> 00:44:29,330 Så den slags ting, du bør være i stand til at påpege det samme. 537 00:44:29,330 --> 00:44:33,890 Du skal vide indsættelse sortere og boble sortere og flette sortere og alle dem. 538 00:44:33,890 --> 00:44:41,420 Det er nemmere at forstå, hvorfor det er dem n kvadreret og n log n og alt dette 539 00:44:41,420 --> 00:44:47,810 fordi jeg tror, ​​der var på en quiz et år, hvis vi dybest set gav dig 540 00:44:47,810 --> 00:44:55,050 en implementering af boble sortere og sagde: "Hvad er køretiden for denne funktion?" 541 00:44:55,050 --> 00:45:01,020 Så hvis du genkende det som boble sortere, så du straks kan sige n potens. 542 00:45:01,020 --> 00:45:05,470 Men hvis du bare ser på det, behøver du ikke engang nødt til at indse det er boble sort; 543 00:45:05,470 --> 00:45:08,990 du kan bare sige dette gør det og det. Dette er n potens. 544 00:45:12,350 --> 00:45:14,710 [Studerende] Er der nogle hårde eksempler du kan komme op med, 545 00:45:14,710 --> 00:45:20,370 ligesom en lignende idé at finde ud af? 546 00:45:20,370 --> 00:45:24,450 >> Jeg tror ikke, vi ville give dig nogen hårde eksempler. 547 00:45:24,450 --> 00:45:30,180 Boblen slags ting er omtrent lige så hård som vi ville gå, 548 00:45:30,180 --> 00:45:36,280 og selv det, så længe du forstå, at du iteration over arrayet 549 00:45:36,280 --> 00:45:41,670 for hvert element i arrayet, som er vil være noget, der er n potens. 550 00:45:45,370 --> 00:45:49,940 Der er generelle spørgsmål, som lige her har vi - Oh. 551 00:45:55,290 --> 00:45:58,530 Bare den anden dag, Doug hævdede, "Jeg har opfundet en algoritme, der kan sortere et array 552 00:45:58,530 --> 00:46:01,780 "Af n tal i O (log n) tid!" 553 00:46:01,780 --> 00:46:04,900 Så hvordan kan vi vide det er umuligt? 554 00:46:04,900 --> 00:46:08,850 [Uhørlig student svar] >> Yeah. 555 00:46:08,850 --> 00:46:13,710 I det mindste, skal du røre ved hvert element i array, 556 00:46:13,710 --> 00:46:16,210 så det er umuligt at sortere et array af - 557 00:46:16,210 --> 00:46:20,850 Hvis alt er i usorteret orden, så du vil komme til at røre alt i array, 558 00:46:20,850 --> 00:46:25,320 så det er umuligt at gøre det i mindre end O n. 559 00:46:27,430 --> 00:46:30,340 [Studerende] Du viste os, at eksempel på at være i stand til at gøre det i O n 560 00:46:30,340 --> 00:46:33,920 hvis du bruger en masse hukommelse. >> Yeah. 561 00:46:33,920 --> 00:46:37,970 Og that's - jeg har glemt hvad that's - Er det tælle slags? 562 00:46:47,360 --> 00:46:51,330 Hmm. Det er et helt tal sortering algoritme. 563 00:46:59,850 --> 00:47:05,100 Jeg var på udkig efter det særlige navn for dette, at jeg ikke kunne huske i sidste uge. 564 00:47:05,100 --> 00:47:13,000 Yeah. Det er de typer af slags, der kan udrette ting i big O n. 565 00:47:13,000 --> 00:47:18,430 Men der er begrænsninger, ligesom du kun kan bruge tal op til et vist antal. 566 00:47:20,870 --> 00:47:24,560 Plus, hvis du forsøger at sortere noget that's - 567 00:47:24,560 --> 00:47:30,750 Hvis dit array er 012, -12, 151, 4 mio 568 00:47:30,750 --> 00:47:35,120 så er enkelt element vil helt ødelægge hele sortering. 569 00:47:42,060 --> 00:47:44,030 >> Spørgsmål? 570 00:47:49,480 --> 00:47:58,870 [Studerende] Hvis du har en rekursiv funktion, og det bare gør det rekursive kald 571 00:47:58,870 --> 00:48:02,230 inden for en tilbagevenden erklæring, er det halerekursive, 572 00:48:02,230 --> 00:48:07,360 og så ville det ikke bruge mere hukommelse under runtime 573 00:48:07,360 --> 00:48:12,550 eller det ville i det mindste bruge sammenlignelige hukommelse som en iterativ løsning? 574 00:48:12,550 --> 00:48:14,530 [Bowden] Ja. 575 00:48:14,530 --> 00:48:19,840 Det ville sandsynligvis være noget langsommere, men ikke rigtig. 576 00:48:19,840 --> 00:48:23,290 Halerekursive er temmelig godt. 577 00:48:23,290 --> 00:48:32,640 Ser igen på stakrammer, lad os sige, at vi har main 578 00:48:32,640 --> 00:48:42,920 og vi har int bar (int x) eller noget. 579 00:48:42,920 --> 00:48:52,310 Dette er ikke en perfekt rekursiv funktion, men tilbagevenden bar (x - 1). 580 00:48:52,310 --> 00:48:57,620 Så selvfølgelig, det er forkert. Du har brug for base-sager og kram. 581 00:48:57,620 --> 00:49:00,360 Men ideen her er, at dette er halerekursive, 582 00:49:00,360 --> 00:49:06,020 hvilket betyder, når main opkald bar det kommer til at få sin stack ramme. 583 00:49:09,550 --> 00:49:12,440 I denne stakramme der kommer til at være lidt blok af hukommelse 584 00:49:12,440 --> 00:49:17,490 der svarer til dens argument x. 585 00:49:17,490 --> 00:49:25,840 Og så lad os sige main sker for at kalde bar (100); 586 00:49:25,840 --> 00:49:30,050 Så x kommer til at starte ud som 100. 587 00:49:30,050 --> 00:49:35,660 Hvis compileren erkender, at dette er en hale rekursiv funktion, 588 00:49:35,660 --> 00:49:38,540 så når bar gør sin rekursivt kald til bar, 589 00:49:38,540 --> 00:49:45,490 i stedet for at lave en ny stak ramme, som er der, hvor stakken begynder at gro i vid udstrækning, 590 00:49:45,490 --> 00:49:48,220 sidste ende vil det løbe ind i bunke og derefter får du segfault'er 591 00:49:48,220 --> 00:49:51,590 fordi hukommelsen begynder at kollidere. 592 00:49:51,590 --> 00:49:54,830 >> Så i stedet for at gøre sit eget stakramme, kan det indser, 593 00:49:54,830 --> 00:49:59,080 hey, jeg aldrig rigtig har brug for at vende tilbage til dette stakramme, 594 00:49:59,080 --> 00:50:08,040 så i stedet vil jeg bare udskifte dette argument med 99 og derefter starte bar hele. 595 00:50:08,040 --> 00:50:11,810 Og så vil det gøre det igen, og det vil nå tilbage bar (x - 1), 596 00:50:11,810 --> 00:50:17,320 og i stedet for at lave en ny stakramme, vil det bare erstatte det aktuelle argument med 98 597 00:50:17,320 --> 00:50:20,740 og derefter hoppe tilbage til begyndelsen af ​​bar. 598 00:50:23,860 --> 00:50:30,430 Disse operationer, der erstatter denne 1 værdi på stakken og hoppe tilbage til begyndelsen, 599 00:50:30,430 --> 00:50:32,430 er temmelig effektiv. 600 00:50:32,430 --> 00:50:41,500 Så ikke alene er det den samme hukommelse skik som en særskilt funktion, som iterativ 601 00:50:41,500 --> 00:50:45,390 fordi du kun bruger 1 stakramme, men du er ikke lider ulemper 602 00:50:45,390 --> 00:50:47,240 for at skulle kalde funktioner. 603 00:50:47,240 --> 00:50:50,240 Opkaldsfunktioner kan være lidt dyrt, fordi det har at gøre alt dette setup 604 00:50:50,240 --> 00:50:52,470 og nedtagning og alle disse ting. 605 00:50:52,470 --> 00:50:58,160 Så denne hale rekursion er god. 606 00:50:58,160 --> 00:51:01,170 [Studerende] Hvorfor er det ikke skaber nye skridt? 607 00:51:01,170 --> 00:51:02,980 Fordi det indser det ikke behøver at. 608 00:51:02,980 --> 00:51:07,800 Opfordringen til bar er bare returnere den rekursivt kald. 609 00:51:07,800 --> 00:51:12,220 Så det behøver ikke at gøre noget med den returnerede værdi. 610 00:51:12,220 --> 00:51:15,120 Det er bare at gå til straks returnere den. 611 00:51:15,120 --> 00:51:20,530 Så det er bare at erstatte sin egen argumentation og starte forfra. 612 00:51:20,530 --> 00:51:25,780 Og også, hvis du ikke har halen rekursive version, 613 00:51:25,780 --> 00:51:31,460 så får du alle disse barer, hvor når denne bar returnerer 614 00:51:31,460 --> 00:51:36,010 det har at returnere sin værdi til denne ene, så det bar straks returnerer 615 00:51:36,010 --> 00:51:39,620 og det returnerer dens værdi til denne ene, så er det bare at gå til straks at returnere 616 00:51:39,620 --> 00:51:41,350 og vende tilbage sin værdi til denne ene. 617 00:51:41,350 --> 00:51:45,350 Så du gemme denne popping alle disse ting ud af stakken 618 00:51:45,350 --> 00:51:48,730 da returværdien bare vil blive passeret hele vejen tilbage op alligevel. 619 00:51:48,730 --> 00:51:55,400 Så hvorfor ikke bare erstatte vores argument med den opdaterede indlæg og starte forfra? 620 00:51:57,460 --> 00:52:01,150 Hvis funktionen ikke er halerekursive, hvis du gør noget lignende - 621 00:52:01,150 --> 00:52:07,530 [Studerende], hvis bar (x + 1). >> Yeah. 622 00:52:07,530 --> 00:52:11,770 >> Så hvis du sætter den i stand, så du laver noget med returværdien. 623 00:52:11,770 --> 00:52:16,260 Eller selv hvis du bare ikke vender tilbage 2 * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Så nu bar (x - 1) behov for at vende tilbage for at det at beregne 2 gange denne værdi, 625 00:52:23,560 --> 00:52:26,140 så nu er det behøver sin egen separate stakramme, 626 00:52:26,140 --> 00:52:31,180 og nu, uanset hvor hårdt du prøver, du vil få brug for - 627 00:52:31,180 --> 00:52:34,410 Dette er ikke halerekursive. 628 00:52:34,410 --> 00:52:37,590 [Studerende] Vil jeg forsøge at bringe en rekursion at sigte mod en hale rekursion - 629 00:52:37,590 --> 00:52:41,450 [Bowden] I en ideel verden, men i CS50 du ikke behøver at. 630 00:52:43,780 --> 00:52:49,280 For at få hale rekursion, generelt, skal du oprette et ekstra argument 631 00:52:49,280 --> 00:52:53,550 hvor bar vil tage int x i y 632 00:52:53,550 --> 00:52:56,990 og y svarer til den ultimative ting, du ønsker at vende tilbage. 633 00:52:56,990 --> 00:53:03,650 Så da dette du vil vende tilbage bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Så det er bare et højt niveau, hvordan du transformerer ting at være halerekursive. 635 00:53:09,810 --> 00:53:13,790 Men den ekstra argument - 636 00:53:13,790 --> 00:53:17,410 Og så i sidste ende, når du har nået dit base case, skal du bare returnere y 637 00:53:17,410 --> 00:53:22,740 fordi du har været akkumulere hele tiden returværdien, du ønsker. 638 00:53:22,740 --> 00:53:27,280 Du slags har gjort det iterativt men ved hjælp af rekursive kald. 639 00:53:32,510 --> 00:53:34,900 Spørgsmål? 640 00:53:34,900 --> 00:53:39,890 [Studerende] Måske omkring pointer aritmetik, ligesom når du bruger strenge. >> Sure. 641 00:53:39,890 --> 00:53:43,610 Pointer aritmetik. 642 00:53:43,610 --> 00:53:48,440 Når du bruger strenge er det nemt, fordi strengene er char stjerner, 643 00:53:48,440 --> 00:53:51,860 chars er evigt og altid en enkelt byte, 644 00:53:51,860 --> 00:53:57,540 og så pointer aritmetik svarer til regelmæssig aritmetiske når du beskæftiger sig med strygere. 645 00:53:57,540 --> 00:54:08,790 Lad os bare sige char * s = "hej". 646 00:54:08,790 --> 00:54:11,430 Så vi har en blok i hukommelsen. 647 00:54:19,490 --> 00:54:22,380 Det kræver 6 bytes, fordi du altid har brug for null terminator. 648 00:54:22,380 --> 00:54:28,620 Og char * s vil pege på begyndelsen af ​​dette array. 649 00:54:28,620 --> 00:54:32,830 Så s peger der. 650 00:54:32,830 --> 00:54:36,710 Nu, dette er dybest set, hvordan enhver matrix virker, 651 00:54:36,710 --> 00:54:40,780 uanset om det var et afkast ved at allokere eller om det er på stakken. 652 00:54:40,780 --> 00:54:47,110 Enhver matrix er grundlæggende en pointer til starten af ​​arrayet, 653 00:54:47,110 --> 00:54:53,640 og derefter en array-operation, enhver indeksering, er bare at gå ind i den pågældende matrix en vis forskydning. 654 00:54:53,640 --> 00:55:05,360 >> Så når jeg siger noget i retning af s [3], og dette kommer til at s og tælle 3 tegn i. 655 00:55:05,360 --> 00:55:12,490 So s [3], har vi 0, 1, 2, 3, således s [3] vil henvise til denne l.. 656 00:55:12,490 --> 00:55:20,460 [Studerende] Og vi kunne nå den samme værdi ved at gøre s + 3 og derefter parenteser stjerne? 657 00:55:20,460 --> 00:55:22,570 Ja. 658 00:55:22,570 --> 00:55:26,010 Dette svarer til * (s + 3); 659 00:55:26,010 --> 00:55:31,240 og det er evigt og altid ækvivalent uanset hvad du gør. 660 00:55:31,240 --> 00:55:34,070 Du behøver aldrig at bruge konsollen syntaks. 661 00:55:34,070 --> 00:55:37,770 Du kan altid bruge * (s + 3) syntaks. 662 00:55:37,770 --> 00:55:40,180 Folk har en tendens til at kunne lide konsollen syntaks, selv om. 663 00:55:40,180 --> 00:55:43,860 [Studerende] Så alle arrays er faktisk bare pointere. 664 00:55:43,860 --> 00:55:53,630 Der er en lille forskel, når jeg siger int x [4]; >> [studerende] Betyder det skabe hukommelsen? 665 00:55:53,630 --> 00:56:03,320 [Bowden] Det vil skabe 4 int'er på stakken, så 16 bytes samlet. 666 00:56:03,320 --> 00:56:05,700 Det kommer til at skabe 16 bytes på stakken. 667 00:56:05,700 --> 00:56:09,190 x er ikke gemt nogen steder. 668 00:56:09,190 --> 00:56:13,420 Det er blot et symbol for starten af ​​ting. 669 00:56:13,420 --> 00:56:17,680 Fordi du erklærede vifte indersiden af ​​denne funktion, 670 00:56:17,680 --> 00:56:22,340 hvad compileren vil gøre er bare at erstatte alle forekomster af variablen x 671 00:56:22,340 --> 00:56:26,400 med, hvor det skete at vælge at sætte disse 16 bytes. 672 00:56:26,400 --> 00:56:30,040 Det kan ikke gøre det med char * s, fordi s er et virkeligt pointer. 673 00:56:30,040 --> 00:56:32,380 Det er gratis at så pege på andre ting. 674 00:56:32,380 --> 00:56:36,140 x er en konstant. Du kan ikke få det punkt til et andet array. >> [Studerende] Okay. 675 00:56:36,140 --> 00:56:43,420 Men denne idé, denne indeksering, er den samme, uanset om det er en traditionel opstilling 676 00:56:43,420 --> 00:56:48,230 eller hvis det er en pointer til noget, eller hvis det er en pointer til en malloced array. 677 00:56:48,230 --> 00:56:59,770 Og i virkeligheden er det så svarer, at det er også det samme. 678 00:56:59,770 --> 00:57:05,440 Det faktisk bare oversætter Hvad er der indeni af konsollerne, og hvad der er tilbage af konsollerne, 679 00:57:05,440 --> 00:57:07,970 lægger dem sammen, og dereferences. 680 00:57:07,970 --> 00:57:14,710 Så dette er lige så gyldig som * (s + 3) eller s [3]. 681 00:57:16,210 --> 00:57:22,090 [Studerende] Kan du have pointers peger på 2-dimensionelle arrays? 682 00:57:22,090 --> 00:57:27,380 >> Det er sværere. Traditionelt, no. 683 00:57:27,380 --> 00:57:34,720 En to-dimensionelle række er blot en 1-dimensionalt array med nogle praktisk syntaks 684 00:57:34,720 --> 00:57:54,110 fordi når jeg siger int x [3] [3], det er virkelig bare 1 array med 9 værdier. 685 00:57:55,500 --> 00:58:03,000 Og så når jeg indeks, compileren ved, hvad jeg mener. 686 00:58:03,000 --> 00:58:13,090 Hvis jeg siger x [1] [2], den kender jeg ønsker at gå til den anden række, så det kommer til at springe de første 3, 687 00:58:13,090 --> 00:58:17,460 og så det ønsker den anden ting i det, så det kommer til at få denne ene. 688 00:58:17,460 --> 00:58:20,480 Men det er stadig bare en enkelt-dimensionel array. 689 00:58:20,480 --> 00:58:23,660 Og så hvis jeg ønskede at tildele en pegepind til denne opstilling, 690 00:58:23,660 --> 00:58:29,770 Jeg vil sige int * p = x; 691 00:58:29,770 --> 00:58:33,220 Den type af x er bare - 692 00:58:33,220 --> 00:58:38,280 Det er groft at sige type x da det er bare et symbol, og det er ikke en egentlig variabel, 693 00:58:38,280 --> 00:58:40,140 men det er bare en int *. 694 00:58:40,140 --> 00:58:44,840 x er blot en pointer til starten af ​​dette. >> [Studerende] Okay. 695 00:58:44,840 --> 00:58:52,560 Og så vil jeg ikke være i stand til at få adgang til [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Jeg tror, ​​der er speciel syntaks for at erklære en pointer, 697 00:58:58,370 --> 00:59:12,480 noget latterligt lignende int (* p [-. noget helt latterlig jeg ikke engang kender. 698 00:59:12,480 --> 00:59:17,090 Men der er en syntaks for at erklære pegepinde som med parenteser og ting. 699 00:59:17,090 --> 00:59:22,960 Det kan ikke engang lade dig gøre det. 700 00:59:22,960 --> 00:59:26,640 Jeg kunne se tilbage på noget, der ville fortælle mig sandheden. 701 00:59:26,640 --> 00:59:34,160 Jeg vil lede efter den senere, hvis der er en syntaks for punkt. Men du vil aldrig se det. 702 00:59:34,160 --> 00:59:39,670 Og selv syntaksen er så arkaisk, at hvis du bruger det, vil folk blive forvirret. 703 00:59:39,670 --> 00:59:43,540 Multidimensional arrays er temmelig sjældne, som det er. 704 00:59:43,540 --> 00:59:44,630 Du temmelig meget - 705 00:59:44,630 --> 00:59:48,490 Tja, hvis du laver matrix ting, det kommer ikke til at være sjældne, 706 00:59:48,490 --> 00:59:56,730 men i C du sjældent skal bruge flerdimensionale arrays. 707 00:59:57,630 --> 01:00:00,470 Yeah. >> [Studerende] Lad os sige du har en virkelig lang array. 708 01:00:00,470 --> 01:00:03,900 >> Så i virtuel hukommelse ser det ud til at være alle på hinanden følgende, 709 01:00:03,900 --> 01:00:05,640 ligesom de elementer, lige ud for hinanden, 710 01:00:05,640 --> 01:00:08,770 men i fysisk hukommelse, ville det være muligt for denne at blive opdelt? >> Ja. 711 01:00:08,770 --> 01:00:16,860 Hvor virtuel hukommelse værker er det bare adskiller - 712 01:00:19,220 --> 01:00:24,860 Enheden for tildelingen er en side, som har tendens til at være 4 kilobyte, 713 01:00:24,860 --> 01:00:29,680 og så når en proces siger, hey, jeg vil bruge denne hukommelse, 714 01:00:29,680 --> 01:00:35,970 operativsystemet vil tildele det 4 kilobyte for den lille blok af hukommelse. 715 01:00:35,970 --> 01:00:39,100 Selv hvis du kun bruge en enkelt lille byte i hele blokken af ​​hukommelse, 716 01:00:39,100 --> 01:00:42,850 operativsystemet vil give det fulde 4 kilobyte. 717 01:00:42,850 --> 01:00:49,410 Så hvad dette betyder, jeg kunne have - lad os sige dette er min stack. 718 01:00:49,410 --> 01:00:53,180 Denne stabel kunne adskilles. Min stak kan være megabyte og megabytes. 719 01:00:53,180 --> 01:00:55,020 Min stack kan være enorme. 720 01:00:55,020 --> 01:01:00,220 Men stakken selv skal opdeles i enkelte sider, 721 01:01:00,220 --> 01:01:09,010 som hvis vi ser på herovre lad os sige dette er vores RAM, 722 01:01:09,010 --> 01:01:16,600 hvis jeg har 2 GB RAM, det er faktisk adresse 0 ligesom den nulte byte af min RAM, 723 01:01:16,600 --> 01:01:22,210 og dette er 2 gigabyte hele vejen herned. 724 01:01:22,210 --> 01:01:27,230 Så denne side kan svare til denne blok herovre. 725 01:01:27,230 --> 01:01:29,400 Denne side kan svare til denne blok herovre. 726 01:01:29,400 --> 01:01:31,560 Denne ene kunne svare til denne ene herovre. 727 01:01:31,560 --> 01:01:35,540 Så styresystemet er gratis at tildele fysisk hukommelse 728 01:01:35,540 --> 01:01:39,320 til de enkelte side vilkårligt. 729 01:01:39,320 --> 01:01:46,180 Og det betyder, at hvis denne grænse sker for at skræve et array, 730 01:01:46,180 --> 01:01:50,070 et array sker for at være tilbage af dette og til højre for denne ordre på en side, 731 01:01:50,070 --> 01:01:54,460 derefter at arrayet vil blive delt i fysisk hukommelse. 732 01:01:54,460 --> 01:01:59,280 Og så når du afslutter programmet, når processen slutter, 733 01:01:59,280 --> 01:02:05,690 Disse tilknytninger bliver slettet, og så er det gratis at bruge disse små blokke til andre ting. 734 01:02:14,730 --> 01:02:17,410 Flere spørgsmål? 735 01:02:17,410 --> 01:02:19,960 [Studerende] Markøren aritmetik. >> Oh yeah. 736 01:02:19,960 --> 01:02:28,410 Strings var lettere, men ser på noget som int'er, 737 01:02:28,410 --> 01:02:35,000 så tilbage til int x [4]; 738 01:02:35,000 --> 01:02:41,810 Hvorvidt dette er en matrix eller om det er en pointer til en malloced vifte af 4 heltal, 739 01:02:41,810 --> 01:02:47,060 det kommer til at blive behandlet på samme måde. 740 01:02:50,590 --> 01:02:53,340 [Studerende] Så arrays er på bunke? 741 01:03:01,400 --> 01:03:05,270 [Bowden] Arrays er ikke på den bunke. >> [Studerende] Oh. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Denne type matrix tendens til at være på stakken 743 01:03:08,320 --> 01:03:12,220 medmindre du erklærede det på - at ignorere globale variable. Brug ikke globale variabler. 744 01:03:12,220 --> 01:03:16,280 Inde i en funktion jeg siger int x [4]; 745 01:03:16,280 --> 01:03:22,520 Det kommer til at skabe en 4-heltal blok på stakken for dette array. 746 01:03:22,520 --> 01:03:26,960 Men denne malloc (4 * sizeof (int)), kommer til at gå på heapen. 747 01:03:26,960 --> 01:03:31,870 Men efter dette punkt kan jeg bruge x og p i stort set den samme måde, 748 01:03:31,870 --> 01:03:36,140 bortset fra de undtagelser, jeg sagde før om du kan tildele p. 749 01:03:36,140 --> 01:03:40,960 Teknisk set deres størrelser er lidt anderledes, men det er helt irrelevant. 750 01:03:40,960 --> 01:03:43,310 Du faktisk aldrig bruge deres størrelser. 751 01:03:48,020 --> 01:03:56,810 Det p jeg kunne sige p [3] = 2; eller x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 Du kan bruge dem i nøjagtig de samme måder. 753 01:03:59,680 --> 01:04:01,570 Så pointer aritmetik nu - Ja. 754 01:04:01,570 --> 01:04:07,390 [Studerende] Har du ikke behøver at gøre p *, hvis du har konsollerne? 755 01:04:07,390 --> 01:04:11,720 Konsollerne er en implicit dereference. >> Okay. 756 01:04:11,720 --> 01:04:20,200 Faktisk også det du siger med det kan du få multidimensionale arrays 757 01:04:20,200 --> 01:05:02,650 med pointere, er, hvad du kan gøre noget lignende, lad os sige, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Jeg vil bare skrive det hele ud først. 759 01:05:37,880 --> 01:05:41,020 Jeg ville ikke have, at én. 760 01:05:41,020 --> 01:05:42,550 Okay. 761 01:05:42,550 --> 01:05:48,910 Hvad jeg gjorde her er - Det bør være pp [i]. 762 01:05:48,910 --> 01:05:53,680 Så pp er en pegepind til en pegepind. 763 01:05:53,680 --> 01:06:02,420 Du mallocing pp til at pege på en række af 5 int stjerner. 764 01:06:02,420 --> 01:06:10,950 Så i hukommelsen, du har på stakken pp. 765 01:06:10,950 --> 01:06:20,150 Det kommer til at pege på en række af 5 blokke, der alle selv pointers. 766 01:06:20,150 --> 01:06:28,210 Og da jeg så malloc hernede, jeg malloc at hver af disse individuelle pointers 767 01:06:28,210 --> 01:06:32,080 skal pege på en separat blok på 4 byte på den bunke. 768 01:06:32,080 --> 01:06:35,870 Så dette peger på 4 byte. 769 01:06:37,940 --> 01:06:40,660 Og denne ene point til en anden 4 byte. 770 01:06:40,660 --> 01:06:43,200 >> Og alle dem peger på deres egne 4 byte. 771 01:06:43,200 --> 01:06:49,080 Dette giver mig en måde at gøre flerdimensionale ting. 772 01:06:49,080 --> 01:06:58,030 Jeg kunne sige pp [3] [4], men nu er det ikke det samme som multidimensionelle arrays 773 01:06:58,030 --> 01:07:05,390 fordi multidimensionelle arrays det oversat [3] [4] til en enkelt forskydning i x array. 774 01:07:05,390 --> 01:07:14,790 Dette dereferences p, tilgår den tredje indeks, så dereferences at 775 01:07:14,790 --> 01:07:20,790 og adgange - 4 ville være ugyldig - den anden indeks. 776 01:07:24,770 --> 01:07:31,430 Betragtninger, da vi havde int x [3] [4] før som en flerdimensional matrix 777 01:07:31,430 --> 01:07:35,740 og når du dobbeltklikker beslag det er virkelig kun en enkelt dereference, 778 01:07:35,740 --> 01:07:40,490 du efter en enkelt pointer og derefter en forskydning, 779 01:07:40,490 --> 01:07:42,850 dette er virkelig 2D referencer. 780 01:07:42,850 --> 01:07:45,840 Du følger 2 separate pointers. 781 01:07:45,840 --> 01:07:50,420 Så dette også teknisk tillader dig at have flerdimensionelle arrays 782 01:07:50,420 --> 01:07:53,550 hvor hver enkelt array er forskellige størrelser. 783 01:07:53,550 --> 01:07:58,000 Så jeg tror takkede multidimensionale arrays er, hvad det hedder 784 01:07:58,000 --> 01:08:01,870 da virkelig den første ting kunne pege på noget, der har 10 elementer, 785 01:08:01,870 --> 01:08:05,540 den anden ting kunne pege på noget, der har 100 elementer. 786 01:08:05,540 --> 01:08:10,790 [Studerende] Er der nogen grænse for antallet af henvisninger, du kan have 787 01:08:10,790 --> 01:08:14,290 peger på andre pointers? >> Nej. 788 01:08:14,290 --> 01:08:17,010 De kan have int ***** p. 789 01:08:18,050 --> 01:08:23,760 Tilbage til pointer aritmetik - >> [studerende] Oh. >> Yeah. 790 01:08:23,760 --> 01:08:35,649 [Studerende] Hvis jeg har int *** p og så vil jeg gøre en dereference og jeg siger p * er lig med denne værdi, 791 01:08:35,649 --> 01:08:39,560 er det kun kommer til at gøre 1 niveau dereferere? >> Ja. 792 01:08:39,560 --> 01:08:43,340 Så hvis jeg vil have adgang til ting, at den sidste pointer peger på - 793 01:08:43,340 --> 01:08:46,210 Så du gør *** p. >> Okay. 794 01:08:46,210 --> 01:08:54,080 Så dette er p point til 1 blok, peger på en anden blok, peger på en anden blok. 795 01:08:54,080 --> 01:09:02,010 Så hvis du gør * p = noget andet, så du ændrer dette 796 01:09:02,010 --> 01:09:13,640 nu peger på en anden blok. >> Okay. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] Og hvis disse blev malloced, så har du nu lækket hukommelse 798 01:09:17,649 --> 01:09:20,430 medmindre du tilfældigvis har forskellige referencer af disse 799 01:09:20,430 --> 01:09:25,270 da du ikke kan komme tilbage til dem, dem, du lige smed. 800 01:09:25,270 --> 01:09:29,550 Pointer aritmetik. 801 01:09:29,550 --> 01:09:36,310 int x [4] kommer til at tildele en vifte af 4 heltal 802 01:09:36,310 --> 01:09:40,670 hvor x vil pege på begyndelsen af ​​grupperingen. 803 01:09:40,670 --> 01:09:50,420 Så når jeg siger noget i retning af x [1], jeg vil have det til at betyde at gå til den anden heltal i array, 804 01:09:50,420 --> 01:09:53,319 hvilket ville være denne. 805 01:09:53,319 --> 01:10:04,190 Men virkelig, det er 4 bytes i arrayet da denne heltal optager 4 byte. 806 01:10:04,190 --> 01:10:08,470 Så en forskydning på 1 virkelig betyder en forskydning på 1 807 01:10:08,470 --> 01:10:12,030 gange større uanset typen af ​​arrayet er. 808 01:10:12,030 --> 01:10:17,170 Dette er en vifte af heltal, så den ved at gøre 1 gange størrelsen af ​​int, når den ønsker at udligne. 809 01:10:17,170 --> 01:10:25,260 Den anden syntaks. Husk, at dette svarer til * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Når jeg siger pointer + 1, hvad de hjemvendte er den adresse, markøren er lagring 811 01:10:35,250 --> 01:10:40,360 plus 1 gange størrelsen af ​​typen af ​​markøren. 812 01:10:40,360 --> 01:10:59,510 Så hvis x = ox100, så x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 Og du kan misbruge dette og sige noget i retning af char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 og nu c vil være den samme adresse som x. 815 01:11:23,050 --> 01:11:26,040 c vil være lig med ox100, 816 01:11:26,040 --> 01:11:31,490 men c + 1 vil være lig med ox101 817 01:11:31,490 --> 01:11:38,030 da pointer aritmetik afhænger af typen af ​​markøren, du tilføjer til. 818 01:11:38,030 --> 01:11:45,390 Så c + 1, det ser på c, det er en char pointer, så det kommer til at tilføje 1 gange størrelsen af ​​char, 819 01:11:45,390 --> 01:11:48,110 der vil altid være 1, så du får 101, 820 01:11:48,110 --> 01:11:54,890 hvorimod hvis jeg gør x, hvilket er også stadig 100, x + 1 vil være 104. 821 01:11:56,660 --> 01:12:06,340 [Studerende] Kan du bruge c + + for at fremme din pointer med 1? 822 01:12:06,340 --> 01:12:09,810 Ja, du kan. 823 01:12:09,810 --> 01:12:16,180 Du kan ikke gøre det med x, da x er bare et symbol, det er en konstant, og du kan ikke ændre x. 824 01:12:16,180 --> 01:12:22,610 >> Men c sker der bare være en pegepind, så c + + er helt i orden, og det vil forøges med 1. 825 01:12:22,610 --> 01:12:32,440 Hvis c var bare en int *, så c + + ville blive 104. 826 01:12:32,440 --> 01:12:41,250 + + Gør pointer aritmetik, ligesom c + 1 ville have gjort pointer aritmetik. 827 01:12:43,000 --> 01:12:48,870 Dette er faktisk, hvordan en masse ting som sammenfletning sort - 828 01:12:49,670 --> 01:12:55,710 I stedet for at skabe kopier af ting, kan du i stedet passere - 829 01:12:55,710 --> 01:13:02,400 Ligesom hvis jeg ønskede at videregive denne halvdel af rækken - lad os slette noget af dette. 830 01:13:04,770 --> 01:13:10,520 Lad os sige, at jeg ønskede at passere denne side af array i en funktion. 831 01:13:10,520 --> 01:13:12,700 Hvad ville jeg gå til denne funktion? 832 01:13:12,700 --> 01:13:17,050 Hvis jeg passerer x, jeg passerer denne adresse. 833 01:13:17,050 --> 01:13:23,780 Men jeg ønsker at videregive denne bestemt adresse. Så hvad skal jeg gå? 834 01:13:23,780 --> 01:13:26,590 [Studerende] Pointer + 2? 835 01:13:26,590 --> 01:13:29,350 [Bowden] Så x + 2. Ja. 836 01:13:29,350 --> 01:13:31,620 Det kommer til at være denne adresse. 837 01:13:31,620 --> 01:13:42,810 Du vil også meget ofte se det som x [2] og derefter adressen på det. 838 01:13:42,810 --> 01:13:47,850 Så du er nødt til at tage adressen af ​​det, fordi beslaget er en implicit dereference. 839 01:13:47,850 --> 01:13:53,250 x [2] refererer til den værdi, der er i denne boks, og du derefter vil adressen på den kasse, 840 01:13:53,250 --> 01:13:56,850 så du siger & x [2]. 841 01:13:56,850 --> 01:14:02,880 Så det er sådan noget i fletningen slags, hvor du vil passere halv listen til noget 842 01:14:02,880 --> 01:14:08,790 du virkelig bare passere & x [2], og nu så langt som den rekursive kald angår, 843 01:14:08,790 --> 01:14:12,510 min nye opstilling starter der. 844 01:14:12,510 --> 01:14:15,130 Last minute spørgsmål. 845 01:14:15,130 --> 01:14:20,050 [Studerende] Hvis vi ikke sætter et og-tegn eller en - hvad er det hedder? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Studerende] Star. >> Teknisk dereference operatør, men - >> [studerende] Dereference. 847 01:14:23,200 --> 01:14:29,310 >> Hvis vi ikke sætte en stjerne eller et og-tegn, hvad sker der, hvis jeg bare sige y = x og x er en pointer? 848 01:14:29,310 --> 01:14:34,620 Hvad er den type af y? >> [Studerende] Jeg vil bare sige, det er pointer 2. 849 01:14:34,620 --> 01:14:38,270 Så hvis du bare sige y = x, nu x og y peger på den samme ting. >> [Studerende] Peg på det samme. 850 01:14:38,270 --> 01:14:45,180 Og hvis x er en int pointer? >> Det ville klage, fordi du ikke kan tildele pointers. 851 01:14:45,180 --> 01:14:46,540 [Elev] Okay. 852 01:14:46,540 --> 01:14:51,860 Husk at pointere, selvom vi trækker dem som pile, 853 01:14:51,860 --> 01:15:02,010 virkelig alle de store - int * x - virkelig alle x er lagring er noget i ox100, 854 01:15:02,010 --> 01:15:06,490 som vi tilfældigvis repræsentere som peger på blok lagret ved 100. 855 01:15:06,490 --> 01:15:19,660 Så når jeg siger int * y = x; jeg bare kopiere ox100 i y, 856 01:15:19,660 --> 01:15:24,630 som vi bare kommer til at repræsentere som y, også peger på ox100. 857 01:15:24,630 --> 01:15:39,810 Og hvis jeg siger int i = (int) x; så jeg kommer til at lagre uanset værdien af ​​ox100 er 858 01:15:39,810 --> 01:15:45,100 indersiden af ​​det, men nu er det kommer til at blive fortolket som et heltal i stedet for en pegepind. 859 01:15:45,100 --> 01:15:49,310 Men du har brug den støbte ellers vil klage. 860 01:15:49,310 --> 01:15:53,300 [Studerende] Så mener du at kaste - 861 01:15:53,300 --> 01:16:00,290 Er det kommer til at være udslagsgivende int for x eller støbning int af y? 862 01:16:00,290 --> 01:16:03,700 [Bowden] Hvad? 863 01:16:03,700 --> 01:16:07,690 [Elev] Okay. Efter disse parenteser er der vil være en x eller ay der? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Enten. x og y er ækvivalente. >> [Studerende] Okay. 865 01:16:11,500 --> 01:16:14,390 Fordi de er begge pointers. >> Yeah. 866 01:16:14,390 --> 01:16:21,050 [Studerende] Så det ville gemme den hexadecimale 100 i heltal form? >> [Bowden] Yeah. 867 01:16:21,050 --> 01:16:23,620 Men ikke værdien af ​​hvad det peger på. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Yeah. >> [Studerende] Så bare adressen i heltal form. Okay. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Hvis du ønskede at for nogle bizarre grund, 870 01:16:34,720 --> 01:16:38,900 kunne du udelukkende beskæftige sig med pegepinde og aldrig beskæftige sig med heltal 871 01:16:38,900 --> 01:16:49,240 og bare være ligesom int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Så du kommer til at blive virkelig forvirret, når pointer aritmetik begynder at ske. 873 01:16:53,000 --> 01:16:56,570 Så de tal, de gemmer er meningsløse. 874 01:16:56,570 --> 01:16:58,940 Det er bare hvordan du ender fortolke dem. 875 01:16:58,940 --> 01:17:02,920 Så jeg er fri til at kopiere ox100 fra en int * til en int, 876 01:17:02,920 --> 01:17:07,790 og jeg er fri til at tildele - Du er sandsynligvis kommer til at få råbte på for ikke støbning - 877 01:17:07,790 --> 01:17:18,160 Jeg er fri til at tildele noget lignende (int *) ox1234 ind i denne vilkårlige int *. 878 01:17:18,160 --> 01:17:25,480 Så ox123 er lige så gyldig en hukommelse adresse, som er & y. 879 01:17:25,480 --> 01:17:32,060 & Y sker for at returnere noget, der er temmelig meget ox123. 880 01:17:32,060 --> 01:17:35,430 [Studerende] Ville det være en rigtig cool måde at gå fra hexadecimal til decimal form, 881 01:17:35,430 --> 01:17:39,230 gerne, hvis du har en pegepind, og du kaster det som en int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] Du kan virkelig bare udskrive med lignende printf. 883 01:17:44,860 --> 01:17:50,300 Lad os sige, at jeg har int y = 100. 884 01:17:50,300 --> 01:18:02,700 Så printf (% d \ n - som du allerede burde vide - udskrive denne som et heltal,% x. 885 01:18:02,700 --> 01:18:05,190 Vi vil bare udskrive det som hexadecimal. 886 01:18:05,190 --> 01:18:10,760 Så en pointer ikke er gemt som hexadecimal, 887 01:18:10,760 --> 01:18:12,960 og et helt tal ikke er gemt som decimal. 888 01:18:12,960 --> 01:18:14,700 Alt er gemt som binær. 889 01:18:14,700 --> 01:18:17,950 Det er bare at vi er tilbøjelige til at vise markører som hexadecimal 890 01:18:17,950 --> 01:18:23,260 fordi vi tænker på ting i disse 4-byte blokke, 891 01:18:23,260 --> 01:18:25,390 og hukommelsesadresser tendens til at være velkendt. 892 01:18:25,390 --> 01:18:28,890 Vi er som, hvis den starter med bf, så tilfældigvis er på stakken. 893 01:18:28,890 --> 01:18:35,560 Så det er bare vores fortolkning af henvisninger som hexadecimal. 894 01:18:35,560 --> 01:18:39,200 Okay. Eventuelle sidste spørgsmål? 895 01:18:39,200 --> 01:18:41,700 >> Jeg vil være her for en smule efter, hvis du har noget andet. 896 01:18:41,700 --> 01:18:46,070 Og det er slutningen af ​​det. 897 01:18:46,070 --> 01:18:48,360 >> [Studerende] Yay! [Bifald] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]