1 00:00:00,000 --> 00:00:02,310 [Powered by Google Translate] [Vecka 4, Fortsättning] 2 00:00:02,310 --> 00:00:04,240 [David J. Malan - Harvard University] 3 00:00:04,240 --> 00:00:07,290 [Detta är CS50. - CS50.TV] 4 00:00:07,290 --> 00:00:11,290 >> Detta är CS50, och detta är slutet på vecka 4. 5 00:00:11,290 --> 00:00:14,030 Så några goda nyheter och dåliga nyheter. 6 00:00:14,030 --> 00:00:26,240 Ingen föreläsning på måndag, ställ inga problem nästa vecka. [Studenter hejar] 7 00:00:26,240 --> 00:00:28,680 Du kommer inte att gilla om detta är på väg. 8 00:00:28,680 --> 00:00:31,590 Men vi har det i stället nästa onsdag, 9 00:00:31,590 --> 00:00:37,740 och det finns också per kursplanen 1 Fredag ​​föreläsning nästa fredag ​​så att vi kan hålla på rätt spår. 10 00:00:37,740 --> 00:00:40,580 Men allt kommer att filmas som vanligt, så att inte oroa dig. 11 00:00:40,580 --> 00:00:44,100 >> Och med avseende på frågesport 0 vad vi ska göra mot veckans slut 12 00:00:44,100 --> 00:00:47,140 är post på kursens hemsida cs50.net en förklaring 13 00:00:47,140 --> 00:00:50,160 om vilken typ av förväntningar bör du ha när det kommer till den första frågesporten. 14 00:00:50,160 --> 00:00:55,100 I allmänhet kommer det att vara flervalsfrågor, sant-falskt, kort svar, korta kodning problem. 15 00:00:55,100 --> 00:00:57,360 Du kommer inte att vänta att genomföra motsvarande 16 00:00:57,360 --> 00:01:00,030 av ett problem som du skulle se på en pset, som du har en dator 17 00:01:00,030 --> 00:01:03,240 och en debugger och liknande, men det kommer att bli små kodning problem. 18 00:01:03,240 --> 00:01:06,900 >> Och faktiskt, den bästa guide för att få en känsla för vad CS50 frågesporter är som 19 00:01:06,900 --> 00:01:09,180 är att gå till cs50.net, gå till frågesporter länken, 20 00:01:09,180 --> 00:01:11,920 och du kan se de senaste åren värde av frågesporter. 21 00:01:11,920 --> 00:01:16,600 Bara inse att läroplanen inte alltid varit densamma genom åren. 22 00:01:16,600 --> 00:01:18,510 Ibland kan vi tillägga, ibland subtrahera, 23 00:01:18,510 --> 00:01:20,670 så om du ser något ämne på ett av de gamla frågesporter 24 00:01:20,670 --> 00:01:25,380 att du har ingen aning om vad det pratar om, det är antingen att vi täckte det 25 00:01:25,380 --> 00:01:27,210 eller att vi inte täckte det. 26 00:01:27,210 --> 00:01:31,110 Men i form av recensioner, denna söndag, måndag och tisdag 27 00:01:31,110 --> 00:01:34,770 samt en kurs hela översyn session på söndag kväll - 28 00:01:34,770 --> 00:01:37,500 tid och plats kommer att meddelas på kursens hemsida - 29 00:01:37,500 --> 00:01:40,120 du har alla möjlighet att granska med kursens undervisning stipendiater 30 00:01:40,120 --> 00:01:44,830 material för detta år, både i snitt och som en fullständig klass, 31 00:01:44,830 --> 00:01:48,400 och de kommer att filmas som vanligt också. 32 00:01:48,400 --> 00:01:53,380 >> Okej. Så utan vidare, en kommentar på godkänd / underkänd och add / drop. 33 00:01:53,380 --> 00:01:57,980 Du kanske har sett mina anteckningar i går kväll, och det är egentligen bara en del ytterligare tillförsikt 34 00:01:57,980 --> 00:02:01,250 att om du hör till dem speciellt mindre bekväm eller någonstans mittemellan 35 00:02:01,250 --> 00:02:04,870 och du känner bara lite i över huvudet, 36 00:02:04,870 --> 00:02:08,430 inser att det är faktiskt ganska vanligt, och det finns en riklig stödstruktur på plats, 37 00:02:08,430 --> 00:02:13,530 varav kontorstid var inställda på att förbättras hela mer per min e kväll, 38 00:02:13,530 --> 00:02:16,520 och inser också att ett alternativ som godkänt / underkänt för en klass som denna 39 00:02:16,520 --> 00:02:21,540 verkligen är tänkt som en mekanism för att ta udden av en kurs som denna, 40 00:02:21,540 --> 00:02:24,200 så igen om du tillbringar de 10, 15, 20 timmar 41 00:02:24,200 --> 00:02:28,160 bara försöka få lite pset till jobbet och du vet att du är 90-95% av vägen dit 42 00:02:28,160 --> 00:02:32,100 men du kan inte hitta några jävla bugg i en godkänd / underkänd modell som är typ av okej. 43 00:02:32,100 --> 00:02:36,230 >> Tanken är att med denna mekanism du sedan kan gå fokusera på dina andra psets 44 00:02:36,230 --> 00:02:39,530 eller sova eller vad det är som du vill fokusera på. 45 00:02:39,530 --> 00:02:43,390 Så inser att du har till denna kommande tisdag - tekniskt den 5: e måndag, 46 00:02:43,390 --> 00:02:50,840 men det är en helgdag, så detta kommer tisdag - att växla från godkänd / underkänd till graderade eller vice versa. 47 00:02:50,840 --> 00:02:54,450 Och om du är riktigt på stupet och tänker släppa helt och hållet, 48 00:02:54,450 --> 00:02:56,440 vänligen fånga mig efter föreläsning eller släpp mig ett meddelande. 49 00:02:56,440 --> 00:02:59,990 Vi vill gärna minst chatt innan du bjuder adjö. 50 00:02:59,990 --> 00:03:03,470 Okej. Så vi började ta stödhjul från förra gången. 51 00:03:03,470 --> 00:03:06,030 Framför allt har vi fokuserat på snöre. 52 00:03:06,030 --> 00:03:09,740 String är något som deklareras i CS50 biblioteket, 53 00:03:09,740 --> 00:03:14,340 särskilt i den filen som heter cs50.h som vi börjar titta på denna och nästa vecka. 54 00:03:14,340 --> 00:03:17,250 Men sträng är egentligen bara en förenkling av något 55 00:03:17,250 --> 00:03:20,980 Det är lite mer arcanely beskrivs som char *. 56 00:03:20,980 --> 00:03:24,090 Röding vi känner till. Det är bara ett enda tecken. 57 00:03:24,090 --> 00:03:28,010 Men * per måndag betecknas vad? >> [Elev] En pekare. 58 00:03:28,010 --> 00:03:31,290 En pekare. Och vad är en pekare? >> [Elev] En adress. 59 00:03:31,290 --> 00:03:33,420 >> Det är som en adress, en plats i minnet. 60 00:03:33,420 --> 00:03:35,910 Vad är en adress eller plats eller minne? 61 00:03:35,910 --> 00:03:40,290 Återigen, vi alla har bärbara datorer med en spelning eller 2 gigabyte RAM-minne sannolikt dessa dagar, 62 00:03:40,290 --> 00:03:44,160 och det betyder att du har en miljard eller 2 miljarder byte värde av minne. 63 00:03:44,160 --> 00:03:46,240 Och det spelar ingen roll egentligen vad det fysiskt ser ut, 64 00:03:46,240 --> 00:03:51,220 men ta på tro att du kan numrera alla de enskilda byte som din egen laptop har - 65 00:03:51,220 --> 00:03:54,580 detta är byte 0, är ​​denna bitgrupp 1, är detta byte 2 miljarder - 66 00:03:54,580 --> 00:03:56,100 och det är precis vad en dator gör. 67 00:03:56,100 --> 00:04:00,030 När du allokera utrymme för en enda karaktär, till exempel, 68 00:04:00,030 --> 00:04:02,480 Det har uppenbarligen att leva någonstans i datorns minne, 69 00:04:02,480 --> 00:04:05,860 och kanske är det på byte nummer 12345, 70 00:04:05,860 --> 00:04:08,470 och det är någonstans här uppe i datorns minne. 71 00:04:08,470 --> 00:04:12,630 Och adressen då detta tecken är 12345. 72 00:04:12,630 --> 00:04:16,140 >> Nu, i vecka 0 igenom nu hittills har vi inte riktigt brydde 73 00:04:16,140 --> 00:04:19,170 var i minnet saker lagras eftersom vi brukar använda symboler, 74 00:04:19,170 --> 00:04:22,540 variabler och arrayer att faktiskt få på våra uppgifter. 75 00:04:22,540 --> 00:04:24,950 Men som med måndag och alla mer idag, du kommer nu att få 76 00:04:24,950 --> 00:04:27,710 alla mer uttrycksfulla funktioner med att skriva program 77 00:04:27,710 --> 00:04:31,330 att verkligen manipulera en dators minne men du tycker passar, 78 00:04:31,330 --> 00:04:33,720 både bra ändamål och dåliga, 79 00:04:33,720 --> 00:04:39,620 buggar är en mycket vanlig följd vid denna punkt att lära här. 80 00:04:39,620 --> 00:04:42,460 Men vad betyder det egentligen att vara char *? 81 00:04:42,460 --> 00:04:46,140 Låt oss gå vidare tillbaka till - och vi ska återkomma till Binky som utlovat idag. 82 00:04:46,140 --> 00:04:48,670 Låt oss gå till ett enkelt exempel här. 83 00:04:48,670 --> 00:04:53,060 Låt mig spara filen som compare.c, och låt mig bara få lite mall kod här 84 00:04:53,060 --> 00:05:00,490 så inkluderar stdio.h, låt mig också ge mig själv omfattar cs50.h. Jag zooma in uppe. 85 00:05:00,490 --> 00:05:05,850 Låt mig börja skriva huvudsakliga int, main (void), och nu vill jag göra något så här: 86 00:05:05,850 --> 00:05:13,520 printf ("Ge mig en sträng:") och sedan kommer jag att använda strängen s får getString 87 00:05:13,520 --> 00:05:16,750 för att få en sträng från användaren, då kommer jag att uppmana användaren att en annan. 88 00:05:16,750 --> 00:05:21,870 ("Ge mig en annan sträng:") och jag kommer att be dem via getString att få det. 89 00:05:21,870 --> 00:05:27,020 Jag kallar det t eftersom t kommer efter s och s är ett fint namn för en sträng om det är ganska allmänna. 90 00:05:27,020 --> 00:05:30,030 Så GetString, och nu vill jag bara göra en sanity check och jag kommer att säga 91 00:05:30,030 --> 00:05:39,770 if (s == t) då jag ska bara tala om för användaren printf ("Du skrev samma sak \ n"); 92 00:05:39,770 --> 00:05:45,520 annars ska jag skriva ut något liknande ("du skrev något annat! \ n") 93 00:05:45,520 --> 00:05:48,460 eller vad meningen kommer att bli. Så något liknande. 94 00:05:48,460 --> 00:05:52,200 Sedan som vanligt, jag återkommer 0 som bara innebar att inget dåligt hänt, 95 00:05:52,200 --> 00:05:54,400 och jag kommer att gå vidare och kompilera och köra programmet. 96 00:05:54,400 --> 00:05:56,540 >> Men på måndag vi körde detta program, 97 00:05:56,540 --> 00:06:00,420 och faktiskt fick veta att HELLO inte HEJ och adjö är inte adjö. 98 00:06:00,420 --> 00:06:03,140 Det beteende som vi såg var lite mer om detta. 99 00:06:03,140 --> 00:06:11,450 Låt mig gå in i min källa katalog, zooma in här, och låt oss gör jämföra. 100 00:06:11,450 --> 00:06:14,570 Sammanställt okej. Låt mig köra jämföra. Ge mig en sträng: HELLO. 101 00:06:14,570 --> 00:06:16,300 Ge mig en annan sträng: HELLO. 102 00:06:16,300 --> 00:06:18,000 Du skrev något annat! 103 00:06:18,000 --> 00:06:22,650 Nåväl, låt mig prova något enklare som 50, 50. Du skrev något annat! 104 00:06:22,650 --> 00:06:25,740 Hej, hej. Så klart är något på gång här. 105 00:06:25,740 --> 00:06:28,440 Men vad var förklaringen till varför? 106 00:06:28,440 --> 00:06:33,850 Tydligen är linje 12 är helt dysfunktionella. 107 00:06:34,300 --> 00:06:39,430 Vad är det grundläggande problemet här? Ja. >> [Elev] Det jämföra adresserna. 108 00:06:39,430 --> 00:06:41,850 Ja, exakt. Det är faktiskt jämföra adresserna 109 00:06:41,850 --> 00:06:44,580 där hej och HELLO lagras. 110 00:06:44,580 --> 00:06:48,290 Det är inte att jämföra bokstäverna HELLO om och om igen, 111 00:06:48,290 --> 00:06:52,370 eftersom vad som verkligen hände, hela tiden vi har använt GetString - 112 00:06:52,370 --> 00:06:56,130 Denna tavlan är återigen vår dators minne, 113 00:06:56,130 --> 00:07:00,100 och låt oss säga att jag kallar GetString efter att ha förklarat en variabel s. 114 00:07:00,100 --> 00:07:01,930 Hur ser mitt minne ut? 115 00:07:01,930 --> 00:07:07,070 Låt oss säga godtyckligt att s ser ut så här. Det är en kvadrat. 116 00:07:07,070 --> 00:07:09,040 Och ganska mycket varje gång jag har ritat en bit av minnet på skärmen 117 00:07:09,040 --> 00:07:12,860 om det är 32 bitar har jag rita rutor som detta eftersom verkligen i apparaten, 118 00:07:12,860 --> 00:07:17,380 en pekare, en adress, är 32 bitar. Det är samma sak som en int. 119 00:07:17,380 --> 00:07:19,420 Som kan variera beroende på datorsystem. 120 00:07:19,420 --> 00:07:24,630 De av er som är vagt bekant med det faktum att din Mac eller PC är 64 bitar, 121 00:07:24,630 --> 00:07:28,120 som betecknar faktiskt att din dator använder 64-bitars pekare, 122 00:07:28,120 --> 00:07:33,730 64-bitars adresser och bland upsides av detta är dina datorer 123 00:07:33,730 --> 00:07:35,560 kan ha mycket mer RAM än förr. 124 00:07:35,560 --> 00:07:39,240 Lång historia kort, tillbaka i dag när datorer används endast 32 bitar 125 00:07:39,240 --> 00:07:42,740 att representera adresser, det största antalet byte du kan representera 126 00:07:42,740 --> 00:07:46,280 i så fall var det om du har 32 bitar? 127 00:07:46,280 --> 00:07:49,590 Så 4 miljarder, höger, eftersom 2 till 32 är 4 miljarder. 128 00:07:49,590 --> 00:07:51,370 Detta antal har återkommande i kursen. 129 00:07:51,370 --> 00:07:55,240 >> Så om du bara har 32 bitar, det högsta antalet du kan räkna till ungefär 4 miljarder. 130 00:07:55,240 --> 00:07:58,750 Men det var en grundläggande begränsning av datorer tills för några år sedan 131 00:07:58,750 --> 00:08:01,180 för om du bara kan räknas som högt som 4 miljarder, 132 00:08:01,180 --> 00:08:05,270 det spelar ingen roll om du köper 8 gigabyte RAM-minne eller till och med 5 gigabyte RAM; 133 00:08:05,270 --> 00:08:07,780 Du kan inte räkna så högt, så det var meningslöst. 134 00:08:07,780 --> 00:08:11,430 Du kan bara komma åt de första 3 eller 4 gigabyte datorns minne. 135 00:08:11,430 --> 00:08:14,410 Det är ett mindre problem nu, och du kan köpa MacBook Pro och Dells 136 00:08:14,410 --> 00:08:17,680 med 8 gigabyte RAM-minne eller ännu mer i dessa dagar. 137 00:08:17,680 --> 00:08:24,100 Men om jag fördela helt enkelt i det här programmet en pekare, som kallas en pekare s 138 00:08:24,100 --> 00:08:28,370 kan det se ut så här på skärmen eftersom vi faktiskt behöver dra tillbaka detta skikt. 139 00:08:28,370 --> 00:08:33,520 Jag fortsätter att säga sträng, men från och med måndag, är sträng verkligen char *, 140 00:08:33,520 --> 00:08:35,590 adressen av vissa tecken. 141 00:08:35,590 --> 00:08:39,280 Så låt oss ta att utbildning hjulet från även om vi kommer att fortsätta att använda GetString för nu. 142 00:08:39,280 --> 00:08:42,600 Så jag har förklarat s, och detta är en bit av minne, 32 bitar. 143 00:08:42,600 --> 00:08:47,370 Vad är här i minnet som standard? >> [Ohörbart elev svar] 144 00:08:47,370 --> 00:08:50,040 Vad är det? >> [Elev] Garbage. >> Garbage. Exakt. 145 00:08:50,040 --> 00:08:54,610 Om du programmeraren inte sätta ett värde i en variabel, vem vet vad det är? 146 00:08:54,610 --> 00:08:57,990 Ibland kan du ha tur och det är 0, är ​​vilken typ av en fin, ren standardvärde, 147 00:08:57,990 --> 00:09:00,310 men som vi såg Måndag, ibland är det fullständigt nonsens, 148 00:09:00,310 --> 00:09:04,130 några riktigt stora positivt eller negativt tal som kom från var? 149 00:09:05,350 --> 00:09:07,010 Ja. >> [Elev] Funktionen innan. >> Ja. 150 00:09:07,010 --> 00:09:10,170 >> Ofta den funktion som fick kallas innan eftersom kom ihåg, 151 00:09:10,170 --> 00:09:13,920 som du kallar funktioner i minnet, tar de upp mer och mer utrymme nerifrån och upp, 152 00:09:13,920 --> 00:09:17,040 och så snart som funktionen returnerar, blir det minne återanvändas 153 00:09:17,040 --> 00:09:20,890 av nästa kille som får kallas, vem använder din samma skiva minne. 154 00:09:20,890 --> 00:09:23,450 Och om du har lämnat skräp där, tidigare värden, 155 00:09:23,450 --> 00:09:28,190 Vi kan förväxla s ha något värde när det verkligen att vi inte har lagt något där. 156 00:09:28,190 --> 00:09:30,960 Så vår RAM på denna punkt ser ut så här. 157 00:09:30,960 --> 00:09:36,030 Nu på höger sida av linjen 7 vi kallar GetString, 158 00:09:36,030 --> 00:09:40,150 som vi har gjort nu i flera veckor, men vad getString egentligen gör? 159 00:09:40,150 --> 00:09:43,350 GetString skriven av CS50 personal är lite intelligent 160 00:09:43,350 --> 00:09:46,500 att så snart som användaren börjar skriva nycklar och träffar Enter, 161 00:09:46,500 --> 00:09:50,010 GetString räknar ut hur många tangenttryckningar gjorde användaren träff, 162 00:09:50,010 --> 00:09:53,360 hur många tecken behöver jag tilldela RAM för. 163 00:09:53,360 --> 00:09:55,660 Och när detta RAM kommer ifrån, vem vet? 164 00:09:55,660 --> 00:09:58,930 Det är någonstans i datorns 2 gigabyte eller whatnot minne. 165 00:09:58,930 --> 00:10:05,200 Men låt oss anta att datorn hittade utrymme för ordet HEJ här. 166 00:10:05,200 --> 00:10:08,710 Ordet jag skrev var H-E-L-L-O. 167 00:10:08,710 --> 00:10:13,510 Och om vi drar detta som en följd av tecken, kan vi dra det så här. 168 00:10:13,510 --> 00:10:17,860 Men jag behöver göra 1 extra sak. Vad hör i slutet av varje sträng i C? 169 00:10:17,860 --> 00:10:20,710 Null karaktär, som vi skriver som \ 0. 170 00:10:20,710 --> 00:10:23,980 Det är tekniskt numret 0, men det omvända snedstrecket gör hela klarare 171 00:10:23,980 --> 00:10:28,150 att detta är bokstavligen numret 0, heltalet 0; 172 00:10:28,150 --> 00:10:32,440 Det är till exempel inte, citat-unquote 0 som du kan skriva på tangentbordet. 173 00:10:32,440 --> 00:10:33,940 Så detta är HELLO. 174 00:10:33,940 --> 00:10:36,350 >> Och vad har vi sagt på måndagen att en funktion som GetString 175 00:10:36,350 --> 00:10:39,580 faktiskt tillbaka alla dessa veckor? 176 00:10:39,580 --> 00:10:43,960 Det är inte returnera en sträng i sig eftersom det inte riktigt har betyder 177 00:10:43,960 --> 00:10:47,710 eftersom strängarna finns inte. De är en slags tillverkning i CS50 biblioteket. 178 00:10:47,710 --> 00:10:51,300 Vad är egentligen en sträng, mer tekniskt? >> [Elev] Det är det första tecknet. 179 00:10:51,300 --> 00:10:55,950 Exakt. Det är helt enkelt adressen till det första tecknet som användaren skrivit in 180 00:10:55,950 --> 00:11:02,810 Så om mitt ord HELLO slutar det upp på byte nummer 123 och sedan vid byte nummer 124, 181 00:11:02,810 --> 00:11:08,320 125, 126 och så vidare, om jag bara nummer mina byte från 0 på upp, 182 00:11:08,320 --> 00:11:12,650 vad som verkligen GetString återvänder är bokstavligen numret 123. 183 00:11:12,650 --> 00:11:19,270 Så vad får placeras i s är antalet 123, inte bokstaven H inte ordet HELLO, 184 00:11:19,270 --> 00:11:23,130 helt enkelt den adress där jag kan hitta den första bokstaven i HELLO. 185 00:11:23,130 --> 00:11:26,500 Men det verkar inte som tillräckligt. Jag bad dig om en sträng, inte ett tecken. 186 00:11:26,500 --> 00:11:32,970 Så hur vet vi eller den dator som ELLO typ av kommer tillsammans med H? 187 00:11:35,760 --> 00:11:37,460 Vad är den typ av avtal som vi har? Ja. 188 00:11:37,460 --> 00:11:40,100 [Eleven] Det håller berättar själv att hitta några fler tecken. >> Exakt. 189 00:11:40,100 --> 00:11:44,570 >> Det är detta människa-dator konvention där när du arbetar med strängar, 190 00:11:44,570 --> 00:11:49,410 annars känd nu som röding stjärnor, behöver du bara räkna ut 191 00:11:49,410 --> 00:11:54,350 där i slutet av varje sträng i livet är att egentligen bara iteration över den med en for-slinga, 192 00:11:54,350 --> 00:11:57,820 en while-slinga, vad som helst, så att när du hittar i slutet av strängen 193 00:11:57,820 --> 00:12:02,160 nu kan du dra slutsatsen att åh, var hela ordet HELLO. 194 00:12:02,160 --> 00:12:04,820 De av er med tidigare erfarenhet av programmering kanske känner i Java 195 00:12:04,820 --> 00:12:09,880 Du kan bara ringa. längd och på andra språk kan du ringa längd eller liknande. 196 00:12:09,880 --> 00:12:14,060 Det beror i många språk, särskilt saker som kallas objektorienterade språk, 197 00:12:14,060 --> 00:12:18,580 längd något är typ av inkapslat inuti en bit data själv, 198 00:12:18,580 --> 00:12:24,000 mycket som vi inkapslade ID och namn och hus inuti en student på måndagen. 199 00:12:24,000 --> 00:12:28,700 Men C är mycket lägre nivå. Det finns inga objekt eller klasser, om du har hört dessa villkor innan. 200 00:12:28,700 --> 00:12:31,490 Allt du har är verkligen minnesadresser. 201 00:12:31,490 --> 00:12:35,540 Så detta är en slags gammaldags sätt att representera intressanta datastrukturer. 202 00:12:35,540 --> 00:12:38,760 Du har ett startvärde som adressen för det första tecknet 203 00:12:38,760 --> 00:12:42,340 och sedan bara någon godtycklig konvention som alla förbinder sig att följa. 204 00:12:42,340 --> 00:12:46,420 Så hur är stränglängd genomförs, vi föreslår? 205 00:12:46,420 --> 00:12:51,360 Strlen, strlen, som vissa av er har nu använt några gånger. Det är ganska enkelt, eller hur? 206 00:12:51,360 --> 00:12:53,060 Det är som 2 rader kod. 207 00:12:53,060 --> 00:12:56,140 Det är ganska mycket en for-slinga av något slag, kanske med ytterligare lokal variabel. 208 00:12:56,140 --> 00:13:00,540 Men strlen har bara att ta en pekare och sedan börja leta efter \ 0. 209 00:13:00,540 --> 00:13:05,190 >> Och så snart den finner det, kan det återgå totala antalet steg som det har tagit i den strängen. 210 00:13:05,190 --> 00:13:07,150 Så vi kan dra slutsatsen detta vad som händer härnäst. 211 00:13:07,150 --> 00:13:11,850 Anta då jag förklarar t som jag har gjort i linje 10. 212 00:13:11,850 --> 00:13:14,280 Detta är något skräp värde. Vem vet först? 213 00:13:14,280 --> 00:13:18,490 Men på den högra sidan av raden av 10 Jag ringer getString igen. 214 00:13:18,490 --> 00:13:20,050 Vem vet var det hamnar? 215 00:13:20,050 --> 00:13:23,830 Låt oss säga godtyckligt att operativsystemet fann utrymme för det vägen hit. 216 00:13:23,830 --> 00:13:28,610 Jag råkar tillfällighet typ H-E-L-L-O igen, 217 00:13:28,610 --> 00:13:31,260 och så att vi kan dra samma typ av bild. 218 00:13:31,260 --> 00:13:34,290 Men det faktum att jag har ritas bilden är avsiktlig 219 00:13:34,290 --> 00:13:37,720 eftersom det är en annan HÄLSNINGAR än denna. 220 00:13:37,720 --> 00:13:43,920 Så här kan detta vara platsen 456, är detta 457, och så vidare. 221 00:13:43,920 --> 00:13:47,170 Så vad får sätta där frågetecknet gång var? 222 00:13:47,170 --> 00:13:50,190 I detta fall 456. 223 00:13:50,190 --> 00:13:53,540 Vi plockar dessa siffror godtyckligt eftersom verkligen efter idag 224 00:13:53,540 --> 00:13:57,110 Vi kommer inte att bry sig så mycket om vad adress någonting är. 225 00:13:57,110 --> 00:14:02,690 Allt vi bryr oss om är att vi kan räkna ut adressen till någon bit data som HELLO. 226 00:14:02,690 --> 00:14:07,100 >> Så egentligen vad de flesta människor gör i datavetenskap när man talar om minnesadresser 227 00:14:07,100 --> 00:14:10,210 och prata om pekare specifikt, 228 00:14:10,210 --> 00:14:14,220 snarare än att bry räkna ut 123 - vem bryr sig om det här faktiskt är, 229 00:14:14,220 --> 00:14:17,440 Vi vet bara att det är någon numerisk adress - 230 00:14:17,440 --> 00:14:22,180 Vi förenklar världen och bara säga att er pekar på det tecknet 231 00:14:22,180 --> 00:14:25,080 och t pekar på det tecknet. 232 00:14:25,080 --> 00:14:27,430 Och det faktum att det är en pil är ganska avsiktligt 233 00:14:27,430 --> 00:14:31,610 eftersom bokstavligen nu s pekar på H och t pekar på den andra H 234 00:14:31,610 --> 00:14:34,720 eftersom i slutet av dagen, spelar det ingen roll vad adressen är, 235 00:14:34,720 --> 00:14:40,240 men det spelar roll att vi har förmågan att uttrycka den adressen med någon del av koden. 236 00:14:40,240 --> 00:14:42,730 Vi har inte riktigt manipulerat dessa adresser bara ännu 237 00:14:42,730 --> 00:14:47,770 så vi får se var vi kan invända och typ av göra saker med pekare, 238 00:14:47,770 --> 00:14:52,030 men nu i linje 12 bokstavligen vilka värden vi jämför 239 00:14:52,030 --> 00:14:55,500 Enligt denna berättelse i linje 12? 240 00:14:56,570 --> 00:15:01,290 Vi säger är 123 lika lika med 456? Och det är definitivt inte fallet. 241 00:15:01,290 --> 00:15:05,320 Och även begreppsmässigt, är denna pekare definitivt inte samma som det 242 00:15:05,320 --> 00:15:09,500 eftersom du ringde getString två gånger och GetString försöker inte vara super smart, 243 00:15:09,500 --> 00:15:12,470 det inte att försöka förverkliga, åh, skrev du HELLO 5 minuter sedan; 244 00:15:12,470 --> 00:15:15,090 Låt mig ge dig samma pekaren som jag gav dig innan, 245 00:15:15,090 --> 00:15:18,450 Det tilldelar bara en ny bit av minnet varje gång du kallar det. 246 00:15:18,450 --> 00:15:20,350 >> Så hur fixar vi det här problemet? 247 00:15:20,350 --> 00:15:24,270 Om högre nivå jag vill jämföra strängar hej och HELLO - 248 00:15:24,270 --> 00:15:28,680 Jag bryr mig inte om tips - hur gör jag besvara frågan, 249 00:15:28,680 --> 00:15:31,980 gjorde användaren skriva samma sak? Vad är nödvändigt här? Ja. 250 00:15:31,980 --> 00:15:35,200 [Elev] Använd en funktion. >> Jag kan använda en funktion ur lådan. 251 00:15:35,200 --> 00:15:38,170 Jag kan använda en funktion som kallas strcmp, s-t-r-c-m-p, 252 00:15:38,170 --> 00:15:41,190 bara den förkortade versionen att säga sträng jämföra. 253 00:15:41,190 --> 00:15:45,070 Och om vi går in till exempel jämföra 2, som är bland dagens åhörarkopior, 254 00:15:45,070 --> 00:15:46,690 Jag gör precis det. 255 00:15:46,690 --> 00:15:51,750 Jag höll allt annat lika från linje 1 ner till 26 eller så, 256 00:15:51,750 --> 00:15:54,360 och nu märker denna del har förändrats bara lite. 257 00:15:54,360 --> 00:15:57,690 Låt oss bortse linje 28 för en stund och bara fokusera på detta. 258 00:15:57,690 --> 00:16:00,410 Vad gjorde vi säga måndag att str jämförelsen gör? 259 00:16:00,410 --> 00:16:05,200 Den hanterar processen att ta 2 pekare, S och T i detta fall, 260 00:16:05,200 --> 00:16:08,480 typ av praktiskt taget sätta fingret på dessa 2 bokstäver, 261 00:16:08,480 --> 00:16:11,530 och vad det måste göra är något som en while-slinga eller en for-slinga, 262 00:16:11,530 --> 00:16:16,050 och det står är dessa samma? Om så är fallet, förflyttar den fingrarna eller pekare framåt. 263 00:16:16,050 --> 00:16:17,970 Är dessa samma, dessa samma, dessa samma, 264 00:16:17,970 --> 00:16:22,710 dessa samma, dessa samma? Och ooh, jag i slutet av strängen både s och t. 265 00:16:22,710 --> 00:16:26,780 Jag har inte hittat några motsägelser. Ja, dessa strängar är desamma. 266 00:16:26,780 --> 00:16:31,940 Och vad jämför str avkastning om 2 strängar är lika, tydligen? Noll. 267 00:16:31,940 --> 00:16:35,900 Så 0 är bra i det här fallet eftersom om det återvänder -1 eller +1, 268 00:16:35,900 --> 00:16:40,560 det betyder att s bara råkar komma före t alfabetiskt eller efter t. 269 00:16:40,560 --> 00:16:43,760 Och varför skulle det vara bra att ha en funktion som talar om vilken sträng kommer före 270 00:16:43,760 --> 00:16:46,720 eller efter i ett lexikon? 271 00:16:46,720 --> 00:16:48,740 [Elev] Söker. >> Sökning och sortering. 272 00:16:48,740 --> 00:16:51,730 >> Så du kan göra saker som binär sökning eller bubbla sortera eller slå samman Sortera 273 00:16:51,730 --> 00:16:53,230 där du måste jämföra saker. 274 00:16:53,230 --> 00:16:56,420 Hittills vi har typ av klippa några hörn och bara talade om sortering 275 00:16:56,420 --> 00:16:59,430 i samband med siffrorna eftersom det är trevligt och lätt att prata om, 276 00:16:59,430 --> 00:17:02,430 men du kan säkert jämföra strängar, äpple och banan, 277 00:17:02,430 --> 00:17:05,349 eftersom om äpple är känt att komma före banan, på liknande sätt, 278 00:17:05,349 --> 00:17:09,319 kan du flytta strängar runt i minnet precis som Rob gjorde med merge Sortera i videon 279 00:17:09,319 --> 00:17:15,880 och vi gjorde här på scenen med val Sortera, införande sortera och bubbla sortera. 280 00:17:15,880 --> 00:17:18,710 Så var annars kan vi ta detta? Låt oss försöka det. 281 00:17:18,710 --> 00:17:23,980 Låt oss slags glömma att lektionen för ett ögonblick och försök nu och kopiera 1.c att göra följande. 282 00:17:23,980 --> 00:17:26,800 I linje 21 Jag säger ut något, 283 00:17:26,800 --> 00:17:28,520 då jag får en sträng från användaren, 284 00:17:28,520 --> 00:17:30,690 då jag kontrollera detta. 285 00:17:30,690 --> 00:17:33,620 Vi har inte riktigt kommit in i denna vana än, men låt oss nu göra detta. 286 00:17:33,620 --> 00:17:40,990 Låt oss faktiskt skal tillbaka detta skikt. Detta är verkligen char *. Den här killen är verkligen char *. 287 00:17:40,990 --> 00:17:45,690 Så vad betyder det att kontrollera om s == NULL? 288 00:17:45,690 --> 00:17:48,380 Det visar sig att när du ringer en funktion som GetString 289 00:17:48,380 --> 00:17:51,540 eller mer generellt bara be en dator för att ge dig lite minne, 290 00:17:51,540 --> 00:17:53,030 något kan gå fel. 291 00:17:53,030 --> 00:17:56,630 Du kan vara galen och be datorn för en terabyte minne 292 00:17:56,630 --> 00:18:01,780 genom att be om biljoner byte minne som bara inte finns i datorn, 293 00:18:01,780 --> 00:18:05,130 men getString och andra funktioner behöver något sätt skriker på dig 294 00:18:05,130 --> 00:18:06,820 om du har bett om för mycket. 295 00:18:06,820 --> 00:18:10,450 Och hur GetString gör detta är om du har bett om mer minne 296 00:18:10,450 --> 00:18:14,250 än vad som finns i datorn, även om det är super, super låg sannolikhet 297 00:18:14,250 --> 00:18:17,730 eftersom ingen av oss kommer att skriva en biljon tecken och sedan trycka Enter, 298 00:18:17,730 --> 00:18:21,980 men låg sannolikhet men det kan vara, vill jag ändå att kontrollera det i fall, 299 00:18:21,980 --> 00:18:26,120 och den speciella värde som getString, svar, och andra funktioner avkastning 300 00:18:26,120 --> 00:18:30,630 om något har gått fel är NULL i alla mössor. 301 00:18:30,630 --> 00:18:36,520 >> Och vad är NULL? NULL råkar vara så att representera en pekare. Det är minnesadress 0. 302 00:18:36,520 --> 00:18:40,800 Världen beslutade att godtyckligt, om detta är min dator minne - vet du vad? - 303 00:18:40,800 --> 00:18:46,260 vi kommer att stjäla bara 1 byte i varje dators minne, och detta är platsen 0. 304 00:18:46,260 --> 00:18:49,560 Vi kommer att ge den ett smeknamn av NULL, och vi kommer att lova 305 00:18:49,560 --> 00:18:52,660 att vi aldrig kommer faktiskt sätta verklig data finns 306 00:18:52,660 --> 00:18:56,770 eftersom vi bara godtyckligt behöver ett speciellt värde, 0, alias NULL, 307 00:18:56,770 --> 00:19:00,230 så att vi kan skrika åt användare om något går fel. 308 00:19:00,230 --> 00:19:03,590 Annars kan du kanske inte vet betyder 0 betyder sätta något här 309 00:19:03,590 --> 00:19:05,490 eller betyder det något gick fel? 310 00:19:05,490 --> 00:19:09,190 Vi måste alla vara överens om att NULL betyder ingenting tillbaka, 311 00:19:09,190 --> 00:19:11,700 ingen faktisk adress returnerades. 312 00:19:11,700 --> 00:19:15,210 Nu, här jag bara anta min mänskliga konvention av jag återvänder 1 från huvud 313 00:19:15,210 --> 00:19:17,040 om något går fel. 314 00:19:17,040 --> 00:19:20,650 Det beror huvud återkomst konvention är att återvända 0 om bra, 315 00:19:20,650 --> 00:19:22,990 1 eller något annat värde om dåliga. 316 00:19:22,990 --> 00:19:28,200 Men GetString och alla funktioner som erbjudanden i minnet returnerar null om något går dåligt. 317 00:19:28,200 --> 00:19:33,480 >> Okej. Så tyvärr, misslyckas linje 27, super enkelt men det är helt för att kopiera strängen. 318 00:19:33,480 --> 00:19:35,740 Varför? Vi kan se detta på följande sätt. 319 00:19:35,740 --> 00:19:40,120 Jag hävdar i linje 27 att göra en kopia av s och kalla det inte. 320 00:19:40,120 --> 00:19:45,790 Så jag inte ber användaren 2 strängar den här gången, jag säger bara värdet i s 321 00:19:45,790 --> 00:19:47,870 bör läggas it också. 322 00:19:47,870 --> 00:19:52,890 Så nu bara för att visa hur trasiga detta är, i linje 29 och framåt vad gör jag? 323 00:19:52,890 --> 00:19:56,980 Först jag kontrollera om längden på t är större än 0. 324 00:19:56,980 --> 00:19:59,330 Det finns vissa sträng där. Användaren skrivit något i. 325 00:19:59,330 --> 00:20:03,410 Vad är linje 32 gör, tydligen? 326 00:20:03,410 --> 00:20:08,910 [Ohörbart elev svar] >> Höger. Du kan typ av sluta det från vad jag sa att det gör. 327 00:20:08,910 --> 00:20:13,200 Men tekniskt är vad detta gör? t [0] representerar vad? 328 00:20:13,200 --> 00:20:15,140 [Studerande] Den nollte karaktär. >> [Malan] Den 0:e karaktär. 329 00:20:15,140 --> 00:20:19,620 Eller mer människoliknande, det första tecknet i t, vad det är, H kanske i detta fall. 330 00:20:19,620 --> 00:20:24,990 Och toupper gör vad den säger. Det kapitaliserar den nollte karaktär t och det förändrar det. 331 00:20:24,990 --> 00:20:28,430 Så detta betyder ta 0:e karaktären av t, gör det versaler, 332 00:20:28,430 --> 00:20:30,320 och lägger tillbaka den i samma läge. 333 00:20:30,320 --> 00:20:35,540 Så om jag skriver hej med gemener, bör denna ändring den gemena h till ett kapital H. 334 00:20:35,540 --> 00:20:41,400 Men problemet är att i ledningarna 35 och 36 vad jag ska göra är att skriva för oss s och t. 335 00:20:41,400 --> 00:20:43,120 Och vad är din känsla? 336 00:20:43,120 --> 00:20:47,250 Vad ska jag faktiskt att se om jag skrivit in hej i alla gemener? 337 00:20:47,250 --> 00:20:52,280 Vad kommer att bli utskrivna? >> [Ohörbart elev svar] >> Vad är det? 338 00:20:52,280 --> 00:20:58,360 [Eleven] Big H och resten små. >> Den stora H och resten små för vilka s eller t? 339 00:20:58,360 --> 00:21:03,170 [Elev] Både. >> Båda. Exakt. Så låt oss se vad som händer här. 340 00:21:03,170 --> 00:21:08,380 >> Låt mig gå vidare och sammanställa denna. Detta är Kopiering1, så Kopiering1. Okej. 341 00:21:08,380 --> 00:21:14,840 Zooma in Låt mig gå vidare och köra Kopiering1, Enter, Säg något: hej små bokstäver. 342 00:21:14,840 --> 00:21:19,570 Det kapitaliserade kopian, men det tydligen aktiverats originalet också, 343 00:21:19,570 --> 00:21:22,070 eftersom det som händer nu i den här berättelsen? 344 00:21:22,070 --> 00:21:27,030 I linje 27 jag faktiskt inte verkar kopiera strängen, 345 00:21:27,030 --> 00:21:30,450 men även om du kanske har intuitivt hoppats att så är fallet, 346 00:21:30,450 --> 00:21:33,680 om du tänker på den här bilden, vad som verkligen har jag gjort? 347 00:21:33,680 --> 00:21:35,410 Hälften av bilden är densamma. 348 00:21:35,410 --> 00:21:39,390 Så låt oss rulla tillbaka i tiden, så att t ännu inte finns i berättelsen. 349 00:21:39,390 --> 00:21:43,160 S kan finnas i berättelsen, men låt oss små bokstäver hej den här gången. 350 00:21:43,160 --> 00:21:46,710 Så låt mig fixa vad jag faktiskt skrivit i. 351 00:21:46,710 --> 00:21:51,280 I det här fallet här har vi H-E-L-L-O. 352 00:21:51,280 --> 00:21:58,050 Vi ska dra det som en följd av tecken, sätta min separator rader här och min \ 0. 353 00:21:58,050 --> 00:22:05,980 Så det är där vi är när linje 1 till 24-ish, ge eller ta, har utförts. 354 00:22:05,980 --> 00:22:07,800 Detta är bilden av mitt minne. 355 00:22:07,800 --> 00:22:10,800 När jag kommer till rad 27, vad händer? 356 00:22:10,800 --> 00:22:14,730 Precis som tidigare, får jag en pekare, som jag ska dra så detta torg. 357 00:22:14,730 --> 00:22:19,740 Det kallas inte. Och vad är dess värde som standard? Vem vet? Vissa skräp värde. 358 00:22:19,740 --> 00:22:22,060 >> Så jag ska abstrakt att bort som ett frågetecken. 359 00:22:22,060 --> 00:22:27,670 Och så snart den högra sidan av linjen 27 utför, vad jag lägger in i t? 360 00:22:27,670 --> 00:22:30,770 Samma sak som finns i talet. 361 00:22:30,770 --> 00:22:34,120 Så om vi för ett ögonblick bort denna abstraktion av pilen och vi säger, 362 00:22:34,120 --> 00:22:40,330 Åh, är detta minne belastning adress 123, när du säger t får s, semikolon, 363 00:22:40,330 --> 00:22:42,700 du bokstavligen sätta 123 här. 364 00:22:42,700 --> 00:22:45,200 Nu om vi sorts förenkla vår värld igen med bilder, 365 00:22:45,200 --> 00:22:48,750 vad du egentligen gjort är bara läggas en annan pil i din värld 366 00:22:48,750 --> 00:22:52,910 som är pekar från t till exakt samma sträng. 367 00:22:52,910 --> 00:22:59,730 Så när i linje 31 och 32 jag faktiskt gå om att byta t [0], 368 00:22:59,730 --> 00:23:05,580 vad är t [0] synes synonymt med nu? s [0] 369 00:23:05,580 --> 00:23:07,030 Så det är allt som händer. 370 00:23:07,030 --> 00:23:09,900 Och även om denna typ av känns lite låg nivå och svårbegripliga 371 00:23:09,900 --> 00:23:12,760 och denna typ av känns kanske intuitivt här bör bara arbetat - 372 00:23:12,760 --> 00:23:15,410 Jag har gjort kopior av saker innan och det bara fungerade - 373 00:23:15,410 --> 00:23:18,590 om du verkligen tänker på vad en sträng egentligen är, det är en char *. 374 00:23:18,590 --> 00:23:21,700 Nå, vad är det? Det är adressen till en viss karaktär. 375 00:23:21,700 --> 00:23:24,930 Då kanske det är mer förnuftigt att när du försöker göra något 376 00:23:24,930 --> 00:23:29,220 Super synes enkla som denna, är allt du gör kopierar en minnesadress. 377 00:23:29,220 --> 00:23:32,530 Du faktiskt inte göra något med strängen själv. 378 00:23:32,530 --> 00:23:37,500 Så även om du har ingen aning om hur man skulle lösa detta problem i kod, 379 00:23:37,500 --> 00:23:45,080 hög nivå, konceptuellt, vad vi behöver göra för att göra ta bestyrkt kopia av s, tydligen? 380 00:23:46,670 --> 00:23:48,820 Ja. >> [Elev] Ge det en ny plats? >> Exakt. 381 00:23:48,820 --> 00:23:50,800 >> Vi måste ge t en helt ny plats. 382 00:23:50,800 --> 00:23:55,230 Vi måste på något sätt skapa en värld där vi får en ny bit av minnet, 383 00:23:55,230 --> 00:24:00,090 som bara för tydlighetens skull ska jag dra till höger nedanför detta, men det behöver inte vara där. 384 00:24:00,090 --> 00:24:04,880 Men det måste vara av samma storlek, så jag ska rita dessa vertikala linjer på samma plats. 385 00:24:04,880 --> 00:24:09,720 Det är bra om det är allt skräp från början. Vem vet vad som fanns där? 386 00:24:09,720 --> 00:24:13,850 Men steg 1 kommer att behöva ge mig så mycket minne som jag behöver 387 00:24:13,850 --> 00:24:18,630 för att passa en kopia av hej då räkna ut hur att kopiera h här, e här, 388 00:24:18,630 --> 00:24:20,390 på l här och så vidare. 389 00:24:20,390 --> 00:24:24,880 Men detta redan borde känna sig lite uppenbar, även om vissa detaljer är fortfarande abstrakt. 390 00:24:24,880 --> 00:24:28,690 Om du vill kopiera den här strängen i detta, det är bara en for-slinga eller en while-slinga 391 00:24:28,690 --> 00:24:31,580 eller något som du har blivit allt mer bekant. 392 00:24:31,580 --> 00:24:35,970 Så låt oss prova det här. Låt mig gå in copy2.c. 393 00:24:35,970 --> 00:24:43,270 I copy2.c vi har nästan samma program förutom linje 27. 394 00:24:43,270 --> 00:24:47,260 Det ser lite komplicerat, men om vi bryter ner det bit för bit, 395 00:24:47,260 --> 00:24:48,950 den vänstra sidan är densamma. 396 00:24:48,950 --> 00:24:52,790 Char * t skapar denna sak i minnet, om än med ett frågetecken 397 00:24:52,790 --> 00:24:54,680 eftersom vi har ingen aning om vad som finns där som standard. 398 00:24:54,680 --> 00:24:57,920 På höger sida vi nu införa en ny funktion, malloc, 399 00:24:57,920 --> 00:25:00,640 för minne fördela, ge mig minne, 400 00:25:00,640 --> 00:25:06,900 och det tar tydligen hur många argument, hur många saker inuti parenteser? 401 00:25:09,660 --> 00:25:12,130 Jag hörde knot 1 och 2, men det är bara 1. 402 00:25:12,130 --> 00:25:15,320 Det finns ingen komma, vilket innebär att det är bara 1 sak innanför parentesen. 403 00:25:15,320 --> 00:25:17,720 Även om det finns andra parenteser, låt mig belysa 404 00:25:17,720 --> 00:25:21,460 vad som finns inuti de yttersta parenteser, och det är detta uttryck: 405 00:25:21,460 --> 00:25:25,880 (Strlen (a) + 1) * sizeof (char). 406 00:25:25,880 --> 00:25:29,190 Så om vi faktiskt tror att detta igenom, detta säger mig längden på talet. 407 00:25:29,190 --> 00:25:34,440 Varför är jag dock lägga till 1 på längden? >> [Ohörbart elev svar] 408 00:25:34,440 --> 00:25:40,200 Exakt. Vi behöver utrymme för den här killen på svansen, det sjätte tecknet som inte har någon engelska innebörd 409 00:25:40,200 --> 00:25:42,250 men har speciella programmatiska innebörd. 410 00:25:42,250 --> 00:25:46,800 >> Så vi behöver en + 1 för att eftersom strlen returnerar den mänskliga förväntningar av längd, 411 00:25:46,800 --> 00:25:50,890 hej eller 5, ger det inte dig den extra null karaktär. 412 00:25:50,890 --> 00:25:52,980 Så jag manuellt lägga detta med + 1. 413 00:25:52,980 --> 00:25:56,060 Och sedan detta, (char) * storlek, har vi inte sett förut. 414 00:25:56,060 --> 00:25:57,480 Detta är inte tekniskt en funktion. 415 00:25:57,480 --> 00:26:04,150 Det är en speciell sökord som bara talar om vilken storlek är av någon datatyp på en dator 416 00:26:04,150 --> 00:26:06,980 eftersom i verkligheten, några av oss har 32-bitars datorer. 417 00:26:06,980 --> 00:26:10,900 Jag har en ganska gammal dator hemma, och det bara använder 32 bitar för att representera pekare. 418 00:26:10,900 --> 00:26:13,900 Och så om jag storleken på en datatyp, kan det vara 32 bitar. 419 00:26:13,900 --> 00:26:18,300 Men om jag använder min nya snygga dator, kan jag få tillbaka ett värde av 64 bitar 420 00:26:18,300 --> 00:26:20,510 för ungefär en adress. 421 00:26:20,510 --> 00:26:25,400 Så i detta fall, bara för att vara mycket säkra, vi kommer inte att hårt kod något liknande - 422 00:26:25,400 --> 00:26:28,740 ja, vad är storleken på en röding enligt vad vi har sagt hittills? 423 00:26:28,740 --> 00:26:34,450 Vi har ganska mycket sagt verbalt att det är 1 byte, och det är ganska mycket sant över hela linjen. 424 00:26:34,450 --> 00:26:37,000 Men återigen, antaganden tenderar att vara dålig. 425 00:26:37,000 --> 00:26:40,850 De leder till buggig programvara om folk använder din programvara på ett sätt du inte tänker. 426 00:26:40,850 --> 00:26:44,750 Så låt oss abstrakta detta bort och bara mer allmänt säga 427 00:26:44,750 --> 00:26:46,830 Jag behöver detta många bitar av minne 428 00:26:46,830 --> 00:26:50,210 och varje bit av minne bör motsvara storleken av ett tecken, 429 00:26:50,210 --> 00:26:54,870 som i själva verket är lika med 1 i detta fall, men det är ett mer allmänt sätt att skriva det. 430 00:26:54,870 --> 00:27:00,460 Så om ordet är hej, hur många byte malloc fördela tydligen för Hello? 431 00:27:00,460 --> 00:27:04,980 [Elev] Sex. >> Sex. Precis så många som vi har frågetecken på skärmen. 432 00:27:04,980 --> 00:27:07,800 Och sedan ta en nu gissning baserat på din förståelse för GetString 433 00:27:07,800 --> 00:27:12,790 vad återvänder malloc antagligen? >> [Elev] En adress. 434 00:27:12,790 --> 00:27:17,020 En adress för vad? Första bit av minnet. 435 00:27:17,020 --> 00:27:20,670 >> Vi har ingen aning om vad som finns där eftersom någon annan funktion 436 00:27:20,670 --> 00:27:23,010 kunde ha använt detta minne tidigare. 437 00:27:23,010 --> 00:27:28,380 Men malloc, liksom GetString, returnerar adressen för den första bitgruppen av minnet 438 00:27:28,380 --> 00:27:30,540 att det har avsatts för dig. 439 00:27:30,540 --> 00:27:38,380 Dock fylla vad den inte göra i denna tomt med ett omvänt snedstreck nolltecken 440 00:27:38,380 --> 00:27:43,030 eftersom det visar sig att du kan använda malloc att allokera något: Ints, strängar, arrayer, 441 00:27:43,030 --> 00:27:45,700 flottar, studerande strukturer. 442 00:27:45,700 --> 00:27:47,750 Du kan använda malloc helt allmänt. 443 00:27:47,750 --> 00:27:51,470 Den bryr sig inte eller måste veta vad du fördela minne för. 444 00:27:51,470 --> 00:27:55,810 Så det vore förmätet att malloc att sätta en \ 0 445 00:27:55,810 --> 00:27:58,340 I slutet av varje bit av minnet det ger dig 446 00:27:58,340 --> 00:28:02,620 eftersom detta \ 0 sak är bara en konvention för stråkar. 447 00:28:02,620 --> 00:28:06,310 Det är inte för Ints, det är inte för flottar, det är inte för studenter. 448 00:28:06,310 --> 00:28:11,730 Och så gotcha med malloc är att bördan är helt på dig programmeraren 449 00:28:11,730 --> 00:28:16,790 att komma ihåg hur många byte man tilldelats och inte någonsin använda en for-slinga 450 00:28:16,790 --> 00:28:21,570 eller en while-slinga och gå förbi gränsen för bit av minne du har fått. 451 00:28:21,570 --> 00:28:23,540 Annorlunda uttryckt så fort du allokera minne, 452 00:28:23,540 --> 00:28:28,510 du kan inte be operativsystemet, åh, förresten, hur stor en bit av minne var detta? 453 00:28:28,510 --> 00:28:32,080 Det är helt upp till dig att komma ihåg om du behöver det värdet. 454 00:28:32,080 --> 00:28:34,330 >> Så låt oss se hur jag går att använda detta minne. 455 00:28:34,330 --> 00:28:38,430 I linje 28 och 29 varför gör jag detta? 456 00:28:39,850 --> 00:28:42,260 Bara total sanity check. 457 00:28:42,260 --> 00:28:45,110 Bara om något gick fel, jag ber för någon galen mängd minne 458 00:28:45,110 --> 00:28:48,690 eller jag har så många saker som körs på datorn att det bara inte tillräckligt med minne, 459 00:28:48,690 --> 00:28:51,780 något liknande, jag åtminstone vill kontrollera null. 460 00:28:51,780 --> 00:28:55,260 I verkligheten kommer de flesta datorer ger dig en illusion av att varje program 461 00:28:55,260 --> 00:28:57,080 kan använda hela din RAM, 462 00:28:57,080 --> 00:29:00,740 men ändå, om användaren skriver in någon galen lång sträng kanske eftersom de är en dålig kille 463 00:29:00,740 --> 00:29:03,440 och de är faktiskt försöker att krascha ditt program eller hacka i det, 464 00:29:03,440 --> 00:29:07,300 du vill åtminstone kontrollera returvärdet av malloc och om det är lika med noll. 465 00:29:07,300 --> 00:29:11,630 Och om det gör det, låt oss bara sluta just nu eftersom jag inte vet vad jag ska göra i så fall. 466 00:29:11,630 --> 00:29:13,950 Hur kopierar jag strängen? Det finns ett par sätt att göra detta. 467 00:29:13,950 --> 00:29:18,850 Det finns str kopiera funktioner i C, men det är super enkelt för oss att göra detta gammaldags sätt. 468 00:29:18,850 --> 00:29:23,110 >> Låt mig först ta reda på vad längd s är. 469 00:29:23,110 --> 00:29:26,930 Jag kunde ha lagt det i slingan utan jag bara lägga ut det här för tydlighetens skull. 470 00:29:26,930 --> 00:29:30,610 Så n lagrar nu längden av den ursprungliga strängen, som tydligen 5. 471 00:29:30,610 --> 00:29:35,290 Sedan i min for-slingan jag iteration från 0 på upp till n, 472 00:29:35,290 --> 00:29:40,940 och på varje iteration Jag sätter s [i] inuti t [i]. 473 00:29:40,940 --> 00:29:45,060 Så det är vad jag antydde med min 2 fingrar pekar på strängarna innan. 474 00:29:45,060 --> 00:29:49,260 Eftersom detta för slinga itererar så här, jag kommer att kopiera H in på här, 475 00:29:49,260 --> 00:29:52,890 e in på här, jag in på här eftersom det är s, är denna t. 476 00:29:52,890 --> 00:29:58,770 Och sedan slutligen, i linje 35 varför gör jag detta? 477 00:29:58,770 --> 00:30:03,770 Jag måste se till att jag slutar strängen t. 478 00:30:03,770 --> 00:30:06,170 Och jag gjorde det här sättet att vara super tydlig. 479 00:30:06,170 --> 00:30:09,510 Men föreslå någon, om du kunde, ett annat sätt att göra detta. 480 00:30:09,510 --> 00:30:13,930 Jag behöver egentligen inte linjen 35. Det finns ett annat sätt att göra detta. 481 00:30:13,930 --> 00:30:18,880 Ja. >> [Ohörbart elev svar] >> Säg det högre. 482 00:30:18,880 --> 00:30:20,960 [Studerande] Mindre än eller lika med. >> Exakt. 483 00:30:20,960 --> 00:30:24,450 Vi kan bara säga mindre än eller lika med n, som i allmänhet har varit dålig 484 00:30:24,450 --> 00:30:28,190 eftersom nästan alltid när vi går upp till en lika sak vi räknar 485 00:30:28,190 --> 00:30:30,000 vi går 1 steg för långt. 486 00:30:30,000 --> 00:30:32,170 Men kom ihåg, hur många byte vi fördela? 487 00:30:32,170 --> 00:30:37,210 Vi tilldelade strlen av s, så 5 + 1 för totalt 6. 488 00:30:37,210 --> 00:30:39,980 Så i det här fallet kunde vi göra något liknande 489 00:30:39,980 --> 00:30:46,450 så att vi kopierar inte bara hej utan även \ 0 i slutet. 490 00:30:46,450 --> 00:30:49,860 Alternativt kan vi använda en funktion som kallas str kopia, strcpy, 491 00:30:49,860 --> 00:30:51,700 men det skulle inte vara nästan lika kul. 492 00:30:51,700 --> 00:30:54,000 Men det är allt den gör under huven. 493 00:30:54,000 --> 00:30:56,050 Då slutligen gör vi samma sak som tidigare. 494 00:30:56,050 --> 00:31:01,620 Jag kapitalisera t och då jag påstår att den ursprungliga ser ut så här och kopian ser ut som. 495 00:31:01,620 --> 00:31:08,570 Så låt oss prova detta nu. Låt mig gå in här. Gör copy2. Vi ska zooma in och köra copy2. 496 00:31:08,570 --> 00:31:13,840 Jag ska skriva in hej med gemener, och faktiskt jag gemener hej som originalet 497 00:31:13,840 --> 00:31:16,930 men kapitalet Hej för kopian. 498 00:31:16,930 --> 00:31:20,300 Men jag är inte klar ännu. Jag behöver göra en sista sak här. 499 00:31:20,300 --> 00:31:28,000 46 och 47 är klart frigöra minne, men vad betyder det egentligen? 500 00:31:28,000 --> 00:31:33,250 Vad gör jag, tror du, genom att ringa linjen 46 och linje 47? 501 00:31:33,250 --> 00:31:38,900 Vilken effekt har det? Ja. 502 00:31:38,900 --> 00:31:43,140 [Ohörbart elev svar] >> Exakt. 503 00:31:43,140 --> 00:31:46,380 >> Du är bara berättar operativsystemet, hej, tack för detta minne. 504 00:31:46,380 --> 00:31:48,320 Du kan nu använda den för någon annan. 505 00:31:48,320 --> 00:31:50,790 Och här är ett perfekt exempel på sopor värden. 506 00:31:50,790 --> 00:31:55,430 Jag har bara använt detta minne för att skriva ner ordet hej i 2 platser, 507 00:31:55,430 --> 00:31:57,490 här, här, här och här. 508 00:31:57,490 --> 00:32:00,910 Så detta är h-E-L-L-O-\ 0. 509 00:32:00,910 --> 00:32:06,960 Men sedan jag telefonlinje 46 och linje 47, och du vet vad som händer där i form av bilden? 510 00:32:06,960 --> 00:32:10,010 Egentligen, vänta, den här bilden är det gamla. 511 00:32:10,010 --> 00:32:12,550 När vi gör kopian är den här killen pekar faktiskt här, 512 00:32:12,550 --> 00:32:16,110 så låt oss ta bort siffrorna och bara abstrakta bort som våra pilar igen. 513 00:32:16,110 --> 00:32:19,370 Vad händer i den här bilden när jag ringer gratis? 514 00:32:19,370 --> 00:32:22,750 [Ohörbart elev svar] >> Inte ens. 515 00:32:22,750 --> 00:32:29,510 Om jag ringa gratis på s och t - typ av en kuggfråga - bilden inte ändras alls 516 00:32:29,510 --> 00:32:33,880 eftersom ringa s och ringer t talar bara operativsystemet, 517 00:32:33,880 --> 00:32:39,010 hej, kan du använda det här minnet igen, men det förändrar inte det till noll 518 00:32:39,010 --> 00:32:41,840 eller några speciella karaktär ändras inte detta, 519 00:32:41,840 --> 00:32:47,350 Det ändrar inte h eller e eller l eller l eller o antingen plats för något annat. 520 00:32:47,350 --> 00:32:51,610 När det gäller bilden så fort du ringer gratis, ingenting förändras. 521 00:32:51,610 --> 00:32:56,570 Och däri ligger ursprunget till sopor värden för om jag senare i detta program 522 00:32:56,570 --> 00:33:01,010 be operativsystemet för mer minne med GetString eller malloc eller något liknande 523 00:33:01,010 --> 00:33:04,900 och operativsystemet säger visst, jag har 12 byte minne bara frigörs, 524 00:33:04,900 --> 00:33:08,080 använda dessa, vad kommer att överlämnas? 525 00:33:08,080 --> 00:33:10,830 Du kommer att lämnas en bit av minne som vi normalt skulle göra 526 00:33:10,830 --> 00:33:13,700 med frågetecken, men vad är de frågetecken? 527 00:33:13,700 --> 00:33:17,000 De råkar vara H-E-L-L-O, H-E-L-L-O. 528 00:33:17,000 --> 00:33:20,940 Dessa är våra nya sopor värden så fort du frigöra detta minne. 529 00:33:20,940 --> 00:33:22,750 >> Det finns en verklig värld konsekvenser även här. 530 00:33:22,750 --> 00:33:24,720 Det händer att göra med RAM-minne, men dina datorer 531 00:33:24,720 --> 00:33:26,720 faktiskt göra samma sak med disk. 532 00:33:26,720 --> 00:33:30,620 Vi pratar om det här i synnerhet med framtida problem uppsättning som fokuserar på kriminalteknik. 533 00:33:30,620 --> 00:33:36,170 Men vad händer egentligen om du har några känslig finansiell fil på skrivbordet 534 00:33:36,170 --> 00:33:39,600 eller någon skissartad JPEG och du drar den till papperskorgen, 535 00:33:39,600 --> 00:33:44,390 vad som händer när du drar den till papperskorgen eller papperskorgen? 536 00:33:44,390 --> 00:33:47,240 Du visste vad jag pratade om. [Skratt] 537 00:33:47,240 --> 00:33:52,370 Vad händer när du har dragit denna bevisning i din papperskorg eller soptunna? 538 00:33:52,370 --> 00:33:55,920 [Ohörbart elev svar] 539 00:33:55,920 --> 00:33:58,000 Tja, så var försiktig. Vad händer när du gör det? 540 00:33:58,000 --> 00:34:01,030 Det korta svaret är ingenting, eller hur? 541 00:34:01,030 --> 00:34:04,790 Sketchy eller känsliga filer är fortfarande bara sitter där någonstans i din hårddisk. 542 00:34:04,790 --> 00:34:07,940 De flesta av oss åtminstone ha lärt sig den hårda vägen att du måste tömma papperskorgen 543 00:34:07,940 --> 00:34:10,429 eller papperskorgen för att verkligen radera filer. 544 00:34:10,429 --> 00:34:13,440 Och faktiskt, när du högerklicka eller kontrollera klick på papperskorgen 545 00:34:13,440 --> 00:34:15,580 eller välj Arkiv, Töm papperskorgen eller vad 546 00:34:15,580 --> 00:34:21,420 och du tömmer faktiskt papperskorg eller papperskorgen, vad som egentligen händer då med den här bilden? 547 00:34:22,810 --> 00:34:25,969 Mer ingenting. Så att inget händer faktiskt på disken. 548 00:34:25,969 --> 00:34:30,880 >> Och om vi bara tillfälligt avvika och skriva - Jag ska bara använda baksidan av denna. 549 00:34:30,880 --> 00:34:34,639 Så nu berättelsen förändras från RAM, som är där program finns 550 00:34:34,639 --> 00:34:39,250 medan du kör dem, till disk, som är där de lagras lång sikt 551 00:34:39,250 --> 00:34:42,920 även när strömmen går ut, för nu - och vi ska återkomma till detta i framtiden - 552 00:34:42,920 --> 00:34:46,380 Låt oss låtsas bara att detta är hårddisken inuti datorn 553 00:34:46,380 --> 00:34:50,110 eftersom förr i tiden de brukade vara cirkulära skivor, ungefär som disketter. 554 00:34:50,110 --> 00:34:55,130 Så om du har några känsliga Excel-fil, kan det ta upp denna bit av minne 555 00:34:55,130 --> 00:34:59,770 på datorns hårddisk, och jag bara dra samma godtyckliga 1s och 0s. 556 00:34:59,770 --> 00:35:03,970 När du drar filen så där till din papperskorg eller Papperskorgen, 557 00:35:03,970 --> 00:35:07,750 bokstavligen ingenting händer eftersom Apple och Microsoft har just beslutat 558 00:35:07,750 --> 00:35:10,450 papperskorgen och papperskorgen är egentligen bara en tillfällig platshållare. 559 00:35:10,450 --> 00:35:14,710 Kanske så småningom OS kommer tömma det för dig, men typiskt, inte göra någonting, 560 00:35:14,710 --> 00:35:17,090 åtminstone tills du är riktigt ont om utrymme. 561 00:35:17,090 --> 00:35:20,870 >> Men när du går till Töm papperskorgen eller Töm papperskorgen, 562 00:35:20,870 --> 00:35:23,460 liknande händer ingenting i denna bild. 563 00:35:23,460 --> 00:35:28,590 Allt som händer är någon annanstans på datorn, finns det någon form av tabell. 564 00:35:28,590 --> 00:35:35,400 Det är ungefär som en liten lathund som säger att, låt oss säga, resume.doc, 565 00:35:35,400 --> 00:35:40,920 så ditt CV i ett Microsoft Word-fil som används för att leva på plats 123 på hårddisken, 566 00:35:40,920 --> 00:35:43,710 inte i minnet och inte i RAM utan på hårddisken, 567 00:35:43,710 --> 00:35:49,050 och dina skissartade JPEG bor på 456, och din Excel-fil bor på 789 eller varifrån. 568 00:35:49,050 --> 00:35:53,640 När du tar bort filer genom att faktiskt tömma papperskorgen eller papperskorgen, 569 00:35:53,640 --> 00:35:59,530 bilden ändras inte. Den 0 och 1 på hårddisken inte gå någonstans. 570 00:35:59,530 --> 00:36:03,930 Men denna tabell, denna lilla databas av slag, gör förändring. 571 00:36:03,930 --> 00:36:08,750 När du tar bort ditt CV är det som om filen tas bort i någon mening, 572 00:36:08,750 --> 00:36:12,790 men alla Datorn glömmer är där den där saken lever på din hårddisk. 573 00:36:12,790 --> 00:36:17,870 Den 0 och 1 som komponera ditt CV eller några av dessa andra filer är fortfarande intakt. 574 00:36:17,870 --> 00:36:21,960 >> Så om du gjorde detta av misstag, det finns fortfarande en icke-noll sannolikhet 575 00:36:21,960 --> 00:36:25,800 att du kan återställa dina data med Norton Utilities eller någon kommersiell programvara 576 00:36:25,800 --> 00:36:29,810 vars syfte i livet är att hitta 0 och 1 som typ av blivit föräldralösa, 577 00:36:29,810 --> 00:36:33,300 glömt här men kvar här, så att du kan få dina data tillbaka. 578 00:36:33,300 --> 00:36:38,410 Eller kriminaltekniska utredare med polisen eller FBI skulle faktiskt ta en hårddisk 579 00:36:38,410 --> 00:36:42,550 och faktiskt leta efter mönster av 0 och 1 som ser ut som JPEG, ser ut som Excel-filer, 580 00:36:42,550 --> 00:36:46,400 och återställa dem så även om datorn har glömt dem där. 581 00:36:46,400 --> 00:36:49,820 Så det enda sättet att verkligen ta bort data, som vi kommer att diskutera i framtiden, 582 00:36:49,820 --> 00:36:54,190 är att skrubba eller torka filen eller hårddisken - 583 00:36:54,190 --> 00:36:56,540 Du kan inte riktigt bli av med 0 och 1 584 00:36:56,540 --> 00:36:59,440 annars skulle du börja med en gigabyte hårddisk 585 00:36:59,440 --> 00:37:02,380 och du skulle sluta med en megabyte hårddisk om du ständigt skulle bort, 586 00:37:02,380 --> 00:37:04,380 bokstavligen, 0 och 1. 587 00:37:04,380 --> 00:37:06,310 Så vad skulle du göra om du verkligen ville täcka dina spår 588 00:37:06,310 --> 00:37:10,510 och det grundläggande problemet är att det finns fortfarande 0 och 1 på disken? 589 00:37:10,510 --> 00:37:14,930 Jag ser någon gestikulerade att du fysiskt skulle bryta enheten. Det kommer att fungera. 590 00:37:14,930 --> 00:37:19,600 [Skratt] Men om det är typ av en dyr lösning, vad skulle vara mer rimligt? 591 00:37:19,600 --> 00:37:23,270 Ja. >> [Elev] Skriv över dem. >> Överskrivning dem med vad? >> [Elev] Övriga uppgifter. 592 00:37:23,270 --> 00:37:29,070 Andra data. Du kan bara skriva din disk med 0s eller 1s eller alla 0: or, alla 1s. 593 00:37:29,070 --> 00:37:31,230 >> Och det är faktiskt vad vissa av programvaran gör. 594 00:37:31,230 --> 00:37:33,570 Du kan köpa programvara eller ens få fri programvara, 595 00:37:33,570 --> 00:37:36,610 och även inbyggt i Mac OS nuförtiden, mindre i Windows, 596 00:37:36,610 --> 00:37:38,660 är förmågan att säkert radera. 597 00:37:38,660 --> 00:37:41,960 Egentligen, om du vill alla kör hem idag om du har en Mac och göra detta, 598 00:37:41,960 --> 00:37:45,740 om du har lite grejer i din papperskorg, kan du göra säker Töm papperskorgen, 599 00:37:45,740 --> 00:37:47,610 som gör just detta. 600 00:37:47,610 --> 00:37:53,350 Snarare än att bara radera filer här, inte radera den inte 0 och 1 här, 601 00:37:53,350 --> 00:38:01,240 Snarare ändrar den bara dem alla, t.ex. för att 0s och punkt, punkt, punkt. 602 00:38:01,240 --> 00:38:05,330 Så en av dina framtida psets faktiskt kommer att vara att avsiktligt återställa data - 603 00:38:05,330 --> 00:38:08,430 fotografier som vi har tagit av människor, platser och saker på campus 604 00:38:08,430 --> 00:38:12,810 som vi ska göra en rättsmedicinsk bild av en digitalkamera minneskort, 605 00:38:12,810 --> 00:38:17,120 vilket är exakt samma idé - och du måste utmanas att faktiskt hitta 606 00:38:17,120 --> 00:38:20,160 de mönster som representerar JPEG på din hårddisk, 607 00:38:20,160 --> 00:38:23,610 ungefär som att tidigare student vars e-post jag läste för några veckor sedan gjorde 608 00:38:23,610 --> 00:38:25,860 att återvinna sin systers fotografier. 609 00:38:25,860 --> 00:38:30,300 Varför tar vi inte en 5-minuters paus här, och vi kommer omgruppera med mer på minnet. 610 00:38:33,030 --> 00:38:38,610 Så här är där det blir lite kluriga, men detta är en mycket kraftfull steg 611 00:38:38,610 --> 00:38:40,480 till att förstå detta desto mer. 612 00:38:40,480 --> 00:38:42,900 Här är ett program som heter pointers.c. 613 00:38:42,900 --> 00:38:45,430 Det är bland dagens exempelkod. 614 00:38:45,430 --> 00:38:51,280 Observera att i de första raderna, 19 till 22, är allt vi gör något liknande GetString 615 00:38:51,280 --> 00:38:54,460 och returnera en adress, lagra den i s.. 616 00:38:54,460 --> 00:38:58,380 Hädanefter för pset även 3 om du vill men pset 4 och på 617 00:38:58,380 --> 00:39:01,030 där du kan börja ta dessa stödhjul utanför dig själv, 618 00:39:01,030 --> 00:39:04,030 finns det ingen anledning att låtsas att strängar finns längre. 619 00:39:04,030 --> 00:39:07,030 Det är verkligen okej att bara börja säga char *. 620 00:39:07,030 --> 00:39:12,610 >> Som en sidoreplik, i online referenser och i böcker kan ofta se stjärnan bredvid variabel. 621 00:39:12,610 --> 00:39:15,600 Du kan även se utrymmen runt båda sidor. 622 00:39:15,600 --> 00:39:17,680 Alla dessa är funktionellt korrekta. 623 00:39:17,680 --> 00:39:21,180 För nu, men vi standardisera på denna metod för att göra Super Clear 624 00:39:21,180 --> 00:39:24,000 att char * är som att säga karaktär pekare. 625 00:39:24,000 --> 00:39:25,680 Det är datatypen. 626 00:39:25,680 --> 00:39:28,730 Och sedan namnet på variabeln är s i detta fall. 627 00:39:28,730 --> 00:39:31,180 Så vi har fått en sträng och vi har kallat det s. 628 00:39:31,180 --> 00:39:35,180 Och sedan ner hit märker att jag gör faktiskt lite knep. 629 00:39:35,180 --> 00:39:39,080 Detta kallas pekare aritmetik, vilket är en slags super enkelt. 630 00:39:39,080 --> 00:39:41,790 Det betyder bara addera och subtrahera tal till pekare. 631 00:39:41,790 --> 00:39:43,660 Men detta fungerar faktiskt. 632 00:39:43,660 --> 00:39:49,170 Detta program skriver tydligen strängen s 1 tecken per rad så att slutresultatet - 633 00:39:49,170 --> 00:39:54,920 Bara så vi kan förstöra där detta går, göra pekare, köra pekare, låt mig zooma in 634 00:39:54,920 --> 00:39:58,940 Låt mig typ i något som hej och typ Enter 635 00:39:58,940 --> 00:40:01,080 och det skrivs 1 tecken per rad. 636 00:40:01,080 --> 00:40:04,730 Fram till för en sekund sedan, skulle vi ha gjort detta med hakparentes notation. 637 00:40:04,730 --> 00:40:09,760 Vi skulle ha en for-slinga, och vi skulle göra printf av s [i] och vi skulle göra det igen och igen och igen 638 00:40:09,760 --> 00:40:11,950 med ett omvänt snedstreck n vid slutet av varje rad. 639 00:40:11,950 --> 00:40:16,800 Men detta program är annorlunda. Detta program använder, bokstavligen, aritmetik. 640 00:40:16,800 --> 00:40:18,860 Så vad händer här? 641 00:40:18,860 --> 00:40:24,720 Först av allt, innan denna slinga ens körs, vad, bara för att vara tydlig, är s egentligen? 642 00:40:24,720 --> 00:40:27,270 S är? >> [Elev] En adress. >> En adress. 643 00:40:27,270 --> 00:40:32,980 >> Och det är adressen, i fallet med hej, det första tecknet i det ordet, vilket är h.. 644 00:40:32,980 --> 00:40:37,370 Så s är, i detta särskilda exempel, adress timmar. 645 00:40:37,370 --> 00:40:41,850 Så vad innebär det att göra s + i? 646 00:40:41,850 --> 00:40:46,280 Tja, börjar jag i 0 i detta for-slinga. Vi har gjort det många gånger. 647 00:40:46,280 --> 00:40:49,760 Jag kommer att gå upp till längden på strängen, tydligen. 648 00:40:49,760 --> 00:40:53,950 Så på den första iteration av denna slinga är jag naturligtvis 0. 649 00:40:53,950 --> 00:41:01,740 Så detta uttryck säger s + i - snarare s +0--det är uppenbarligen bara är. 650 00:41:01,740 --> 00:41:04,320 Så vad är * är här? 651 00:41:04,320 --> 00:41:08,530 Nu vi använder stjärnan i ett något annorlunda sätt. 652 00:41:08,530 --> 00:41:13,080 Låt mig gå vidare och bli av med t eftersom vi är klara talar om t och kopior av s. 653 00:41:13,080 --> 00:41:15,540 Nu vill vi bara att berätta en historia där s. 654 00:41:15,540 --> 00:41:20,090 Och så i detta ögonblick, efter att ha typen String, ser vår värld helt som det gjorde innan 655 00:41:20,090 --> 00:41:26,630 med bara s lagra adress h och mer allmänt pekar på strängen hej. 656 00:41:26,630 --> 00:41:33,170 Om jag nu gör en rad som * (s + i), låt oss prova detta. 657 00:41:33,170 --> 00:41:40,140 Så * (s + i). Låt mig förenkla detta eftersom det är 0, så detta är * (S +0). 658 00:41:40,140 --> 00:41:43,790 Jo, vänta en minut. Ytterligare förenkla. Detta är * (er). 659 00:41:43,790 --> 00:41:47,020 Nåväl, nu parentes är typ av dum, så nu ska vi bara göra * s. 660 00:41:47,020 --> 00:41:50,540 Så i det första variant av denna slinga, den linjen som är markerad, 26, 661 00:41:50,540 --> 00:41:53,650 är ganska mycket motsvarar skriva detta. 662 00:41:53,650 --> 00:41:56,040 Vad är datatypen för * s? 663 00:41:56,040 --> 00:42:00,770 I detta sammanhang, eftersom stjärnan råkar vara bredvid s själva, 664 00:42:00,770 --> 00:42:04,930 men mer specifikt, eftersom vi inte längre förklara s 665 00:42:04,930 --> 00:42:09,730 vi inte skapar en variabel längre, det finns inget omnämnande av char * i linje 26, 666 00:42:09,730 --> 00:42:14,280 Det finns inget omnämnande av sökordet strängen använder vi bara en variabel som heter s, 667 00:42:14,280 --> 00:42:19,650 det visar sig nu stjärnan har något annorlunda och visserligen förvirrande mening. 668 00:42:19,650 --> 00:42:26,590 * S betyder här att gå till adressen i S och skriva ut allt finns där. 669 00:42:26,590 --> 00:42:33,750 Så s är här, * s - ungefär som rännor och stegar, följ pilen - här. 670 00:42:33,750 --> 00:42:35,850 Så detta är * s. 671 00:42:35,850 --> 00:42:39,060 >> Så vad blir tryckt på den första iteration av den slinga i linje 26? 672 00:42:39,060 --> 00:42:42,170 Jag skriver ut% c, som är platshållare för ett tecken, 673 00:42:42,170 --> 00:42:48,520 sedan en \ n för en ny linje. * (S + i) där i är 0 är just detta. 674 00:42:48,520 --> 00:42:53,670 Så vad röding lägger jag in för% c? H. 675 00:42:53,670 --> 00:42:56,900 I nästa iteration av slingan - du kan nog se vart detta kommer - 676 00:42:56,900 --> 00:43:01,350 nästa iteration i är uppenbarligen 1, så detta innebär s +1, 677 00:43:01,350 --> 00:43:05,580 och så nu jag behöver parenteserna för nu stjärnan behöver säga 678 00:43:05,580 --> 00:43:08,620 gå till minnesadress s +1. 679 00:43:08,620 --> 00:43:14,170 Vad är s? Låt oss rulla tillbaka i tiden och säga detta pil nu faktiskt inte gör oss några favörer. 680 00:43:14,170 --> 00:43:18,450 Låt oss mer specifikt säga att detta lagrar numret 123 681 00:43:18,450 --> 00:43:25,110 eftersom starten av denna sträng hej, är denna adress 123, är denna 124, och så vidare. 682 00:43:25,110 --> 00:43:30,550 Så på den andra iterationen när jag säger er en, det är som att säga 123 1, 683 00:43:30,550 --> 00:43:35,340 annars känd som 124, så vad röding blir tryckt på den andra iterationen? 684 00:43:35,340 --> 00:43:37,850 E vid minnesadress 124. 685 00:43:37,850 --> 00:43:44,440 Då + igen, 125, 126, 127, och denna slinga slutar tack och lov innan vi får här 686 00:43:44,440 --> 00:43:49,040 eftersom jag använder strlen att se till att jag inte räknas för högt. 687 00:43:49,040 --> 00:43:50,810 Så det är också det. 688 00:43:50,810 --> 00:43:55,000 Återigen, detta är bara som om vi hade gjort en vecka sedan. 689 00:43:55,000 --> 00:43:59,200 Låt mig skriva det på raden under, även om vi inte vill göra båda. 690 00:43:59,200 --> 00:44:02,500 Detta är identiskt nu detta. 691 00:44:02,500 --> 00:44:08,310 >> Så även om s är en sträng, som vi har kalla det i veckor, är är verkligen en char *. 692 00:44:08,310 --> 00:44:13,270 Så om vi vill vara super anal, det är verkligen lämpligt att skriva den särskilda karaktären 693 00:44:13,270 --> 00:44:17,490 vid den i: te platsen med hjälp av dessa numeriska adresser och denna stjärna operatör, 694 00:44:17,490 --> 00:44:20,470 men ärligt talat, det är bara så mycket renare. Så detta är inte dåligt. 695 00:44:20,470 --> 00:44:26,720 Ingen anledning att sluta göra linjen 27 här, men 26 är funktionellt densamma, 696 00:44:26,720 --> 00:44:31,570 och det är funktionellt samma för exakt de skäl som vi har diskuterat hittills. 697 00:44:31,570 --> 00:44:33,650 Och slutligen, är 29 bara god praxis. 698 00:44:33,650 --> 00:44:38,420 Ringa gratis s innebär att du nu är att ge tillbaka det minne som GetString gav dig 699 00:44:38,420 --> 00:44:41,630 eftersom igen, som jag nämnde måndag, getString flera veckor 700 00:44:41,630 --> 00:44:44,180 har inför en bugg i koden. 701 00:44:44,180 --> 00:44:46,490 Din kod i veckor haft minnesläckor 702 00:44:46,490 --> 00:44:49,970 där du har begärt GetString för minne, men du har aldrig varit att ge det tillbaka. 703 00:44:49,970 --> 00:44:53,410 Och det medvetet valdes av oss pedagogiskt 704 00:44:53,410 --> 00:44:55,880 eftersom det är alldeles för mycket att tänka på ett tidigt stadium. 705 00:44:55,880 --> 00:44:57,710 Men nu behöver vi mer symmetri. 706 00:44:57,710 --> 00:45:00,830 Om du frågar datorn för minnet, vilket är fallet för GetString, 707 00:45:00,830 --> 00:45:02,820 såsom är fallet uppenbarligen för malloc, 708 00:45:02,820 --> 00:45:07,970 måste du nu för pset 4 framåt också gratis sådan minne. 709 00:45:07,970 --> 00:45:11,650 Notera att detta är annorlunda från att säga int n. 710 00:45:11,650 --> 00:45:15,040 Du behöver inte att befria detta eftersom du inte ringde GetString 711 00:45:15,040 --> 00:45:16,890 och du inte ringa malloc. 712 00:45:16,890 --> 00:45:20,610 >> Och även om du heter getInt som vi kommer så småningom se, 713 00:45:20,610 --> 00:45:25,520 GetInt inte allokera inte minne för dig eftersom du faktiskt kan skicka runt heltal 714 00:45:25,520 --> 00:45:29,430 och flyter och tecken precis som vi har gjort i flera veckor. 715 00:45:29,430 --> 00:45:33,960 Strängar, men är speciella eftersom verkligen att de är sammanlänkningen av flera tecken. 716 00:45:33,960 --> 00:45:37,450 Så de är bara annorlunda tecken, flyter och Ints och liknande. 717 00:45:37,450 --> 00:45:39,980 Men vi kommer tillbaka till det inom kort. 718 00:45:39,980 --> 00:45:44,920 Eventuella frågor sedan om detta i början av pekare? Ja. 719 00:45:44,920 --> 00:45:49,690 [Ohörbart elev fråga] 720 00:45:49,690 --> 00:45:51,440 Ah, mycket bra fråga. 721 00:45:51,440 --> 00:45:55,790 En av de få saker som C faktiskt gör för dig, som är bekvämt, 722 00:45:55,790 --> 00:46:00,110 är det siffror för dig vilken storlek är av datatypen 723 00:46:00,110 --> 00:46:03,060 och gör då den typen av multiplikation för dig. 724 00:46:03,060 --> 00:46:06,610 Detta är irrelevant i fråga om tecken eftersom nästan alltid en röding är 1 byte, 725 00:46:06,610 --> 00:46:08,150 så detta fungerar bara. 726 00:46:08,150 --> 00:46:11,220 Men för den skull diskussionen, om du verkligen skriva heltal 727 00:46:11,220 --> 00:46:15,500 och du försöker skriva ut ett visst värde är som pekade på ett heltal, 728 00:46:15,500 --> 00:46:20,720 Du heller inte skulle behöva göra + 4 * jag bara för att en int är 4 bytes. 729 00:46:20,720 --> 00:46:25,780 Pointer aritmetiska innebär att C och kompilatorn göra allt matematik för dig. 730 00:46:25,780 --> 00:46:29,190 Allt du behöver bry sig om är räkningen i form av den mänskliga förnuft. Ja. 731 00:46:29,190 --> 00:46:35,200 [Elev] Om du deklarerar en sträng i en for-slinga, har du att frigöra den senare? 732 00:46:35,200 --> 00:46:36,760 Bra fråga. 733 00:46:36,760 --> 00:46:41,390 >> Om du deklarerat en sträng inne i for-slingan, behöver du frigöra det senare? 734 00:46:41,390 --> 00:46:47,520 Du behöver bara att frigöra minne som du fördela med GetString eller malloc. 735 00:46:47,520 --> 00:46:53,110 Så om du bara säga något i stil - låt mig ställa klammerparenteser nu så all kod är relaterad. 736 00:46:53,110 --> 00:46:58,580 Om du gjorde något, om än buggily, så här, char * t = s, 737 00:46:58,580 --> 00:47:03,450 du behöver inte fria t eftersom t inte innebar någon omnämnande av malloc eller GetString. 738 00:47:03,450 --> 00:47:08,960 Om däremot du gjorde det, GetString, så ja, skulle du behöva fri t. 739 00:47:08,960 --> 00:47:14,350 Och i själva verket är din enda chans att göra det nu inuti denna slinga, för samma nummer av omfattning 740 00:47:14,350 --> 00:47:16,060 att vi har diskuterat tidigare. 741 00:47:16,060 --> 00:47:18,830 Annars skulle du vara fördela minne, fördela minne, fördela minne, 742 00:47:18,830 --> 00:47:21,230 och i slutet av programmet eftersom du är utanför den slinga, 743 00:47:21,230 --> 00:47:24,240 t finns inte, men du har aldrig berättat operativsystemet 744 00:47:24,240 --> 00:47:26,750 att du inte behöver att minnet längre. 745 00:47:26,750 --> 00:47:30,430 Och snart för pset 4 eller 5 kommer vi förse dig med ett program som heter Valgrind, 746 00:47:30,430 --> 00:47:34,160 som likadana i andemening som GDB att det har fått något av en hemlig gränssnitt, 747 00:47:34,160 --> 00:47:35,750 men dess syfte i livet är att hjälpa dig. 748 00:47:35,750 --> 00:47:39,380 Och Valgrind är ett program som i framtiden kommer att söka dina program 749 00:47:39,380 --> 00:47:42,550 söker minnesläckor, oavsett om GetString eller malloc, 750 00:47:42,550 --> 00:47:47,800 som vi börjar använda allt mer som vi slutar använda CS50 biblioteket så mycket. 751 00:47:47,800 --> 00:47:53,030 Vi har äntligen nu slags ordförråd och den typ av mental modell i teorin 752 00:47:53,030 --> 00:47:55,170 som att lösa detta brutna programmet. 753 00:47:55,170 --> 00:47:59,410 >> Så i detta brutna programmet, fungerar swap inuti swap, 754 00:47:59,410 --> 00:48:05,280 men det aldrig fungerat i huvud eftersom huvud gick i x-och y, återkallande, 755 00:48:05,280 --> 00:48:07,260 och de antogs i av värden, så att säga. 756 00:48:07,260 --> 00:48:09,330 Kopior av dem gavs att byta. 757 00:48:09,330 --> 00:48:12,520 Vid slutet av swap hade a och b faktiskt bytts, 758 00:48:12,520 --> 00:48:16,120 men naturligtvis x och y, som vi diskuterade på måndagen, inte hade varit. 759 00:48:16,120 --> 00:48:19,940 Så jag föreslår i grönt här att detta är faktiskt en lösning här. 760 00:48:19,940 --> 00:48:22,640 Och faktiskt, låt mig flytta mina stjärnor bara för att vara konsekvent 761 00:48:22,640 --> 00:48:24,440 även om, återigen, funktionellt detta ingen roll. 762 00:48:24,440 --> 00:48:28,730 I framtiden veckorna kommer vi att förklara när och varför det spelar roll. 763 00:48:28,730 --> 00:48:30,600 Så i grönt nu är en lösning. 764 00:48:30,600 --> 00:48:33,700 Ärligt talat, det ser en hel del Messier eftersom jag har alla dessa stjärnor. 765 00:48:33,700 --> 00:48:35,380 Låt mig påpeka en sak. 766 00:48:35,380 --> 00:48:40,040 Den översta raden här där det står int * a och int * b 767 00:48:40,040 --> 00:48:42,820 är i grunden gör samma sak som det alltid har gjort. 768 00:48:42,820 --> 00:48:47,070 Det förklarar 2 argument eller parametrar att byta, 769 00:48:47,070 --> 00:48:49,940 av vilka den första är en int pekare kallas, 770 00:48:49,940 --> 00:48:53,100 den andra är en int pekare som heter b.. 771 00:48:53,100 --> 00:48:55,770 Det enda som är nytt på denna punkt är det faktum att det finns en stjärna där. 772 00:48:55,770 --> 00:48:59,340 >> Vad betyder det? A är inte en int, är b inte en int. 773 00:48:59,340 --> 00:49:04,100 A är adressen till en int och b är adressen till en annan int. 774 00:49:04,100 --> 00:49:06,980 Här nere är det här jag erkänna C blir förvirrande. 775 00:49:06,980 --> 00:49:09,790 Nu vi använder en stjärna, men det har olika innebörd i detta sammanhang. 776 00:49:09,790 --> 00:49:13,150 Eftersom vi inte förklara tips som vi är här uppe, 777 00:49:13,150 --> 00:49:15,500 Här är vi dereferencing saker. 778 00:49:15,500 --> 00:49:21,520 Så tekniskt, stjärnan i detta sammanhang för den första, andra och tredje raden inuti swap 779 00:49:21,520 --> 00:49:24,560 är att gå på dereference aktör och som bara innebär att det. 780 00:49:24,560 --> 00:49:27,400 Så precis som fingret följde på pilen för att h 781 00:49:27,400 --> 00:49:31,100 * Ett sätt att gå till den adressen och hitta mig int som finns där. 782 00:49:31,100 --> 00:49:34,250 * B innebär gå till adressen och skicka mig vad som finns där. 783 00:49:34,250 --> 00:49:40,730 Så låt oss rita bilden från måndag nu med en bunt ramar, 784 00:49:40,730 --> 00:49:43,130 den nedre av vilka kommer att vara huvud, 785 00:49:43,130 --> 00:49:47,600 den övre av vilka kommer att vara swap, 786 00:49:47,600 --> 00:49:50,880 så att vår värld ser ut precis som måndag, så här. 787 00:49:50,880 --> 00:49:53,620 Här är en bit av minne som främsta kommer att använda. 788 00:49:53,620 --> 00:49:56,520 >> Minns måndag att programmet bara hade 2 variabler, 789 00:49:56,520 --> 00:50:01,930 en som heter X och en som heter y och jag hade lagt siffrorna 1 och 2. 790 00:50:01,930 --> 00:50:06,580 Nu när jag ringer byta som jag gjorde i måndags, 791 00:50:06,580 --> 00:50:11,000 tidigare när jag använde den röda versionen av programmet, ser som så här, 792 00:50:11,000 --> 00:50:17,470 Jag fick 2 parametrar, a och b, och vad gjorde vi skriver här och här? 793 00:50:17,470 --> 00:50:21,160 Bara 1 och 2, bokstavligen kopior av x och y.. 794 00:50:21,160 --> 00:50:23,070 Idag har vi ändra på det. 795 00:50:23,070 --> 00:50:28,510 Idag istället för att passera i Ints a och b ska vi passera i 2 adresser. 796 00:50:28,510 --> 00:50:34,290 Dessa adresser råkar peka vare sin, men dessa adresser inte Ints själva. 797 00:50:34,290 --> 00:50:37,330 De är adresser. Det är som en postadress i stället. 798 00:50:37,330 --> 00:50:40,580 Så nu måste vi bara ge mig själv lite mer i detalj på skärmen. 799 00:50:40,580 --> 00:50:43,250 Det här är min dators minne som det har varit hela dagen. 800 00:50:43,250 --> 00:50:45,120 Nu behöver vi någon godtycklig numrering system. 801 00:50:45,120 --> 00:50:50,580 Så låt oss bara säga, bara av en slump, att detta är minnesadress 123, 124. 802 00:50:50,580 --> 00:50:55,660 Låt oss bara säga att detta är 125, det är 126, och så vidare, men det är helt godtycklig. 803 00:50:55,660 --> 00:50:58,590 Vi behöver bara lite numrering i mitt minne. 804 00:50:58,590 --> 00:51:04,030 Så nu när jag faktiskt passera i x och y, jag kommer inte att passera i x-och y; 805 00:51:04,030 --> 00:51:08,400 Jag ska passera i postadress, så att säga, av x och y 806 00:51:08,400 --> 00:51:11,870 så att det får lagras här och här är inte 1 och 2, 807 00:51:11,870 --> 00:51:16,030 men om du kan se min lilla text får vad gick in här och här? 808 00:51:16,030 --> 00:51:23,340 [Ohörbart elev svar] >> Exakt. 123 får sätta här och 124 får sätta här. 809 00:51:23,340 --> 00:51:28,910 >> Nu, eftersom jag använde stjärnan i denna allra första raden upp här på toppen, 810 00:51:28,910 --> 00:51:34,340 mitt program vet bara att 123 och 124, även om de är uppenbarligen heltal 811 00:51:34,340 --> 00:51:40,160 att någon människa skulle kunna märka, bör de tolkas som adresser, numeriska adresser. 812 00:51:40,160 --> 00:51:43,250 De är inte i sig själva Ints, de är adresser, 813 00:51:43,250 --> 00:51:46,120 och det är för att jag har uttryckligen sätta stjärnor där. 814 00:51:46,120 --> 00:51:51,360 Så nu i min första, andra och tredje raden av faktiska koden vad som händer här? 815 00:51:51,360 --> 00:51:53,380 Låt oss dra resten av bilden. 816 00:51:53,380 --> 00:51:56,980 Tmp är precis som det var på måndag. Inget särskilt om tmp. 817 00:51:56,980 --> 00:52:03,060 Det är bara en lokal 32 bitar variabel och inuti att jag tydligen lagra värdet av * en. 818 00:52:03,060 --> 00:52:08,580 Nu, om jag bara sagt tmp = a, vad skulle jag sätta här? >> [Elev] 123. 819 00:52:08,580 --> 00:52:10,370 123. Men det är inte vad jag gör. 820 00:52:10,370 --> 00:52:13,670 Jag säger tmp = * en. Star medel dit. 821 00:52:13,670 --> 00:52:19,370 Så här är en, 123. Hur går jag dit? Låtsas som det finns en pil. 822 00:52:19,370 --> 00:52:24,460 Tja, det är det, 1. Så vad får lagras i tmp, tydligen? Bara 1. 823 00:52:24,460 --> 00:52:29,620 Så med andra ord är TMP * a, * ett sätt att gå till den adress som befinner sig i en, 824 00:52:29,620 --> 00:52:31,320 vilket är tydligen 123. 825 00:52:31,320 --> 00:52:33,910 >> Okej, här är vi på plats 123, ser jag siffran 1, 826 00:52:33,910 --> 00:52:35,670 så jag ska sätta siffran 1 där. 827 00:52:35,670 --> 00:52:39,020 Nu vad gör jag i linje 2, * a = * b? 828 00:52:39,020 --> 00:52:44,570 Den här är lite mer engagerade för nu vad som är en? Det är 123. 829 00:52:44,570 --> 00:52:50,220 Så * en är där? Precis där jag var innan. Så gå dit. Okej. 830 00:52:50,220 --> 00:52:53,420 Nu slutligen och slutligen det börjar vettigt, förhoppningsvis, 831 00:52:53,420 --> 00:53:00,280 * B betyder vad som finns i b? 124. Så jag måste gå dit, vilket är 2. 832 00:53:00,280 --> 00:53:03,430 Så vad lägger jag var? 833 00:53:03,430 --> 00:53:10,100 2 går in här eftersom * b går in * en. Så jag ska göra det. 834 00:53:10,100 --> 00:53:13,120 Och du kan redan se, kanske att vi är så mycket närmare 835 00:53:13,120 --> 00:53:17,710 att lösa detta dumma, enkla problem korrekt för första gången 836 00:53:17,710 --> 00:53:20,920 för nu har vi fortfarande ett minne av vad X var, 837 00:53:20,920 --> 00:53:23,230 Vi har 2 kopior visserligen av y, 838 00:53:23,230 --> 00:53:25,850 men linje 3 säger nu * b. 839 00:53:25,850 --> 00:53:31,080 Så här är b.. * B innebär dit. Så var är platsen 124? 840 00:53:31,080 --> 00:53:35,560 Det är tydligen här. Så vad lägger jag här? Uppenbarligen, tmp. 841 00:53:35,560 --> 00:53:39,600 Så nu gör jag det. Så jag har en här och 2 här. 842 00:53:39,600 --> 00:53:43,560 Och nu vad om allt detta, 123, den 124 och 1? 843 00:53:43,560 --> 00:53:47,910 Så snart swap återvänder, är detta minne så gott som förlorad 844 00:53:47,910 --> 00:53:51,070 eftersom så snart swap avkastning, operativsystemet 845 00:53:51,070 --> 00:53:54,190 är fri att använda minnet igen i framtiden. 846 00:53:54,190 --> 00:53:58,870 Endast viktigaste minne längst ner på denna så kallade stack sticker runt. 847 00:53:58,870 --> 00:54:01,470 >> Och så har vi äntligen nu en fungerande version. 848 00:54:01,470 --> 00:54:06,310 Låt mig gå in swap.c, och märker följande. 849 00:54:06,310 --> 00:54:11,280 På toppen av det program jag har ändrat min prototyp som int * a och int * b.. 850 00:54:11,280 --> 00:54:15,000 Så det enda jag bytt för att gå från rött, som var dåligt, till grönt, vilket är bra, 851 00:54:15,000 --> 00:54:17,350 är jag lagt dessa stjärnor i dag. 852 00:54:17,350 --> 00:54:21,520 Men sedan här i byta själv var jag tvungen att kopiera, klistra det var bara på bilden. 853 00:54:21,520 --> 00:54:24,140 Jag har en stjärna här, stjärnan här - som matchar prototypen - 854 00:54:24,140 --> 00:54:27,930 och sedan alla dessa saker nu stjärnor utom TMP 855 00:54:27,930 --> 00:54:30,680 eftersom användningen av en temporär variabel, det är inget nytt där. 856 00:54:30,680 --> 00:54:33,040 Jag behöver bara tillfällig förvaring för en int. 857 00:54:33,040 --> 00:54:34,820 Så vi behöver inte en stjärna där. 858 00:54:34,820 --> 00:54:39,310 Vi behöver bara stjärnan så att vi kan korsa den här typen av godtyckliga gräns 859 00:54:39,310 --> 00:54:42,900 mellan dessa 2 bilder i min dators minne. 860 00:54:42,900 --> 00:54:45,630 Men en sista sak måste förändras, och du kanske har skymtat det redan. 861 00:54:45,630 --> 00:54:48,810 Vilka andra linjen är naturligtvis annorlunda nu? >> [Elev] & x. 862 00:54:48,810 --> 00:54:53,270 >> Ja, så 25 sista kodraden jag behöver ändra för att det ska fungera. 863 00:54:53,270 --> 00:54:58,360 För en vecka sedan och även på måndag linje 25 såg ut så här, byta x och y, 864 00:54:58,360 --> 00:55:02,020 och detta var bara bröts för om du säger swap (x, y) 865 00:55:02,020 --> 00:55:05,660 du ger kopior av x och y för att byta, så det gör sin grej, 866 00:55:05,660 --> 00:55:09,080 men du aldrig faktiskt förändras x-och y självt. 867 00:55:09,080 --> 00:55:12,880 Så även om du aldrig har sett denna karaktär innan med et-tecknet i koden, 868 00:55:12,880 --> 00:55:15,860 bara ta en gissning. Vad gör et-tecknet, tydligen? 869 00:55:15,860 --> 00:55:17,890 [Elev] Europaparlamentet adressen. >> Europaparlamentet adressen. 870 00:55:17,890 --> 00:55:21,160 Så et-tecknet säger ge mig adressen till x. 871 00:55:21,160 --> 00:55:25,590 Vem vet var det är? Det råkar vara 123. Jag bryr mig inte. Ge mig adressen till x. 872 00:55:25,590 --> 00:55:28,340 & Y betyder ge mig adressen till y.. 873 00:55:28,340 --> 00:55:34,450 Och vid den tidpunkten berättelsen är helt förenligt med den bild vi drog för en stund sedan. 874 00:55:34,450 --> 00:55:38,310 >> Så jag ska erkänna pekare, säkert för mig när jag först började lära mig detta, 875 00:55:38,310 --> 00:55:40,570 var definitivt en av de svåraste sakerna att linda mig runt. 876 00:55:40,570 --> 00:55:43,760 Men inser, särskilt som vi håller att leka med sådana här saker, 877 00:55:43,760 --> 00:55:48,030 Om du bryter ner det till dessa super enkla typ av intellektuellt ointressant problem 878 00:55:48,030 --> 00:55:52,270 att bara flytta siffror runt, svaret på en hel del förvirring med pekare 879 00:55:52,270 --> 00:55:56,590 verkligen kan härledas från dessa mycket grundläggande mekanik. 880 00:55:56,590 --> 00:55:59,070 Här är en adress. Gå dit med stjärnan. 881 00:55:59,070 --> 00:56:03,830 Eller omvänt, här en-tecken. Räkna ut vad adressen egentligen är. 882 00:56:03,830 --> 00:56:06,270 Okej. 883 00:56:06,270 --> 00:56:09,000 Så där är allt detta minne kommer från? 884 00:56:09,000 --> 00:56:12,360 Vi har ritat den här bilden ett par gånger, och jag håller lovande att vi ska komma tillbaka till det, 885 00:56:12,360 --> 00:56:14,920 men här är representationen av datorns minne 886 00:56:14,920 --> 00:56:17,420 Det är lite mer märkt än vår svarta tavlan här är. 887 00:56:17,420 --> 00:56:21,590 Texten segmentet överst representerar vad när det gäller ditt program? 888 00:56:21,590 --> 00:56:26,090 [Ohörbart elev svar] >> Ursäkta? Säg igen. 889 00:56:26,090 --> 00:56:28,660 [Elev] själva programmet. >> Själva programmet. 890 00:56:28,660 --> 00:56:32,430 >> Så 0s och 1s att du har sammanställt efter att ha skrivit C-kod och sedan köra klang 891 00:56:32,430 --> 00:56:35,910 och generera 0 och 1 avslutar upp att få stoppade det i minnet 892 00:56:35,910 --> 00:56:38,570 eftersom när du dubbelklickar på en ikon på din Mac eller PC 893 00:56:38,570 --> 00:56:43,010 eller köra ett kommando som Mario i din prompt, din 0 och 1 från disk 894 00:56:43,010 --> 00:56:45,700 få laddas in i minnet så att datorn kan manipulera dem 895 00:56:45,700 --> 00:56:47,540 och verkställa dem snabbare. 896 00:56:47,540 --> 00:56:50,880 Så initierade data och oinitierade uppgifter kommer vi att tala inte mycket om dem, 897 00:56:50,880 --> 00:56:52,420 men de är bara globala variabler. 898 00:56:52,420 --> 00:56:54,710 Initierat betyder globala variabler som du gav värden; 899 00:56:54,710 --> 00:56:59,300 oinitierad betyder globala variabler som du ännu inte gav värden. 900 00:56:59,300 --> 00:57:01,900 Sedan finns dessa miljövariabler som jag ska helt våg min hand på, 901 00:57:01,900 --> 00:57:04,860 men de finns där och som lagrar saker som ditt användarnamn 902 00:57:04,860 --> 00:57:08,090 och andra slags lägre nivå detaljer. 903 00:57:08,090 --> 00:57:12,880 Men de saftigaste bitarna av ditt minne layout är denna sak kallad stapeln och högen. 904 00:57:12,880 --> 00:57:17,470 Stapeln igen, att vara tydlig, är minnet som används när funktioner kallas, 905 00:57:17,470 --> 00:57:19,710 när det finns lokala variabler 906 00:57:19,710 --> 00:57:22,120 och när det finns parametrar som skickas runt. 907 00:57:22,120 --> 00:57:24,490 Allt som händer i stapeln. 908 00:57:24,490 --> 00:57:29,570 Högen vi inte pratat om, men ta en gissning som använder högen. 909 00:57:31,120 --> 00:57:32,690 Bara en annan bit av minnet. 910 00:57:32,690 --> 00:57:36,620 Det händer att dras här på toppen, men det är en godtycklig illustrerad konvention. 911 00:57:36,620 --> 00:57:41,670 Vem tydligen använt minne från högen i veckor? 912 00:57:41,670 --> 00:57:44,830 Det är tekniskt dig men indirekt. >> [Elev] GetString. 913 00:57:44,830 --> 00:57:47,950 GetString och malloc. Så här är den grundläggande skillnaden. 914 00:57:47,950 --> 00:57:51,300 >> Du vet de senaste veckorna att om du behöver minne, deklarera en variabel. 915 00:57:51,300 --> 00:57:54,560 Om du behöver massor av minne, förklarar en rad rätt inne i din funktion. 916 00:57:54,560 --> 00:57:59,620 Men problemet vi har hållit inför är om du deklarerar variabler lokalt inuti funktioner, 917 00:57:59,620 --> 00:58:05,340 så snart som funktionen returnerar, vad händer till minnet och de variabler? 918 00:58:05,340 --> 00:58:09,620 Bara sorts det inte längre din, eller hur? Det försvinner bara typ av konceptuellt. 919 00:58:09,620 --> 00:58:13,950 Det är fortfarande fysiskt där, naturligtvis, men det är inte längre din rätt att använda. 920 00:58:13,950 --> 00:58:17,160 Detta är naturligtvis problematiskt om du vill skriva funktioner i livet 921 00:58:17,160 --> 00:58:20,440 som faktiskt allokera minne och inte ge det tillbaka omedelbart. 922 00:58:20,440 --> 00:58:24,180 Ett typexempel: GetString s syfte i livet är att inte ha någon aning i förväg 923 00:58:24,180 --> 00:58:26,390 hur stor av en sträng ska jag skriva på tangentbordet, 924 00:58:26,390 --> 00:58:30,390 men det måste kunna allokera minne för att hålla David eller hej 925 00:58:30,390 --> 00:58:32,860 eller en hel uppsats som användaren kan ha skrivit in 926 00:58:32,860 --> 00:58:35,280 Så GetString har använt malloc. 927 00:58:35,280 --> 00:58:38,910 Malloc måste därför använder inte stacken, 928 00:58:38,910 --> 00:58:40,770 i stället är det med denna sak som kallas högen. 929 00:58:40,770 --> 00:58:44,430 Det finns inget annat om minnet. Det är inte snabbare eller långsammare eller nåt sånt. 930 00:58:44,430 --> 00:58:46,570 Det är bara fysiskt på en annan plats. 931 00:58:46,570 --> 00:58:50,120 >> Men regeln är att minnet som är fördelas på högen 932 00:58:50,120 --> 00:58:56,180 kommer aldrig tas ifrån dig tills du anropar - ta en gissning - gratis. 933 00:58:56,180 --> 00:59:00,510 Däremot något minne du ber om på stacken genom att bara förklara en rad 934 00:59:00,510 --> 00:59:03,320 eller förklara en variabel som vi har gjort i flera veckor, 935 00:59:03,320 --> 00:59:05,640 att som standard hamnar på stacken. 936 00:59:05,640 --> 00:59:09,550 Och det fungerar bra 90% av tiden, men på de mer sällsynta tillfällen 937 00:59:09,550 --> 00:59:12,470 där du vill allokera minne och hålla den runt, 938 00:59:12,470 --> 00:59:14,730 då du behöver använda en funktion som malloc. 939 00:59:14,730 --> 00:59:19,370 Eller har vi använt en funktion som GetString, vilket i sin tur använder malloc. 940 00:59:19,370 --> 00:59:23,300 Låt oss se om detta kan bryta ner och sedan ta en titt på Binky. 941 00:59:23,300 --> 00:59:25,820 Vi ska återkomma till detta i framtiden. 942 00:59:25,820 --> 00:59:29,270 Här är en super enkelt program som i de första 2 rader gör vad? 943 00:59:29,270 --> 00:59:33,460 På engelska, vad dessa första 2 rader kod gör inuti huvud? 944 00:59:33,460 --> 00:59:35,600 [Ohörbart elev svar] 945 00:59:35,600 --> 00:59:37,880 Försiktig. Det ger inte mig adressen till x eller y.. 946 00:59:37,880 --> 00:59:41,840 [Elev] Ger pekare vare sin. >> Bra. Ge mig 2 pekare till heltal. 947 00:59:41,840 --> 00:59:45,130 Med andra ord, ge mig 2 bitar av minne som jag håller teckning idag, 948 00:59:45,130 --> 00:59:46,950 även om jag raderat det nu, som fyrkanter. 949 00:59:46,950 --> 00:59:50,000 Ge mig 2 bitar av minne, som kallas en x, som kallas en y - 950 00:59:50,000 --> 00:59:54,320 tidigare jag kallade dem s och t - och vad som är den typ av denna bit av minnet? 951 00:59:54,320 --> 00:59:57,160 Det kommer att lagra en adress. 952 00:59:57,160 --> 00:59:59,110 Det är av typen int *. 953 00:59:59,110 --> 01:00:01,630 >> Så adressen för en int kommer så småningom leva i x, 954 01:00:01,630 --> 01:00:03,860 adressen för en int kommer så småningom leva i y, 955 01:00:03,860 --> 01:00:08,460 men i början, vad är inne i x-och y? Vem vet? Garbage värden. 956 01:00:08,460 --> 01:00:10,180 Det har ingenting att göra med pekare. 957 01:00:10,180 --> 01:00:12,720 Om vi ​​har inte satt något där, vem vet vad egentligen där? 958 01:00:12,720 --> 01:00:18,950 Nu, X. Vad händer här? Detta är legit nu eftersom x är en pekare. Det är en int *. 959 01:00:18,950 --> 01:00:21,870 Så det betyder att jag kan sätta i x adressen av någon bit av minnet. 960 01:00:21,870 --> 01:00:25,120 Vad återvänder malloc? Perfekt, returneras adresser, 961 01:00:25,120 --> 01:00:28,510 adressen för den första bitgruppen i en hel bit av minne. 962 01:00:28,510 --> 01:00:31,140 Hur många byte detta fördela tydligen, till exempel i skåpet? 963 01:00:31,140 --> 01:00:33,510 Vad är storleken på en int? 4. 964 01:00:33,510 --> 01:00:36,600 Om du tänker tillbaka på vecka 1, det är inte super viktigt att alltid komma ihåg att, 965 01:00:36,600 --> 01:00:38,870 men i detta fall är det bra att veta, 4 byte. 966 01:00:38,870 --> 01:00:41,770 Så detta avsätter på heap 4 byte 967 01:00:41,770 --> 01:00:46,110 och det återvänder adressen för den första att mig godtyckligt. 968 01:00:46,110 --> 01:00:47,700 Nu, vad X gör? 969 01:00:47,700 --> 01:00:52,200 A * x = 42 som gör vad? 970 01:00:52,200 --> 01:00:57,150 Om det vid denna punkt i berättelsen har vi x, som ser ut så här med några skräp värde, 971 01:00:57,150 --> 01:01:04,120 detta är nu y med vissa skräp värde, nu i linje 3 Jag har tilldelats 4 byte. 972 01:01:04,120 --> 01:01:06,950 Denna bild ser huvudsak så här. 973 01:01:06,950 --> 01:01:12,010 Eller mer specifikt, om detta är godtyckligt adress 123, det är vad vår berättelse nu ser ut. 974 01:01:12,010 --> 01:01:23,940 * X = 42 nu betyder vad? Det innebär att gå till adressen 123 och uppskattar antalet 42 där. 975 01:01:23,940 --> 01:01:26,220 Jag behöver inte dra dessa linjer eftersom vi inte gör strängar. 976 01:01:26,220 --> 01:01:29,480 >> Jag borde ha just skrivit det så här, och bara för demonstration skull, 977 01:01:29,480 --> 01:01:33,240 42 som en int typ av tar upp mycket utrymme, 4 byte. 978 01:01:33,240 --> 01:01:35,960 Så det är vad som har hänt där, men det finns ett problem nu. 979 01:01:35,960 --> 01:01:40,580 * Y = 13. Vad kommer att hända här? 980 01:01:40,580 --> 01:01:46,470 Problemet är * y i vår förenklade värld betyder bara att gå till adressen i y.. 981 01:01:46,470 --> 01:01:48,590 Vad finns i Y? Det är lite sopor värde. 982 01:01:48,590 --> 01:01:53,150 Så låt oss anta att det skräp värde är 5551212, något galet så. 983 01:01:53,150 --> 01:01:56,750 * Y betyder Gå till adress 5.551.212. 984 01:01:56,750 --> 01:02:00,450 Det är som här. Det finns inte, till exempel. 985 01:02:00,450 --> 01:02:05,310 Så * y blir 13 betyder jag försöker dra 13 här. Det existerar inte. 986 01:02:05,310 --> 01:02:08,790 Jag har överskridit segment av tavlan. Vad får jag? 987 01:02:08,790 --> 01:02:14,930 Det kryptiskt meddelande segmenteringsfel eftersom jag försöker sätta i minnet 988 01:02:14,930 --> 01:02:19,470 ett värde som 13 på en plats som inte finns. 989 01:02:19,470 --> 01:02:23,900 Resten av programmet kan fungera okej, men fram till den punkt det inte. 990 01:02:23,900 --> 01:02:25,350 Så låt oss försöka att berätta den här historien. 991 01:02:25,350 --> 01:02:27,830 Vi ska återkomma till detta när vi har pratat om hex. 992 01:02:27,830 --> 01:02:30,290 Låt oss gå tillbaka till detta och avsluta med denna sak som kallas Binky, 993 01:02:30,290 --> 01:02:33,710 vilket minns är en Stanford professor sitter hemma leker med Claymation, 994 01:02:33,710 --> 01:02:36,380 att berätta historien om exakt samma program. 995 01:02:36,380 --> 01:02:40,580 Det är bara ca 3 minuter långa. Här har vi Binky. 996 01:02:40,580 --> 01:02:45,030 [Manlig talare på video] Hey Binky, vakna. Det är dags för pekaren kul. 997 01:02:45,030 --> 01:02:50,080 [Binky] Vad är det? Lär dig mer om pekare? Åh, karamell! 998 01:02:50,080 --> 01:02:53,700 [Manlig talare] Jo, för att komma igång, jag antar att vi kommer att behöva ett par tips. 999 01:02:53,700 --> 01:02:57,890 >> [Binky] Okej. Denna kod tilldelar 2 pekare som kan peka till heltal. 1000 01:02:57,890 --> 01:03:02,220 [Manlig talare] Okej. Jag ser de 2 pekare, men de verkar inte vara att peka på någonting. 1001 01:03:02,220 --> 01:03:05,550 [Binky] Det stämmer. Inledningsvis tyder pekare inte till någonting. 1002 01:03:05,550 --> 01:03:09,270 De saker som de pekar på kallas pointees, och ställa upp dem är ett separat steg. 1003 01:03:09,270 --> 01:03:12,330 [Manlig talare] Åh, höger, höger. Jag visste det. De pointees är separata. 1004 01:03:12,330 --> 01:03:15,630 Er, så hur tilldela dig en pointee? 1005 01:03:15,630 --> 01:03:21,510 [Binky] Okej. Denna kod tilldelar en ny heltal pointee, och denna del set x peka på den. 1006 01:03:21,510 --> 01:03:23,500 [Manlig talare] Hej, det ser bättre ut. 1007 01:03:23,500 --> 01:03:26,030 Så gör det att göra något. >> [Binky] Okej. 1008 01:03:26,030 --> 01:03:30,300 Jag ska dereference pekaren X för att lagra numret 42 i sin pointee. 1009 01:03:30,300 --> 01:03:34,410 För detta trick jag behöver min trollstav av dereferencing. 1010 01:03:34,410 --> 01:03:38,610 [Manlig talare] Din trollstav för dereferencing? Det är bra. 1011 01:03:38,610 --> 01:03:44,230 [Binky] Detta är vad koden ser ut. Jag ska bara ställa in antalet och ... [Popping ljud] 1012 01:03:44,230 --> 01:03:46,100 [Manlig talare] Hej titta, där det går. 1013 01:03:46,100 --> 01:03:50,990 Så gör en dereference på x följer pilen för att komma åt sin pointee, 1014 01:03:50,990 --> 01:03:53,230 i detta fall för att lagra 42 där. 1015 01:03:53,230 --> 01:03:57,630 Hej, prova att använda den för att lagra numret 13 genom den andra pekaren, y. 1016 01:03:57,630 --> 01:04:03,250 [Binky] Okej. Jag ska bara gå hit till Y och få numret 13 inrättat 1017 01:04:03,250 --> 01:04:08,360 och sedan ta staven av dereferencing och bara ... [Surrande ljud] Whoa! 1018 01:04:08,360 --> 01:04:10,980 [Manlig talare] Åh hej, kom det inte fungerar. 1019 01:04:10,980 --> 01:04:14,870 >> Säg, Binky, jag tror inte dereferencing y är en bra idé 1020 01:04:14,870 --> 01:04:17,880 eftersom inrättandet av pointee är ett separat steg 1021 01:04:17,880 --> 01:04:19,850 och jag tror inte att vi någonsin gjorde det. 1022 01:04:19,850 --> 01:04:21,770 [Binky] Hmm, bra poäng. 1023 01:04:21,770 --> 01:04:26,640 [Manlig talare] Ja. Vi tilldelades pekaren y, men vi har aldrig satt det att peka på en pointee. 1024 01:04:26,640 --> 01:04:28,780 [Binky] Hmm, mycket uppmärksam. 1025 01:04:28,780 --> 01:04:30,690 [Manlig talare] Hej, du ser bra där, Binky. 1026 01:04:30,690 --> 01:04:34,160 Kan du fixa det så att y pekar på samma pointee som x? >> [Binky] Visst. 1027 01:04:34,160 --> 01:04:37,100 Jag använder min trollstav av pekare uppdrag. 1028 01:04:37,100 --> 01:04:39,070 [Manlig talare] Är det kommer att bli ett problem som förut? 1029 01:04:39,070 --> 01:04:40,840 [Binky] Nej, detta inte vidrör pointees. 1030 01:04:40,840 --> 01:04:44,780 Det förändrar bara en pekare att peka på samma sak som en annan. [Popping ljud] 1031 01:04:44,780 --> 01:04:48,570 [Manlig talare] Åh, ser jag. Nu y pekar på samma plats som x. 1032 01:04:48,570 --> 01:04:51,140 Så vänta. Nu y är fast. Den har en pointee. 1033 01:04:51,140 --> 01:04:54,520 Så du kan prova staven för dereferencing igen för att skicka 13 över. 1034 01:04:54,520 --> 01:04:58,130 [Binky] Eh, okej. Här går. [Popping ljud] 1035 01:04:58,130 --> 01:05:01,250 [Manlig talare] Titta på det. Nu dereferencing fungerar på y.. 1036 01:05:01,250 --> 01:05:05,200 Och eftersom pekare delar att en pointee de båda se 13. 1037 01:05:05,200 --> 01:05:06,910 [Binky] Ja, delning. Oavsett. 1038 01:05:06,910 --> 01:05:08,880 >> Så ska vi byta plats nu? 1039 01:05:08,880 --> 01:05:11,420 [Manlig talare] Oh titta, vi är ute i tid. >> [Binky] Men - 1040 01:05:11,420 --> 01:05:13,880 [Manlig talare] Kom bara ihåg de 3 pekaren reglerna. 1041 01:05:13,880 --> 01:05:18,630 Nummer 1 är den grundläggande strukturen att du har en pekare och det pekar på en pointee. 1042 01:05:18,630 --> 01:05:23,120 Men pekaren och pointee är separata, och vanligt fel är att inrätta en pekare 1043 01:05:23,120 --> 01:05:25,680 utan att glömma att ge det en pointee. 1044 01:05:25,680 --> 01:05:29,580 Nummer 2 börjar pekaren dereferencing på pekaren och följer dess pil över 1045 01:05:29,580 --> 01:05:31,060 att få tillgång till dess pointee. 1046 01:05:31,060 --> 01:05:34,340 Som vi alla vet, detta fungerar endast om det finns en pointee, 1047 01:05:34,340 --> 01:05:36,460 vilken typ av kommer tillbaka till regel nummer 1. 1048 01:05:36,460 --> 01:05:39,870 Nummer 3, tar pekaren uppgift en pekare och ändrar den 1049 01:05:39,870 --> 01:05:42,390 att peka på samma pointee som annan pekare. 1050 01:05:42,390 --> 01:05:45,890 Så efter uppdraget kommer de 2 pekare peka på samma pointee. 1051 01:05:45,890 --> 01:05:47,800 Ibland kallas delning. 1052 01:05:47,800 --> 01:05:50,910 >> Och det är allt som finns att det verkligen. Hejdå nu. 1053 01:05:50,910 --> 01:05:55,840 Detta är Binky. Detta är CS50. Vi ses nästa vecka. [Applåder] 1054 01:05:55,840 --> 01:05:59,000 >> [CS50.TV]