1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Vecka 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 [Detta är CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> Okej, det här CS50, och detta är början på vecka 4, 5 00:00:12,000 --> 00:00:16,000 och detta är en av de långsammaste möjliga sortering algoritmer. 6 00:00:16,000 --> 00:00:19,000 Vilket var det att vi bara sett det? 7 00:00:19,000 --> 00:00:24,000 Det var bubbla sortera, så Big O (n ^ 2) + summa, 8 00:00:24,000 --> 00:00:28,000 och faktiskt är vi inte de enda i denna värld att verka för att känna 9 00:00:28,000 --> 00:00:30,000 vilken bubbla sortera är eller dess gångtid. 10 00:00:30,000 --> 00:00:33,000 I själva verket var detta en intervju med Eric Schmidt på Google 11 00:00:33,000 --> 00:00:45,000 och tidigare senator Barack Obama för bara några år sedan. 12 00:00:45,000 --> 00:00:48,000 >> Nu senator, du är här på Google, 13 00:00:48,000 --> 00:00:54,000 och jag gillar att tänka på ordförandeskapet som en anställningsintervju. 14 00:00:54,000 --> 00:00:58,000 Nu är det svårt att få ett jobb som president, och du går igenom stelhet nu. 15 00:00:58,000 --> 00:01:00,000 Det är också svårt att få ett jobb på Google. 16 00:01:00,000 --> 00:01:05,000 Vi har frågor, och vi ber våra kandidater frågor, 17 00:01:05,000 --> 00:01:10,000 och detta är från Larry Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Ni tror att jag skojar? Det är precis här. 19 00:01:14,000 --> 00:01:18,000 Vad är det mest effektiva sättet att sortera en miljon 32-bitars heltal? 20 00:01:18,000 --> 00:01:21,000 [Skratt] 21 00:01:21,000 --> 00:01:24,000 Väl 22 00:01:24,000 --> 00:01:26,000 Jag är ledsen. >> Nej, nej, nej, nej. 23 00:01:26,000 --> 00:01:34,000 Jag tror att bubblan Sortera skulle vara fel väg att gå. 24 00:01:34,000 --> 00:01:39,000 >> Kom igen, som berättade honom det? 25 00:01:39,000 --> 00:01:43,000 Förra veckan minns vi tog en paus från kod, åtminstone för en dag, 26 00:01:43,000 --> 00:01:46,000 och började fokusera på några högre nivå idéer och problemlösning mer allmänt 27 00:01:46,000 --> 00:01:49,000 i samband med sökning och sortering, 28 00:01:49,000 --> 00:01:53,000 och vi introducerade något som vi inte slap detta namn på förra veckan, 29 00:01:53,000 --> 00:01:56,000 men asymptotiska notation, Big O, Big Omega, 30 00:01:56,000 --> 00:02:00,000 och ibland den stora Theta notation, och dessa var helt enkelt sätt 31 00:02:00,000 --> 00:02:02,000 att beskriva gångtid av algoritmer, 32 00:02:02,000 --> 00:02:05,000 hur mycket tid det tar för en algoritm för att köra. 33 00:02:05,000 --> 00:02:08,000 >> Och du kanske minns att du pratade om gångtid i termer av storlek 34 00:02:08,000 --> 00:02:11,000 av insignalen, som vi vanligtvis kallar N, vad problemet kan vara, 35 00:02:11,000 --> 00:02:13,000 där n är antalet personer i rummet, 36 00:02:13,000 --> 00:02:17,000 antalet sidor i en telefonbok, och vi började skriva saker 37 00:02:17,000 --> 00:02:21,000 som O (n ^ 2) eller O (n) eller O (n log n), 38 00:02:21,000 --> 00:02:24,000 och även när matten inte riktigt träna så perfekt 39 00:02:24,000 --> 00:02:28,000 och det var n ^ - n / 2 eller något liknande 40 00:02:28,000 --> 00:02:31,000 Vi skulle i stället bara kasta bort en del av de lägre ordningens termer, 41 00:02:31,000 --> 00:02:34,000 och motivationen finns att vi verkligen vill ha ett 42 00:02:34,000 --> 00:02:37,000 slags objektivt sätt att utvärdera 43 00:02:37,000 --> 00:02:39,000 prestanda program eller utförande av algoritmer 44 00:02:39,000 --> 00:02:42,000 att vid slutet av dagen har ingenting att göra, till exempel, 45 00:02:42,000 --> 00:02:45,000 med hastigheten på din dator idag. 46 00:02:45,000 --> 00:02:47,000 >> Till exempel, om du implementerar bubbla sortera, 47 00:02:47,000 --> 00:02:50,000 eller du genomför samman sortera eller val Sortera på dagens dator, 48 00:02:50,000 --> 00:02:53,000 en 2 GHz dator och du kör den, 49 00:02:53,000 --> 00:02:56,000 och det tar ett visst antal sekunder, nästa år finns en 3 GHz 50 00:02:56,000 --> 00:02:59,000 eller en 4 GHz dator, och du kan då hävda att "Wow, min algoritm 51 00:02:59,000 --> 00:03:03,000 är nu dubbelt så snabb ", när i själva verket det är naturligtvis inte fallet. 52 00:03:03,000 --> 00:03:06,000 Det är bara hårdvaran har blivit snabbare, men datorn 53 00:03:06,000 --> 00:03:10,000 har inte, och så vill vi verkligen att kasta bort saker som 54 00:03:10,000 --> 00:03:13,000 multiplar av 2 eller multipler av 3 när det gäller att beskriva 55 00:03:13,000 --> 00:03:17,000 hur snabbt eller hur långsamt en algoritm är och egentligen bara fokusera 56 00:03:17,000 --> 00:03:20,000 på n eller någon faktor därav, 57 00:03:20,000 --> 00:03:24,000 lite ström därav som i fallet med slag från förra veckan. 58 00:03:24,000 --> 00:03:27,000 Och minns att med hjälp av sammanslagning Sortera 59 00:03:27,000 --> 00:03:31,000 vi kunde göra så mycket bättre än bubbla sortera och välja Sortera 60 00:03:31,000 --> 00:03:33,000 och även införande sortera. 61 00:03:33,000 --> 00:03:36,000 >> Vi kom ner till n log n, och igen, 62 00:03:36,000 --> 00:03:39,000 ihåg att log n generellt refererar till något som växer 63 00:03:39,000 --> 00:03:43,000 långsammare sedan n, så n log n hittills var bra 64 00:03:43,000 --> 00:03:45,000 eftersom det var mindre än N ^. 65 00:03:45,000 --> 00:03:47,000 Men för att uppnå n log n med merge sort 66 00:03:47,000 --> 00:03:51,000 vad var det grundläggande fröet till en idé som vi var tvungna att utnyttja 67 00:03:51,000 --> 00:03:54,000 att vi belånade också tillbaka i vecka 0? 68 00:03:54,000 --> 00:03:58,000 Hur kunde vi ta itu med sortering problemet skickligt med merge sort? 69 00:03:58,000 --> 00:04:04,000 Vad var den viktigaste insikten, kanske? 70 00:04:04,000 --> 00:04:07,000 Någon alls. 71 00:04:07,000 --> 00:04:09,000 Okej, låt oss ta ett steg tillbaka. 72 00:04:09,000 --> 00:04:11,000 Beskriv samman Sortera med egna ord. 73 00:04:11,000 --> 00:04:15,000 Hur gick det? 74 00:04:15,000 --> 00:04:17,000 Okej, vi ro tillbaka till vecka 0. 75 00:04:17,000 --> 00:04:19,000 Okej, ja. 76 00:04:19,000 --> 00:04:22,000 [Ohörbart-student] 77 00:04:22,000 --> 00:04:26,000 Okej, bra, så vi delade matris med tal i 2 delar. 78 00:04:26,000 --> 00:04:29,000 Vi sorterade båda dessa delar, och sedan vi samman dem, 79 00:04:29,000 --> 00:04:33,000 och vi har sett denna idé tidigare att ta ett problem som det här stora 80 00:04:33,000 --> 00:04:36,000 och hugga upp den i ett problem som det här stora eller här stor. 81 00:04:36,000 --> 00:04:38,000 >> Minns exemplet telefonboken. 82 00:04:38,000 --> 00:04:42,000 Minns själv-räkningen algoritm från veckor sedan, 83 00:04:42,000 --> 00:04:45,000 så slå ihop sortera sammanfattade denna pseudokod här. 84 00:04:45,000 --> 00:04:48,000 När du gett n element, först var det förnuft kontrollera. 85 00:04:48,000 --> 00:04:51,000 Om n <2 då inte göra något alls 86 00:04:51,000 --> 00:04:55,000 eftersom om n <2 då n är givetvis 0 eller 1, 87 00:04:55,000 --> 00:04:57,000 och så om det är antingen 0 eller 1 det finns inget att sortera. 88 00:04:57,000 --> 00:04:59,000 Du är klar. 89 00:04:59,000 --> 00:05:01,000 Din lista är redan trivialt sorteras. 90 00:05:01,000 --> 00:05:04,000 Men annars om du har 2 eller flera element gå vidare och dela dem 91 00:05:04,000 --> 00:05:06,000 i 2 halvor, vänster och höger. 92 00:05:06,000 --> 00:05:09,000 Sortera varje av dessa halvor och sedan slå ihop de sorterade halvorna. 93 00:05:09,000 --> 00:05:13,000 Men problemet här är att vid första anblicken detta känns som om vi punting. 94 00:05:13,000 --> 00:05:17,000 Detta är en cirkulär definition att om jag bad dig att sortera dessa n element 95 00:05:17,000 --> 00:05:22,000 och du säger "Okej, bra, vi sorterar de n / 2 och de N / 2 element," 96 00:05:22,000 --> 00:05:27,000 då min nästa fråga kommer att vara "Fint, hur du sorterar n / 2 element?" 97 00:05:27,000 --> 00:05:30,000 >> Men på grund av strukturen av detta program, 98 00:05:30,000 --> 00:05:33,000 eftersom det är denna basfallet, så att säga, 99 00:05:33,000 --> 00:05:39,000 detta speciella fall som säger att om n 00:05:42,000 Svarar inte med samma cirkulära svar. 101 00:05:42,000 --> 00:05:46,000 Denna process kommer detta Konjunkturberoende sluta så småningom. 102 00:05:46,000 --> 00:05:50,000 Om jag ber dig "sortera dessa n element", och du säger: "Fine, sortera dessa n / 2," 103 00:05:50,000 --> 00:05:53,000 då du säger, "Fine, sortera dessa N / 4, n / 8, n/16," 104 00:05:53,000 --> 00:05:56,000 så småningom kommer du dela med ett tillräckligt stort antal 105 00:05:56,000 --> 00:05:59,000 att du har bara 1 del kvar, då du kan säga, 106 00:05:59,000 --> 00:06:02,000 "Här, här är en sorterad enda element." 107 00:06:02,000 --> 00:06:06,000 Sedan briljans av denna algoritm upp här är att härleda från det faktum 108 00:06:06,000 --> 00:06:09,000 att när du har alla dessa individuellt sorterade listor, 109 00:06:09,000 --> 00:06:12,000 vilka alla är av storlek 1, som tycks vara meningslöst, 110 00:06:12,000 --> 00:06:15,000 när du börjar slå samman dem och sammanfoga dem 111 00:06:15,000 --> 00:06:19,000 du bygga upp slutligen som Rob gjorde i videon en slutligen sorterad lista. 112 00:06:19,000 --> 00:06:22,000 >> Men denna idé sträcker sig långt utanför sortering. 113 00:06:22,000 --> 00:06:26,000 Det är denna idé inbäddad i programmet kallas rekursion, 114 00:06:26,000 --> 00:06:29,000 tanken där du är ett program, 115 00:06:29,000 --> 00:06:32,000 och lösa vissa problem du kallar dig själv, 116 00:06:32,000 --> 00:06:36,000 eller sätta i samband med programspråk du är en funktion, 117 00:06:36,000 --> 00:06:39,000 och för att lösa ett problem, du funktionen kallar dig 118 00:06:39,000 --> 00:06:42,000 igen och igen och igen, men du funktionen 119 00:06:42,000 --> 00:06:44,000 kan inte kalla dig oändligt många gånger. 120 00:06:44,000 --> 00:06:47,000 Så småningom måste du botten, så att säga, 121 00:06:47,000 --> 00:06:49,000 och har en del hårdkodad bas tillstånd som säger 122 00:06:49,000 --> 00:06:53,000 vid denna tidpunkt sluta kalla dig så att hela processen 123 00:06:53,000 --> 00:06:56,000 Slutligen hindrar faktiskt. 124 00:06:56,000 --> 00:06:58,000 Vad betyder detta egentligen till recurse? 125 00:06:58,000 --> 00:07:01,000 >> Låt oss se om vi kan göra en enkel, trivialt exempel med, säg, 126 00:07:01,000 --> 00:07:03,000 3 personer med mig här på scenen, om någon är bekväm. 127 00:07:03,000 --> 00:07:06,000 1, kom upp, 2 och 3. 128 00:07:06,000 --> 00:07:09,000 Om du 3 vill komma upp hit. 129 00:07:09,000 --> 00:07:12,000 Om du vill stå bredvid mig här i en linje, antar att problemet till hands 130 00:07:12,000 --> 00:07:15,000 är räkna mycket trivialt antalet personer som är här. 131 00:07:15,000 --> 00:07:18,000 Men ärligt talat, jag är trött på alla dessa räknar exempel. 132 00:07:18,000 --> 00:07:21,000 Detta kommer att ta tid, 1, 2, och punkt, punkt, punkt. 133 00:07:21,000 --> 00:07:23,000 Det kommer att ta evigheter. 134 00:07:23,000 --> 00:07:25,000 Jag vill hellre bara punt problemet helt och hållet med hjälp av, vad heter du? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, okej. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly och? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly, och Willy. 138 00:07:31,000 --> 00:07:34,000 Just nu har jag ställt frågan av någon 139 00:07:34,000 --> 00:07:37,000 hur många människor är upp på denna scen och jag har ingen aning. 140 00:07:37,000 --> 00:07:40,000 Detta är en riktigt lång lista, och så istället ska jag göra detta trick. 141 00:07:40,000 --> 00:07:43,000 Jag ska be personen bredvid mig att göra det mesta av arbetet, 142 00:07:43,000 --> 00:07:46,000 och när hon är klar gör det mesta av arbetet 143 00:07:46,000 --> 00:07:49,000 Jag ska göra den minsta mängden arbete möjligt och bara lägga 1 144 00:07:49,000 --> 00:07:51,000 till vad hennes svar är, så nu kör vi. 145 00:07:51,000 --> 00:07:54,000 Jag har blivit tillfrågad om hur många personer är på scenen. 146 00:07:54,000 --> 00:07:57,000 Hur många personer är på scenen till vänster om dig? 147 00:07:57,000 --> 00:08:00,000 Vänster om mig? >> Okej, men inte fuska. 148 00:08:00,000 --> 00:08:04,000 Det är bra, det är riktigt, men om vi vill fortsätta denna logik 149 00:08:04,000 --> 00:08:08,000 låt oss anta att du på samma sätt vill stakbåten detta problem till vänster om dig, 150 00:08:08,000 --> 00:08:11,000 så i stället svara direkt gå vidare och bara vältra över ansvaret. 151 00:08:11,000 --> 00:08:14,000 Åh, hur många människor till vänster om mig? 152 00:08:14,000 --> 00:08:16,000 Hur många människor är till vänster? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Skratt] 155 00:08:27,000 --> 00:08:30,000 Okej, så 0, så vad nu Willy gjort 156 00:08:30,000 --> 00:08:33,000 är du tillbaka ditt svar denna riktning säger 0. 157 00:08:33,000 --> 00:08:36,000 Nu, vad ska du göra? >> 1. 158 00:08:36,000 --> 00:08:39,000 Okej, så du är 1, så att du säger: "Okej, jag kommer att lägga 1 159 00:08:39,000 --> 00:08:41,000 till vad Willys räkna var "så 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Du är nu 1 så ditt svar till just nu- 161 00:08:43,000 --> 00:08:45,000 1. >> Och mitt skulle vara 2. 162 00:08:45,000 --> 00:08:48,000 Bra, så du tar den tidigare svar 1, 163 00:08:48,000 --> 00:08:51,000 lägga den minimala mängden arbete du vill göra, vilket är en. 164 00:08:51,000 --> 00:08:55,000 Du har nu 2, och du sedan ge mig vilket värde? 165 00:08:55,000 --> 00:08:57,000 3, jag menar, ledsen, 2. 166 00:08:57,000 --> 00:08:59,000 Bra. 167 00:08:59,000 --> 00:09:02,000 >> Tja, vi hade 0 till vänster. 168 00:09:02,000 --> 00:09:05,000 Sedan hade vi 1, och sedan lägger vi till 2, 169 00:09:05,000 --> 00:09:07,000 och nu är du lämnar mig numret 2, 170 00:09:07,000 --> 00:09:10,000 och så jag säger, okej, +1, 3. 171 00:09:10,000 --> 00:09:13,000 Det finns faktiskt 3 personer som står bredvid mig på den här scenen, 172 00:09:13,000 --> 00:09:16,000 så vi kunde har uppenbarligen gjort detta mycket linjärt, 173 00:09:16,000 --> 00:09:19,000 mycket på det uppenbara sätt, men vad gjorde vi verkligen? 174 00:09:19,000 --> 00:09:21,000 Vi tog ett problem av storlek 3 initialt. 175 00:09:21,000 --> 00:09:24,000 Vi bröt sedan ner i ett problem av storlek 2, 176 00:09:24,000 --> 00:09:27,000 då ett problem av storlek 1, och sedan slutligen basfallet 177 00:09:27,000 --> 00:09:29,000 var verkligen, åh, det är ingen där, 178 00:09:29,000 --> 00:09:33,000 varvid Willy tillbaka praktiken en hårdkodad svar ett par gånger, 179 00:09:33,000 --> 00:09:36,000 och den andra bubblades sedan upp, bubblade upp, bubblade upp, 180 00:09:36,000 --> 00:09:39,000 och därefter genom tillsats i detta ytterligare 1 181 00:09:39,000 --> 00:09:41,000 Vi har genomfört denna grundläggande idé om rekursion. 182 00:09:41,000 --> 00:09:44,000 >> Nu, i det här fallet det verkligen inte lösa ett problem 183 00:09:44,000 --> 00:09:46,000 någon mer effektivt då vi har sett hittills. 184 00:09:46,000 --> 00:09:48,000 Men tänk om de algoritmer vi gjort på scenen hittills. 185 00:09:48,000 --> 00:09:51,000 Vi hade 8 papperslappar på tavlan, 186 00:09:51,000 --> 00:09:55,000 på video när Sean letade efter numret 7, och vad gjorde han egentligen gjort? 187 00:09:55,000 --> 00:09:58,000 Tja, gjorde han inte någon form av söndra och härska. 188 00:09:58,000 --> 00:10:01,000 Han gjorde inte någon form av rekursion. 189 00:10:01,000 --> 00:10:03,000 Snarare gjorde han just detta linjära algoritm. 190 00:10:03,000 --> 00:10:07,000 Men när vi introducerade idén av sorterade siffror på scenen lever förra veckan 191 00:10:07,000 --> 00:10:09,000 sedan hade vi denna instinkt att gå till mitten, 192 00:10:09,000 --> 00:10:13,000 då vi hade en mindre lista med storlek 4 eller annan lista över storlek 4, 193 00:10:13,000 --> 00:10:17,000 och sedan hade vi exakt samma problem, så vi upprepade upprepas upprepas. 194 00:10:17,000 --> 00:10:19,000 Med andra ord, recursed vi. 195 00:10:19,000 --> 00:10:24,000 Tack så mycket till våra 3 volontärer här för att visa rekursion med oss. 196 00:10:24,000 --> 00:10:28,000 >> Låt oss se om vi inte kan göra det nu lite mer konkret, 197 00:10:28,000 --> 00:10:30,000 lösa ett problem som vi återigen kunde göra ganska enkelt, 198 00:10:30,000 --> 00:10:34,000 men vi kommer att använda det som en språngbräda för att genomföra denna grundläggande idé. 199 00:10:34,000 --> 00:10:37,000 Om jag vill beräkna summan av en massa siffror, 200 00:10:37,000 --> 00:10:39,000 till exempel om du passerar i nummer 3, 201 00:10:39,000 --> 00:10:42,000 Jag vill ge dig värdet av Sigma 3, 202 00:10:42,000 --> 00:10:46,000 så summan av 3 + 2 + 1 + 0. 203 00:10:46,000 --> 00:10:48,000 Jag vill komma tillbaka svaret 6, 204 00:10:48,000 --> 00:10:51,000 så vi genomföra denna sigma funktion, denna summering funktion 205 00:10:51,000 --> 00:10:54,000 att återigen tar i indata och returnerar sedan summan 206 00:10:54,000 --> 00:10:57,000 av detta antal hela vägen ner till 0. 207 00:10:57,000 --> 00:10:59,000 Vi kan göra detta ganska enkelt, eller hur? 208 00:10:59,000 --> 00:11:01,000 Vi kan göra detta med någon form av looping struktur, 209 00:11:01,000 --> 00:11:04,000 så låt mig gå vidare och få detta igång. 210 00:11:04,000 --> 00:11:07,000 >> Inkludera stdio.h. 211 00:11:07,000 --> 00:11:09,000 Låt mig få mig in i huvud att arbeta med här. 212 00:11:09,000 --> 00:11:12,000 Låt oss spara detta som sigma.c. 213 00:11:12,000 --> 00:11:14,000 Sen ska jag gå in här, och jag kommer att förklara en int n, 214 00:11:14,000 --> 00:11:18,000 och jag ska göra följande medan användaren inte samarbetar. 215 00:11:18,000 --> 00:11:22,000 Medan användaren inte har gett mig ett positivt tal 216 00:11:22,000 --> 00:11:26,000 Låt mig gå vidare och få dem för n = getInt, 217 00:11:26,000 --> 00:11:28,000 och låt mig ge dem några instruktioner om vad de ska göra, 218 00:11:28,000 --> 00:11:33,000 så printf ("positivt heltal please"). 219 00:11:33,000 --> 00:11:39,000 Bara något relativt enkelt som detta så att när vi träffar ledningen 14 220 00:11:39,000 --> 00:11:42,000 Vi har nu ett positivt heltal förmodligen i n. 221 00:11:42,000 --> 00:11:44,000 >> Nu ska vi göra något med den. 222 00:11:44,000 --> 00:11:50,000 Låt mig gå vidare och beräkna summan, så int sum = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma är bara summering, så jag bara skriva det på avancerad vägen. 224 00:11:54,000 --> 00:11:56,000 Vi ska bara kalla det sigma där. 225 00:11:56,000 --> 00:11:58,000 Det är summan, och nu ska jag skriva ut resultatet, 226 00:11:58,000 --> 00:12:08,000 printf ("Summan är% d \ n", summa). 227 00:12:08,000 --> 00:12:11,000 Och sedan ska jag tillbaka 0 för bra åtgärd. 228 00:12:11,000 --> 00:12:15,000 Vi har gjort allt det här programmet kräver förutom den intressanta delen, 229 00:12:15,000 --> 00:12:18,000 vilket är att faktiskt genomföra sigma funktion. 230 00:12:18,000 --> 00:12:22,000 >> Låt mig gå ner hit till botten, och låt mig förklara funktionen Sigma. 231 00:12:22,000 --> 00:12:26,000 Det måste ta en variabel som är av typen heltal, 232 00:12:26,000 --> 00:12:30,000 och vad datatyp vill jag återvända förmodligen från Sigma? 233 00:12:30,000 --> 00:12:34,000 Int för att jag vill att det ska matcha mina förväntningar på linje 15. 234 00:12:34,000 --> 00:12:37,000 Här inne Låt mig gå vidare och genomföra detta 235 00:12:37,000 --> 00:12:41,000 på ett ganska enkelt sätt. 236 00:12:41,000 --> 00:12:45,000 >> Låt oss gå vidare och säga int summa = 0, 237 00:12:45,000 --> 00:12:47,000 och nu ska jag gå har lite för slinga här 238 00:12:47,000 --> 00:12:50,000 det kommer att säga något sådant, 239 00:12:50,000 --> 00:13:01,000 for (int i = 0; I <= antal, i + +) summa + = jag. 240 00:13:01,000 --> 00:13:05,000 Och då ska jag återvända summan. 241 00:13:05,000 --> 00:13:07,000 Jag kunde ha genomfört detta i ett antal olika sätt. 242 00:13:07,000 --> 00:13:09,000 Jag kunde ha använt en while-slinga. 243 00:13:09,000 --> 00:13:11,000 Jag kunde ha hoppat med summan variabeln om jag verkligen ville, 244 00:13:11,000 --> 00:13:15,000 men kort sagt, har vi bara en funktion som om jag inte goof förklarar summa är 0. 245 00:13:15,000 --> 00:13:18,000 Sen itererar från 0 till upp genom numret, 246 00:13:18,000 --> 00:13:23,000 och på varje iteration det tillägger att nuvarande värde till summan och återgår sedan summan. 247 00:13:23,000 --> 00:13:25,000 >> Nu finns det en liten optimering här. 248 00:13:25,000 --> 00:13:29,000 Detta är förmodligen en bortkastad steg, men så var det. Det är bra för nu. 249 00:13:29,000 --> 00:13:32,000 Vi är åtminstone vara noggrann och gå 0 hela vägen på upp. 250 00:13:32,000 --> 00:13:34,000 Inte mycket hårt och ganska enkelt, 251 00:13:34,000 --> 00:13:37,000 men det visar sig att med Sigma funktion vi har samma möjligheter 252 00:13:37,000 --> 00:13:39,000 som vi gjorde här på scenen. 253 00:13:39,000 --> 00:13:42,000 På scen vi räknade hur många människor var bredvid mig, 254 00:13:42,000 --> 00:13:47,000 men i stället om vi ville räkna antalet 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 ner till 0 vi kunde på samma sätt punt till en funktion 256 00:13:51,000 --> 00:13:55,000 att jag istället beskriva som rekursiv. 257 00:13:55,000 --> 00:13:57,000 Här låt oss göra en snabb förstånd kontrollera och se till att jag inte goof. 258 00:13:57,000 --> 00:14:00,000 >> Jag vet att det finns minst en sak i det här programmet som jag gjorde fel. 259 00:14:00,000 --> 00:14:04,000 När jag slog in kommer jag att få någon form av yelling på mig? 260 00:14:04,000 --> 00:14:06,000 Vad ska jag bli skrek åt om? 261 00:14:06,000 --> 00:14:11,000 Ja, jag glömde prototypen, så jag använder en funktion som kallas sigma på linje 15, 262 00:14:11,000 --> 00:14:16,000 men det är inte deklarerat förrän ledningen 22, så jag bäst proaktivt gå upp här 263 00:14:16,000 --> 00:14:22,000 och förklara en prototyp, och jag ska säga int sigma (int antal), och det är det. 264 00:14:22,000 --> 00:14:24,000 Det genomförs i botten. 265 00:14:24,000 --> 00:14:27,000 >> Eller annat sätt jag skulle kunna lösa detta, 266 00:14:27,000 --> 00:14:30,000 Jag kunde flytta funktionen uppe, vilket inte är dåligt, 267 00:14:30,000 --> 00:14:32,000 men åtminstone när programmen börjar bli långa, uppriktigt sagt, 268 00:14:32,000 --> 00:14:35,000 Jag tror att det finns ett värde i att alltid ha stora upptill 269 00:14:35,000 --> 00:14:38,000 så att du i läsaren kan öppna filen och sedan omedelbart se 270 00:14:38,000 --> 00:14:40,000 vad programmet gör utan att behöva söka igenom det 271 00:14:40,000 --> 00:14:42,000 söker det huvudsakliga funktion. 272 00:14:42,000 --> 00:14:49,000 Låt oss gå ner till min terminalfönster här, försöka göra Sigma gör Sigma, 273 00:14:49,000 --> 00:14:51,000 och jag skruvade upp här också. 274 00:14:51,000 --> 00:14:55,000 Implicit deklaration av funktion getInt betyder att jag har glömt att göra vad? 275 00:14:55,000 --> 00:14:57,000 [Ohörbart-student] 276 00:14:57,000 --> 00:15:00,000 Bra, så uppenbarligen ett vanligt misstag, så låt oss sätta upp detta här, 277 00:15:00,000 --> 00:15:04,000 cs50.h, och nu ska vi gå tillbaka till min terminalfönster. 278 00:15:04,000 --> 00:15:08,000 >> Jag rensa skärmen, och jag ska köra gör Sigma. 279 00:15:08,000 --> 00:15:11,000 Det verkar ha sammanställt. Låt mig nu kör sigma. 280 00:15:11,000 --> 00:15:15,000 Jag skriver i nummer 3, och jag fick 6, så inte en rigorös kontroll, 281 00:15:15,000 --> 00:15:18,000 men åtminstone det verkar fungera vid första anblicken, men nu ska vi slita isär, 282 00:15:18,000 --> 00:15:21,000 och låt oss utnyttja faktiskt idén om rekursion, igen, 283 00:15:21,000 --> 00:15:24,000 på ett mycket enkelt sammanhang så att i ett par veckor 284 00:15:24,000 --> 00:15:27,000 när vi börjar utforska snyggare datastrukturer än arrayer 285 00:15:27,000 --> 00:15:30,000 Vi har ett annat verktyg i verktygslådan som man kan 286 00:15:30,000 --> 00:15:33,000 manipulera dessa datastrukturer som vi får se. 287 00:15:33,000 --> 00:15:36,000 Detta är den iterativa tillvägagångssätt loop synsätt. 288 00:15:36,000 --> 00:15:39,000 >> Låt mig i stället nu göra detta. 289 00:15:39,000 --> 00:15:44,000 Låt mig i stället säga att summan av antalet 290 00:15:44,000 --> 00:15:48,000 ner till 0 är egentligen samma sak som 291 00:15:48,000 --> 00:15:53,000 nummer + sigma (nummer - 1). 292 00:15:53,000 --> 00:15:57,000 Med andra ord, precis som på scenen jag punted till varje människor bredvid mig, 293 00:15:57,000 --> 00:16:00,000 och de i sin tur hålls punting tills vi slutligen bottnade på Willy, 294 00:16:00,000 --> 00:16:03,000 som var tvungen att återvända en hårdkodad svar som 0. 295 00:16:03,000 --> 00:16:07,000 Här nu är vi på samma sätt punting till Sigma 296 00:16:07,000 --> 00:16:10,000 samma funktion som kallades ursprungligen, men det viktigaste insikten här 297 00:16:10,000 --> 00:16:12,000 är att vi inte kallar Sigma identiskt. 298 00:16:12,000 --> 00:16:14,000 Vi är inte passerar i n. 299 00:16:14,000 --> 00:16:17,000 Vi tydligt passerar i antal - 1, 300 00:16:17,000 --> 00:16:20,000 så en något mindre problem, något mindre problem. 301 00:16:20,000 --> 00:16:23,000 >> Tyvärr är detta inte riktigt en lösning ännu, och innan vi fixa 302 00:16:23,000 --> 00:16:26,000 vad som kan hoppa ut så självklart på några av er 303 00:16:26,000 --> 00:16:28,000 Låt mig gå vidare och köra göra. 304 00:16:28,000 --> 00:16:30,000 Det verkar att sammanställa okej. 305 00:16:30,000 --> 00:16:32,000 Låt mig köra Sigma med 6. 306 00:16:32,000 --> 00:16:37,000 Hoppsan, låt mig köra Sigma med 6. 307 00:16:37,000 --> 00:16:42,000 Vi har sett det här förut, om än oavsiktligt förra gången också. 308 00:16:42,000 --> 00:16:48,000 Varför fick jag denna kryptiska segmenteringsfel? Ja. 309 00:16:48,000 --> 00:16:50,000 [Ohörbart-student] 310 00:16:50,000 --> 00:16:53,000 Det finns ingen basfall, och mer specifikt, vad hände antagligen? 311 00:16:53,000 --> 00:16:58,000 Detta är ett symptom på vad beteende? 312 00:16:58,000 --> 00:17:00,000 Säg det lite högre. 313 00:17:00,000 --> 00:17:02,000 [Ohörbart-student] 314 00:17:02,000 --> 00:17:05,000 Det är en oändlig slinga effektivt och problemet med oändliga slingor 315 00:17:05,000 --> 00:17:08,000 när de omfattar rekursion i detta fall en funktion som kallar sig, 316 00:17:08,000 --> 00:17:10,000 vad som händer varje gång du ringer en funktion? 317 00:17:10,000 --> 00:17:13,000 Jo, tänker tillbaka på hur vi lade ut minnet i en dator. 318 00:17:13,000 --> 00:17:16,000 Vi sade att det finns denna bit av minnet som kallas stapeln som är längst ner, 319 00:17:16,000 --> 00:17:19,000 och varje gång du ringer en funktion lite mer minne får sätta 320 00:17:19,000 --> 00:17:24,000 på denna så kallade stacken med den funktionen lokala variabler eller parametrar, 321 00:17:24,000 --> 00:17:27,000 så om Sigma kallar sigma samtal Sigma kallar Sigma 322 00:17:27,000 --> 00:17:29,000  kallar Sigma där gör denna historia slut? 323 00:17:29,000 --> 00:17:31,000 >> Tja, det så småningom överskridanden den totala mängden 324 00:17:31,000 --> 00:17:33,000 minne som du har tillgång till din dator. 325 00:17:33,000 --> 00:17:37,000 Du överskridande det segment som du ska hålla sig inom, 326 00:17:37,000 --> 00:17:40,000 och du får denna segmenteringsfel, dumpade kärna, 327 00:17:40,000 --> 00:17:43,000 och vad kärnan dumpade betyder är att jag nu har en fil som heter kärna 328 00:17:43,000 --> 00:17:46,000 vilket är en fil som innehåller nollor och ettor 329 00:17:46,000 --> 00:17:49,000 som faktiskt i framtiden kommer att vara diagnostiskt användbar. 330 00:17:49,000 --> 00:17:52,000 Om det inte är uppenbart att du var ditt fel är 331 00:17:52,000 --> 00:17:54,000 kan du faktiskt göra lite kriminalteknisk analys, så att säga, 332 00:17:54,000 --> 00:17:58,000 på denna kärna dumpfilen, vilket återigen bara en massa nollor och ettor 333 00:17:58,000 --> 00:18:02,000 som representerar huvudsakligen läget i ditt program i minnet 334 00:18:02,000 --> 00:18:05,000 det ögonblick den kraschade på detta sätt. 335 00:18:05,000 --> 00:18:11,000 >> Den fixa här är att vi inte bara kan blint återvända Sigma, 336 00:18:11,000 --> 00:18:14,000 Antalet + Sigma en något mindre problem. 337 00:18:14,000 --> 00:18:16,000 Vi måste ha någon form av bas fallet här, 338 00:18:16,000 --> 00:18:19,000 och vad bör basfallet förmodligen? 339 00:18:19,000 --> 00:18:22,000 [Ohörbart-student] 340 00:18:22,000 --> 00:18:25,000 Okej, så länge antalet är positivt att vi borde faktiskt returnera denna, 341 00:18:25,000 --> 00:18:29,000 eller annorlunda uttryckt, om antalet är, säg, <= till 0 342 00:18:29,000 --> 00:18:32,000 vet du vad, jag ska gå vidare och returnera 0, 343 00:18:32,000 --> 00:18:36,000 ungefär som Willy gjorde, och annat, jag ska gå vidare 344 00:18:36,000 --> 00:18:41,000 och returnera detta, så det är inte så mycket kortare 345 00:18:41,000 --> 00:18:44,000 än den iterativa version som vi piskade upp först använda en for-slinga, 346 00:18:44,000 --> 00:18:48,000 men märker att det finns denna typ av elegans till det. 347 00:18:48,000 --> 00:18:51,000 Istället för att returnera ett visst antal och utför allt detta matte 348 00:18:51,000 --> 00:18:54,000 och lägga upp saker med lokala variabler 349 00:18:54,000 --> 00:18:57,000 du istället säger "Okej, om detta är en super lätt problem, 350 00:18:57,000 --> 00:19:01,000 som antalet är <0, låt mig genast tillbaka 0. " 351 00:19:01,000 --> 00:19:03,000 >> Vi kommer inte att bry stödja negativa tal, 352 00:19:03,000 --> 00:19:05,000 så jag ska hård kod värdet 0. 353 00:19:05,000 --> 00:19:08,000 Men annars, för att genomföra denna idé om att summera 354 00:19:08,000 --> 00:19:11,000 alla dessa siffror tillsammans kan du effektivt ta en liten bit 355 00:19:11,000 --> 00:19:14,000 ur problemet, ungefär som vi gjorde här på scenen, 356 00:19:14,000 --> 00:19:18,000 då punt resten av problemet till nästa person, 357 00:19:18,000 --> 00:19:20,000 men i detta fall nästa person är själv. 358 00:19:20,000 --> 00:19:22,000 Det är en samma namn funktion. 359 00:19:22,000 --> 00:19:25,000 Bara ge det en mindre och mindre och mindre problem varje gång, 360 00:19:25,000 --> 00:19:28,000 och även om vi har inte riktigt formaliserade saker i koden här 361 00:19:28,000 --> 00:19:33,000 Detta är exakt vad som händer i veckan 0 med telefonboken. 362 00:19:33,000 --> 00:19:36,000 Detta är exakt vad som hände i senaste veckorna med Sean 363 00:19:36,000 --> 00:19:39,000 och med våra demonstrationer för att söka efter nummer. 364 00:19:39,000 --> 00:19:42,000 Det tar ett problem och dela det igen och igen. 365 00:19:42,000 --> 00:19:44,000 >> Med andra ord, det finns ett sätt nu att översätta 366 00:19:44,000 --> 00:19:47,000 denna verkliga världen konstruktion, denna högre nivå konstruktion 367 00:19:47,000 --> 00:19:51,000 av söndra och härska och göra något och om igen 368 00:19:51,000 --> 00:19:56,000 i kod, så detta är något vi kommer att se igen med tiden. 369 00:19:56,000 --> 00:20:00,000 Nu, som en sidoreplik, om du är ny till rekursion bör du åtminstone förstår nu 370 00:20:00,000 --> 00:20:02,000 varför detta är roligt. 371 00:20:02,000 --> 00:20:05,000 Jag ska gå till google.com, 372 00:20:05,000 --> 00:20:17,000 och jag kommer att söka efter några tips och tricks om rekursion skriver. 373 00:20:17,000 --> 00:20:21,000 Tala om för personen bredvid dig om de inte skrattar just nu. 374 00:20:21,000 --> 00:20:23,000 Menade du rekursion? 375 00:20:23,000 --> 00:20:25,000 Menade du-ah, där vi går. 376 00:20:25,000 --> 00:20:28,000 Okej, nu att resten av alla. 377 00:20:28,000 --> 00:20:30,000 Lite påskägg inbäddad någonstans där i Google. 378 00:20:30,000 --> 00:20:33,000 Som en sidoreplik, en av länkarna som vi sätter på kursens hemsida 379 00:20:33,000 --> 00:20:36,000 för idag är just detta nät av olika sortering algoritmer, 380 00:20:36,000 --> 00:20:39,000 av vilka vi tittade på i förra veckan, men vad är trevligt om denna visualisering 381 00:20:39,000 --> 00:20:43,000 som du försöker att slå dig runt olika saker relaterade till algoritmer 382 00:20:43,000 --> 00:20:46,000 vet att du kan mycket enkelt nu börja med olika typer av insatser. 383 00:20:46,000 --> 00:20:50,000 Ingångarna vände alla ingångar mesta sorteras, ingångarna slumpmässigt och så vidare. 384 00:20:50,000 --> 00:20:53,000 När du försöker igen, urskilja dessa saker i ditt sinne 385 00:20:53,000 --> 00:20:57,000 inse att denna URL på kursens hemsida på Föreläsningar sidan 386 00:20:57,000 --> 00:21:00,000 kan hjälpa dig anledning genom några av dem. 387 00:21:00,000 --> 00:21:05,000 >> Idag har vi äntligen lösa detta problem från en tid tillbaka, 388 00:21:05,000 --> 00:21:08,000 vilket var att denna swap funktionen fungerade bara inte, 389 00:21:08,000 --> 00:21:12,000 och vad som var det grundläggande problemet med denna funktion swap, 390 00:21:12,000 --> 00:21:15,000 vars mål var återigen byta ett värde här och här 391 00:21:15,000 --> 00:21:17,000 så att detta händer? 392 00:21:17,000 --> 00:21:20,000 Detta faktiskt inte fungerar. Varför? 393 00:21:20,000 --> 00:21:22,000 Ja. 394 00:21:22,000 --> 00:21:28,000 [Ohörbart-student] 395 00:21:28,000 --> 00:21:31,000 Exakt, förklaringen till detta bugginess 396 00:21:31,000 --> 00:21:34,000 bara var att när du ringer funktioner i C 397 00:21:34,000 --> 00:21:38,000 och dessa funktioner tar argument, som a och b här, 398 00:21:38,000 --> 00:21:42,000 du passerar i en kopia av det värde som du ger till den funktionen. 399 00:21:42,000 --> 00:21:46,000 Du är inte tillhandahåller de ursprungliga värdena själva, 400 00:21:46,000 --> 00:21:49,000 så vi såg detta i samband med buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, som såg lite ut så här. 402 00:21:52,000 --> 00:21:57,000 >> Minns att vi hade x och y initieras till 1 och 2, respektive. 403 00:21:57,000 --> 00:21:59,000 Vi skrivs sedan ut vad de var. 404 00:21:59,000 --> 00:22:03,000 Jag hävdade då att jag byta dem genom att ringa byte av x, y. 405 00:22:03,000 --> 00:22:06,000 Men problemet var att byta fungerade, 406 00:22:06,000 --> 00:22:10,000 men bara inom ramen för swappen fungerar själv. 407 00:22:10,000 --> 00:22:13,000 Så snart vi träffar ledningen 40 de bytt värden 408 00:22:13,000 --> 00:22:16,000 kastades bort och så ingenting 409 00:22:16,000 --> 00:22:21,000 i den ursprungliga funktionen viktigaste var faktiskt förändrats alls, 410 00:22:21,000 --> 00:22:26,000 så om du tror då vad detta ser ut när det gäller vårt minne 411 00:22:26,000 --> 00:22:29,000 om denna vänster sida av kortet representerar- 412 00:22:29,000 --> 00:22:33,000 och jag ska göra mitt bästa för att alla ska se detta, om det vänstra sidan av brädet 413 00:22:33,000 --> 00:22:37,000 representerar exempelvis ditt RAM-minne, och stapeln kommer att växa på upp detta sätt, 414 00:22:37,000 --> 00:22:43,000 och vi kallar en funktion som huvud, och viktigaste har 2 lokala variabler, x och y, 415 00:22:43,000 --> 00:22:48,000 låt oss beskriva dem som x här, och låt oss beskriva dessa som y här, 416 00:22:48,000 --> 00:22:55,000 och låt oss sätta i värdena 1 och 2, så detta här är stora, 417 00:22:55,000 --> 00:22:58,000 och när huvudsakliga anropar swap-funktionen i operativsystemet 418 00:22:58,000 --> 00:23:02,000 ger swap-funktionen en egen sträng minne på stacken, 419 00:23:02,000 --> 00:23:04,000 sin egen ram på stacken, så att säga. 420 00:23:04,000 --> 00:23:08,000 Det fördelar också 32 bitar för dessa Ints. 421 00:23:08,000 --> 00:23:11,000 Det händer att kalla dem A och B, men det är helt godtycklig. 422 00:23:11,000 --> 00:23:13,000 Det kunde ha kallat dem vad det vill, men vad händer när huvud 423 00:23:13,000 --> 00:23:19,000 samtal swap är det tar detta 1, sätter en kopia där sätter en kopia där. 424 00:23:19,000 --> 00:23:23,000 >> Det finns 1 annan lokal variabel i swap, men kallas vad? >> Tmp. 425 00:23:23,000 --> 00:23:27,000 Tmp, så låt mig ge mig ytterligare 32 bitar här, 426 00:23:27,000 --> 00:23:29,000 och vad gjorde jag i den här funktionen? 427 00:23:29,000 --> 00:23:34,000 Jag sa int tmp får en, så en har 1, så jag gjorde det när vi senast spelade med detta exempel. 428 00:23:34,000 --> 00:23:39,000 Sedan en blir B, så b är 2, så nu blir detta 2, 429 00:23:39,000 --> 00:23:42,000 och nu B får temp, så temp är 1, 430 00:23:42,000 --> 00:23:44,000 så nu B blir detta. 431 00:23:44,000 --> 00:23:46,000 Det är bra. Det fungerade. 432 00:23:46,000 --> 00:23:49,000 Men sedan så snart som funktionen returnerar 433 00:23:49,000 --> 00:23:52,000 swap minne försvinner effektivt så att den kan återanvändas 434 00:23:52,000 --> 00:23:58,000 av någon annan funktion i framtiden, och viktigaste är naturligtvis helt oförändrad. 435 00:23:58,000 --> 00:24:00,000 Vi behöver ett sätt att i grunden lösa detta problem, 436 00:24:00,000 --> 00:24:03,000 och idag ska vi äntligen har ett sätt att göra detta innebär att 437 00:24:03,000 --> 00:24:06,000 Vi kan införa något som kallas en pekare. 438 00:24:06,000 --> 00:24:09,000 Det visar sig att vi kan lösa detta problem 439 00:24:09,000 --> 00:24:12,000 inte genom passage i kopior av x-och y 440 00:24:12,000 --> 00:24:18,000 utan genom att i vad, tror du, att byta funktion? 441 00:24:18,000 --> 00:24:20,000 Ja, hur är adressen? 442 00:24:20,000 --> 00:24:22,000 Vi har inte riktigt pratat om adresser i stor detalj, 443 00:24:22,000 --> 00:24:25,000 men om denna tavlan är min dators minne 444 00:24:25,000 --> 00:24:28,000 Vi skulle säkert börja numreringen byte i min RAM 445 00:24:28,000 --> 00:24:31,000 och säga att detta är byte # 1, är detta byte # 2, byte # 3, 446 00:24:31,000 --> 00:24:35,000 byte # 4, byte # ... 2 miljarder om jag har 2 gigabyte RAM-minne, 447 00:24:35,000 --> 00:24:38,000 så vi kan säkert komma med några godtyckliga numreringsschema 448 00:24:38,000 --> 00:24:41,000 för alla enskilda bitgrupper i datorns minne. 449 00:24:41,000 --> 00:24:43,000 >> Vad händer om istället när jag pendling 450 00:24:43,000 --> 00:24:47,000 snarare än pass i kopior av x-och y 451 00:24:47,000 --> 00:24:51,000 varför inte jag gå istället in adressen till X här, 452 00:24:51,000 --> 00:24:55,000 adress y här, i huvudsak postadress 453 00:24:55,000 --> 00:24:59,000 av x och y, eftersom byta då, om han informeras 454 00:24:59,000 --> 00:25:01,000 av adressen i minnet av x och y, 455 00:25:01,000 --> 00:25:04,000 sedan byta om vi tränade honom lite, 456 00:25:04,000 --> 00:25:07,000 Han skulle kunna köra till den adressen, så att säga, 457 00:25:07,000 --> 00:25:11,000 x, och ändra antalet där, sedan köra till adressen y, 458 00:25:11,000 --> 00:25:16,000 ändra antalet där, även när det inte faktiskt få kopior av dessa värden själv, 459 00:25:16,000 --> 00:25:19,000 så även om vi talade om detta som främsta minne 460 00:25:19,000 --> 00:25:23,000 och detta som swap minne de mäktiga och den farliga delen av C 461 00:25:23,000 --> 00:25:28,000 är att varje funktion kan röra minnet någonstans i datorn, 462 00:25:28,000 --> 00:25:32,000 och detta är kraftfull i att du kan göra mycket fina saker med datorprogram i C. 463 00:25:32,000 --> 00:25:36,000 Detta är farligt eftersom du kan också skruva upp mycket lätt. 464 00:25:36,000 --> 00:25:39,000 I själva verket, till en av de vanligaste sätten för program dessa dagar utnyttjas 465 00:25:39,000 --> 00:25:42,000 fortfarande är för en programmerare inte inse 466 00:25:42,000 --> 00:25:45,000 att han eller hon tillåter en data 467 00:25:45,000 --> 00:25:49,000 skrivas på en plats i minnet som inte var avsett. 468 00:25:49,000 --> 00:25:51,000 >> Till exempel, förklarar han eller hon en rad storlek 10 469 00:25:51,000 --> 00:25:56,000 men sedan råkar försöker sätta 11 byte i den mängd minne, 470 00:25:56,000 --> 00:25:59,000 och du börjar röra delar av minnet som inte längre är giltiga. 471 00:25:59,000 --> 00:26:02,000 Bara för att kontextuella detta kan en del av er vet att 472 00:26:02,000 --> 00:26:06,000 programvara frågar ofta du serienummer eller nycklar registrering, 473 00:26:06,000 --> 00:26:08,000 Photoshop och Word och program som detta. 474 00:26:08,000 --> 00:26:12,000 Det finns sprickor, som några av er vet, på nätet där du kan köra ett litet program, 475 00:26:12,000 --> 00:26:14,000 och voila, inget mer begäran om ett serienummer. 476 00:26:14,000 --> 00:26:16,000 Hur det fungerar? 477 00:26:16,000 --> 00:26:21,000 I många fall är dessa saker är helt enkelt finna i datorerna 478 00:26:21,000 --> 00:26:24,000 textsegment i datorns faktiska nollor och ettor 479 00:26:24,000 --> 00:26:28,000 var är den funktionen där serienumret begärs, 480 00:26:28,000 --> 00:26:31,000 och du skriver det utrymmet, eller medan programmet körs 481 00:26:31,000 --> 00:26:33,000 Du kan räkna ut var nyckeln faktiskt lagras 482 00:26:33,000 --> 00:26:37,000 med något som kallas en debugger, och du kan knäcka programvara på det sättet. 483 00:26:37,000 --> 00:26:40,000 Detta är inte att säga att detta är vårt mål för de närmaste dagarna, 484 00:26:40,000 --> 00:26:42,000 men det har mycket verkliga konsekvenser. 485 00:26:42,000 --> 00:26:45,000 Att en råkar involvera stöld av mjukvara, 486 00:26:45,000 --> 00:26:47,000 men det finns också äventyrande av hela maskiner. 487 00:26:47,000 --> 00:26:50,000 >> Faktum är att när webbsidor dessa dagar utnyttjas 488 00:26:50,000 --> 00:26:53,000 och äventyras och data läckt och lösenord stjäls 489 00:26:53,000 --> 00:26:58,000 detta mycket ofta avser dålig förvaltning av ett minne, 490 00:26:58,000 --> 00:27:01,000 eller, när det gäller databaser, underlåtenhet förutse 491 00:27:01,000 --> 00:27:03,000 kontradiktoriskt ingång, så mer om detta under de kommande veckorna, 492 00:27:03,000 --> 00:27:07,000 men nu bara en förhandstitt på den typ av skador som du kan göra 493 00:27:07,000 --> 00:27:11,000 genom att inte riktigt förstå hur saker och ting fungerar under huven. 494 00:27:11,000 --> 00:27:14,000 Låt oss gå om att förstå varför detta är bruten 495 00:27:14,000 --> 00:27:17,000 med ett verktyg som kommer att bli mer och mer användbar 496 00:27:17,000 --> 00:27:19,000 som våra program blir mer komplexa. 497 00:27:19,000 --> 00:27:21,000 Hittills när du har haft en bugg i programmet 498 00:27:21,000 --> 00:27:23,000 Hur har du gått om felsökning det? 499 00:27:23,000 --> 00:27:25,000 Vad har din teknik varit hittills, oavsett undervisas av din TF 500 00:27:25,000 --> 00:27:27,000 eller bara självlärd? 501 00:27:27,000 --> 00:27:29,000 [Student] printf. 502 00:27:29,000 --> 00:27:31,000 Printf så printf har förmodligen varit din vän i att om du vill se 503 00:27:31,000 --> 00:27:33,000 vad som händer inne i ditt program 504 00:27:33,000 --> 00:27:36,000 du sätter bara printf här, printf här printf här. 505 00:27:36,000 --> 00:27:38,000 Då du kör det, och du får en hel massa saker på skärmen 506 00:27:38,000 --> 00:27:43,000 som du kan använda för att sedan sluta sig till vad som faktiskt är fel i programmet. 507 00:27:43,000 --> 00:27:45,000 >> Printf tenderar att vara en mycket kraftfull sak, 508 00:27:45,000 --> 00:27:47,000 men det är en mycket manuell process. 509 00:27:47,000 --> 00:27:49,000 Du måste sätta ett printf här, en printf här, 510 00:27:49,000 --> 00:27:51,000 och om du lägger den i en slinga så kan du få 100 rader 511 00:27:51,000 --> 00:27:53,000 av produktionen som du sedan måste sålla bland. 512 00:27:53,000 --> 00:27:58,000 Det är inte en mycket användarvänlig och interaktiv mekanism för felsökning program, 513 00:27:58,000 --> 00:28:00,000 men tack och lov finns det alternativ. 514 00:28:00,000 --> 00:28:03,000 Det finns ett program, till exempel, som kallas GDB, GNU Debugger, 515 00:28:03,000 --> 00:28:06,000 som är lite mystisk i hur du använder den. 516 00:28:06,000 --> 00:28:08,000 Det är lite komplicerat, men ärligt talat, 517 00:28:08,000 --> 00:28:11,000 Detta är en av de saker där om du in i denna och nästa vecka 518 00:28:11,000 --> 00:28:14,000 den extra timme för att förstå något som GDB 519 00:28:14,000 --> 00:28:18,000 det kommer att spara dig förmodligen tiotals timmar på lång sikt, 520 00:28:18,000 --> 00:28:21,000 Så med det, låt mig ge er en teaser på hur det här fungerar. 521 00:28:21,000 --> 00:28:23,000 >> Jag är i mitt terminalfönster. 522 00:28:23,000 --> 00:28:26,000 Låt mig gå vidare och sammanställa detta program, buggy3. 523 00:28:26,000 --> 00:28:28,000 Det är redan aktuell. 524 00:28:28,000 --> 00:28:31,000 Låt mig köra det precis som vi gjorde för ett tag sedan, och faktiskt, det brutna. 525 00:28:31,000 --> 00:28:34,000 Men varför är detta? Jag kanske skruvas upp swap-funktionen. 526 00:28:34,000 --> 00:28:37,000 Kanske är det a och b. Jag är inte riktigt flytta dem runt på rätt sätt. 527 00:28:37,000 --> 00:28:39,000 Låt mig gå vidare och göra det. 528 00:28:39,000 --> 00:28:43,000 Snarare än att bara springa buggy3 låt mig istället köra programmet GDB, 529 00:28:43,000 --> 00:28:48,000 och jag ska berätta det för att köra buggy3, 530 00:28:48,000 --> 00:28:52,000 och jag ska inkludera en argumentation kommandorad,-tui, 531 00:28:52,000 --> 00:28:55,000 och vi sätta detta i framtida problem på spec att påminna. 532 00:28:55,000 --> 00:28:57,000 Och nu detta svartvita gränssnitt dök upp som, återigen, 533 00:28:57,000 --> 00:28:59,000 är lite överväldigande i början eftersom det är allt det här 534 00:28:59,000 --> 00:29:02,000 garantiinformation här nere, men åtminstone det är något bekant. 535 00:29:02,000 --> 00:29:04,000 I den övre delen av fönstret är min faktiska koden, 536 00:29:04,000 --> 00:29:08,000 och om jag bläddra upp här Låt mig rulla till toppen av min fil, 537 00:29:08,000 --> 00:29:11,000 och faktiskt, det finns buggy3.c och meddelande längst ner i fönstret 538 00:29:11,000 --> 00:29:13,000 Jag har denna GDB prompten. 539 00:29:13,000 --> 00:29:16,000 >> Detta är inte samma sak som min normala John Harvard prompten. 540 00:29:16,000 --> 00:29:19,000 Detta är en fråga som kommer att tillåta mig att styra GDB. 541 00:29:19,000 --> 00:29:21,000 GDB är en debugger. 542 00:29:21,000 --> 00:29:24,000 En debugger är ett program som låter dig gå igenom 543 00:29:24,000 --> 00:29:27,000 genomförande av programmet rad för rad för rad, 544 00:29:27,000 --> 00:29:30,000 vägen gör något som du vill att programmet, 545 00:29:30,000 --> 00:29:33,000 även ringa funktioner eller söker, ännu viktigare, 546 00:29:33,000 --> 00:29:35,000 på olika variabla värden. 547 00:29:35,000 --> 00:29:37,000 Låt oss gå vidare och göra det. 548 00:29:37,000 --> 00:29:40,000 Jag ska gå vidare och skriva in körning på GDB s snabba, 549 00:29:40,000 --> 00:29:43,000 så märker längst ner till vänster på skärmen jag har skrivit springa, 550 00:29:43,000 --> 00:29:45,000 och jag har in hit, och vad gjorde det då? 551 00:29:45,000 --> 00:29:50,000 Det körde bokstavligen mitt program, men jag såg faktiskt mycket gå på här 552 00:29:50,000 --> 00:29:55,000 eftersom jag inte har faktiskt sagt debugger 553 00:29:55,000 --> 00:29:57,000 att pausa vid en viss tidpunkt. 554 00:29:57,000 --> 00:29:59,000 Bara skriva körning kör programmet. 555 00:29:59,000 --> 00:30:01,000 Jag faktiskt inte se någonting. Jag kan inte manipulera den. 556 00:30:01,000 --> 00:30:03,000 >> Istället Låt mig göra det här. 557 00:30:03,000 --> 00:30:08,000 Vid denna GDB prompten Låt mig istället skriver break, ange. 558 00:30:08,000 --> 00:30:10,000 Det är inte vad jag menade att skriva. 559 00:30:10,000 --> 00:30:13,000 Låt oss i stället skriver break. 560 00:30:13,000 --> 00:30:15,000 Med andra ord vill jag ställa något som kallas en brytpunkt, 561 00:30:15,000 --> 00:30:18,000 som träffande heter eftersom det kommer att bryta eller pausa 562 00:30:18,000 --> 00:30:21,000 genomförande av programmet på den platsen. 563 00:30:21,000 --> 00:30:23,000 Main är namnet på min funktion. 564 00:30:23,000 --> 00:30:25,000 Observera att GDB är ganska smart. 565 00:30:25,000 --> 00:30:28,000 Det räknat ut att huvud råkar börja ungefär vid linjen 18 566 00:30:28,000 --> 00:30:32,000 av buggy3.c och sedan märker här uppe till vänster 567 00:30:32,000 --> 00:30:34,000 b + ligger precis intill rad 18. 568 00:30:34,000 --> 00:30:38,000 Det är påminna mig om att jag har en brytpunkt på linje 18. 569 00:30:38,000 --> 00:30:42,000 Den här gången när jag skriver springa, jag ska köra mitt program 570 00:30:42,000 --> 00:30:45,000 tills den träffar den brytpunkten, 571 00:30:45,000 --> 00:30:48,000 så att programmet gör en paus för mig på rad 18. 572 00:30:48,000 --> 00:30:50,000 Nu kör vi, spring. 573 00:30:50,000 --> 00:30:53,000 Ingenting verkar ha hänt, men meddelande nere till vänster 574 00:30:53,000 --> 00:30:58,000 start program buggy3, brytpunkt 1 i main på buggy3.c linje 18. 575 00:30:58,000 --> 00:31:00,000 Vad kan jag göra nu? 576 00:31:00,000 --> 00:31:03,000 >> Märker jag kan börja skriva saker som utskrift, 577 00:31:03,000 --> 00:31:08,000 inte printf, skriva ut X, och nu det är konstigt. 578 00:31:08,000 --> 00:31:11,000 $ 1 är bara en kuriositet, som vi får se 579 00:31:11,000 --> 00:31:14,000 varje gång du skriver ut något du får en ny $ värde. 580 00:31:14,000 --> 00:31:18,000 Det är så att du kan hänvisa till tidigare värden skull, 581 00:31:18,000 --> 00:31:21,000 men nu vad utskrift säger mig är att värdet av x vid denna punkt i berättelsen 582 00:31:21,000 --> 00:31:26,000 är tydligen 134.514.032. 583 00:31:26,000 --> 00:31:29,000 Vad? Var kom det även komma från? 584 00:31:29,000 --> 00:31:31,000 [Ohörbart-student] 585 00:31:31,000 --> 00:31:34,000 I själva verket är detta vad vi kallar ett skräp värde, och vi har inte pratat om det här ännu, 586 00:31:34,000 --> 00:31:37,000 men anledningen till att du initierar variabler 587 00:31:37,000 --> 00:31:40,000 är uppenbarligen så att de har något värde som du vill att de ska ha. 588 00:31:40,000 --> 00:31:44,000 Men fångsten ihåg att du kan deklarera variabler 589 00:31:44,000 --> 00:31:46,000 som jag gjorde för en stund sedan i min sigma exempel 590 00:31:46,000 --> 00:31:48,000 utan att faktiskt ge dem ett värde. 591 00:31:48,000 --> 00:31:50,000 Minns vad jag gjorde över här i Sigma. 592 00:31:50,000 --> 00:31:52,000 Jag förklarade n men vilket värde gav jag den? 593 00:31:52,000 --> 00:31:56,000 Ingen, eftersom jag visste att under de närmaste raderna 594 00:31:56,000 --> 00:31:59,000 GetInt skulle ta hand om problemet med att sätta ett värde inuti n. 595 00:31:59,000 --> 00:32:02,000 >> Men vid denna punkt i berättelsen om linjen 11 596 00:32:02,000 --> 00:32:05,000 och linje 12 och linje 13 och linje 14 597 00:32:05,000 --> 00:32:08,000 i alla de flera rader vad är värdet på n? 598 00:32:08,000 --> 00:32:10,000 I C du bara vet inte. 599 00:32:10,000 --> 00:32:14,000 Det är i allmänhet lite skräp värde, några helt slumpmässigt nummer 600 00:32:14,000 --> 00:32:17,000 som är kvar i huvudsak från några tidigare funktion 601 00:32:17,000 --> 00:32:21,000 ha körts så ditt program körs 602 00:32:21,000 --> 00:32:24,000 ihåg att funktionen blir funktionen, funktion, funktion. 603 00:32:24,000 --> 00:32:27,000 Alla dessa ramar får sätta på minnet, och sedan de funktioner tillbaka, 604 00:32:27,000 --> 00:32:31,000 och precis som jag föreslog med radergummi deras minne så småningom återanvänds. 605 00:32:31,000 --> 00:32:37,000 Tja, det råkar vara så att denna variabel x i detta program 606 00:32:37,000 --> 00:32:41,000 verkar ha innehållit något skräp värde som 134514032 607 00:32:41,000 --> 00:32:44,000 från någon tidigare funktion, inte en som jag skrev. 608 00:32:44,000 --> 00:32:47,000 Det kan vara något som kommer effektivt med operativsystemet, 609 00:32:47,000 --> 00:32:49,000 någon funktion under huven. 610 00:32:49,000 --> 00:32:52,000 >> Okej, det är bra, men låt oss nu gå vidare till nästa rad. 611 00:32:52,000 --> 00:32:55,000 Om jag skriver "nästa" på min GDB snabbt och jag slog in, 612 00:32:55,000 --> 00:32:58,000 märker att lyfta flyttas ner till linjen 19, 613 00:32:58,000 --> 00:33:01,000 men den logiska innebörden är att linje 18 614 00:33:01,000 --> 00:33:06,000 har nu avslutat köra, så om jag återigen skriver "print x" 615 00:33:06,000 --> 00:33:10,000 Jag skulle nu se 1, och faktiskt, det gör jag. 616 00:33:10,000 --> 00:33:14,000 Återigen är $ grejer ett sätt att GDB påminner dig 617 00:33:14,000 --> 00:33:17,000 vad historia utskrifter är att du har gjort. 618 00:33:17,000 --> 00:33:21,000 Låt mig gå vidare och skriva ut y, och faktiskt, y någon galen värde samt, 619 00:33:21,000 --> 00:33:24,000 men no big deal eftersom i linje 19 är vi på väg att tilldela den 620 00:33:24,000 --> 00:33:27,000 värdet 2, så låt mig skriva "nästa" igen. 621 00:33:27,000 --> 00:33:29,000 Och nu är vi på den printf raden. 622 00:33:29,000 --> 00:33:31,000 Låt mig göra tryckta x. 623 00:33:31,000 --> 00:33:34,000 Låt mig göra utskriften y.. Ärligt talat, jag börjar bli lite trött att skriva detta. 624 00:33:34,000 --> 00:33:38,000 Låt mig istället skriva "skärm x" och "skärm y" 625 00:33:38,000 --> 00:33:41,000 och nu varje gång jag skriver ett kommando i framtiden 626 00:33:41,000 --> 00:33:45,000 Jag kommer att påminnas om vad som är x och y, vad är x och y, vad är x och y. 627 00:33:45,000 --> 00:33:48,000 >> Jag kan också, som en sidoreplik, skriv "info lokalbefolkningen." 628 00:33:48,000 --> 00:33:50,000 Info är ett speciellt kommando. 629 00:33:50,000 --> 00:33:52,000 Lokalbefolkningen betyder det visar mig de lokala variablerna. 630 00:33:52,000 --> 00:33:55,000 Bara i fall jag glömmer eller det är en galen, komplicerad funktion 631 00:33:55,000 --> 00:33:57,000 att jag eller någon annan skrev info lokalbefolkningen kommer att berätta 632 00:33:57,000 --> 00:34:00,000 vad är alla lokala variabler inuti denna lokal funktion 633 00:34:00,000 --> 00:34:03,000 som du kan bry sig om om du vill rota. 634 00:34:03,000 --> 00:34:07,000 Nu printf är på väg att genomföra, så låt mig gå vidare och bara typ "nästa". 635 00:34:07,000 --> 00:34:10,000 Eftersom vi är i denna miljö vi inte faktiskt ser det 636 00:34:10,000 --> 00:34:14,000 exekvera här nere, men märker det börjar bli lite sargade här. 637 00:34:14,000 --> 00:34:17,000 Men märker det övergripande skärmen där, 638 00:34:17,000 --> 00:34:21,000 så det är inte ett perfekt program här, men det är okej eftersom jag kan alltid rota runt 639 00:34:21,000 --> 00:34:23,000 med tryck om jag vill. 640 00:34:23,000 --> 00:34:26,000 >> Låt mig skriva nästa gång, och nu här är den intressanta delen. 641 00:34:26,000 --> 00:34:29,000 Vid denna punkt i berättelsen y är 2, och x är 1, 642 00:34:29,000 --> 00:34:32,000 som föreslås här, och igen, 643 00:34:32,000 --> 00:34:35,000 Anledningen till detta är automatiskt visar nu att jag använde kommandot 644 00:34:35,000 --> 00:34:40,000 display X och Y visas, så nu jag skriver nästa 645 00:34:40,000 --> 00:34:43,000 i teorin x och y bör bli bytas. 646 00:34:43,000 --> 00:34:45,000 Nu vet vi redan att inte kommer att vara fallet, 647 00:34:45,000 --> 00:34:49,000 men vi får se på ett ögonblick hur vi kan dyka djupare för att räkna ut varför det är sant. 648 00:34:49,000 --> 00:34:54,000 Nästa, och tyvärr är y fortfarande 2 och x är fortfarande 1, och jag kan bekräfta så mycket. 649 00:34:54,000 --> 00:34:56,000 Skriv X, tryck y. 650 00:34:56,000 --> 00:34:59,000 I själva verket har ingen swapping faktiskt hände, så låt oss börja här över. 651 00:34:59,000 --> 00:35:01,000 Tydligt swap är bruten. 652 00:35:01,000 --> 00:35:04,000 Låt oss istället skriva "kör" igen. 653 00:35:04,000 --> 00:35:07,000 Låt mig säga ja, jag vill starta om den från början anger. 654 00:35:07,000 --> 00:35:09,000 >> Nu är jag tillbaka upp på rad 18. 655 00:35:09,000 --> 00:35:11,000 Notera nu x och y är skräp värden igen. 656 00:35:11,000 --> 00:35:15,000 Nästa, nästa, nästa, nästa. 657 00:35:15,000 --> 00:35:17,000 Om jag får uttråkad jag kan också bara skriva n. för nästa. 658 00:35:17,000 --> 00:35:21,000 Du kan förkorta det till kortast möjliga sekvensen av tecken. 659 00:35:21,000 --> 00:35:23,000 Pendla nu bruten. 660 00:35:23,000 --> 00:35:25,000 Låt oss dyka i, så istället för att skriva nästa, 661 00:35:25,000 --> 00:35:30,000 nu ska jag skriva steg så att jag kliva in i denna funktion 662 00:35:30,000 --> 00:35:33,000 så att jag kan gå igenom det, så jag slog steg och ange. 663 00:35:33,000 --> 00:35:37,000 Observera att belysa hoppar ner lägre i mitt program till linje 36. 664 00:35:37,000 --> 00:35:39,000 Nu vad är de lokala variablerna? 665 00:35:39,000 --> 00:35:41,000 Info lokalbefolkningen. 666 00:35:41,000 --> 00:35:43,000 Inget riktigt än eftersom vi inte har fått till den raden, 667 00:35:43,000 --> 00:35:47,000 så låt oss gå vidare och säga "nästa". 668 00:35:47,000 --> 00:35:50,000 Nu verkar vi ha tmp, skriva ut tmp. 669 00:35:50,000 --> 00:35:52,000 Garbage värde, eller hur? Jag tror det. 670 00:35:52,000 --> 00:35:55,000 Vad sägs om ut en, skriv ut B, 1 och 2? 671 00:35:55,000 --> 00:35:58,000 I ett ögonblick, så fort jag skriver nästa gång 672 00:35:58,000 --> 00:36:02,000 TMP kommer att ta på ett värde av 1, förhoppningsvis, 673 00:36:02,000 --> 00:36:05,000 eftersom TMP kommer att tilldelas värdet av en. 674 00:36:05,000 --> 00:36:08,000 >> Nu låt oss göra ut en, skriv ut B, 675 00:36:08,000 --> 00:36:11,000 men nu ut tmp, och det är verkligen 1. 676 00:36:11,000 --> 00:36:14,000 Låt mig göra härnäst. Låt mig göra härnäst. 677 00:36:14,000 --> 00:36:16,000 Jag är klar swap-funktionen. 678 00:36:16,000 --> 00:36:19,000 Jag är fortfarande inne i den i linje 40, så låt mig skriva ut en, 679 00:36:19,000 --> 00:36:22,000 print b och jag bryr mig inte vad TMP är. 680 00:36:22,000 --> 00:36:27,000 Det ser ut som swap är korrekt när det gäller att byta a och b. 681 00:36:27,000 --> 00:36:31,000 Men om jag nu skriver nästa, hoppa jag tillbaka till rad 25, 682 00:36:31,000 --> 00:36:34,000 och naturligtvis, om jag skriver i x-och skriv ut y 683 00:36:34,000 --> 00:36:38,000 de är fortfarande oförändrad, så vi har inte åtgärdat problemet. 684 00:36:38,000 --> 00:36:41,000 Men diagnostiskt nu kanske med detta GDB programmet 685 00:36:41,000 --> 00:36:44,000 Vi har åtminstone fått ett steg närmare att förstå 686 00:36:44,000 --> 00:36:47,000 vad som händer fel utan att strö vår kod genom att sätta en printf här, 687 00:36:47,000 --> 00:36:50,000 printf här printf här och sedan köra det om och om igen 688 00:36:50,000 --> 00:36:52,000 försöker lista ut vad som går fel. 689 00:36:52,000 --> 00:36:55,000 >> Jag ska gå vidare och avsluta ur detta helt och hållet med sluta. 690 00:36:55,000 --> 00:36:57,000 Det kommer att sedan säga, "Quit egentligen?" Ja. 691 00:36:57,000 --> 00:37:00,000 Nu är jag tillbaka på min normala ledtexten och jag är klar med GDB. 692 00:37:00,000 --> 00:37:03,000 Som en sidoreplik, behöver du inte använda den här-tui flagga. 693 00:37:03,000 --> 00:37:07,000 Faktum är att om du utelämnar det får du i huvudsak den nedre halvan av skärmen. 694 00:37:07,000 --> 00:37:11,000 Om jag skriver så break och sedan köra 695 00:37:11,000 --> 00:37:15,000 Jag kan fortfarande köra mitt program, men vad det kommer att göra är textuellt 696 00:37:15,000 --> 00:37:18,000 bara visa mig den aktuella raden en i taget. 697 00:37:18,000 --> 00:37:21,000 The-TUI, text användargränssnitt, 698 00:37:21,000 --> 00:37:25,000 bara visar dig mer av programmet på en gång, vilket är nog lite begreppsmässigt enklare. 699 00:37:25,000 --> 00:37:27,000 Men i själva verket kan jag göra precis bredvid, nästa, nästa, 700 00:37:27,000 --> 00:37:30,000 och jag kommer att se en rad i taget, och om jag verkligen vill se vad som händer 701 00:37:30,000 --> 00:37:35,000 Jag kan skriva lista och se en massa närliggande linjer. 702 00:37:35,000 --> 00:37:39,000 >> Det finns en video som vi har bett att du tittar på problemet sätter 3 703 00:37:39,000 --> 00:37:43,000 där Nate täcker några av de invecklade GDB, 704 00:37:43,000 --> 00:37:46,000 och detta är en av dessa saker, ärligt, där några icke-triviala andel av dig 705 00:37:46,000 --> 00:37:49,000 kommer aldrig röra GDB, och det kommer att vara en dålig sak 706 00:37:49,000 --> 00:37:53,000 eftersom bokstavligen kommer du att sluta spendera mer tid senare den här terminen 707 00:37:53,000 --> 00:37:56,000 jagar insekter så skulle du om du sätter i den halvtimme / timme 708 00:37:56,000 --> 00:38:00,000 denna vecka och nästa lärande att bli bekant med GDB. 709 00:38:00,000 --> 00:38:02,000 Printf var din vän. 710 00:38:02,000 --> 00:38:05,000 GDB bör nu vara din vän. 711 00:38:05,000 --> 00:38:08,000 >> Eventuella frågor om GDB? 712 00:38:08,000 --> 00:38:12,000 Och här är en snabb lista över några av de mest kraftfulla och användbara kommandon. 713 00:38:12,000 --> 00:38:15,000 Ja. >> Kan du skriva ut en sträng? 714 00:38:15,000 --> 00:38:17,000 Kan du skriva ut en sträng? Absolut. 715 00:38:17,000 --> 00:38:19,000 Det behöver inte bara vara heltal. 716 00:38:19,000 --> 00:38:22,000 Om en variabel s är en sträng skriv bara i tryck ar. 717 00:38:22,000 --> 00:38:24,000 Det kommer att visa dig vad som strängvariabel är. 718 00:38:24,000 --> 00:38:26,000 [Ohörbart-student] 719 00:38:26,000 --> 00:38:28,000 Det kommer att ge dig adressen och strängen själv. 720 00:38:28,000 --> 00:38:32,000 Det kommer att visa er båda. 721 00:38:32,000 --> 00:38:34,000 Och en sista sak, bara för att de är bra att veta också. 722 00:38:34,000 --> 00:38:37,000 Bakåtspårning och ram, låt mig dyka in i denna en sista gång, 723 00:38:37,000 --> 00:38:39,000 exakt samma program med GDB. 724 00:38:39,000 --> 00:38:44,000 Låt mig gå vidare och köra textversion användargränssnittet, 725 00:38:44,000 --> 00:38:46,000 break. 726 00:38:46,000 --> 00:38:49,000 Låt mig gå vidare och köra igen. Här är jag. 727 00:38:49,000 --> 00:38:55,000 Nu låt mig gå nästa, nästa, nästa, nästa, nästa, steg anger. 728 00:38:55,000 --> 00:39:00,000 >> Och nu antar jag nu swap medvetet, men jag är som "Fan, vad var värdet av x?" 729 00:39:00,000 --> 00:39:02,000 Jag kan inte göra X längre. 730 00:39:02,000 --> 00:39:05,000 Jag kan inte göra y eftersom de inte är i omfattning. 731 00:39:05,000 --> 00:39:07,000 De är inte i sitt sammanhang, men inga problem. 732 00:39:07,000 --> 00:39:09,000 Jag kan skriva bakåtspårning. 733 00:39:09,000 --> 00:39:13,000 Det visar mig alla de funktioner som har utförts fram till denna tidpunkt. 734 00:39:13,000 --> 00:39:16,000 Observera att en på botten, huvud, ställer upp med huvud 735 00:39:16,000 --> 00:39:18,000 vara på undersidan av vår bild här. 736 00:39:18,000 --> 00:39:22,000 Det faktum att swap är ovanför rader med swap är över det i minnet här, 737 00:39:22,000 --> 00:39:26,000 och om jag vill komma tillbaka till huvudgruppen tillfälligt kan jag säga "ram". 738 00:39:26,000 --> 00:39:30,000 Vilket nummer? Main är ram nummer 1. 739 00:39:30,000 --> 00:39:32,000 Jag ska gå vidare och säga "ram 1." 740 00:39:32,000 --> 00:39:36,000 >> Nu är jag tillbaka i main, och jag kan skriva ut X, och jag kan skriva ut y, 741 00:39:36,000 --> 00:39:40,000 men jag kan inte skriva ut a eller b. 742 00:39:40,000 --> 00:39:43,000 Men jag kan om jag säger, "Okej, vänta en minut. Där var swappen?" 743 00:39:43,000 --> 00:39:46,000 Låt mig gå vidare och säga "ram 0." 744 00:39:46,000 --> 00:39:48,000 Nu är jag tillbaka där jag vill vara, och som en sidoreplik 745 00:39:48,000 --> 00:39:52,000 Det finns andra kommandon också, som om du verkligen får uttråkad skriva nästa, nästa, nästa, nästa, 746 00:39:52,000 --> 00:39:56,000 Du kan generellt säga saker som "nästa 10" och som kommer att gå igenom de kommande 10 rader. 747 00:39:56,000 --> 00:39:59,000 Du kan också skriva "fortsätt" när du verkligen få nog av stega igenom den. 748 00:39:59,000 --> 00:40:05,000 Fortsätt att köra ditt program utan avbrott tills den träffar en annan brytpunkt, 749 00:40:05,000 --> 00:40:07,000 antingen i en slinga eller längre ner i programmet. 750 00:40:07,000 --> 00:40:11,000 >> I det här fallet har vi fortsatt till slutet, och programmet avslutades normalt. 751 00:40:11,000 --> 00:40:13,000 Det är ett fint sätt, sämre process. 752 00:40:13,000 --> 00:40:16,000 Bara ditt program avslutades normalt. 753 00:40:16,000 --> 00:40:24,000 Mer om det i videon och felsökning sessioner framöver. 754 00:40:24,000 --> 00:40:26,000 Det var en hel del. 755 00:40:26,000 --> 00:40:35,000 Låt oss ta vår 5-minuters paus här, och vi ska återkomma med structs och filer. 756 00:40:35,000 --> 00:40:38,000 >> Om du har dykt in i denna veckas pset redan 757 00:40:38,000 --> 00:40:41,000 du vet att vi använder i distributionen koden, 758 00:40:41,000 --> 00:40:45,000 den källkod som vi ger till dig som en startpunkt, en del nya tekniker. 759 00:40:45,000 --> 00:40:50,000 I synnerhet introducerade vi den nya sökord som kallas struct för struktur, 760 00:40:50,000 --> 00:40:53,000 så att vi kan skapa anpassade variabler slag. 761 00:40:53,000 --> 00:40:57,000 Vi införde också begreppet fil-I / O, fil ingång och utgång, 762 00:40:57,000 --> 00:41:00,000 och det är så att vi kan spara tillståndet 763 00:41:00,000 --> 00:41:03,000 av din Scramble styrelsen att en fil på skiva 764 00:41:03,000 --> 00:41:06,000 så att undervisningen stipendiater och jag kan förstå 765 00:41:06,000 --> 00:41:09,000 vad som händer på insidan av ditt program utan att manuellt behöva spela 766 00:41:09,000 --> 00:41:11,000 dussintals spel av Scramble. 767 00:41:11,000 --> 00:41:13,000 Vi kan göra detta mer automatedly. 768 00:41:13,000 --> 00:41:18,000 >> Denna idé om en struktur löser ett ganska övertygande problem. 769 00:41:18,000 --> 00:41:21,000 Antag att vi vill genomföra något program 770 00:41:21,000 --> 00:41:25,000 som håller på något sätt reda på information om studenter, 771 00:41:25,000 --> 00:41:28,000 och studenter kan ha, till exempel ett ID, ett namn 772 00:41:28,000 --> 00:41:31,000 och ett hus på en plats som Harvard, så dessa är 3 bitar av information 773 00:41:31,000 --> 00:41:34,000 Vi vill behålla runt, så låt mig gå vidare och börja skriva ett litet program här, 774 00:41:34,000 --> 00:41:38,000 omfatta stdio.h. 775 00:41:38,000 --> 00:41:42,000 Låt mig göra inkludera cs50.h. 776 00:41:42,000 --> 00:41:44,000 Och sedan starta min huvudsakliga funktion. 777 00:41:44,000 --> 00:41:46,000 Jag kommer inte bry sig om några kommandoradsargument, 778 00:41:46,000 --> 00:41:49,000 och här vill jag ha en student, så jag kommer att säga 779 00:41:49,000 --> 00:41:54,000 en student har ett namn, så jag kommer att säga "sträng namn." 780 00:41:54,000 --> 00:41:59,000 Sen ska jag säga en elev har också ett ID, så int id, 781 00:41:59,000 --> 00:42:03,000 och en elev har ett hus, så jag också kommer att säga "sträng hus." 782 00:42:03,000 --> 00:42:06,000 Då ska jag beställa dessa lite mer rent så här. 783 00:42:06,000 --> 00:42:11,000 Okej, nu har jag 3 variabler som man kan representera en student, så "en student". 784 00:42:11,000 --> 00:42:15,000 >> Och nu vill jag fylla dessa värden, så låt mig gå vidare och säga något i stil 785 00:42:15,000 --> 00:42:18,000 "Id = 123." 786 00:42:18,000 --> 00:42:21,000 Namn kommer att få David. 787 00:42:21,000 --> 00:42:24,000 Låt oss säga hus kommer att få Mather, 788 00:42:24,000 --> 00:42:31,000 och då ska jag göra något godtyckligt som printf ("% s, 789 00:42:31,000 --> 00:42:37,000 vars ID är% d, bor i% s. 790 00:42:37,000 --> 00:42:41,000 Och nu, vad jag vill koppla in här, den ena efter den andra? 791 00:42:41,000 --> 00:42:47,000 Namn, ID, hus, avkastning 0. 792 00:42:47,000 --> 00:42:50,000 Okej, om jag skruvas upp någonstans här 793 00:42:50,000 --> 00:42:54,000 Jag tror att vi har en ganska bra program som lagrar en elev. 794 00:42:54,000 --> 00:42:57,000 Naturligtvis är det inte så intressant. Vad händer om jag vill ha 2 studenter? 795 00:42:57,000 --> 00:42:59,000 Det är ingen stor sak. Jag kan stödja 2 personer. 796 00:42:59,000 --> 00:43:03,000 Låt mig gå vidare och belysa detta och gå ner hit, 797 00:43:03,000 --> 00:43:09,000 och jag kan säga "id = 456" för någon som Rob som bor i Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Okej, vänta, men jag kan inte kalla dem samma sak, 799 00:43:12,000 --> 00:43:15,000 och det ser ut som jag kommer att behöva kopiera detta, 800 00:43:15,000 --> 00:43:19,000 så låt mig säga att dessa kommer att vara Davids variabler, 801 00:43:19,000 --> 00:43:23,000 och låt mig få lite kopior av dessa för Rob. 802 00:43:23,000 --> 00:43:27,000 Vi ringer dessa Rob men detta kommer inte att fungera nu 803 00:43:27,000 --> 00:43:33,000 eftersom jag har-vänta, låt oss ändra mig ID1, NAME1 och House1. 804 00:43:33,000 --> 00:43:35,000 Rob blir 2, 2. 805 00:43:35,000 --> 00:43:42,000 Jag måste ändra detta här, här, här, här, här, här. 806 00:43:42,000 --> 00:43:45,000 Vänta, hur Tommy? Låt oss göra det igen. 807 00:43:45,000 --> 00:43:49,000 Självklart om du fortfarande tror att det är ett bra sätt att göra detta, det är inte, 808 00:43:49,000 --> 00:43:52,000 så kopiera / klistra dåligt. 809 00:43:52,000 --> 00:43:55,000 Men vi löste en vecka sedan. 810 00:43:55,000 --> 00:43:59,000 >> Vad var vår lösning när vi ville ha flera instanser av samma datatyp? 811 00:43:59,000 --> 00:44:01,000 [Studenter] En array. 812 00:44:01,000 --> 00:44:03,000 En array, så låt mig försöka städa upp det här. 813 00:44:03,000 --> 00:44:07,000 Låt mig göra några rum för mig själv på toppen, och låt mig istället göra det här. 814 00:44:07,000 --> 00:44:12,000 Vi ringer dessa människor, och i stället ska jag säga "int id," 815 00:44:12,000 --> 00:44:14,000 och jag kommer att stödja 3 av oss för nu. 816 00:44:14,000 --> 00:44:18,000 Jag kommer att säga "strängnamn," och jag stöder 3 av oss, 817 00:44:18,000 --> 00:44:22,000 och då ska jag säga "string hus", och jag kommer att stödja 3 av oss. 818 00:44:22,000 --> 00:44:26,000 Nu här i stället för David att få sina egna lokala variabler 819 00:44:26,000 --> 00:44:28,000 Vi kan bli av dem. 820 00:44:28,000 --> 00:44:30,000 Det känns bra att vi städa upp detta. 821 00:44:30,000 --> 00:44:35,000 Jag kan då säga David kommer att bli [0] och namn [0] 822 00:44:35,000 --> 00:44:38,000 och hus [0]. 823 00:44:38,000 --> 00:44:41,000 Och sedan Rob vi liknande kan spara på detta. 824 00:44:41,000 --> 00:44:46,000 Låt oss sätta detta här nere, så han kommer att godtyckligt bli id ​​[1]. 825 00:44:46,000 --> 00:44:50,000 Han kommer att bli namn [1], 826 00:44:50,000 --> 00:44:53,000 och sedan slutligen, hus [1]. 827 00:44:53,000 --> 00:44:57,000 >> Fortfarande lite tråkiga, och nu har jag att lista ut, 828 00:44:57,000 --> 00:45:03,000 så låt oss säga "namn [0], id [0], hus [0], 829 00:45:03,000 --> 00:45:06,000 och låt oss pluralize här. 830 00:45:06,000 --> 00:45:09,000 Ids, ids, ids. 831 00:45:09,000 --> 00:45:12,000 Och igen, jag gör det, så igen, jag tillgripa redan kopiera / klistra igen, 832 00:45:12,000 --> 00:45:14,000 så oddsen är att det finns en annan lösning här. 833 00:45:14,000 --> 00:45:18,000 Jag kan nog städa upp ytterligare med en ögla eller något liknande, 834 00:45:18,000 --> 00:45:21,000 så kort sagt, det är lite bättre men fortfarande känns 835 00:45:21,000 --> 00:45:24,000 Jag tillgriper kopiera / klistra in, men även detta, jag hävdar, 836 00:45:24,000 --> 00:45:27,000 är egentligen inte i grunden rätt lösning eftersom 837 00:45:27,000 --> 00:45:29,000 vad händer om någon gång vi bestämmer du vad? 838 00:45:29,000 --> 00:45:32,000 Vi har verkligen borde ha lagrar e-postadresser för David och Rob 839 00:45:32,000 --> 00:45:34,000 och alla andra i det här programmet. 840 00:45:34,000 --> 00:45:36,000 Vi bör också lagra telefonnummer. 841 00:45:36,000 --> 00:45:39,000 Vi bör också lagra nödnummer kontakt. 842 00:45:39,000 --> 00:45:41,000 Vi har alla dessa bitar av data som vi vill lagra, 843 00:45:41,000 --> 00:45:43,000 så hur ska du gå om att göra det? 844 00:45:43,000 --> 00:45:46,000 >> Du deklarerar en array upptill, och sedan manuellt lägga till 845 00:45:46,000 --> 00:45:49,000 en e-postadress [0], e-postadress [1] 846 00:45:49,000 --> 00:45:51,000 för David och Rob och så vidare. 847 00:45:51,000 --> 00:45:56,000 Men det är egentligen bara ett antagande som ligger bakom denna konstruktion 848 00:45:56,000 --> 00:45:59,000 att jag använder äran systemet att veta att 849 00:45:59,000 --> 00:46:03,000 [I] i varje flera arrayer 850 00:46:03,000 --> 00:46:06,000 bara så råkar hänvisa till samma person, 851 00:46:06,000 --> 00:46:10,000 så [0] i ids är nummer 123, 852 00:46:10,000 --> 00:46:13,000 och jag kommer att anta att namnen [0] 853 00:46:13,000 --> 00:46:16,000 är samma person namn och hus [0] 854 00:46:16,000 --> 00:46:21,000 är samma person hus och så vidare för alla de olika uppsättningarna som jag skapar. 855 00:46:21,000 --> 00:46:24,000 Men märker att det inte finns någon grundläggande koppling 856 00:46:24,000 --> 00:46:27,000 bland de 3 bitar av information, id, namn och hus, 857 00:46:27,000 --> 00:46:32,000 även om företaget vi försöker modell i detta program är inte matriser. 858 00:46:32,000 --> 00:46:35,000 Arrayer är just detta programmatiska sätt att göra detta. 859 00:46:35,000 --> 00:46:38,000 Vad vi verkligen vill att modellera i vårt program är en person 860 00:46:38,000 --> 00:46:41,000 som David, en person som Rob inuti vilken 861 00:46:41,000 --> 00:46:46,000 eller inkapsling är ett namn och ID och ett hus. 862 00:46:46,000 --> 00:46:49,000 >> Kan vi uttrycka något denna idé om inkapsling 863 00:46:49,000 --> 00:46:52,000 där en person har ett ID, ett namn och ett hus 864 00:46:52,000 --> 00:46:55,000 och inte ta till verkligen denna hacka där vi bara 865 00:46:55,000 --> 00:46:58,000 lita på att fästet något 866 00:46:58,000 --> 00:47:02,000 hänvisar till samma mänskliga enhet i var och en av dessa olika matriser? 867 00:47:02,000 --> 00:47:04,000 Vi kan faktiskt göra detta. 868 00:47:04,000 --> 00:47:08,000 Låt mig gå över huvud för nu, och låt mig skapa min egen datatyp 869 00:47:08,000 --> 00:47:10,000 för riktigt första gången. 870 00:47:10,000 --> 00:47:14,000 Vi använde den här tekniken i Scramble, 871 00:47:14,000 --> 00:47:17,000 men här kommer jag att gå vidare och skapa en datatyp 872 00:47:17,000 --> 00:47:19,000 och du vet vad, jag ska kalla det student eller person 873 00:47:19,000 --> 00:47:23,000 och jag kommer att använda typedef för definiera en typ. 874 00:47:23,000 --> 00:47:25,000 Jag ska säga att detta är en struktur, 875 00:47:25,000 --> 00:47:29,000 och då denna struktur kommer att vara av typen elev, vi säger, 876 00:47:29,000 --> 00:47:31,000 även om det är lite av den nu för mig. 877 00:47:31,000 --> 00:47:33,000 Vi säger "int id." 878 00:47:33,000 --> 00:47:35,000 Vi säger "sträng namn." 879 00:47:35,000 --> 00:47:37,000 Då kommer vi att säga "sträng hus" 880 00:47:37,000 --> 00:47:40,000 så nu i slutet av dessa få rader kod 881 00:47:40,000 --> 00:47:45,000 Jag har just lärt klang att det finns 882 00:47:45,000 --> 00:47:49,000 en datatyp förutom Ints, förutom strängar, förutom dubbel, förutom flyter. 883 00:47:49,000 --> 00:47:54,000 >> Från och med denna tidpunkt linje 11, finns det nu en ny datatyp som kallas studenter, 884 00:47:54,000 --> 00:47:58,000 och nu kan jag förklara en student variabel någonstans jag vill, 885 00:47:58,000 --> 00:48:01,000 så låt mig rulla ner hit till människor. 886 00:48:01,000 --> 00:48:05,000 Nu kan jag bli av med detta, och jag kan gå tillbaka till David hit, 887 00:48:05,000 --> 00:48:10,000 och för David kan jag faktiskt säga att David, 888 00:48:10,000 --> 00:48:13,000 Vi kan bokstavligen namnge variabeln efter mig, 889 00:48:13,000 --> 00:48:16,000 kommer att vara av typen elev. 890 00:48:16,000 --> 00:48:18,000 Detta kan se lite konstigt, men det är inte så annorlunda 891 00:48:18,000 --> 00:48:22,000 från att förklara något som int eller en sträng eller en flottör. 892 00:48:22,000 --> 00:48:24,000 Det råkar vara så att kallas elev nu 893 00:48:24,000 --> 00:48:28,000 och om jag vill sätta något inuti denna struktur 894 00:48:28,000 --> 00:48:31,000 Jag har nu att använda en ny bit syntax, men det är ganska enkelt, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" i huvudstaden D, 896 00:48:39,000 --> 00:48:42,000 och david.house = "Mather," 897 00:48:42,000 --> 00:48:46,000 och nu kan jag bli av med det här här. 898 00:48:46,000 --> 00:48:51,000 Märker vi nu gjort om vår program verkligen ett mycket bättre sätt 899 00:48:51,000 --> 00:48:54,000 i att nu vårt program speglar den verkliga världen. 900 00:48:54,000 --> 00:48:57,000 >> Det finns en verklig uppfattning om en person eller en student. 901 00:48:57,000 --> 00:49:02,000 Här har vi nu en C version av en person eller mer specifikt en student. 902 00:49:02,000 --> 00:49:05,000 Inuti den personen är dessa relevanta egenskaper, 903 00:49:05,000 --> 00:49:10,000 ID, namn och hus, så Rob blir i princip samma sak här nere, 904 00:49:10,000 --> 00:49:14,000 så eleven rob, och nu rob.id = 456, 905 00:49:14,000 --> 00:49:17,000 rob.name = "Rob." 906 00:49:17,000 --> 00:49:20,000 Det faktum att variabeln heter Rob är typ av meningslöst. 907 00:49:20,000 --> 00:49:22,000 Vi kunde ha kallat det x eller y eller z. 908 00:49:22,000 --> 00:49:25,000 Vi döpte bara det Rob vara semantiskt konsekvent, 909 00:49:25,000 --> 00:49:28,000 men egentligen namnet är inne i det området i sig, 910 00:49:28,000 --> 00:49:30,000 så nu har jag det här. 911 00:49:30,000 --> 00:49:33,000 Även detta inte känns som den bästa designen i att jag har svårt kodad David. 912 00:49:33,000 --> 00:49:35,000 Jag har svårt kodad Rob. 913 00:49:35,000 --> 00:49:39,000 Och jag har fortfarande att ta till vissa kopiera och klistra varje gång jag vill ha nya variabler. 914 00:49:39,000 --> 00:49:43,000 Dessutom måste jag tydligen ge alla dessa variabler ett namn, 915 00:49:43,000 --> 00:49:46,000 även om jag hade mycket hellre beskriva dessa variabler 916 00:49:46,000 --> 00:49:48,000  mer allmänt som studerande. 917 00:49:48,000 --> 00:49:52,000 >> Nu kan vi slå ihop de idéer som har arbetat bra för oss 918 00:49:52,000 --> 00:49:56,000 och istället säga: "Vet du vad, ge mig en variabel som heter studenter, 919 00:49:56,000 --> 00:50:01,000 och låt oss har det vara storlek 3 ", så nu kan jag förfina detta ytterligare, 920 00:50:01,000 --> 00:50:04,000 bli av med manuellt deklarerade David, 921 00:50:04,000 --> 00:50:08,000 och jag kan utan att säga något i stil med studenter [0] här. 922 00:50:08,000 --> 00:50:11,000 Jag kan då säga studenter [0] här, 923 00:50:11,000 --> 00:50:14,000 studenter [0] här, och så vidare, och jag kan gå runt 924 00:50:14,000 --> 00:50:16,000 och städa upp det för Rob. 925 00:50:16,000 --> 00:50:19,000 Jag kan också gå om nu kanske lägga till en slinga 926 00:50:19,000 --> 00:50:23,000 och använda GetString och getInt att faktiskt få dessa värden från användaren. 927 00:50:23,000 --> 00:50:27,000 Jag kunde gå om att lägga en konstant eftersom det är allmänt dålig praxis 928 00:50:27,000 --> 00:50:29,000 till hårt kod några godtyckligt antal som 3 här 929 00:50:29,000 --> 00:50:33,000 och sedan bara ihåg att du ska lägga mer än 3 studenter i den. 930 00:50:33,000 --> 00:50:36,000 Det skulle förmodligen vara bättre att använda # define överst på min fil 931 00:50:36,000 --> 00:50:40,000 och faktor som ut, så ja, låt mig gå vidare och generalisera detta. 932 00:50:40,000 --> 00:50:43,000 >> Låt mig öppna upp ett exempel som är bland dagens 933 00:50:43,000 --> 00:50:46,000 exempel i förväg, structs1. 934 00:50:46,000 --> 00:50:49,000 Detta är en mer komplett program som använder # define upp här 935 00:50:49,000 --> 00:50:51,000 och säger att vi kommer att ha 3 studenter som standard. 936 00:50:51,000 --> 00:50:54,000 Här jag förklara en klass värd elever, 937 00:50:54,000 --> 00:50:57,000 så ett klassrum med elever, och nu är jag använder en slinga 938 00:50:57,000 --> 00:51:00,000 bara för att göra koden lite mer elegant, fylla klassen 939 00:51:00,000 --> 00:51:05,000 med användarens input, så iterera från i = 0 på upp till studenter, vilket är 3. 940 00:51:05,000 --> 00:51:07,000 Och då jag fråga användaren i denna version 941 00:51:07,000 --> 00:51:10,000  vad är studentens id, och jag får det med getInt. 942 00:51:10,000 --> 00:51:13,000 Vad är studentens namn, och då får jag det med GetString. 943 00:51:13,000 --> 00:51:15,000 Vad är studentens hus? Jag får det med GetString. 944 00:51:15,000 --> 00:51:19,000 Och därefter på botten här bestämde jag mig bara för att ändra 945 00:51:19,000 --> 00:51:22,000 hur jag skriver ut dem och att faktiskt använda en slinga, 946 00:51:22,000 --> 00:51:24,000 och som jag skriver? 947 00:51:24,000 --> 00:51:27,000 Enligt kommentaren jag skriver någon i Mather, 948 00:51:27,000 --> 00:51:30,000 och det är det så Rob och Tommy och så vidare-faktiskt Tommys i Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy och David skulle skrivas i detta fall, men hur detta fungerar? 950 00:51:34,000 --> 00:51:40,000 Vi har inte sett denna funktion tidigare, men ta en gissning om vad detta innebär. 951 00:51:40,000 --> 00:51:42,000 Jämför strängar. 952 00:51:42,000 --> 00:51:45,000 >> Det är lite icke uppenbara hur jämförs strängar eftersom det visar sig 953 00:51:45,000 --> 00:51:49,000 Om den returnerar 0 betyder strängarna är lika. 954 00:51:49,000 --> 00:51:53,000 Om den returnerar en -1 betyder en kommer alfabetiskt före den andra, 955 00:51:53,000 --> 00:51:57,000 och om den återvänder en som betyder den andra ord kommer alfabetiskt 956 00:51:57,000 --> 00:52:00,000 innan den andra, och du kan titta på nätet eller på man-sidan 957 00:52:00,000 --> 00:52:04,000 för att se exakt vilken väg som är vilken, men allt detta nu gör är det säger 958 00:52:04,000 --> 00:52:09,000 om [i]. huset är lika med "Mather" 959 00:52:09,000 --> 00:52:13,000 sedan gå vidare och skriva ut den och den är i Mather. 960 00:52:13,000 --> 00:52:16,000 Men här är något vi inte har sett förut, och vi ska återkomma till detta. 961 00:52:16,000 --> 00:52:21,000 Jag minns inte att någonsin behöva göra detta i någon av mina program. 962 00:52:21,000 --> 00:52:24,000 Gratis är tydligen hänvisar till minne, frigöra minne, 963 00:52:24,000 --> 00:52:31,000 men vad minnet jag befria tydligen i denna slinga längst ner i detta program? 964 00:52:31,000 --> 00:52:34,000 Det ser ut som att jag frigör en persons namn 965 00:52:34,000 --> 00:52:37,000 och en persons hus, men varför är det? 966 00:52:37,000 --> 00:52:41,000 >> Det visar sig alla dessa veckor som du har använt GetString 967 00:52:41,000 --> 00:52:45,000 Vi har typ av varit att införa en bugg i alla dina program. 968 00:52:45,000 --> 00:52:51,000 GetString genom design allokerar minne så att den kan återgå till en sträng, 969 00:52:51,000 --> 00:52:55,000 som David eller Rob, och du kan sedan göra vad du vill 970 00:52:55,000 --> 00:52:59,000 med den strängen i ditt program eftersom vi har reserverat minne för dig. 971 00:52:59,000 --> 00:53:02,000 Problemet är hela tiden varje gång du ringer getString 972 00:53:02,000 --> 00:53:05,000 vi, författarna GetString, har begärt att operativsystemet 973 00:53:05,000 --> 00:53:07,000 att ge oss lite RAM för denna sträng. 974 00:53:07,000 --> 00:53:09,000 Ge oss lite RAM för detta nästa sträng. 975 00:53:09,000 --> 00:53:11,000 Ge oss lite mer RAM-minne för nästa sträng. 976 00:53:11,000 --> 00:53:13,000 Vad du är programmerare, har aldrig gjort 977 00:53:13,000 --> 00:53:15,000 ger oss detta minne tillbaka, 978 00:53:15,000 --> 00:53:17,000 så för dessa flera veckor alla program som du har skrivit 979 00:53:17,000 --> 00:53:20,000 ha haft vad som kallas ett minne språng där de fortsätter att använda 980 00:53:20,000 --> 00:53:24,000 mer och mer minne varje gång du ringer GetString, och det är bra. 981 00:53:24,000 --> 00:53:27,000 Vi gör medvetet att under de första veckorna, eftersom det inte är så intressant 982 00:53:27,000 --> 00:53:29,000 att oroa där strängen kommer ifrån. 983 00:53:29,000 --> 00:53:34,000 Allt du vill är ordet Rob att komma tillbaka när användaren skriver in den 984 00:53:34,000 --> 00:53:38,000 >> Men framåt vi nu måste börja bli mer sofistikerade om detta. 985 00:53:38,000 --> 00:53:42,000 Varje gång vi allokera minne vi bättre så småningom lämna tillbaka den. 986 00:53:42,000 --> 00:53:45,000 Annars i den verkliga världen på din Mac eller PC du kan ha ibland upplevt 987 00:53:45,000 --> 00:53:50,000 symptom där datorn lamslagits småningom 988 00:53:50,000 --> 00:53:54,000 eller dumma snurrande badboll är bara ockuperar datorns 989 00:53:54,000 --> 00:53:56,000 Hela uppmärksamhet och du kan inte göra saker. 990 00:53:56,000 --> 00:54:00,000 Det kan förklaras av ett antal buggar, men bland de möjliga fel 991 00:54:00,000 --> 00:54:03,000 saker och ting kallas minnesläckor där någon som skrev att mjukvara 992 00:54:03,000 --> 00:54:07,000 du använder inte ihåg att frigöra minne 993 00:54:07,000 --> 00:54:10,000 att han eller hon frågade operativsystemet för, 994 00:54:10,000 --> 00:54:14,000 inte använder GetString, eftersom det är en CS50 sak, men med liknande funktioner 995 00:54:14,000 --> 00:54:16,000 som ber operativsystemet för minnet. 996 00:54:16,000 --> 00:54:19,000 Om du eller de skruva upp och aldrig återvända som minne 997 00:54:19,000 --> 00:54:24,000 ett symptom på det kan vara att ett program saktar och saktar och saktar ner 998 00:54:24,000 --> 00:54:26,000 om du kommer ihåg att ringa gratis. 999 00:54:26,000 --> 00:54:28,000 >> Vi ska återkomma till när och varför du skulle ringa gratis, 1000 00:54:28,000 --> 00:54:32,000 men låt oss gå vidare bara för bra åtgärd och försök köra detta program. 1001 00:54:32,000 --> 00:54:35,000 Detta kallades structs1 skriver. 1002 00:54:35,000 --> 00:54:40,000 Låt mig gå vidare och köra structs1, 123, David Mather, 1003 00:54:40,000 --> 00:54:47,000 456, Rob Kirkland, 789, 1004 00:54:47,000 --> 00:54:50,000 Tommy Mather, och vi ser Davids i Mather, Tommys i Mather. 1005 00:54:50,000 --> 00:54:53,000 Detta är bara en liten sanity kontrollera att programmet fungerar. 1006 00:54:53,000 --> 00:54:56,000 Nu, tyvärr är det här programmet lite frustrerande att 1007 00:54:56,000 --> 00:55:00,000 Jag gjorde allt arbete, jag skrev i 9 olika strängar, tryck enter, 1008 00:55:00,000 --> 00:55:04,000 fick höra som var i Mather, men självklart visste jag vem som var i Mather redan eftersom jag skrev det. 1009 00:55:04,000 --> 00:55:07,000 Det skulle vara minst trevligt om detta program är mer som en databas 1010 00:55:07,000 --> 00:55:10,000 och det minns faktiskt vad jag har skrivit in 1011 00:55:10,000 --> 00:55:12,000 så jag aldrig mer behöver in dessa studiedokumentation. 1012 00:55:12,000 --> 00:55:15,000 Kanske är det som en registrarial system. 1013 00:55:15,000 --> 00:55:21,000 >> Vi kan göra detta med denna teknik som kallas fil I / O, fil ingång och utgång, 1014 00:55:21,000 --> 00:55:24,000 ett mycket allmänt sätt att säga när du vill läsa filer eller skriva filer 1015 00:55:24,000 --> 00:55:26,000 du kan göra detta med en viss uppsättning funktioner. 1016 00:55:26,000 --> 00:55:29,000 Låt mig gå vidare och öppna detta exempel structs2.c, 1017 00:55:29,000 --> 00:55:33,000 som är nästan identisk, men låt oss se vad det nu gör. 1018 00:55:33,000 --> 00:55:36,000 På toppen av filen förklarar jag en klass elever. 1019 00:55:36,000 --> 00:55:38,000 Jag fyller sedan klassen med användarens input, 1020 00:55:38,000 --> 00:55:41,000 så dessa kodrader är som exakt förr. 1021 00:55:41,000 --> 00:55:45,000 Sen om jag bläddra ner här jag skriver ut alla som är i Mather gillar godtyckligt tidigare, 1022 00:55:45,000 --> 00:55:47,000 men detta är en intressant nyhet. 1023 00:55:47,000 --> 00:55:51,000 Dessa rader kod är nya, och de introducerar något här, 1024 00:55:51,000 --> 00:55:55,000 Fil, alla mössor, och det har * i här. 1025 00:55:55,000 --> 00:55:58,000 Låt mig flytta hit, en * hit också. 1026 00:55:58,000 --> 00:56:00,000 >> Denna funktion har vi inte sett förut, fopen, 1027 00:56:00,000 --> 00:56:03,000 men det betyder filen öppen, så låt oss skumma igenom dessa, 1028 00:56:03,000 --> 00:56:05,000 och detta är något vi ska återkomma till i framtida psets, 1029 00:56:05,000 --> 00:56:10,000 men denna linje här öppnar huvudsak en fil som heter databas, 1030 00:56:10,000 --> 00:56:13,000 och det öppnar specifikt på ett sådant sätt att den kan göra vad på det? 1031 00:56:13,000 --> 00:56:15,000 [Ohörbart-student] 1032 00:56:15,000 --> 00:56:19,000 Just det, så "w" betyder bara att det talar operativsystemet 1033 00:56:19,000 --> 00:56:21,000 öppna filen så att jag kan skriva till den. 1034 00:56:21,000 --> 00:56:23,000 Jag vill inte läsa den. Jag vill inte bara titta på det. 1035 00:56:23,000 --> 00:56:26,000 Jag vill ändra det och lägga saker eventuellt till det, 1036 00:56:26,000 --> 00:56:28,000 och filen kommer att kallas databas. 1037 00:56:28,000 --> 00:56:30,000 Detta skulle kunna kallas något. 1038 00:56:30,000 --> 00:56:32,000 Detta kan vara database.txt. Detta skulle kunna vara. Db. 1039 00:56:32,000 --> 00:56:37,000 Detta kan vara ett ord som foo, men jag godtyckligt valde att namnge filen databasen. 1040 00:56:37,000 --> 00:56:42,000 Detta är en liten sanity check som vi ska återkomma till i detalj över tid, 1041 00:56:42,000 --> 00:56:47,000 Om fp, för fil pekare, inte lika NULL betyder allt är bra. 1042 00:56:47,000 --> 00:56:51,000 >> Lång historia kort, funktioner som fopen misslyckas ibland. 1043 00:56:51,000 --> 00:56:53,000 Kanske filen inte finns. Kanske du är ute skivutrymmet. 1044 00:56:53,000 --> 00:56:55,000 Kanske du inte har behörighet till mappen, 1045 00:56:55,000 --> 00:56:58,000 så om fopen returnerar null något dåligt hänt. 1046 00:56:58,000 --> 00:57:02,000 Omvänt, om fopen inte returnerar null allt är bra 1047 00:57:02,000 --> 00:57:04,000 och jag kan börja skriva till den här filen. 1048 00:57:04,000 --> 00:57:06,000 Här är ett nytt trick. 1049 00:57:06,000 --> 00:57:08,000 Detta är en for-slinga som är iteration över alla mina elever, 1050 00:57:08,000 --> 00:57:10,000 och detta ser så liknar vad vi har gjort tidigare, 1051 00:57:10,000 --> 00:57:15,000 men denna funktion är en kusin till printf kallas fprintf för fil printf, 1052 00:57:15,000 --> 00:57:18,000 och märker att det är annorlunda i bara 2 sätt. 1053 00:57:18,000 --> 00:57:20,000 Ett, börjar det med f istället för p, 1054 00:57:20,000 --> 00:57:23,000 men sedan dess första argument är tydligen vad? 1055 00:57:23,000 --> 00:57:25,000 [Studenter] Fil. >> Det är en fil. 1056 00:57:25,000 --> 00:57:30,000 Denna sak kallad fp, som vi kommer så småningom retas isär vad en fil pekare är, 1057 00:57:30,000 --> 00:57:35,000 men nu fp representerar helt enkelt filen som jag har öppnat, 1058 00:57:35,000 --> 00:57:41,000 så fprintf här säger skriva ut denna användarens ID till filen, inte på skärmen. 1059 00:57:41,000 --> 00:57:44,000 Skriv användarens namn till filen, inte på skärmen, 1060 00:57:44,000 --> 00:57:47,000 huset till filen, inte på skärmen, och sedan ner hit, naturligtvis, 1061 00:57:47,000 --> 00:57:50,000 stänger filen och sedan ner här gratis minnet. 1062 00:57:50,000 --> 00:57:53,000 >> Den enda skillnaden mellan denna version 2 och version 1 1063 00:57:53,000 --> 00:57:58,000 är införandet av fopen och denna fil med * 1064 00:57:58,000 --> 00:58:01,000 och denna föreställning om fprintf, så låt oss se vad slutresultatet är. 1065 00:58:01,000 --> 00:58:03,000 Låt mig gå in i min terminalfönster. 1066 00:58:03,000 --> 00:58:06,000 Låt mig köra structs2 skriver. 1067 00:58:06,000 --> 00:58:09,000 Ser ut som allt är bra. Låt oss köra structs2. 1068 00:58:09,000 --> 00:58:15,000 123, David Mather, 456, Rob Kirkland, 1069 00:58:15,000 --> 00:58:19,000 789, Tommy Mather skriver. 1070 00:58:19,000 --> 00:58:23,000 Ser ut som det betedde samma sak, men om jag gör nu ls 1071 00:58:23,000 --> 00:58:28,000 märke till vad filen är här bland alla min kod, databas, 1072 00:58:28,000 --> 00:58:32,000 så låt oss öppna den, gedit i databasen och titta på det. 1073 00:58:32,000 --> 00:58:34,000 Det är inte den sexigaste av filformat. 1074 00:58:34,000 --> 00:58:38,000 Det är verkligen en del av data linje per linje per rad, 1075 00:58:38,000 --> 00:58:42,000 men de av er som använder Excel eller CSV-filer, kommaseparerade värden, 1076 00:58:42,000 --> 00:58:47,000 Jag kunde verkligen ha använt fprintf att istället kanske göra något liknande 1077 00:58:47,000 --> 00:58:50,000 så att jag kunde faktiskt skapa motsvarigheten till en Excel-fil 1078 00:58:50,000 --> 00:58:53,000 genom att separera saker med kommatecken, inte bara nya linjer. 1079 00:58:53,000 --> 00:58:56,000 >> I det här fallet om jag istället hade använt kommatecken istället för nya linjer 1080 00:58:56,000 --> 00:59:01,000 Jag kunde bokstavligen öppna databasfilen i Excel om jag istället fick det att se ut så här. 1081 00:59:01,000 --> 00:59:03,000 Kort sagt, nu när vi har makten att skriva till filer 1082 00:59:03,000 --> 00:59:07,000 Vi kan nu börja kvarstående uppgifter, hålla den runt på skiva 1083 00:59:07,000 --> 00:59:10,000 så att vi kan hålla information kring om och om igen. 1084 00:59:10,000 --> 00:59:14,000 Kallelse ett par andra saker som är nu lite mer bekant. 1085 00:59:14,000 --> 00:59:16,000 På toppen av detta C-fil har vi en typedef 1086 00:59:16,000 --> 00:59:21,000 eftersom vi ville skapa en datatyp som representerar ett ord, 1087 00:59:21,000 --> 00:59:25,000 så denna typ kallas ord, och inuti denna struktur 1088 00:59:25,000 --> 00:59:27,000 det är lite finare nu. 1089 00:59:27,000 --> 00:59:30,000 Varför ett ord som består av till synes en matris? 1090 00:59:30,000 --> 00:59:33,000 Vad är ett ord bara intuitivt? 1091 00:59:33,000 --> 00:59:35,000 >> Det är en mängd tecken. 1092 00:59:35,000 --> 00:59:37,000 Det är en följd av tecken rygg mot rygg mot rygg. 1093 00:59:37,000 --> 00:59:41,000 Bokstäver i versaler råkar vara vi godtyckligt säga den maximala längden 1094 00:59:41,000 --> 00:59:44,000 av något ord i ordlistan som vi använder för Scramble. 1095 00:59:44,000 --> 00:59:46,000 Varför har jag en en? 1096 00:59:46,000 --> 00:59:48,000 Den nolltecken. 1097 00:59:48,000 --> 00:59:51,000 Minns när vi gjorde Bananagrams exemplet vi behövde ett speciellt värde 1098 00:59:51,000 --> 00:59:55,000 vid slutet av ordet för att hålla reda 1099 00:59:55,000 --> 00:59:59,000 var ord som faktiskt slut och som problemet inställda specifikationen säger 1100 00:59:59,000 --> 01:00:03,000 Här vi umgås med ett givet ord ett booleskt värde, 1101 01:00:03,000 --> 01:00:05,000 en flagga, så att säga, sant eller falskt. 1102 01:00:05,000 --> 01:00:09,000 Har du hittat detta ord redan, eftersom vi inser 1103 01:00:09,000 --> 01:00:13,000 vi behöver verkligen ett sätt att minnas inte bara vad ett ord är Scramble 1104 01:00:13,000 --> 01:00:15,000 men om du är människa, funnit det 1105 01:00:15,000 --> 01:00:20,000 så att om du hittar ordet "det" man inte bara kan skriva, ange, den, in, den, skriv in 1106 01:00:20,000 --> 01:00:23,000 och få 3 poäng, 3 poäng, 3 poäng, 3 poäng. 1107 01:00:23,000 --> 01:00:26,000 Vi vill kunna svartlista ordet genom att ange en bool 1108 01:00:26,000 --> 01:00:29,000 till true om du har redan hittat det, och så det är därför vi 1109 01:00:29,000 --> 01:00:31,000 inkapslade den i denna struktur. 1110 01:00:31,000 --> 01:00:35,000 >> Nu här i Scramble finns här andra struct som kallas ordboken. 1111 01:00:35,000 --> 01:00:39,000 Frånvarande här är ordet typedef eftersom i detta fall 1112 01:00:39,000 --> 01:00:43,000 vi behövde för att kapsla in idén om en ordbok, 1113 01:00:43,000 --> 01:00:46,000 och en ordlista innehåller en massa ord, 1114 01:00:46,000 --> 01:00:49,000 som antyds av denna array, och hur många av dessa ord finns det? 1115 01:00:49,000 --> 01:00:51,000 Nåväl, vad denna variabel kallas storleken säger. 1116 01:00:51,000 --> 01:00:53,000 Men vi behöver bara en ordbok. 1117 01:00:53,000 --> 01:00:55,000 Vi behöver inte en datatyp som kallas ordbok. 1118 01:00:55,000 --> 01:00:58,000 Vi behöver bara en av dem, så det visar sig i C 1119 01:00:58,000 --> 01:01:03,000 att om du inte säger typedef, du bara säga struct så inne i klammerparenteser 1120 01:01:03,000 --> 01:01:05,000 du sätter dina variabler, då du sätter namnet. 1121 01:01:05,000 --> 01:01:09,000 Detta förklarar en variabel som heter lexikon 1122 01:01:09,000 --> 01:01:11,000 som ser ut så här. 1123 01:01:11,000 --> 01:01:16,000 Däremot är dessa linjer skapar en återanvändbar datastruktur som kallas ord 1124 01:01:16,000 --> 01:01:19,000 att du kan skapa flera kopior av, precis som vi skapade 1125 01:01:19,000 --> 01:01:22,000 flera kopior av studenter. 1126 01:01:22,000 --> 01:01:24,000 >> Vad kan detta i slutändan oss att göra? 1127 01:01:24,000 --> 01:01:30,000 Låt mig gå tillbaka till, låt oss säga, en enklare exempel från enklare tider, 1128 01:01:30,000 --> 01:01:34,000 och låt mig öppna upp, låt oss säga, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 Problemet här till hands är att faktiskt dra tillbaka 1130 01:01:38,000 --> 01:01:41,000 lagret av en sträng och börjar ta bort dessa stödhjul 1131 01:01:41,000 --> 01:01:44,000 eftersom det visar sig att en sträng hela tiden 1132 01:01:44,000 --> 01:01:47,000 är som vi lovade i vecka 1 egentligen bara ett smeknamn, 1133 01:01:47,000 --> 01:01:51,000 en synonym från CS50 biblioteket för något som ser lite mer kryptisk, 1134 01:01:51,000 --> 01:01:53,000 char *, och vi har sett denna stjärna förut. 1135 01:01:53,000 --> 01:01:55,000 Vi såg det i samband med filer. 1136 01:01:55,000 --> 01:01:59,000 >> Låt oss nu se varför vi har gömt denna detalj under en tid nu. 1137 01:01:59,000 --> 01:02:02,000 Här är en fil som heter compare1.c, 1138 01:02:02,000 --> 01:02:07,000 och ber tydligen användaren för 2 strängar, s och t, 1139 01:02:07,000 --> 01:02:11,000 och sedan försöker jämföra dessa strängar för jämställdhet i linje 26, 1140 01:02:11,000 --> 01:02:14,000 och om de är lika står det: "Du skrev samma sak," 1141 01:02:14,000 --> 01:02:17,000 och om de inte är lika står det: "Du skrev olika saker." 1142 01:02:17,000 --> 01:02:19,000 Låt mig gå vidare och köra programmet. 1143 01:02:19,000 --> 01:02:23,000 Låt mig gå in i min källa katalog, göra en compare1. Det sammanställs okej. 1144 01:02:23,000 --> 01:02:25,000 Låt mig köra compare1. 1145 01:02:25,000 --> 01:02:27,000 Jag zooma in, in. 1146 01:02:27,000 --> 01:02:29,000 Säg något. HELLO. 1147 01:02:29,000 --> 01:02:32,000 Jag ska säga något igen. HELLO. 1148 01:02:32,000 --> 01:02:34,000 Jag definitivt inte typ olika saker. 1149 01:02:34,000 --> 01:02:37,000 >> Låt mig prova detta igen. BYE BYE. 1150 01:02:37,000 --> 01:02:40,000 Definitivt inte annorlunda, så vad som händer här? 1151 01:02:40,000 --> 01:02:44,000 Tja, vad som verkligen jämförs i linje 26? 1152 01:02:44,000 --> 01:02:46,000 [Ohörbart-student] 1153 01:02:46,000 --> 01:02:49,000 Ja, så visar det sig att en sträng, datatyp är typ av en vit lögn. 1154 01:02:49,000 --> 01:02:53,000 En sträng är en char *, men vad är en char *? 1155 01:02:53,000 --> 01:02:56,000 En char *, som man säger, är en pekare, 1156 01:02:56,000 --> 01:03:00,000 och en pekare är effektivt en adress, 1157 01:03:00,000 --> 01:03:05,000 en summa plats i minnet, och om du råkar ha skrivit in ett ord som HELLO, 1158 01:03:05,000 --> 01:03:08,000 minns från tidigare diskussioner om strängar 1159 01:03:08,000 --> 01:03:16,000 Detta är som ordet HELLO. 1160 01:03:16,000 --> 01:03:19,000 Kom ihåg att ett ord som HELLO kan representeras 1161 01:03:19,000 --> 01:03:22,000 som en array av tecken som denna 1162 01:03:22,000 --> 01:03:25,000 och sedan med ett specialtecken i slutet kallas noll karaktär, 1163 01:03:25,000 --> 01:03:27,000 som \ betecknar. 1164 01:03:27,000 --> 01:03:29,000 Vad är egentligen en sträng? 1165 01:03:29,000 --> 01:03:32,000 Observera att detta är flera bitar av minne, 1166 01:03:32,000 --> 01:03:36,000 och i själva verket är i slutet av det enda kända när du tittar genom hela strängen 1167 01:03:36,000 --> 01:03:38,000 letar efter den speciella null karaktär. 1168 01:03:38,000 --> 01:03:41,000 Men om det är en bit av minne från min dators minne, 1169 01:03:41,000 --> 01:03:44,000 låt oss säga godtyckligt att strängen bara hade tur, 1170 01:03:44,000 --> 01:03:47,000 och det blev placerad i början av datorns RAM-minne. 1171 01:03:47,000 --> 01:03:54,000 Detta är bitgruppen 0, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> När jag säger något i stil med GetString och jag string s = GetString 1173 01:04:02,000 --> 01:04:04,000 vad som verkligen är tillbaka? 1174 01:04:04,000 --> 01:04:08,000 För de senaste veckorna, är vad som verkligen lagras i s 1175 01:04:08,000 --> 01:04:13,000 är inte den här strängen i sig, men i detta fall vad som lagras är 1176 01:04:13,000 --> 01:04:18,000 numret 0 eftersom det GetString faktiskt gör 1177 01:04:18,000 --> 01:04:20,000 är det inte återvänder fysiskt en sträng. 1178 01:04:20,000 --> 01:04:22,000 Som inte ens verkligen göra konceptuella mening. 1179 01:04:22,000 --> 01:04:24,000 Vad den gör avkastning är ett nummer. 1180 01:04:24,000 --> 01:04:28,000 Det antalet är adressen HELLO i minnet, 1181 01:04:28,000 --> 01:04:32,000 och strängen är då, om vi skal tillbaka detta skikt, inte sträng egentligen inte existerar. 1182 01:04:32,000 --> 01:04:35,000 Det är bara en förenkling av CS50 biblioteket. 1183 01:04:35,000 --> 01:04:38,000 >> Detta är verkligen något som kallas char *. 1184 01:04:38,000 --> 01:04:41,000 Char vettigt eftersom det är ett ord, som HELLO? 1185 01:04:41,000 --> 01:04:44,000 Tja, det är en serie av tecken, en serie tecken. 1186 01:04:44,000 --> 01:04:47,000 Char * innebär adressen till en karaktär, 1187 01:04:47,000 --> 01:04:50,000 så vad innebär det att returnera en sträng? 1188 01:04:50,000 --> 01:04:53,000 Ett trevligt och enkelt sätt att returnera en sträng 1189 01:04:53,000 --> 01:04:57,000 snarare än att försöka räkna ut hur jag återvänder till 5 eller 6 olika byte 1190 01:04:57,000 --> 01:05:01,000 Låt mig återvända till den adress som byte? 1191 01:05:01,000 --> 01:05:03,000 Den första. 1192 01:05:03,000 --> 01:05:06,000 Med andra ord, låt mig ge er adressen till ett tecken i minnet. 1193 01:05:06,000 --> 01:05:10,000 Det är vad char * representerar adressen till en enda tecken i minnet. 1194 01:05:10,000 --> 01:05:12,000 Ring den variabeln är. 1195 01:05:12,000 --> 01:05:15,000 Butik i s just adress, som jag godtyckligt sagt är 0, 1196 01:05:15,000 --> 01:05:19,000 bara för att hålla det enkelt, men i verkligheten är det i allmänhet ett större antal. 1197 01:05:19,000 --> 01:05:21,000 >> Vänta lite. 1198 01:05:21,000 --> 01:05:23,000 Om du bara ger mig adressen till det första tecknet, hur vet jag vad adressen är 1199 01:05:23,000 --> 01:05:25,000 av det andra tecknet, den tredje, den fjärde och den femte? 1200 01:05:25,000 --> 01:05:27,000 [Ohörbart-student] 1201 01:05:27,000 --> 01:05:31,000 Du vet bara om slutet på strängen är genom denna behändiga trick, 1202 01:05:31,000 --> 01:05:35,000 så när du använder något som printf, vad printf bokstavligen tar sin argumentation, 1203 01:05:35,000 --> 01:05:39,000 ihåg att vi använder denna% s platshållare och sedan passera i 1204 01:05:39,000 --> 01:05:41,000 variabeln som är lagra en sträng. 1205 01:05:41,000 --> 01:05:47,000 Vad du verkligen passerar är adressen för det första tecknet i strängen. 1206 01:05:47,000 --> 01:05:50,000 Printf använder sedan en for-slinga eller en while-slinga vid mottagning den adressen, 1207 01:05:50,000 --> 01:05:53,000 till exempel 0, så låt mig göra det nu, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n" s); 1209 01:06:02,000 --> 01:06:07,000 När jag ringer printf ("% s \ n" s), vad jag verkligen ge printf med 1210 01:06:07,000 --> 01:06:13,000 är adressen för det första tecknet i s, vilken i detta fall godtyckliga är H. 1211 01:06:13,000 --> 01:06:16,000 >> Hur vet printf exakt vad som ska visas på skärmen? 1212 01:06:16,000 --> 01:06:19,000 Den person som genomfört genomförts printf en while-slinga eller en for-loop 1213 01:06:19,000 --> 01:06:23,000 som säger inte detta tecken lika med speciella noll karaktär? 1214 01:06:23,000 --> 01:06:25,000 Om inte, skriva ut den. Vad sägs om den här? 1215 01:06:25,000 --> 01:06:28,000 Om inte skriva ut det, skriva ut det, skriva ut det, skriva ut det. 1216 01:06:28,000 --> 01:06:32,000 Det här är en speciell. Stoppa utskriften och återgå till användaren. 1217 01:06:32,000 --> 01:06:35,000 Och det är bokstavligen allt som har hänt under huven, 1218 01:06:35,000 --> 01:06:38,000 och det är mycket att smälta på den första dagen av en klass, 1219 01:06:38,000 --> 01:06:43,000 men nu är det verkligen byggsten förståelse allt 1220 01:06:43,000 --> 01:06:46,000 som pågått på insidan av vår dators minne, 1221 01:06:46,000 --> 01:06:49,000 och så småningom kommer vi reta detta åt med lite hjälp 1222 01:06:49,000 --> 01:06:51,000 från en av våra vänner vid Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> Professor Nick Parlante vid Stanford har gjort denna underbara videosekvens 1224 01:06:56,000 --> 01:06:58,000 från alla möjliga olika språk som infördes 1225 01:06:58,000 --> 01:07:00,000 denna lilla Claymation tecken Binky. 1226 01:07:00,000 --> 01:07:03,000 Rösten du ska höra på bara några sekunder förhandstitt 1227 01:07:03,000 --> 01:07:05,000 är att en Stanford professor och du får 1228 01:07:05,000 --> 01:07:07,000 bara 5 eller 6 sekunder av detta just nu, 1229 01:07:07,000 --> 01:07:09,000 men detta är tonen som vi kan sluta idag 1230 01:07:09,000 --> 01:07:11,000 och börja på onsdag. 1231 01:07:11,000 --> 01:07:15,000 Jag ger dig Pointer Kul med Binky, förhandsgranskningen. 1232 01:07:15,000 --> 01:07:18,000 [♪ Musik ♪] [Professor Parlante] Hej, Binky. 1233 01:07:18,000 --> 01:07:21,000 Vakna. Det är dags för pekaren kul. 1234 01:07:21,000 --> 01:07:24,000 [Binky] Vad är det? Lär dig mer om pekare? 1235 01:07:24,000 --> 01:07:26,000 Åh, karamell! 1236 01:07:26,000 --> 01:07:29,000 >> Vi kommer att se dig på onsdag. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]