1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [§ 4 - Mer komfortabelt] 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, i tilfelle dere ikke visste det. 5 00:00:14,810 --> 00:00:20,970 Det er i utgangspunktet på alt du kunne ha sett i klassen eller burde ha sett i klassen. 6 00:00:20,970 --> 00:00:26,360 Det inkluderer pekere, selv om de er en svært nylig tema. 7 00:00:26,360 --> 00:00:29,860 Du bør i det minste forstå de høye nivåene av dem. 8 00:00:29,860 --> 00:00:34,760 Noe som ble gått over i klassen du bør forstå for quiz. 9 00:00:34,760 --> 00:00:37,320 Så hvis du har spørsmål om dem, kan du be dem nå. 10 00:00:37,320 --> 00:00:43,280 Men dette kommer til å bli en svært student-ledede session hvor dere stille spørsmål, 11 00:00:43,280 --> 00:00:45,060 så forhåpentligvis folk har spørsmål. 12 00:00:45,060 --> 00:00:48,020 Har noen spørsmål? 13 00:00:49,770 --> 00:00:52,090 Ja. >> [Student] Kan du gå over pekere igjen? 14 00:00:52,090 --> 00:00:54,350 Jeg skal gå over pekere. 15 00:00:54,350 --> 00:00:59,180 Alle dine variabler nødvendigvis lever i minnet, 16 00:00:59,180 --> 00:01:04,450 men vanligvis du ikke bekymre deg for det, og du bare si x + 2 og y + 3 17 00:01:04,450 --> 00:01:07,080 og kompilatoren vil finne ut hvor ting lever for deg. 18 00:01:07,080 --> 00:01:12,990 Når du arbeider med pekere, nå er du eksplisitt bruker disse minne adresser. 19 00:01:12,990 --> 00:01:19,800 Slik at en enkelt variabel vil bare noensinne leve på en enkelt adresse til enhver tid. 20 00:01:19,800 --> 00:01:24,040 Hvis vi ønsker å erklære en peker, hva slags kommer til å se ut? 21 00:01:24,040 --> 00:01:26,210 >> Jeg ønsker å erklære en peker p. Hvordan ser den typen ut? 22 00:01:26,210 --> 00:01:33,530 [Student] int * p. >> Ja. Så int * p. 23 00:01:33,530 --> 00:01:38,030 Og hvordan gjør jeg det peke x? >> [Student] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Så ampersand er bokstavelig talt kalles adressen til operatør. 25 00:01:45,300 --> 00:01:50,460 Så når jeg sier og x det blir minnet adressen til variabelen x. 26 00:01:50,460 --> 00:01:56,790 Så nå har jeg pekeren p, og hvor som helst i koden min kan jeg bruke * p 27 00:01:56,790 --> 00:02:02,960 eller jeg kunne bruke x og det vil være akkurat det samme. 28 00:02:02,960 --> 00:02:09,520 (* P). Hva er dette å gjøre? Hva betyr den stjernen? 29 00:02:09,520 --> 00:02:13,120 [Student] Det betyr en verdi på det tidspunktet. >> Ja. 30 00:02:13,120 --> 00:02:17,590 Så hvis vi ser på det, kan det være svært nyttig å trekke ut diagrammer 31 00:02:17,590 --> 00:02:22,230 der dette er en liten boks minne for x, som tilfeldigvis har verdien 4, 32 00:02:22,230 --> 00:02:25,980 så har vi en liten boks minne for p, 33 00:02:25,980 --> 00:02:31,590 og så p peker på x, så vi trekker en pil fra p til x. 34 00:02:31,590 --> 00:02:40,270 Så når vi sier * p vi sier gå til boksen som er p. 35 00:02:40,270 --> 00:02:46,480 Star er følge pilen og deretter gjøre hva du vil med den boksen der. 36 00:02:46,480 --> 00:03:01,090 Så jeg kan si * p = 7, og som vil gå til boksen som er x og forandring som til 7. 37 00:03:01,090 --> 00:03:13,540 Eller jeg kan si int z = * p * 2, det er forvirrende fordi det er star, stjerne. 38 00:03:13,540 --> 00:03:19,230 Den ene stjerne er dereferencing p, den andre stjerne multiplisere med 2. 39 00:03:19,230 --> 00:03:26,780 Legg merke til at jeg kunne ha like godt erstattet * p med x. 40 00:03:26,780 --> 00:03:29,430 Du kan bruke dem på samme måte. 41 00:03:29,430 --> 00:03:38,000 Og så senere jeg kan ha p peker til en helt ny ting. 42 00:03:38,000 --> 00:03:42,190 Jeg kan bare si p = &z; 43 00:03:42,190 --> 00:03:44,940 Så nå P ikke lenger peker til x, det peker til z. 44 00:03:44,940 --> 00:03:50,510 Og hver gang jeg gjør * p er det samme som å gjøre z. 45 00:03:50,510 --> 00:03:56,170 Så nyttige ting om dette er når vi begynner å få inn funksjoner. 46 00:03:56,170 --> 00:03:59,790 >> Det er litt nytteløst å erklære en peker som peker til noe 47 00:03:59,790 --> 00:04:03,140 og da er du bare dereferencing det 48 00:04:03,140 --> 00:04:06,060 når du kunne ha brukt den opprinnelige variabelen til å begynne med. 49 00:04:06,060 --> 00:04:18,190 Men når du kommer inn funksjoner - så la oss si at vi har noen funksjon, int foo, 50 00:04:18,190 --> 00:04:32,810 som tar en peker og bare gjør * p = 6; 51 00:04:32,810 --> 00:04:39,990 Som vi har sett før med swap, kan du ikke gjøre en effektiv swap og en egen funksjon 52 00:04:39,990 --> 00:04:45,180 ved bare passerer heltall fordi alt i C er alltid bestått av verdi. 53 00:04:45,180 --> 00:04:48,360 Selv når du passerer pekere du passerer verdi. 54 00:04:48,360 --> 00:04:51,940 Det bare så skjer at disse verdiene er minneadresser. 55 00:04:51,940 --> 00:05:00,770 Så når jeg sier foo (p), jeg har bestått pekeren inn i funksjonen Foo 56 00:05:00,770 --> 00:05:03,910 og deretter Foo gjør * p = 6; 57 00:05:03,910 --> 00:05:08,600 Så innsiden av den funksjonen, er * p fremdeles tilsvarende x, 58 00:05:08,600 --> 00:05:12,720 men jeg kan ikke bruke x innsiden av den funksjonen fordi det ikke scoped innenfor denne funksjonen. 59 00:05:12,720 --> 00:05:19,510 Så * p = 6 er den eneste måten jeg kan få tilgang til en lokal variabel fra en annen funksjon. 60 00:05:19,510 --> 00:05:23,600 Eller, vel, pekere er den eneste måten jeg kan få tilgang til en lokal variabel fra en annen funksjon. 61 00:05:23,600 --> 00:05:31,600 [Student] La oss si at du ønsket å returnere en peker. Hvor nøyaktig gjør du det? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Tilbake en peker som i noe sånt int y = 3; retur & y? >> [Student] Yeah. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Okay. Du bør aldri gjøre dette. Dette er ille. 64 00:05:48,480 --> 00:05:59,480 Jeg tror jeg så i disse foredrag lysbilder du begynte å se hele denne diagram av minne 65 00:05:59,480 --> 00:06:02,880 der opp her har du minne adresse 0 66 00:06:02,880 --> 00:06:09,550 og ned her har du minneadresser 4 konserter eller 2 til 32. 67 00:06:09,550 --> 00:06:15,120 Så da har du noen ting og noen ting og da har du din stabel 68 00:06:15,120 --> 00:06:21,780 og du har fått din haug, som du nettopp begynt å lære om, vokser opp. 69 00:06:21,780 --> 00:06:24,390 [Student] Er ikke haugen over stabelen? 70 00:06:24,390 --> 00:06:27,760 >> Ja. Haugen er på toppen, er det ikke? >> [Student] Vel, la han 0 på toppen. 71 00:06:27,760 --> 00:06:30,320 [Student] Oh, la han 0 på toppen. >> [Student] Oh, okay. 72 00:06:30,320 --> 00:06:36,060 Ansvarsfraskrivelse: Anywhere med CS50 du kommer til å se det på denne måten. >> [Student] Okay. 73 00:06:36,060 --> 00:06:40,290 Det er bare det at når du først ser stabler, 74 00:06:40,290 --> 00:06:45,000 som når du tenker på en stabel du tenker på å stable ting på toppen av hverandre. 75 00:06:45,000 --> 00:06:50,810 Så vi har en tendens til å snu dette rundt slik stabelen vokser opp som en stabel normalt ville 76 00:06:50,810 --> 00:06:55,940 istedenfor bunken hengende ned. >> [Student] Ikke masser teknisk vokse opp også, skjønt? 77 00:06:55,940 --> 00:07:01,100 Det kommer an på hva du mener med å vokse opp. 78 00:07:01,100 --> 00:07:04,010 Bunken og heap alltid vokse i motsatt retning. 79 00:07:04,010 --> 00:07:09,420 En stabel er alltid vokser opp i den forstand at det vokser opp 80 00:07:09,420 --> 00:07:12,940 mot høyere minne adresser, og haugen vokser ned 81 00:07:12,940 --> 00:07:17,260 i at det vokser mot lavere minneadresser. 82 00:07:17,260 --> 00:07:20,250 Slik at toppen er 0, og bunnen er høye fysiske adresser. 83 00:07:20,250 --> 00:07:26,390 De er begge vokser, bare i motsatt retning. 84 00:07:26,390 --> 00:07:29,230 [Student] Jeg mente at fordi du sa at du setter stabelen på bunnen 85 00:07:29,230 --> 00:07:33,640 fordi det virker mer intuitivt fordi for bunken for å starte på toppen av en haug, 86 00:07:33,640 --> 00:07:37,520 heap er på toppen av seg selv også, så that - >> Ja. 87 00:07:37,520 --> 00:07:44,960 Du også tenke på haugen som vokser opp og større, men bunken mer. 88 00:07:44,960 --> 00:07:50,280 Så stabelen er den som vi på en måte ønsker å vise oppveksten. 89 00:07:50,280 --> 00:07:55,390 Men overalt hvor du ser ellers kommer til å vise adresse 0 øverst 90 00:07:55,390 --> 00:07:59,590 og det høyeste minne adressen nederst, så dette er din vanlige syn på minne. 91 00:07:59,590 --> 00:08:02,100 >> Har du et spørsmål? 92 00:08:02,100 --> 00:08:04,270 [Student] Kan du fortelle oss mer om haugen? 93 00:08:04,270 --> 00:08:06,180 Ja. Jeg får til det i et sekund. 94 00:08:06,180 --> 00:08:12,220 Først kommer tilbake til hvorfor retur og y er en dårlig ting, 95 00:08:12,220 --> 00:08:18,470 på stakken har du en haug av stabelen rammer som representerer alle funksjoner 96 00:08:18,470 --> 00:08:20,460 som har blitt kalt. 97 00:08:20,460 --> 00:08:27,990 Så ignorerer tidligere ting, er toppen av stabelen din alltid kommer til å være den viktigste funksjonen 98 00:08:27,990 --> 00:08:33,090 siden det er den første funksjonen som blir kalt. 99 00:08:33,090 --> 00:08:37,130 Og når du ringer opp en annen funksjon, stabelen kommer til å vokse ned. 100 00:08:37,130 --> 00:08:41,640 Så hvis jeg kaller noen funksjon, foo, og det får sin egen stack frame, 101 00:08:41,640 --> 00:08:47,280 den kan kalle noen funksjon, bar, det får sin egen stack ramme. 102 00:08:47,280 --> 00:08:49,840 Og bar kan være rekursiv, og det kan kalle seg selv, 103 00:08:49,840 --> 00:08:54,150 og slik at andre kall til bar kommer til å få sin egen stack ramme. 104 00:08:54,150 --> 00:08:58,880 Og så hva som foregår i disse stabel rammer er alle lokale variabler 105 00:08:58,880 --> 00:09:03,450 og alle funksjonsargumenter at - 106 00:09:03,450 --> 00:09:08,730 Noen ting som er lokalt scoped til denne funksjonen gå i disse stabel rammer. 107 00:09:08,730 --> 00:09:21,520 Så det betyr at når jeg sa noe sånt som bar er en funksjon, 108 00:09:21,520 --> 00:09:29,270 Jeg bare kommer til å erklære et heltall og deretter returnere en peker til denne heltall. 109 00:09:29,270 --> 00:09:33,790 Så hvor bor y? 110 00:09:33,790 --> 00:09:36,900 [Student] y bor i baren. >> [Bowden] Yeah. 111 00:09:36,900 --> 00:09:45,010 Et sted i denne lille plassen minne er en littler firkant som har y i den. 112 00:09:45,010 --> 00:09:53,370 Når jeg kommer tilbake og y, er jeg tilbake en peker til denne lille blokk med minne. 113 00:09:53,370 --> 00:09:58,400 Men så når en funksjon returnerer, får sin stack ramme popped av stabelen. 114 00:10:01,050 --> 00:10:03,530 Og det er derfor det kalles stabelen. 115 00:10:03,530 --> 00:10:06,570 Det er som stabelen datastrukturen, hvis du vet hva det er. 116 00:10:06,570 --> 00:10:11,580 Eller selv som en stabel av skuffene er alltid eksemplet 117 00:10:11,580 --> 00:10:16,060 main kommer til å gå på bunnen, så den første funksjonen du ringe kommer til å gå på toppen av det, 118 00:10:16,060 --> 00:10:20,400 og du ikke kan komme tilbake til hovedsiden til du kommer tilbake fra alle funksjoner som har blitt kalt 119 00:10:20,400 --> 00:10:22,340 som har blitt plassert på toppen av den. 120 00:10:22,340 --> 00:10:28,650 >> [Student] Så hvis du gjorde gjøre returnere & y, at verdien kan endres uten varsel. 121 00:10:28,650 --> 00:10:31,290 Ja, det er - >> [student] Det kan bli overskrevet. >> Ja. 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 vil også være en int * bar fordi den returnerer en peker, 124 00:10:38,040 --> 00:10:41,310 så det returtype er int *. 125 00:10:41,310 --> 00:10:46,500 Hvis du prøver å bruke returverdien av denne funksjonen, er det udefinert oppførsel 126 00:10:46,500 --> 00:10:51,770 fordi det peker i dårlig hukommelse. >> [Student] Okay. 127 00:10:51,770 --> 00:11:01,250 Så hva om, for eksempel, erklærte 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 [Student] Vi snakket om hvordan når vi drar ting til vår papirkurven 130 00:11:07,730 --> 00:11:11,750 de er faktisk ikke slettet, vi bare miste sine pekere. 131 00:11:11,750 --> 00:11:15,550 Så i dette tilfellet gjør vi faktisk slette verdien eller er det fortsatt det i minnet? 132 00:11:15,550 --> 00:11:19,130 For det meste, det kommer til å fortsatt være der. 133 00:11:19,130 --> 00:11:24,220 Men la oss si at vi tilfeldigvis ringe noen annen funksjon, Baz. 134 00:11:24,220 --> 00:11:28,990 Baz kommer til å få sin egen stack ramme på her. 135 00:11:28,990 --> 00:11:31,470 Det kommer til å bli overskriving alt dette ting, 136 00:11:31,470 --> 00:11:34,180 og hvis du senere prøve og bruke pekeren som du fikk før, 137 00:11:34,180 --> 00:11:35,570 det er ikke til å være den samme verdi. 138 00:11:35,570 --> 00:11:38,150 Det kommer til å ha endret bare fordi du ringte funksjonen baz. 139 00:11:38,150 --> 00:11:43,080 [Student] Men hadde vi ikke, ville vi fortsatt få 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] I all sannsynlighet, ville du. 141 00:11:44,990 --> 00:11:49,670 Men du kan ikke stole på det. C sier bare udefinert oppførsel. 142 00:11:49,670 --> 00:11:51,920 >> [Student] Oh, det gjør det. Okay. 143 00:11:51,920 --> 00:11:58,190 Så når du ønsker å returnere en peker, dette er hvor malloc kommer i bruk. 144 00:12:00,930 --> 00:12:15,960 Jeg skriver egentlig bare returnere malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Vi vil gå igjennom malloc mer i et sekund, men ideen om malloc er alle dine lokale variabler 146 00:12:24,050 --> 00:12:26,760 alltid gå på stakken. 147 00:12:26,760 --> 00:12:31,570 Noe som er malloced går på haugen, og det vil for evig og alltid være på haugen 148 00:12:31,570 --> 00:12:34,490 før du eksplisitt frigjøre den. 149 00:12:34,490 --> 00:12:42,130 Så dette betyr at når du malloc noe, det kommer til å overleve etter at funksjonen returnerer. 150 00:12:42,130 --> 00:12:46,800 [Student] Vil det overleve etter at programmet slutter å kjøre? >> Nei 151 00:12:46,800 --> 00:12:53,180 Ok, så det kommer til å være der til programmet er helt ferdig å kjøre. >> Ja. 152 00:12:53,180 --> 00:12:57,510 Vi kan gå over detaljer om hva som skjer når programmet stopper. 153 00:12:57,510 --> 00:13:02,150 Du må kanskje minne meg, men det er en egen ting helt. 154 00:13:02,150 --> 00:13:04,190 [Student] Så malloc skaper en peker? >> Ja. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [student] Jeg tror malloc betegner en blokk med minne som en peker kan bruke. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Jeg vil at diagrammet igjen. >> [Student] Så denne funksjonen fungerer, skjønt? 157 00:13:19,610 --> 00:13:26,430 [Student] Yeah, malloc betegner en blokk med minne som du kan bruke, 158 00:13:26,430 --> 00:13:30,470 og da er det returnerer adressen til den første blokken i dette minnet. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Yeah. Så når du malloc, du flytte noen minneblokk 160 00:13:36,750 --> 00:13:38,260 det er for tiden i haugen. 161 00:13:38,260 --> 00:13:43,040 Hvis haugen er for liten, så haugen er bare kommer til å vokse, og det vokser i denne retningen. 162 00:13:43,040 --> 00:13:44,650 Så la oss si haugen er for liten. 163 00:13:44,650 --> 00:13:49,960 Da er det i ferd med å vokse litt og returnere en peker til denne blokken som bare vokste. 164 00:13:49,960 --> 00:13:55,130 Når du gratis ting, du gjør mer plass i haugen, 165 00:13:55,130 --> 00:14:00,030 så da senere ringer til malloc kan gjenbruke at minnet som du hadde tidligere frigjort. 166 00:14:00,030 --> 00:14:09,950 Det viktige ting om malloc og gratis er at det gir deg full kontroll 167 00:14:09,950 --> 00:14:12,700 over levetiden for disse minneblokker. 168 00:14:12,700 --> 00:14:15,420 Globale variabler er alltid live. 169 00:14:15,420 --> 00:14:18,500 Lokale variabler er i live innenfor sitt omfang. 170 00:14:18,500 --> 00:14:22,140 Så snart du går forbi en krøllete brace, lokale variabler er døde. 171 00:14:22,140 --> 00:14:28,890 Malloced minne er i live når du vil den skal være i live 172 00:14:28,890 --> 00:14:33,480 og deretter frigjøres når du forteller det til å bli utgitt. 173 00:14:33,480 --> 00:14:38,420 De er faktisk de eneste tre typer minne, egentlig. 174 00:14:38,420 --> 00:14:41,840 Det er automatisk minnehåndtering, som er bunken. 175 00:14:41,840 --> 00:14:43,840 Ting skjer for deg automatisk. 176 00:14:43,840 --> 00:14:46,910 Når du sier int x, er minne for int x. 177 00:14:46,910 --> 00:14:51,630 Når x går ut av omfanget, er minnet gjenvunnet til x. 178 00:14:51,630 --> 00:14:54,790 Så er det dynamisk minnehåndtering, som er hva malloc er, 179 00:14:54,790 --> 00:14:56,740 som er når du har kontroll. 180 00:14:56,740 --> 00:15:01,290 Du dynamisk bestemme når minne bør og ikke bør tildeles. 181 00:15:01,290 --> 00:15:05,050 Og så er det statisk, noe som betyr bare at det lever evig, 182 00:15:05,050 --> 00:15:06,610 som er det globale variabler er. 183 00:15:06,610 --> 00:15:10,240 De er bare alltid i minnet. 184 00:15:10,960 --> 00:15:12,760 >> Spørsmål? 185 00:15:14,490 --> 00:15:17,230 [Student] Kan du definere en blokk bare ved hjelp av klammeparentes 186 00:15:17,230 --> 00:15:21,220 men ikke å måtte ha en hvis setningen eller en stund uttalelse eller noe sånt? 187 00:15:21,220 --> 00:15:29,130 Du kan definere en blokk som i en funksjon, men som har klammeparentes også. 188 00:15:29,130 --> 00:15:32,100 [Student] Så du kan ikke bare ha som en tilfeldig par klammeparentes i koden 189 00:15:32,100 --> 00:15:35,680 som har lokale variabler? >> Ja, det kan du. 190 00:15:35,680 --> 00:15:45,900 Innsiden av int bar kunne vi ha {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 Som er ment å være her. 192 00:15:48,440 --> 00:15:52,450 Men som definerer fullstendig omfanget av int y. 193 00:15:52,450 --> 00:15:57,320 Etter at andre krøllete brace, kan y ikke brukes lenger. 194 00:15:57,910 --> 00:16:00,630 Du nesten aldri gjøre det, though. 195 00:16:02,940 --> 00:16:07,370 Komme tilbake til hva som skjer når et program slutter, 196 00:16:07,370 --> 00:16:18,760 Det er litt av en misforståelse / halv løgn at vi gir for å bare gjøre ting enklere. 197 00:16:18,760 --> 00:16:24,410 Vi forteller deg at når du allokere minne 198 00:16:24,410 --> 00:16:29,860 du fordele noen del av RAM for den variabelen. 199 00:16:29,860 --> 00:16:34,190 Men du er ikke egentlig direkte berøre RAM noensinne i programmene dine. 200 00:16:34,190 --> 00:16:37,490 Hvis du tenker på det, hvordan jeg trakk - 201 00:16:37,490 --> 00:16:44,330 Og faktisk, hvis du går gjennom i GDB vil du se det samme. 202 00:16:51,120 --> 00:16:57,590 Uavhengig av hvor mange ganger du kjører programmet eller hvilket program du kjører, 203 00:16:57,590 --> 00:16:59,950 stabelen alltid skal starte - 204 00:16:59,950 --> 00:17:06,510 du alltid kommer til å se variabler rundt adresse oxbffff noe. 205 00:17:06,510 --> 00:17:09,470 Det er vanligvis et sted i den regionen. 206 00:17:09,470 --> 00:17:18,760 Men hvordan kan to programmer muligens ha pekere til samme minne? 207 00:17:20,640 --> 00:17:27,650 [Student] Det er en oppkonstruert utpeking av hvor oxbfff er ment å være på RAM 208 00:17:27,650 --> 00:17:31,320 som faktisk kan være på forskjellige steder avhengig av når funksjonen ble kalt. 209 00:17:31,320 --> 00:17:35,920 Ja. Begrepet er virtuelt minne. 210 00:17:35,920 --> 00:17:42,250 Ideen er at hver enkelt prosess, hver eneste program som kjører på datamaskinen 211 00:17:42,250 --> 00:17:49,450 har sin egen - la oss anta 32 bits - helt uavhengig adresse plass. 212 00:17:49,450 --> 00:17:51,590 Dette er adressen plass. 213 00:17:51,590 --> 00:17:56,220 Det har sine egne helt uavhengig 4 gigabyte å bruke. 214 00:17:56,220 --> 00:18:02,220 >> Så hvis du kjører to programmer samtidig, ser dette programmet 4 gigabyte til seg selv, 215 00:18:02,220 --> 00:18:04,870 dette programmet ser 4 gigabyte til seg selv, 216 00:18:04,870 --> 00:18:07,720 og det er umulig for dette programmet å dereference en peker 217 00:18:07,720 --> 00:18:10,920 og ender opp med minne fra dette programmet. 218 00:18:10,920 --> 00:18:18,200 Og hva virtuelt minne er en kartlegging fra en prosesser adresse plass 219 00:18:18,200 --> 00:18:20,470 til faktiske ting på RAM. 220 00:18:20,470 --> 00:18:22,940 Så det er opp til operativsystemet for å vite det, 221 00:18:22,940 --> 00:18:28,080 hei, når denne fyren dereferences pekeren oxbfff, som egentlig betyr 222 00:18:28,080 --> 00:18:31,040 at han ønsker RAM byte 1000, 223 00:18:31,040 --> 00:18:38,150 mens hvis dette programmet dereferences oxbfff, ønsker han virkelig RAM byte 10000. 224 00:18:38,150 --> 00:18:41,590 De kan være vilkårlig langt fra hverandre. 225 00:18:41,590 --> 00:18:48,730 Dette er også sant av ting innenfor en enkelt prosesser adresse plass. 226 00:18:48,730 --> 00:18:54,770 Så ut som det ser alle fire gigabyte til seg selv, men la oss si - 227 00:18:54,770 --> 00:18:57,290 [Student] Har hver enkelt prosess - 228 00:18:57,290 --> 00:19:01,350 La oss si du har en datamaskin med bare 4 gigabyte RAM. 229 00:19:01,350 --> 00:19:06,430 Ser hver enkelt prosess hele 4 gigabyte? >> Ja. 230 00:19:06,430 --> 00:19:13,060 Men de fire gigabyte det ser er en løgn. 231 00:19:13,060 --> 00:19:20,460 Det er bare den tror den har alt dette minnet fordi den ikke vet noen annen prosess eksisterer. 232 00:19:20,460 --> 00:19:28,140 Det vil bare bruke så mye minne som det faktisk er behov for. 233 00:19:28,140 --> 00:19:32,340 Operativsystemet er ikke tenkt å gi RAM til denne prosessen 234 00:19:32,340 --> 00:19:35,750 hvis det ikke bruker minnet på dette hele regionen. 235 00:19:35,750 --> 00:19:39,300 Det kommer ikke til å gi den minne for regionen. 236 00:19:39,300 --> 00:19:54,780 Men ideen er at - Jeg prøver å tenke på - jeg kan ikke tenke på en analogi. 237 00:19:54,780 --> 00:19:56,780 Analogier er vanskelig. 238 00:19:57,740 --> 00:20:02,700 Ett av problemene virtuelt minne eller en av de tingene det er å løse 239 00:20:02,700 --> 00:20:06,810 at prosesser skal være helt uvitende om hverandre. 240 00:20:06,810 --> 00:20:12,140 Og så kan du skrive et program som bare dereferences noen peker, 241 00:20:12,140 --> 00:20:19,340 liker bare skrive et program som sier * (ox1234), 242 00:20:19,340 --> 00:20:22,890 og det er dereferencing minneadresse 1234. 243 00:20:22,890 --> 00:20:28,870 >> Men det er opp til operativsystemet for å deretter oversette hva 1234 betyr. 244 00:20:28,870 --> 00:20:33,960 Så hvis 1234 skjer for å være en gyldig minne adresse for denne prosessen, 245 00:20:33,960 --> 00:20:38,800 som det er på stakken eller noe, da dette vil returnere verdien av at minneadresse 246 00:20:38,800 --> 00:20:41,960 så langt som prosessen vet. 247 00:20:41,960 --> 00:20:47,520 Men hvis 1234 er ikke en gyldig adresse, som det skjer til land 248 00:20:47,520 --> 00:20:52,910 i noen lite stykke minne her som er utenfor stabelen og utover haugen 249 00:20:52,910 --> 00:20:57,200 og du har egentlig ikke brukt det, så det er da du får ting som segfaults 250 00:20:57,200 --> 00:21:00,260 fordi du berører minne som du ikke bør berøre. 251 00:21:07,180 --> 00:21:09,340 Dette er også tilfelle - 252 00:21:09,340 --> 00:21:15,440 En 32-bits system, betyr 32 biter du har 32 bits for å definere et minne adresse. 253 00:21:15,440 --> 00:21:22,970 Det er derfor pekere er 8 byte fordi 32 bits er 8 byte - eller 4 byte. 254 00:21:22,970 --> 00:21:25,250 Pekere er 4 byte. 255 00:21:25,250 --> 00:21:33,680 Så når du ser en peker som oxbfffff, er at - 256 00:21:33,680 --> 00:21:40,080 Innenfor et gitt program kan du bare lage en vilkårlig pekeren, 257 00:21:40,080 --> 00:21:46,330 alt fra ox0 til okse 8 f's - FFFFFFFF. 258 00:21:46,330 --> 00:21:49,180 [Student] Sa du ikke at de er 4 byte? >> Ja. 259 00:21:49,180 --> 00:21:52,730 [Student] Så hver byte vil ha - >> [Bowden] Heksadesimal. 260 00:21:52,730 --> 00:21:59,360 Heksadesimal - 5, 6, 7, 8. Så pekere du kommer til å alltid se i heksadesimal. 261 00:21:59,360 --> 00:22:01,710 Det er bare hvordan vi klassifiserer pekere. 262 00:22:01,710 --> 00:22:05,240 Hver 2 sifrene i heksadesimal er 1 byte. 263 00:22:05,240 --> 00:22:09,600 Så det kommer til å bli 8 heksadesimale sifre for 4 bytes. 264 00:22:09,600 --> 00:22:14,190 Så hver eneste peker på en 32-bit system skal være 4 byte, 265 00:22:14,190 --> 00:22:18,550 noe som betyr at i prosessen kan du konstruere vilkårlige 4 byte 266 00:22:18,550 --> 00:22:20,550 og foreta en peker ut av det, 267 00:22:20,550 --> 00:22:32,730 noe som betyr at så langt som det er klar, kan det ta en hel 2 til 32 byte minne. 268 00:22:32,730 --> 00:22:34,760 Selv om det ikke egentlig har tilgang til den, 269 00:22:34,760 --> 00:22:40,190 selv om datamaskinen bare har 512 megabyte, mener det det har så mye minne. 270 00:22:40,190 --> 00:22:44,930 Og operativsystemet er smart nok til at det vil bare tildele hva du faktisk trenger. 271 00:22:44,930 --> 00:22:49,630 Det betyr ikke bare gå, oh, en ny prosess: 4 konserter. 272 00:22:49,630 --> 00:22:51,930 >> Ja. >> [Student] Hva betyr oksen? Hvorfor skriver du det? 273 00:22:51,930 --> 00:22:54,980 Det er bare symbolet for heksadesimal. 274 00:22:54,980 --> 00:22:59,590 Når du ser et tall start med okse, de påfølgende ting er heksadesimal. 275 00:23:01,930 --> 00:23:05,760 [Student] Du skulle forklare om hva som skjer når et program slutter. >> Ja. 276 00:23:05,760 --> 00:23:09,480 Hva skjer når et program slutter er operativsystemet 277 00:23:09,480 --> 00:23:13,600 bare sletter kartlegginger som den har for disse adressene, og det er det. 278 00:23:13,600 --> 00:23:17,770 Operativsystemet kan nå bare gi som minne til et annet program å bruke. 279 00:23:17,770 --> 00:23:19,490 [Student] Okay. 280 00:23:19,490 --> 00:23:24,800 Så når du tildeler noe på haugen eller stable eller globale variabler eller noe, 281 00:23:24,800 --> 00:23:27,010 de bare forsvinner så snart programmet avsluttes 282 00:23:27,010 --> 00:23:32,120 fordi operativsystemet er nå fri til å gi den minne til andre prosesser. 283 00:23:32,120 --> 00:23:35,150 [Student] Selv om det er sannsynligvis fortsatt verdier skrevet i? >> Ja. 284 00:23:35,150 --> 00:23:37,740 Verdiene er sannsynligvis fortsatt der. 285 00:23:37,740 --> 00:23:41,570 Det er bare det kommer til å være vanskelig å få på dem. 286 00:23:41,570 --> 00:23:45,230 Det er mye vanskeligere å få på dem enn det er å få på en slettet fil 287 00:23:45,230 --> 00:23:51,450 fordi den slettede filen slags sitter der i lang tid, og harddisken er mye større. 288 00:23:51,450 --> 00:23:54,120 Så det kommer til å overskrive ulike deler av minnet 289 00:23:54,120 --> 00:23:58,640 før det skjer for å overskrive del av minnet som filen pleide å være på. 290 00:23:58,640 --> 00:24:04,520 Men hovedminne, RAM, du sykle gjennom mye raskere, 291 00:24:04,520 --> 00:24:08,040 så det kommer til veldig raskt bli overskrevet. 292 00:24:10,300 --> 00:24:13,340 Spørsmål om dette eller noe annet? 293 00:24:13,340 --> 00:24:16,130 [Student] Jeg har spørsmål om et annet tema. >> Ok. 294 00:24:16,130 --> 00:24:19,060 Har noen spørsmål om dette? 295 00:24:20,170 --> 00:24:23,120 >> Okay. Annet tema. >> [Student] Okay. 296 00:24:23,120 --> 00:24:26,550 Jeg gikk gjennom noen av de praktiske testene, 297 00:24:26,550 --> 00:24:30,480 og i en av dem ble det snakket om sizeof 298 00:24:30,480 --> 00:24:35,630 og verdien som den returnerer eller ulike variable typer. >> Ja. 299 00:24:35,630 --> 00:24:45,060 Og det sies at både int og lang både avkastning 4, slik at de er begge 4 byte. 300 00:24:45,060 --> 00:24:48,070 Er det noen forskjell mellom en int og en lang, eller er det det samme? 301 00:24:48,070 --> 00:24:50,380 Ja, det er en forskjell. 302 00:24:50,380 --> 00:24:52,960 C-standard - 303 00:24:52,960 --> 00:24:54,950 Jeg sannsynligvis kommer til å rote. 304 00:24:54,950 --> 00:24:58,800 C-standarden er akkurat hva C er, den offisielle dokumentasjonen av C. 305 00:24:58,800 --> 00:25:00,340 Dette er hva den sier. 306 00:25:00,340 --> 00:25:08,650 Så C standarden sier bare at en røye vil for evig og alltid være en byte. 307 00:25:10,470 --> 00:25:19,040 Alt etter som - en kort er alltid bare definert som å være større enn eller lik en char. 308 00:25:19,040 --> 00:25:23,010 Dette kan være strengt større enn, men ikke positiv. 309 00:25:23,010 --> 00:25:31,940 En int er bare definert som å være større enn eller lik en kort. 310 00:25:31,940 --> 00:25:36,210 Og en lang er bare definert som å være større enn eller lik en int. 311 00:25:36,210 --> 00:25:41,600 Og en lang lang er større enn eller lik en lang. 312 00:25:41,600 --> 00:25:46,610 Så det eneste C-standarden definerer er den relative bestilling av alt. 313 00:25:46,610 --> 00:25:54,880 Den faktiske mengden minne om at ting tar opp er vanligvis opp til implementering, 314 00:25:54,880 --> 00:25:57,640 men det er ganske godt definert på dette punktet. >> [Student] Okay. 315 00:25:57,640 --> 00:26:02,490 Så shorts er nesten alltid kommer til å være to bytes. 316 00:26:04,920 --> 00:26:09,950 Ints er nesten alltid kommer til å være 4 byte. 317 00:26:12,070 --> 00:26:15,340 Lange lengter nesten alltid kommer til å være 8 byte. 318 00:26:17,990 --> 00:26:23,160 Og lengter, det avhenger av om du bruker en 32-bit eller 64-bit system. 319 00:26:23,160 --> 00:26:27,450 Så lenge skal tilsvare den type system. 320 00:26:27,450 --> 00:26:31,920 Hvis du bruker en 32-bit system som Appliance, kommer det til å være 4 byte. 321 00:26:34,530 --> 00:26:42,570 Hvis du bruker en 64-bit like mye nyere datamaskiner, kommer det til å være 8 byte. 322 00:26:42,570 --> 00:26:45,230 >> Ints er nesten alltid 4 bytes på dette punktet. 323 00:26:45,230 --> 00:26:47,140 Lange lengter er nesten alltid 8 byte. 324 00:26:47,140 --> 00:26:50,300 I det siste, brukte ints å bare være to bytes. 325 00:26:50,300 --> 00:26:56,840 Men merker at dette helt tilfredsstiller alle disse relasjoner større enn og lik. 326 00:26:56,840 --> 00:27:01,280 Så lenge er perfekt lov til å være av samme størrelse som et heltall, 327 00:27:01,280 --> 00:27:04,030 og det er også lov til å være av samme størrelse som en lang lang. 328 00:27:04,030 --> 00:27:11,070 Og det bare så skjer for å være det i 99,999% av systemer, er det kommer til å være lik 329 00:27:11,070 --> 00:27:15,800 enten en int eller en lang lang. Det avhenger bare av 32-bit eller 64-bit. >> [Student] Okay. 330 00:27:15,800 --> 00:27:24,600 I flyter, hvordan er desimaltegn utpekt i form av bits? 331 00:27:24,600 --> 00:27:27,160 Liker som binære? >> Ja. 332 00:27:27,160 --> 00:27:30,570 Du trenger ikke å vite at for CS50. 333 00:27:30,570 --> 00:27:32,960 Du trenger ikke engang vite at i 61. 334 00:27:32,960 --> 00:27:37,350 Du trenger ikke lære at virkelig i et kurs. 335 00:27:37,350 --> 00:27:42,740 Det er bare en representasjon. 336 00:27:42,740 --> 00:27:45,440 Jeg glemmer den eksakte bit parseller. 337 00:27:45,440 --> 00:27:53,380 Ideen om flyttall er at du tildele et bestemt antall biter til å representere - 338 00:27:53,380 --> 00:27:56,550 I utgangspunktet er alt i vitenskapelig notasjon. 339 00:27:56,550 --> 00:28:05,600 Så du tildele et bestemt antall biter til å representere selve nummeret, som 1,2345. 340 00:28:05,600 --> 00:28:10,200 Jeg kan aldri representere et tall med flere siffer enn 5. 341 00:28:12,200 --> 00:28:26,300 Da har du også sette av et bestemt antall biter, slik at det har en tendens til å være like 342 00:28:26,300 --> 00:28:32,810 du kan bare gå opp til et visst antall, som det er den største eksponenten du kan ha, 343 00:28:32,810 --> 00:28:36,190 og du kan bare gå ned til en viss eksponent, 344 00:28:36,190 --> 00:28:38,770 sånn er det minste eksponenten du kan ha. 345 00:28:38,770 --> 00:28:44,410 >> Jeg husker ikke nøyaktig hvordan bitene tildelt alle disse verdiene, 346 00:28:44,410 --> 00:28:47,940 men et visst antall biter er dedikert til 1,2345, 347 00:28:47,940 --> 00:28:50,930 en annen visst antall bits er dedikert til eksponent, 348 00:28:50,930 --> 00:28:55,670 og det er bare mulig å representere en eksponent av en viss størrelse. 349 00:28:55,670 --> 00:29:01,100 [Student] Og en dobbel? Er at som en ekstra lang float? >> Ja. 350 00:29:01,100 --> 00:29:07,940 Det er det samme som en dupp bortsett fra nå du bruker 8 byte i stedet for 4 byte. 351 00:29:07,940 --> 00:29:11,960 Nå vil du kunne bruke 9 sifre eller 10 sifre, 352 00:29:11,960 --> 00:29:16,630 og dette vil være i stand til å gå opp til 300 i stedet for 100. >> [Student] Okay. 353 00:29:16,630 --> 00:29:21,550 Og flyter finnes også 4 bytes. >> Ja. 354 00:29:21,550 --> 00:29:27,520 Vel, igjen, det avhenger sannsynligvis samlet på generell implementering, 355 00:29:27,520 --> 00:29:30,610 men flyter er 4 byte, dobler er 8. 356 00:29:30,610 --> 00:29:33,440 Dobler kalles dobbelt fordi de er dobbelt så stort som flyter. 357 00:29:33,440 --> 00:29:38,380 [Student] Okay. Og er det dobler dobbelt? >> Det er det ikke. 358 00:29:38,380 --> 00:29:43,660 Jeg tror - >> [student] Liker lange lengter? >> Ja. Jeg tror ikke det. Ja. 359 00:29:43,660 --> 00:29:45,950 [Student] På fjorårets test var det et spørsmål om den viktigste funksjonen 360 00:29:45,950 --> 00:29:49,490 å være en del av programmet. 361 00:29:49,490 --> 00:29:52,310 Svaret var at det ikke trenger å være en del av programmet. 362 00:29:52,310 --> 00:29:55,100 I hvilken situasjon? Det er det jeg så. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Det virker - >> [student] Hvilken situasjon? 364 00:29:59,090 --> 00:30:02,880 Har du problemet? >> [Student] Ja, jeg kan definitivt dra det opp. 365 00:30:02,880 --> 00:30:07,910 Det trenger ikke å være, teknisk, men i utgangspunktet er tenkt å være. 366 00:30:07,910 --> 00:30:10,030 [Student] Jeg så en på en annen årets. 367 00:30:10,030 --> 00:30:16,220 Det var som Sant eller usant: Et gyldig - >> Å, en c-fil.? 368 00:30:16,220 --> 00:30:18,790 . [Student] Enhver c filen må ha - [både tale på en gang - uforståelig] 369 00:30:18,790 --> 00:30:21,120 Okay. Så det er separate. 370 00:30:21,120 --> 00:30:26,800 >> A. C-fil trenger bare å inneholde funksjoner. 371 00:30:26,800 --> 00:30:32,400 Du kan kompilere en fil til maskinkode, binær, uansett, 372 00:30:32,400 --> 00:30:36,620 uten at det er kjørbar ennå. 373 00:30:36,620 --> 00:30:39,420 En gyldig kjørbar må ha en hovedfunksjon. 374 00:30:39,420 --> 00:30:45,460 Du kan skrive 100 funksjoner i en fil, men ingen viktigste 375 00:30:45,460 --> 00:30:48,800 og deretter kompilere det ned til binær, 376 00:30:48,800 --> 00:30:54,460 Så skriver du en annen fil som bare har main men det kaller en haug av disse funksjonene 377 00:30:54,460 --> 00:30:56,720 i denne binærfil over her. 378 00:30:56,720 --> 00:31:01,240 Og så når du gjør den kjørbare, det er hva det linker gjør 379 00:31:01,240 --> 00:31:05,960 er det kombinerer disse to binære filer i en kjørbar. 380 00:31:05,960 --> 00:31:11,400 Så en. C-fil ikke trenger å ha en hovedfunksjon i det hele tatt. 381 00:31:11,400 --> 00:31:19,220 Og på store kode baser vil du se tusenvis av. C-filer og en main fil. 382 00:31:23,960 --> 00:31:26,110 Flere spørsmål? 383 00:31:29,310 --> 00:31:31,940 [Student] Det var et annet spørsmål. 384 00:31:31,940 --> 00:31:36,710 Det sa gjør er en kompilator. Sant eller usant? 385 00:31:36,710 --> 00:31:42,030 Og svaret var falsk, og jeg forsto hvorfor det er ikke som Clang. 386 00:31:42,030 --> 00:31:44,770 Men hva kaller vi gjør hvis det ikke? 387 00:31:44,770 --> 00:31:49,990 Gjøre er i utgangspunktet bare - jeg kan se nøyaktig det de kaller det. 388 00:31:49,990 --> 00:31:52,410 Men det går bare kommandoer. 389 00:31:53,650 --> 00:31:55,650 Gjør. 390 00:31:58,240 --> 00:32:00,870 Jeg kan trekke dette opp. Ja. 391 00:32:10,110 --> 00:32:13,180 Oh, yeah. Gjør også gjør det. 392 00:32:13,180 --> 00:32:17,170 Dette sier hensikten med make-verktøyet er å bestemme automatisk 393 00:32:17,170 --> 00:32:19,610 der deler av et stort program som trenger en ny 394 00:32:19,610 --> 00:32:22,350 og utstede kommandoer å rekompilere dem. 395 00:32:22,350 --> 00:32:27,690 Du kan lage lage filer som er helt enorm. 396 00:32:27,690 --> 00:32:33,210 Gjør ser på tidsangivelser for filer og, som vi sa 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 linker 398 00:32:36,930 --> 00:32:39,270 at de er satt sammen til en kjørbar. 399 00:32:39,270 --> 00:32:43,810 Så hvis du har 10 forskjellige filer og gjøre en endring i en av dem, 400 00:32:43,810 --> 00:32:47,870 så hva gjør kommer til å gjøre er bare rekompilere at en fil 401 00:32:47,870 --> 00:32:50,640 og deretter koble alt sammen. 402 00:32:50,640 --> 00:32:53,020 Men det er mye dummere enn det. 403 00:32:53,020 --> 00:32:55,690 Det er opp til deg å fullstendig definere at det er hva det skal gjøre. 404 00:32:55,690 --> 00:32:59,560 Det som standard har evnen til å gjenkjenne denne tidsangivelsen ting, 405 00:32:59,560 --> 00:33:03,220 men du kan skrive en make-fil for å gjøre noe. 406 00:33:03,220 --> 00:33:09,150 Du kan skrive en make-fil slik at når du skriver at det bare cd-er til en annen katalog. 407 00:33:09,150 --> 00:33:15,560 Jeg var frustrert fordi jeg takle alt inne i Appliance min 408 00:33:15,560 --> 00:33:21,740 og da jeg vise PDF-filen fra Mac. 409 00:33:21,740 --> 00:33:30,720 >> Så jeg går til Finder og jeg kan ikke gå, koble til serveren, 410 00:33:30,720 --> 00:33:36,950 og serveren jeg kobler til er min Appliance, og da jeg åpner opp PDF 411 00:33:36,950 --> 00:33:40,190 som blir utarbeidet av LaTeX. 412 00:33:40,190 --> 00:33:49,320 Men jeg begynte å bli frustrert fordi hver eneste gang jeg trengte å oppdatere PDF, 413 00:33:49,320 --> 00:33:53,900 Jeg måtte kopiere den til en bestemt katalog at det kunne få tilgang 414 00:33:53,900 --> 00:33:57,710 og det var å få irriterende. 415 00:33:57,710 --> 00:34:02,650 Så i stedet skrev jeg en make-fil, som du må definere hvordan det gjør ting. 416 00:34:02,650 --> 00:34:06,130 Hvordan du gjør i denne er PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Akkurat som alle andre lag file - eller jeg antar at du ikke har sett gjøre filer, 418 00:34:10,090 --> 00:34:13,510 men vi har i Appliance en global lag fil som bare sier, 419 00:34:13,510 --> 00:34:16,679 Hvis du kompilere et C-fil, kan du bruke Clang. 420 00:34:16,679 --> 00:34:20,960 Og så her i min make-fil som jeg gjør jeg si, 421 00:34:20,960 --> 00:34:25,020 denne filen du skal ønske å kompilere med PDF LaTeX. 422 00:34:25,020 --> 00:34:27,889 Og så er det PDF LaTeX som gjør det kompilering. 423 00:34:27,889 --> 00:34:31,880 Gjør ikke kompilering. Det er bare å kjøre disse kommandoene i den rekkefølgen jeg spesifisert. 424 00:34:31,880 --> 00:34:36,110 Så det går PDF LaTeX, kopierer det opp til katalogen jeg ønsker det skal kopieres til, 425 00:34:36,110 --> 00:34:38,270 det cd-er til katalogen og gjør andre ting, 426 00:34:38,270 --> 00:34:42,380 men alt det gjør er gjenkjenne når en fil endres, 427 00:34:42,380 --> 00:34:45,489 og hvis den endres, så vil det kjøre kommandoene som det er ment å kjøre 428 00:34:45,489 --> 00:34:48,760 Når filen endres. >> [Student] Okay. 429 00:34:50,510 --> 00:34:54,420 Jeg vet ikke hvor de globale gjøre filer er for meg å sjekke det ut. 430 00:34:57,210 --> 00:35:04,290 Andre spørsmål? Alt fra fortiden quizer? Eventuelle pekeren ting? 431 00:35:06,200 --> 00:35:08,730 Det er subtile ting med pekere som - 432 00:35:08,730 --> 00:35:10,220 Jeg har ikke tenkt å være i stand til å finne en quiz spørsmål om det - 433 00:35:10,220 --> 00:35:16,250 men akkurat som denne typen ting. 434 00:35:19,680 --> 00:35:24,060 Sørg for at du forstår at når jeg sier int * x * y - 435 00:35:24,890 --> 00:35:28,130 Dette er ikke akkurat noe her, antar jeg. 436 00:35:28,130 --> 00:35:32,140 Men som * x * y, de er to variabler som er på stakken. 437 00:35:32,140 --> 00:35:37,220 Når jeg sier x = malloc (sizeof (int)), x fortsatt en variabel på stakken, 438 00:35:37,220 --> 00:35:41,180 malloc er noen blokk over i haugen, og vi har x peker på haugen. 439 00:35:41,180 --> 00:35:43,900 >> Så noe på stakken peker på haugen. 440 00:35:43,900 --> 00:35:48,100 Når du malloc noe, er du nødvendigvis lagre den på innsiden av en peker. 441 00:35:48,100 --> 00:35:55,940 Slik at pekeren er på stakken, er malloced blokk på haugen. 442 00:35:55,940 --> 00:36:01,240 Mange mennesker får forvirret og si int * x = malloc, x er på haugen. 443 00:36:01,240 --> 00:36:04,100 Nei Hva x peker til er på haugen. 444 00:36:04,100 --> 00:36:08,540 x selv er på stakken, med mindre en eller annen grunn være deg x har en global variabel, 445 00:36:08,540 --> 00:36:11,960 i hvilket tilfelle det skjer for å være i en annen region av minnet. 446 00:36:13,450 --> 00:36:20,820 Så holde orden, disse boks og pil diagrammer er ganske vanlig for quiz. 447 00:36:20,820 --> 00:36:25,740 Eller hvis det ikke er på quiz 0, vil det være på quiz en. 448 00:36:27,570 --> 00:36:31,940 Du bør vite alle disse, trinnene i kompilering 449 00:36:31,940 --> 00:36:35,740 siden du måtte svare på spørsmål om disse. Ja. 450 00:36:35,740 --> 00:36:38,940 [Student] Kan vi gå over disse trinnene - >> Sure. 451 00:36:48,340 --> 00:36:58,640 Før trinn og kompilere har vi forbehandling, 452 00:36:58,640 --> 00:37:16,750 kompilering, montering, og linking. 453 00:37:16,750 --> 00:37:21,480 Forbehandling. Hva gjør det? 454 00:37:29,720 --> 00:37:32,290 Det er den enkleste skritt i - vel, ikke som - 455 00:37:32,290 --> 00:37:35,770 det betyr ikke at det bør være opplagt, men det er den enkleste trinnet. 456 00:37:35,770 --> 00:37:38,410 Dere kan gjennomføre det selv. Ja. 457 00:37:38,410 --> 00:37:43,410 [Student] Ta det du har i din inneholder som dette, og det kopierer og deretter også definerer. 458 00:37:43,410 --> 00:37:49,250 Det ser for ting som # include og # definere, 459 00:37:49,250 --> 00:37:53,800 og det bare kopierer og limer hva de egentlig mener. 460 00:37:53,800 --> 00:37:59,240 Så når du sier # include cs50.h er preprosessor kopiere og lime cs50.h 461 00:37:59,240 --> 00:38:01,030 inn i den linjen. 462 00:38:01,030 --> 00:38:06,640 Når du sier # define x å være 4, går preprosessor gjennom hele programmet 463 00:38:06,640 --> 00:38:10,400 og erstatter alle forekomster av x med 4. 464 00:38:10,400 --> 00:38:17,530 Så preprosessor tar en gyldig C-fil og utganger en gyldig C-fil 465 00:38:17,530 --> 00:38:20,300 hvor ting har blitt kopiert og limt inn. 466 00:38:20,300 --> 00:38:24,230 Så nå kompilering. Hva gjør det? 467 00:38:25,940 --> 00:38:28,210 [Student] Det går fra C til binær. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] Det går ikke hele veien til binær. 469 00:38:30,970 --> 00:38:34,220 [Student] til maskinkode da? >> Det er ikke maskinkode. 470 00:38:34,220 --> 00:38:35,700 [Student] Assembly? >> Assembly. 471 00:38:35,700 --> 00:38:38,890 Det går til Assembly før det går hele veien til C-kode, 472 00:38:38,890 --> 00:38:45,010 og de fleste språk gjøre noe som dette. 473 00:38:47,740 --> 00:38:50,590 Plukke noen høyt nivå språk, og hvis du kommer til å kompilere den, 474 00:38:50,590 --> 00:38:52,390 det er sannsynlig å kompilere i trinn. 475 00:38:52,390 --> 00:38:58,140 Først det kommer til å kompilere Python til C, så det kommer til å kompilere C til Assembly, 476 00:38:58,140 --> 00:39:01,600 og deretter Montering kommer til å bli oversatt til binær. 477 00:39:01,600 --> 00:39:07,800 Så kompilere kommer til å bringe den fra C til forsamlingen. 478 00:39:07,800 --> 00:39:12,130 Ordet kompilering betyr vanligvis bringe det fra et høyere nivå 479 00:39:12,130 --> 00:39:14,340 til et lavere nivå programmeringsspråk. 480 00:39:14,340 --> 00:39:19,190 Så dette er den eneste skritt i kompilering der du starter med et høyt nivå språk 481 00:39:19,190 --> 00:39:23,270 og ender opp i en lav-nivå språk, og det er derfor trinnet kalles kompilering. 482 00:39:25,280 --> 00:39:33,370 [Student] Under kompilering, la oss si at du har gjort # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Vil kompilatoren rekompilere cs50.h, som funksjonene som er der inne, 484 00:39:42,190 --> 00:39:45,280 og oversette det til Assembly kode i tillegg, 485 00:39:45,280 --> 00:39:50,830 eller vil den kopiere og lime noe som har vært pre-Assembly? 486 00:39:50,830 --> 00:39:56,910 cs50.h vil stort sett aldri ende opp i Assembly. 487 00:39:59,740 --> 00:40:03,680 Ting som funksjon prototyper og ting er bare for deg å være forsiktig. 488 00:40:03,680 --> 00:40:09,270 Det garanterer at kompilatoren kan sjekke ting som du ringer funksjoner 489 00:40:09,270 --> 00:40:12,910 med riktig retur typer og de riktige argumenter og sånt. 490 00:40:12,910 --> 00:40:18,350 >> Så cs50.h vil bli preprocessed i filen, og deretter når det er kompilering 491 00:40:18,350 --> 00:40:22,310 det er i utgangspunktet kastet bort etter at det sørger for at alt kalles riktig. 492 00:40:22,310 --> 00:40:29,410 Men funksjonene som er definert i CS50 biblioteket, som er atskilt fra cs50.h, 493 00:40:29,410 --> 00:40:33,610 de vil ikke bli særskilt kompilert. 494 00:40:33,610 --> 00:40:37,270 Som faktisk vil komme ned i å knytte skritt, så vi får til det i et sekund. 495 00:40:37,270 --> 00:40:40,100 Men først, hva er montering? 496 00:40:41,850 --> 00:40:44,500 [Student] Assembly til binære? >> Ja. 497 00:40:46,300 --> 00:40:48,190 Montering. 498 00:40:48,190 --> 00:40:54,710 Vi kaller ikke det kompilering fordi Assembly er ganske mye en ren oversettelse av binære. 499 00:40:54,710 --> 00:41:00,230 Det er svært lite logikk i å gå fra Assembly til binær. 500 00:41:00,230 --> 00:41:03,180 Det er akkurat som å se opp i en tabell, oh, har vi denne instruksjonen; 501 00:41:03,180 --> 00:41:06,290 som tilsvarer binær 01110. 502 00:41:10,200 --> 00:41:15,230 Og slik at filene som montering generelt utganger er. O-filer. 503 00:41:15,230 --> 00:41:19,020 Og. O-filer er hva vi sier før, 504 00:41:19,020 --> 00:41:21,570 hvordan en fil ikke trenger å ha en hovedfunksjon. 505 00:41:21,570 --> 00:41:27,640 Hvilken som helst fil kan kompileres ned til en. O fil så lenge det er en gyldig C-fil. 506 00:41:27,640 --> 00:41:30,300 Det kan kompileres ned til. O. 507 00:41:30,300 --> 00:41:43,030 Nå er knytte hva som faktisk bringer en haug med. O filer og bringer dem til en kjørbar. 508 00:41:43,030 --> 00:41:51,110 Og så hva linking gjør er at du kan tenke på CS50 biblioteket som en. O-fil. 509 00:41:51,110 --> 00:41:56,980 Det er en allerede kompilert binærfil. 510 00:41:56,980 --> 00:42:03,530 Og så når du kompilere filen, din hallo.c, som kaller GetString, 511 00:42:03,530 --> 00:42:06,360 hallo.c blir utarbeidet ned til hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o er nå i binær. 513 00:42:08,910 --> 00:42:12,830 Den bruker GetString, så det må gå over til cs50.o, 514 00:42:12,830 --> 00:42:16,390 og linker smooshes dem sammen og kopierer GetString inn i denne filen 515 00:42:16,390 --> 00:42:20,640 og kommer ut med en kjørbar som har alle funksjoner det er behov for. 516 00:42:20,640 --> 00:42:32,620 Så cs50.o er faktisk ikke en O-fil, men det er nært nok til at det ikke er noen grunnleggende forskjell. 517 00:42:32,620 --> 00:42:36,880 Så knytte bare bringer en haug med filer sammen 518 00:42:36,880 --> 00:42:41,390 som hver for seg inneholder alle de funksjoner jeg trenger å bruke 519 00:42:41,390 --> 00:42:46,120 og skaper den kjørbare som faktisk vil kjøre. 520 00:42:48,420 --> 00:42:50,780 >> Og så det er også hva vi sier før 521 00:42:50,780 --> 00:42:55,970 der du kan ha 1000. c-filer, kompilere du dem alle til. o-filer, 522 00:42:55,970 --> 00:43:00,040 som trolig vil ta en stund, så endrer en. c-fil. 523 00:43:00,040 --> 00:43:05,480 Du trenger bare å rekompilere at 1. C-fil og deretter koble alt annet, 524 00:43:05,480 --> 00:43:07,690 koble alt sammen igjen. 525 00:43:09,580 --> 00:43:11,430 [Student] Når vi kobler vi skriver lcs50? 526 00:43:11,430 --> 00:43:20,510 Ja, så-lcs50. Det flagget signaler til linker som du bør knytte i biblioteket. 527 00:43:26,680 --> 00:43:28,910 Spørsmål? 528 00:43:41,310 --> 00:43:46,860 Har vi gått over binær annet enn at 5 sekunder i første forelesning? 529 00:43:50,130 --> 00:43:53,010 Jeg tror ikke det. 530 00:43:55,530 --> 00:43:58,820 Du bør vite alle de store Os at vi har gått over, 531 00:43:58,820 --> 00:44:02,670 og du bør være i stand til, hvis vi ga deg en funksjon, 532 00:44:02,670 --> 00:44:09,410 bør du være i stand til å si at det er stor O, omtrent. Eller godt, er stor O grov. 533 00:44:09,410 --> 00:44:15,300 Så hvis du ser nestet for løkker looping over samme rekke ting, 534 00:44:15,300 --> 00:44:22,260 som int i, i > [student] n squared. >> Det tendens til å være n squared. 535 00:44:22,260 --> 00:44:25,280 Hvis du har trippel nestet, pleier det å være n cubed. 536 00:44:25,280 --> 00:44:29,330 Så den slags ting du bør være i stand til å peke ut umiddelbart. 537 00:44:29,330 --> 00:44:33,890 Du trenger å vite innsetting sortere og boble sortere og flette sortere og alle disse. 538 00:44:33,890 --> 00:44:41,420 Det er lettere å forstå hvorfor de er de n kvadrerte og n log n og alle som 539 00:44:41,420 --> 00:44:47,810 fordi jeg tror det var på en quiz ett år der vi i utgangspunktet ga deg 540 00:44:47,810 --> 00:44:55,050 en implementering av boble sortere og sa: «Hva er kjøretiden til denne funksjonen?" 541 00:44:55,050 --> 00:45:01,020 Så hvis du kjenner det som boble sortere, så kan du umiddelbart si n squared. 542 00:45:01,020 --> 00:45:05,470 Men hvis du bare ser på det, trenger du ikke engang trenger å innse det boble slag; 543 00:45:05,470 --> 00:45:08,990 du kan bare si at dette er å gjøre dette og dette. Dette er n squared. 544 00:45:12,350 --> 00:45:14,710 [Student] Er det noen tøffe eksempler du kan komme opp med, 545 00:45:14,710 --> 00:45:20,370 som en lignende idé å finne ut? 546 00:45:20,370 --> 00:45:24,450 >> Jeg tror ikke vi vil gi deg noen tøffe eksempler. 547 00:45:24,450 --> 00:45:30,180 Boblen slags ting er omtrent like tøff som vi ville gå, 548 00:45:30,180 --> 00:45:36,280 og selv det, så lenge du forstår at du gjentar i rekken 549 00:45:36,280 --> 00:45:41,670 for hvert element i matrisen, som er tenkt å være noe som er n squared. 550 00:45:45,370 --> 00:45:49,940 Det er generelle spørsmål, som akkurat her vi har - Oh. 551 00:45:55,290 --> 00:45:58,530 Bare den andre dagen, Doug hevdet: "Jeg har oppfunnet en algoritme som kan sortere en rekke 552 00:45:58,530 --> 00:46:01,780 "Av n tall i O (log n) tid!" 553 00:46:01,780 --> 00:46:04,900 Så hvordan vet vi at er umulig? 554 00:46:04,900 --> 00:46:08,850 [Uhørlig student respons] >> Ja. 555 00:46:08,850 --> 00:46:13,710 I det minste, må du ta hvert element i matrisen, 556 00:46:13,710 --> 00:46:16,210 så det er umulig å sortere en rekke - 557 00:46:16,210 --> 00:46:20,850 Hvis alt er i usortert orden, så du kommer til å berøre alt i rekken, 558 00:46:20,850 --> 00:46:25,320 så det er umulig å gjøre det på mindre enn O n. 559 00:46:27,430 --> 00:46:30,340 [Student] Du viste oss at eksempel på å være i stand til å gjøre det i O n 560 00:46:30,340 --> 00:46:33,920 hvis du bruker mye minne. >> Ja. 561 00:46:33,920 --> 00:46:37,970 Og that - jeg glemmer hva that - Er det teller slag? 562 00:46:47,360 --> 00:46:51,330 Hmm. Som er et heltall sortering algoritme. 563 00:46:59,850 --> 00:47:05,100 Jeg var på utkikk etter den spesielle navn for dette at jeg ikke kunne huske forrige uke. 564 00:47:05,100 --> 00:47:13,000 Ja. Disse er de typene sorterer som kan utføre ting i store O n. 565 00:47:13,000 --> 00:47:18,430 Men det er begrensninger, som du bare kan bruke heltall opp til et visst antall. 566 00:47:20,870 --> 00:47:24,560 Pluss hvis du prøver å sortere noe that - 567 00:47:24,560 --> 00:47:30,750 Hvis matrise er 012, -12, 151, 4 millioner, 568 00:47:30,750 --> 00:47:35,120 så det eneste element skal fullstendig ødelegge hele sortering. 569 00:47:42,060 --> 00:47:44,030 >> Spørsmål? 570 00:47:49,480 --> 00:47:58,870 [Student] Hvis du har en rekursiv funksjon, og det bare gjør rekursive samtaler 571 00:47:58,870 --> 00:48:02,230 innenfor en retur uttalelse, er at halen rekursive 572 00:48:02,230 --> 00:48:07,360 og så ville det ikke bruke mer minne under kjøring 573 00:48:07,360 --> 00:48:12,550 eller det ville i det minste bruke sammenlignbare minne 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 trolig være noe lavere, men egentlig ikke. 576 00:48:19,840 --> 00:48:23,290 Hale rekursiv er ganske bra. 577 00:48:23,290 --> 00:48:32,640 Ser igjen på stack rammer, la oss si vi har hoved 578 00:48:32,640 --> 00:48:42,920 og vi har int bar (int x) eller noe. 579 00:48:42,920 --> 00:48:52,310 Dette er ikke et perfekt rekursiv funksjon, men gå tilbake bar (x - 1). 580 00:48:52,310 --> 00:48:57,620 Så åpenbart, dette er feil. Du trenger basen saker og ting. 581 00:48:57,620 --> 00:49:00,360 Men ideen her er at dette er halen rekursive 582 00:49:00,360 --> 00:49:06,020 som betyr at når main samtaler bar det kommer til å få sin stack ramme. 583 00:49:09,550 --> 00:49:12,440 I denne bunken ramme det kommer til å bli en liten blokk med minne 584 00:49:12,440 --> 00:49:17,490 som korresponderer med dens argument x. 585 00:49:17,490 --> 00:49:25,840 Og så la oss si viktigste skjer ringe bar (100); 586 00:49:25,840 --> 00:49:30,050 Så x kommer til å starte ut som 100. 587 00:49:30,050 --> 00:49:35,660 Dersom kompilatoren erkjenner at dette er en hale rekursiv funksjon, 588 00:49:35,660 --> 00:49:38,540 så når bar gjør sin rekursive kall til bar, 589 00:49:38,540 --> 00:49:45,490 stedet for å lage en ny bunke ramme, som er der stabelen begynner å vokse i stor grad, 590 00:49:45,490 --> 00:49:48,220 til slutt vil det kjøre inn i haugen og så får du segfaults 591 00:49:48,220 --> 00:49:51,590 fordi minnet begynner å kollidere. 592 00:49:51,590 --> 00:49:54,830 >> Så i stedet for å lage sin egen stack ramme, kan det realisere, 593 00:49:54,830 --> 00:49:59,080 hei, jeg egentlig aldri trenger å komme tilbake til denne stabelen ramme, 594 00:49:59,080 --> 00:50:08,040 så i stedet jeg vil bare erstatte dette argumentet med 99 og deretter starte bar over alt. 595 00:50:08,040 --> 00:50:11,810 Og da vil det gjøre det igjen, og det vil nå returnere bar (x - 1), 596 00:50:11,810 --> 00:50:17,320 og i stedet for å lage en ny bunke ramme, vil det bare erstatte sin nåværende argument med 98 597 00:50:17,320 --> 00:50:20,740 og deretter hoppe tilbake til begynnelsen av linjen. 598 00:50:23,860 --> 00:50:30,430 Disse operasjonene, erstatte det en verdi på stakken og hoppe tilbake til begynnelsen, 599 00:50:30,430 --> 00:50:32,430 er ganske effektiv. 600 00:50:32,430 --> 00:50:41,500 Så ikke bare er dette det samme minnebruken som en egen funksjon som er iterativ 601 00:50:41,500 --> 00:50:45,390 fordi du bare bruker en stabel ramme, men du er ikke lider downsides 602 00:50:45,390 --> 00:50:47,240 av å måtte ringe funksjoner. 603 00:50:47,240 --> 00:50:50,240 Samtalefunksjoner kan være litt dyrt fordi det har å gjøre alt dette oppsettet 604 00:50:50,240 --> 00:50:52,470 og teardown og alt dette. 605 00:50:52,470 --> 00:50:58,160 Så dette halen rekursjon er bra. 606 00:50:58,160 --> 00:51:01,170 [Student] Hvorfor det ikke opprette nye trinn? 607 00:51:01,170 --> 00:51:02,980 Fordi det innser det ikke behov for. 608 00:51:02,980 --> 00:51:07,800 Kallet til baren er bare tilbake den rekursive kall. 609 00:51:07,800 --> 00:51:12,220 Slik at det ikke trenger å gjøre noe med returverdi. 610 00:51:12,220 --> 00:51:15,120 Det er bare kommer til å umiddelbart returnere den. 611 00:51:15,120 --> 00:51:20,530 Så det er bare kommer til å erstatte sin egen argumentasjon og starte på nytt. 612 00:51:20,530 --> 00:51:25,780 Og også, hvis du ikke har halen rekursive versjonen, 613 00:51:25,780 --> 00:51:31,460 så får du alle disse barene der når denne baren returnerer 614 00:51:31,460 --> 00:51:36,010 det har å returnere verdien til denne, da bar straks tilbake 615 00:51:36,010 --> 00:51:39,620 og den returnerer verdien til denne, så er det bare kommer til å umiddelbart returnere 616 00:51:39,620 --> 00:51:41,350 og returnere verdien til denne. 617 00:51:41,350 --> 00:51:45,350 Så du sparer dette dukker alle disse tingene ut av stabelen 618 00:51:45,350 --> 00:51:48,730 siden returverdien er bare kommer til å bli vedtatt hele veien tilbake opp uansett. 619 00:51:48,730 --> 00:51:55,400 Så hvorfor ikke bare erstatte vår argument med den oppdaterte argument og starte på nytt? 620 00:51:57,460 --> 00:52:01,150 Hvis funksjonen ikke er halen rekursive, hvis du gjør noe sånt - 621 00:52:01,150 --> 00:52:07,530 [Student] hvis bar (x + 1). >> Ja. 622 00:52:07,530 --> 00:52:11,770 >> Så hvis du setter den i stand, så du gjør noe med returverdi. 623 00:52:11,770 --> 00:52:16,260 Eller selv om du bare gjøre return 2 * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Så nå bar (x - 1) må returnere for at det å beregne 2 ganger denne verdien, 625 00:52:23,560 --> 00:52:26,140 så nå det trenger sin egen separate stack frame, 626 00:52:26,140 --> 00:52:31,180 og nå, uansett hvor hardt du prøver, du kommer til å trenge å - 627 00:52:31,180 --> 00:52:34,410 Dette er ikke hale rekursiv. 628 00:52:34,410 --> 00:52:37,590 [Student] Vil jeg prøve å få en rekursjon å satse på en hale rekursjon - 629 00:52:37,590 --> 00:52:41,450 [Bowden] I en ideell verden, men i CS50 du ikke må. 630 00:52:43,780 --> 00:52:49,280 For å få halen rekursjon, generelt, setter du opp en ekstra argument 631 00:52:49,280 --> 00:52:53,550 hvor baren vil ta int x inn y 632 00:52:53,550 --> 00:52:56,990 og y tilsvarer den ultimate ting du ønsker å returnere. 633 00:52:56,990 --> 00:53:03,650 Så da dette kommer du til å være tilbake bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Så det er bare et høyt nivå hvordan du forvandle ting å være halen rekursiv. 635 00:53:09,810 --> 00:53:13,790 Men den ekstra argument - 636 00:53:13,790 --> 00:53:17,410 Og så til slutt når du når base case, du bare returnere y 637 00:53:17,410 --> 00:53:22,740 fordi du har vært samler hele tiden avkastningen verdien du vil. 638 00:53:22,740 --> 00:53:27,280 Du slags har gjort det iterativt men ved hjelp av rekursive samtaler. 639 00:53:32,510 --> 00:53:34,900 Spørsmål? 640 00:53:34,900 --> 00:53:39,890 [Student] Kanskje om pekeren aritmetikk, som når du bruker strenger. >> Ja. 641 00:53:39,890 --> 00:53:43,610 Peker aritmetikk. 642 00:53:43,610 --> 00:53:48,440 Når du bruker strenger er det lett fordi strengene er røye stjerner, 643 00:53:48,440 --> 00:53:51,860 chars er evig og alltid en enkelt byte, 644 00:53:51,860 --> 00:53:57,540 og så pekeren aritmetiske tilsvarer vanlig aritmetikk når du arbeider med strenger. 645 00:53:57,540 --> 00:54:08,790 La oss bare si char * s = "hallo". 646 00:54:08,790 --> 00:54:11,430 Så vi har en blokk i minnet. 647 00:54:19,490 --> 00:54:22,380 Den trenger 6 byte fordi du alltid må null terminator. 648 00:54:22,380 --> 00:54:28,620 Og røye * s kommer til å peke til begynnelsen av denne tabellen. 649 00:54:28,620 --> 00:54:32,830 Så s påpeker det. 650 00:54:32,830 --> 00:54:36,710 Nå er dette i utgangspunktet hvordan noen matrise fungerer, 651 00:54:36,710 --> 00:54:40,780 uavhengig av om det var en retur etter malloc eller om det er på stakken. 652 00:54:40,780 --> 00:54:47,110 Hvilkensomhelst matrise er i utgangspunktet en peker til starten av tabellen, 653 00:54:47,110 --> 00:54:53,640 og deretter noen utvalg drift, noe indeksering, er bare å gå inn i denne matrisen en viss forskyvning. 654 00:54:53,640 --> 00:55:05,360 >> Så når jeg sier noe sånt som s [3], og dette kommer til å s og teller tre tegn i. 655 00:55:05,360 --> 00:55:12,490 Så s [3], har vi 0, 1, 2, 3, så s [3] er til å referere til denne l. 656 00:55:12,490 --> 00:55:20,460 [Student] Og vi kunne nå den samme verdien ved å gjøre s + 3 og deretter parentes stjerne? 657 00:55:20,460 --> 00:55:22,570 Ja. 658 00:55:22,570 --> 00:55:26,010 Tilsvarer dette * (r + 3); 659 00:55:26,010 --> 00:55:31,240 og det er for evig og alltid tilsvarende uansett hva du gjør. 660 00:55:31,240 --> 00:55:34,070 Du aldri trenger å bruke braketten syntaks. 661 00:55:34,070 --> 00:55:37,770 Du kan alltid bruke * (s + 3) syntaks. 662 00:55:37,770 --> 00:55:40,180 Folk har en tendens til å like braketten syntaks, skjønt. 663 00:55:40,180 --> 00:55:43,860 [Student] Så alle arrays er faktisk bare pekere. 664 00:55:43,860 --> 00:55:53,630 Det er en liten forskjell når jeg sier int x [4]; >> [student] Skaper at minnet? 665 00:55:53,630 --> 00:56:03,320 [Bowden] Det kommer til å skape fire ints på stakken, så 16 bytes totalt. 666 00:56:03,320 --> 00:56:05,700 Det kommer til å skape 16 bytes på stakken. 667 00:56:05,700 --> 00:56:09,190 x er ikke lagret noe sted. 668 00:56:09,190 --> 00:56:13,420 Det er bare et symbol henviser til starten av tingen. 669 00:56:13,420 --> 00:56:17,680 Fordi du erklærte rekke innsiden av denne funksjonen, 670 00:56:17,680 --> 00:56:22,340 hva kompilatoren kommer til å gjøre er å erstatte bare alle forekomster av variabelen x 671 00:56:22,340 --> 00:56:26,400 med der det skjedde å velge å sette disse 16 bytes. 672 00:56:26,400 --> 00:56:30,040 Det kan ikke gjøre det med char * s fordi s er en faktisk peker. 673 00:56:30,040 --> 00:56:32,380 Det er gratis å peke til andre ting. 674 00:56:32,380 --> 00:56:36,140 x er en konstant. Du kan ikke ha det punktet til en annen tabell. >> [Student] Okay. 675 00:56:36,140 --> 00:56:43,420 Men denne ideen, denne indeksering, er den samme uavhengig av om det er en tradisjonell rekke 676 00:56:43,420 --> 00:56:48,230 eller om det er en peker til noe, eller hvis det er en peker til en malloced array. 677 00:56:48,230 --> 00:56:59,770 Og faktisk, det er så tilsvarer det som også er det samme. 678 00:56:59,770 --> 00:57:05,440 Det faktisk bare oversetter hva er innsiden av vinkelen og hva som er igjen av brakettene, 679 00:57:05,440 --> 00:57:07,970 legger dem sammen, og dereferences. 680 00:57:07,970 --> 00:57:14,710 Så dette er like gyldig som * (s + 3) eller s [3]. 681 00:57:16,210 --> 00:57:22,090 [Student] Kan du ha pekere peker til 2-dimensjonale arrays? 682 00:57:22,090 --> 00:57:27,380 >> Det er vanskeligere. Tradisjonelt, nei. 683 00:57:27,380 --> 00:57:34,720 En 2-dimensjonal array er bare en 1-dimensjonal array med noen lettvint syntaks 684 00:57:34,720 --> 00:57:54,110 fordi når jeg sier int x [3] [3], dette er egentlig bare en rekke med ni verdier. 685 00:57:55,500 --> 00:58:03,000 Og så når jeg indeksen, vet kompilatoren hva jeg mener. 686 00:58:03,000 --> 00:58:13,090 Hvis jeg sier x [1] [2], det vet jeg ønsker å gå til andre rad, så det kommer til å hoppe over de første 3, 687 00:58:13,090 --> 00:58:17,460 og da er det ønsker andre ting i det, så det kommer til å få denne. 688 00:58:17,460 --> 00:58:20,480 Men det er fortsatt kun en enkelt-dimensjonal array. 689 00:58:20,480 --> 00:58:23,660 Og så hvis jeg ønsket å tildele en peker til denne matrisen, 690 00:58:23,660 --> 00:58:29,770 Jeg vil si int * p = x; 691 00:58:29,770 --> 00:58:33,220 Typen av x er bare - 692 00:58:33,220 --> 00:58:38,280 Det er grovt å si type x siden det er bare et symbol, og det er ikke en faktisk 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 bare en peker til starten av dette. >> [Student] Okay. 695 00:58:44,840 --> 00:58:52,560 Og så vil jeg ikke være i stand til å få tilgang til [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Jeg tror det er spesiell syntaks for å erklære en peker, 697 00:58:58,370 --> 00:59:12,480 noe latterlig som int (* p [-. noe helt latterlig jeg ikke engang kjenner. 698 00:59:12,480 --> 00:59:17,090 Men det er en syntaks for å erklære pekere som med parenteser og ting. 699 00:59:17,090 --> 00:59:22,960 Det kan ikke engang la deg gjøre det. 700 00:59:22,960 --> 00:59:26,640 Jeg kunne se tilbake på noe som ville fortelle meg sannheten. 701 00:59:26,640 --> 00:59:34,160 Jeg vil se etter det senere, hvis det er en syntaks for punkt. Men du vil aldri se det. 702 00:59:34,160 --> 00:59:39,670 Og selv syntaksen er så arkaisk at hvis du bruker det, vil folk bli forvirret. 703 00:59:39,670 --> 00:59:43,540 Flerdimensjonale arrays er ganske sjelden som den er. 704 00:59:43,540 --> 00:59:44,630 Du ganske mye - 705 00:59:44,630 --> 00:59:48,490 Vel, hvis du gjør matrise ting det ikke kommer til å være sjeldne, 706 00:59:48,490 --> 00:59:56,730 men i C du sjelden kommer til å bruke flerdimensjonale arrays. 707 00:59:57,630 --> 01:00:00,470 Ja. >> [Student] La oss si du har en veldig lang rekke. 708 01:00:00,470 --> 01:00:03,900 >> Så i virtuelt minne ville det synes å være alt sammenhengende, 709 01:00:03,900 --> 01:00:05,640 som elementene rett ved siden av hverandre, 710 01:00:05,640 --> 01:00:08,770 men i det fysiske minnet, vil det være mulig for at det skal deles opp? >> Ja. 711 01:00:08,770 --> 01:00:16,860 Hvordan virtuelle minnet fungerer er det som skiller nettopp - 712 01:00:19,220 --> 01:00:24,860 Enheten for tildeling er en side, som har en tendens til å være 4 kilobyte, 713 01:00:24,860 --> 01:00:29,680 og så når en prosess sier hei, jeg ønsker å bruke dette minnet, 714 01:00:29,680 --> 01:00:35,970 operativsystemet kommer til å fordele det 4 kilobyte for den lille blokk med minne. 715 01:00:35,970 --> 01:00:39,100 Selv om du bare bruker én liten byte i hele blokken med minne, 716 01:00:39,100 --> 01:00:42,850 operativsystemet kommer til å gi det hele 4 kilobyte. 717 01:00:42,850 --> 01:00:49,410 Så hva dette betyr er at jeg kunne ha - la oss si dette er min stack. 718 01:00:49,410 --> 01:00:53,180 Denne stabel kan skilles. Stabelen min kan være megabyte og megabyte. 719 01:00:53,180 --> 01:00:55,020 Stabelen min kan være stor. 720 01:00:55,020 --> 01:01:00,220 Men bunken selv må deles inn i individuelle sider, 721 01:01:00,220 --> 01:01:09,010 som hvis vi ser på over her la oss si dette er vår RAM, 722 01:01:09,010 --> 01:01:16,600 hvis jeg har 2 GB RAM, dette er faktisk adresse 0 som zeroth byte RAM min, 723 01:01:16,600 --> 01:01:22,210 og dette er 2 gigabyte hele veien ned her. 724 01:01:22,210 --> 01:01:27,230 Så denne siden kan tilsvare denne blokken over her. 725 01:01:27,230 --> 01:01:29,400 Denne siden kan tilsvare denne blokken over her. 726 01:01:29,400 --> 01:01:31,560 Dette kan tilsvare dette over her. 727 01:01:31,560 --> 01:01:35,540 Slik at operativsystemet er gratis å tildele fysisk minne 728 01:01:35,540 --> 01:01:39,320 til en enkelt side vilkårlig. 729 01:01:39,320 --> 01:01:46,180 Og det betyr at hvis denne grensen skjer med skreve en matrise, 730 01:01:46,180 --> 01:01:50,070 en rekke skjer for å bli forlatt av dette og høyre for denne rekkefølgen på en side, 731 01:01:50,070 --> 01:01:54,460 så denne matrisen kommer til å bli delt i fysisk minne. 732 01:01:54,460 --> 01:01:59,280 Og så når du avslutter programmet, når prosessen er ferdig, 733 01:01:59,280 --> 01:02:05,690 disse kartlegginger får slettet og da er det gratis å bruke disse små blokker for andre ting. 734 01:02:14,730 --> 01:02:17,410 Flere spørsmål? 735 01:02:17,410 --> 01:02:19,960 [Student] Pekeren aritmetikk. >> Oh yeah. 736 01:02:19,960 --> 01:02:28,410 Strenger var lettere, men ser på noe som ints, 737 01:02:28,410 --> 01:02:35,000 så tilbake til int x [4]; 738 01:02:35,000 --> 01:02:41,810 Hvorvidt dette er en matrise eller om det er en peker til en malloced utvalg av 4 heltall, 739 01:02:41,810 --> 01:02:47,060 det kommer til å bli behandlet på samme måte. 740 01:02:50,590 --> 01:02:53,340 [Student] Så arrays er på haugen? 741 01:03:01,400 --> 01:03:05,270 [Bowden] Arrays er ikke på haugen. >> [Student] Oh. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Denne typen matrise tendens til å være på stabelen 743 01:03:08,320 --> 01:03:12,220 med mindre du erklært det på - ignorerer globale variabler. Ikke bruke globale variabler. 744 01:03:12,220 --> 01:03:16,280 Innsiden av en funksjon jeg si int x [4]; 745 01:03:16,280 --> 01:03:22,520 Det kommer til å lage et 4-tall blokk på stakken for denne matrisen. 746 01:03:22,520 --> 01:03:26,960 Men dette malloc (4 * sizeof (int)); kommer til å gå på haugen. 747 01:03:26,960 --> 01:03:31,870 Men etter dette punktet kan jeg bruke x og p i ganske mye de samme måter, 748 01:03:31,870 --> 01:03:36,140 annet enn unntakene jeg sa før om du kan tilordne p. 749 01:03:36,140 --> 01:03:40,960 Teknisk, deres størrelser er litt forskjellig, men det er helt irrelevant. 750 01:03:40,960 --> 01:03:43,310 Du aldri bruke sine størrelser. 751 01:03:48,020 --> 01:03:56,810 P jeg kunne si p [3] = 2, eller x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 Du kan bruke dem i nøyaktig de samme måter. 753 01:03:59,680 --> 01:04:01,570 Så peker aritmetikk nå - Ja. 754 01:04:01,570 --> 01:04:07,390 [Student] Har du ikke trenger å gjøre p * hvis du har brakettene? 755 01:04:07,390 --> 01:04:11,720 Konsollene er en implisitt dereferanse. >> Ok. 756 01:04:11,720 --> 01:04:20,200 Egentlig også hva du sier med kan du få flerdimensjonale arrays 757 01:04:20,200 --> 01:05:02,650 med pekere, hva du kan gjøre er noe sånt som, la oss si, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Jeg skal bare skrive det ut først. 759 01:05:37,880 --> 01:05:41,020 Jeg ønsker ikke at ett. 760 01:05:41,020 --> 01:05:42,550 Okay. 761 01:05:42,550 --> 01:05:48,910 Det jeg gjorde her er - Det burde være pp [i]. 762 01:05:48,910 --> 01:05:53,680 Så pp er en peker til en peker. 763 01:05:53,680 --> 01:06:02,420 Du mallocing pp å peke på en rekke av 5 int stjerner. 764 01:06:02,420 --> 01:06:10,950 Så i minnet du har på stakken pp. 765 01:06:10,950 --> 01:06:20,150 Det kommer til å peke på en rekke av 5 blokker som alle selv pekere. 766 01:06:20,150 --> 01:06:28,210 Og så når jeg malloc her nede, malloc jeg at hver av de individuelle pekere 767 01:06:28,210 --> 01:06:32,080 skal peke til en egen blokk av 4 byte på haugen. 768 01:06:32,080 --> 01:06:35,870 Så dette peker på fire byte. 769 01:06:37,940 --> 01:06:40,660 Og dette peker til en annen 4 byte. 770 01:06:40,660 --> 01:06:43,200 >> Og alle av dem peker på sine egne fire byte. 771 01:06:43,200 --> 01:06:49,080 Dette gir meg en måte å gjøre flerdimensjonale ting. 772 01:06:49,080 --> 01:06:58,030 Jeg kan si pp [3] [4], men nå er dette ikke det samme som flerdimensjonale arrays 773 01:06:58,030 --> 01:07:05,390 fordi flerdimensjonale matriser den oversatt [3] [4] i en enkelt offset i X-matrisen. 774 01:07:05,390 --> 01:07:14,790 Dette dereferences p, åpner den tredje indeksen, da dereferences som 775 01:07:14,790 --> 01:07:20,790 og tilganger - 4 ville være ugyldig - den andre indeksen. 776 01:07:24,770 --> 01:07:31,430 Mens når vi hadde int x [3] [4] før som en flerdimensjonal matrise 777 01:07:31,430 --> 01:07:35,740 og når du dobbeltklikker braketten det er egentlig bare en enkelt dereferanse, 778 01:07:35,740 --> 01:07:40,490 du etter en enkelt pekeren og deretter en offset, 779 01:07:40,490 --> 01:07:42,850 dette er virkelig 2D referanser. 780 01:07:42,850 --> 01:07:45,840 Du følger to separate pekere. 781 01:07:45,840 --> 01:07:50,420 Så dette også teknisk lar deg ha flerdimensjonale arrays 782 01:07:50,420 --> 01:07:53,550 hvor hver enkelt matrise er forskjellige størrelser. 783 01:07:53,550 --> 01:07:58,000 Så jeg tror taggete flerdimensjonale arrays er hva det heter 784 01:07:58,000 --> 01:08:01,870 siden egentlig det første kunne vise til noe som har 10 elementer, 785 01:08:01,870 --> 01:08:05,540 den andre tingen kunne vise til noe som har 100 elementer. 786 01:08:05,540 --> 01:08:10,790 [Student] Er det noen grense for hvor mange tips du kan ha 787 01:08:10,790 --> 01:08:14,290 peker til andre pekere? >> Nei 788 01:08:14,290 --> 01:08:17,010 Du kan ha int ***** p. 789 01:08:18,050 --> 01:08:23,760 Tilbake til pekeren aritmetiske - >> [student] Oh. >> Ja. 790 01:08:23,760 --> 01:08:35,649 [Student] Hvis jeg har int *** p og så gjør jeg en dereferencing og jeg sier p * er lik denne verdien, 791 01:08:35,649 --> 01:08:39,560 er det bare kommer til å gjøre en grad av dereferencing? >> Ja. 792 01:08:39,560 --> 01:08:43,340 Så hvis jeg ønsker å få tilgang til ting som det siste pekeren peker på - 793 01:08:43,340 --> 01:08:46,210 Så gjør du *** p. >> Ok. 794 01:08:46,210 --> 01:08:54,080 Så dette er p peker på en blokk, peker på en annen blokk, peker til en annen blokk. 795 01:08:54,080 --> 01:09:02,010 Så hvis du gjør * p = noe annet, så du endrer dette 796 01:09:02,010 --> 01:09:13,640 til nå peker til en annen blokk. >> Ok. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] Og hvis disse ble malloced, da har du nå lekket minne 798 01:09:17,649 --> 01:09:20,430 med mindre du tilfeldigvis har forskjellige referanser av disse 799 01:09:20,430 --> 01:09:25,270 siden du ikke kan komme tilbake til de de som du bare kastet bort. 800 01:09:25,270 --> 01:09:29,550 Peker aritmetikk. 801 01:09:29,550 --> 01:09:36,310 int x [4]; kommer til å tildele en rekke 4 heltall 802 01:09:36,310 --> 01:09:40,670 der x kommer til å peke på begynnelsen av tabellen. 803 01:09:40,670 --> 01:09:50,420 Så når jeg sier noe sånt x [1]; jeg vil den skal bety gå til andre heltall i rekken, 804 01:09:50,420 --> 01:09:53,319 som ville være denne. 805 01:09:53,319 --> 01:10:04,190 Men virkelig, det er 4 byte inn i matrisen siden dette heltall tar opp 4 bytes. 806 01:10:04,190 --> 01:10:08,470 Så en forskyvning av 1 betyr egentlig en forskyvning av en 807 01:10:08,470 --> 01:10:12,030 ganger størrelsen av uansett type matrisen er. 808 01:10:12,030 --> 01:10:17,170 Dette er en matrise av heltall, slik at den vet å gjøre en ganger størrelsen av int når den ønsker å offset. 809 01:10:17,170 --> 01:10:25,260 Den andre syntaksen. Husk at dette er ekvivalent med * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Når jeg sier pekeren + 1, hva som returnerer er adressen som pekeren er lagring 811 01:10:35,250 --> 01:10:40,360 pluss 1 ganger størrelsen av den typen pekeren. 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 misbruke dette og si noe sånt som char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 og nå c kommer til å være den samme adressen som x. 815 01:11:23,050 --> 01:11:26,040 c kommer til å være lik ox100, 816 01:11:26,040 --> 01:11:31,490 men c + 1 kommer til å være lik ox101 817 01:11:31,490 --> 01:11:38,030 siden pekeren aritmetiske avhenger av hvilken type peker som du legger til. 818 01:11:38,030 --> 01:11:45,390 Så c + 1, det ser ut på c, det er en røye peker, så det kommer til å legge en ganger størrelsen av røye, 819 01:11:45,390 --> 01:11:48,110 som alltid kommer til å være 1, slik at du får 101, 820 01:11:48,110 --> 01:11:54,890 mens hvis jeg gjør x, som er også fremdeles 100, x + 1 kommer til å bli 104. 821 01:11:56,660 --> 01:12:06,340 [Student] Kan du bruke c + + for å avansere pekeren med 1? 822 01:12:06,340 --> 01:12:09,810 Ja, det kan du. 823 01:12:09,810 --> 01:12:16,180 Du kan ikke gjøre det med x fordi x er bare et symbol, det er en konstant, du kan ikke endre x. 824 01:12:16,180 --> 01:12:22,610 >> Men c skjer til å bare være en peker, så c + + er helt gyldig, og det vil øke med 1. 825 01:12:22,610 --> 01:12:32,440 Hvis c var bare en int *, så c + + ville bli 104. 826 01:12:32,440 --> 01:12:41,250 + + Gjør pekeren aritmetiske like c + 1 ville ha gjort pekeren aritmetikk. 827 01:12:43,000 --> 01:12:48,870 Dette er faktisk hvor mange ting som fusjonerer sort - 828 01:12:49,670 --> 01:12:55,710 I stedet for å lage kopier av ting, kan du i stedet gå - 829 01:12:55,710 --> 01:13:02,400 Som om jeg ønsket å passere denne halvdelen av tabellen - la oss slette noe av dette. 830 01:13:04,770 --> 01:13:10,520 La oss si at jeg ønsket å passere denne siden av tabellen i en funksjon. 831 01:13:10,520 --> 01:13:12,700 Hva ville jeg gå over til den funksjonen? 832 01:13:12,700 --> 01:13:17,050 Hvis jeg passerer x, jeg passerer denne adressen. 833 01:13:17,050 --> 01:13:23,780 Men jeg ønsker å passere denne adressen. Så hva skal jeg passere? 834 01:13:23,780 --> 01:13:26,590 [Student] 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 å være denne adressen. 837 01:13:31,620 --> 01:13:42,810 Du vil også svært ofte ser det som x [2] og deretter adressen til. 838 01:13:42,810 --> 01:13:47,850 Så du må ta adressen på det fordi braketten er en implisitt dereferanse. 839 01:13:47,850 --> 01:13:53,250 x [2] refererer til verdien som er i denne boksen, og så vil adressen til boksen, 840 01:13:53,250 --> 01:13:56,850 så du sier og x [2]. 841 01:13:56,850 --> 01:14:02,880 Så det er hvordan noe i fletting slag der du ønsker å passere halve listen til noe 842 01:14:02,880 --> 01:14:08,790 du egentlig bare passere & x [2], og nå så langt som den rekursive kall er opptatt av, 843 01:14:08,790 --> 01:14:12,510 min nye utvalg starter der. 844 01:14:12,510 --> 01:14:15,130 Siste liten spørsmål. 845 01:14:15,130 --> 01:14:20,050 [Student] Hvis vi ikke sette en ampersand eller - hva er det heter? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Student] Star. >> Teknisk dereferanse operatør, men - >> [student] dereferanse. 847 01:14:23,200 --> 01:14:29,310 >> Hvis vi ikke setter en stjerne eller en ampersand, hva skjer hvis jeg bare si y = x og x er en peker? 848 01:14:29,310 --> 01:14:34,620 Hva er den type y? >> [Student] Jeg vil bare si det er pekeren 2. 849 01:14:34,620 --> 01:14:38,270 Så hvis du bare si y = x, nå x og y peker til det samme. >> [Student] Pek på det samme. 850 01:14:38,270 --> 01:14:45,180 Og hvis x er en int peker? >> Det ville klage fordi du ikke kan tildele pekere. 851 01:14:45,180 --> 01:14:46,540 [Student] Okay. 852 01:14:46,540 --> 01:14:51,860 Husk at pekere, selv om vi trekker dem som piler, 853 01:14:51,860 --> 01:15:02,010 egentlig alt de store - int * x - virkelig alle x er lagring er noe som ox100, 854 01:15:02,010 --> 01:15:06,490 som vi tilfeldigvis til å representere så peker til blokken lagret ved 100. 855 01:15:06,490 --> 01:15:19,660 Så når jeg sier int * y = x, jeg bare kopiere ox100 inn y, 856 01:15:19,660 --> 01:15:24,630 som vi bare kommer til å representere som y, også peker til ox100. 857 01:15:24,630 --> 01:15:39,810 Og hvis jeg sier int i = (int) x; så jeg kommer til å lagre hva verdien av ox100 er 858 01:15:39,810 --> 01:15:45,100 innsiden av den, men nå kommer det til å bli tolket som et heltall i stedet for en peker. 859 01:15:45,100 --> 01:15:49,310 Men du trenger kastet ellers vil klage. 860 01:15:49,310 --> 01:15:53,300 [Student] Så mener du å kaste - 861 01:15:53,300 --> 01:16:00,290 Er det kommer til å bli kastet int av x eller støping int av y? 862 01:16:00,290 --> 01:16:03,700 [Bowden] Hva? 863 01:16:03,700 --> 01:16:07,690 [Student] Okay. Etter disse parentes er det skal være en x eller ay det? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Enten. x og y er ekvivalente. >> [Student] Okay. 865 01:16:11,500 --> 01:16:14,390 Fordi de er begge pekere. >> Ja. 866 01:16:14,390 --> 01:16:21,050 [Student] Så det ville lagre den heksadesimale 100 i heltall form? >> [Bowden] Yeah. 867 01:16:21,050 --> 01:16:23,620 Men ikke verdien av hva den peker på. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Yeah. >> [Student] Så bare adressen i heltall form. Okay. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Hvis du ønsket å for noen bisarre grunn, 870 01:16:34,720 --> 01:16:38,900 du kan utelukkende håndtere pekere og aldri håndtere heltall 871 01:16:38,900 --> 01:16:49,240 og bare være som int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Så du kommer til å bli veldig forvirret når pekeren aritmetiske begynner å skje. 873 01:16:53,000 --> 01:16:56,570 Så tallene at de lagrer er meningsløse. 874 01:16:56,570 --> 01:16:58,940 Det er bare hvordan du ende opp tolke dem. 875 01:16:58,940 --> 01:17:02,920 Så jeg er fri til å kopiere ox100 fra en int * til en int, 876 01:17:02,920 --> 01:17:07,790 og jeg er fri til å tildele - du sannsynligvis kommer til å få skreket til for ikke å kaste - 877 01:17:07,790 --> 01:17:18,160 Jeg er fri til å tildele noe sånt (int *) ox1234 inn i denne vilkårlig int *. 878 01:17:18,160 --> 01:17:25,480 Så ox123 er like gyldig et minne adresse som er & y. 879 01:17:25,480 --> 01:17:32,060 & Y skjer å returnere noe som er ganske mye ox123. 880 01:17:32,060 --> 01:17:35,430 [Student] Vil det være en veldig kul måte å gå fra heksadesimale til desimal form, 881 01:17:35,430 --> 01:17:39,230 som om du har en peker og du kastet det som en int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] Du kan egentlig bare skrive ut ved hjelp som printf. 883 01:17:44,860 --> 01:17:50,300 La oss si at jeg int y = 100. 884 01:17:50,300 --> 01:18:02,700 Så printf (% d \ n - som du bør allerede vet - ut at som et heltall,% x. 885 01:18:02,700 --> 01:18:05,190 Vi får bare skrive det som heksadesimal. 886 01:18:05,190 --> 01:18:10,760 Så en peker ikke lagres som heksadesimale, 887 01:18:10,760 --> 01:18:12,960 og et heltall ikke er lagret som desimaltegn. 888 01:18:12,960 --> 01:18:14,700 Alt er lagret som binært. 889 01:18:14,700 --> 01:18:17,950 Det er bare det at vi har en tendens til å vise pekere som heksadesimal 890 01:18:17,950 --> 01:18:23,260 fordi vi tenker på ting i disse 4-byte blokker, 891 01:18:23,260 --> 01:18:25,390 og minneadresser tendens til å være kjent. 892 01:18:25,390 --> 01:18:28,890 Vi er som, hvis den starter med bf, så det skjer for å være på stakken. 893 01:18:28,890 --> 01:18:35,560 Så det er bare vår tolkning av pekere som heksadesimal. 894 01:18:35,560 --> 01:18:39,200 Okay. Noen siste spørsmål? 895 01:18:39,200 --> 01:18:41,700 >> Jeg vil være her for litt etter hvis du har noe annet. 896 01:18:41,700 --> 01:18:46,070 Og det er slutten på den. 897 01:18:46,070 --> 01:18:48,360 >> [Student] Yay! [Applaus] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]