1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Uke 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 [Dette er CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> Greit, dette er CS50, og dette er starten på uke 4, 5 00:00:12,000 --> 00:00:16,000 og dette er en av de langsomste mulige sortering algoritmer. 6 00:00:16,000 --> 00:00:19,000 Som var det at vi bare så det? 7 00:00:19,000 --> 00:00:24,000 Det var boble sortere, for stor O (n ^ 2) + sum, 8 00:00:24,000 --> 00:00:28,000 og faktisk vi er ikke de eneste i denne verden for å synes å vite 9 00:00:28,000 --> 00:00:30,000 hva boble typen er eller dets kjøretid. 10 00:00:30,000 --> 00:00:33,000 Dette var faktisk et intervju med Eric Schmidt fra Google 11 00:00:33,000 --> 00:00:45,000 og tidligere senator Barack Obama bare noen få år siden. 12 00:00:45,000 --> 00:00:48,000 >> Nå Senator, du er her på Google, 13 00:00:48,000 --> 00:00:54,000 og jeg liker å tenke på formannskapet som et jobbintervju. 14 00:00:54,000 --> 00:00:58,000 Nå er det vanskelig å få en jobb som president, og du går gjennom påkjenningene nå. 15 00:00:58,000 --> 00:01:00,000 Det er også vanskelig å få en jobb hos Google. 16 00:01:00,000 --> 00:01:05,000 Vi har spørsmål, og vi ber våre kandidater spørsmål, 17 00:01:05,000 --> 00:01:10,000 og dette er fra Larry Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Dere tror jeg tuller? Det er rett her. 19 00:01:14,000 --> 00:01:18,000 Hva er den mest effektive måten å sortere en million 32-bit heltall? 20 00:01:18,000 --> 00:01:21,000 [Latter] 21 00:01:21,000 --> 00:01:24,000 Godt 22 00:01:24,000 --> 00:01:26,000 Jeg beklager. >> Nei, nei, nei, nei. 23 00:01:26,000 --> 00:01:34,000 Jeg tror boblen slag ville være feil vei å gå. 24 00:01:34,000 --> 00:01:39,000 >> Kom igjen, som fortalte ham dette? 25 00:01:39,000 --> 00:01:43,000 Forrige uke husker vi tok en pause fra kode, i hvert fall for en dag, 26 00:01:43,000 --> 00:01:46,000 og begynte å fokusere på noen høyere nivå ideer og problemløsning mer generelt 27 00:01:46,000 --> 00:01:49,000 i sammenheng med søking og sortering, 28 00:01:49,000 --> 00:01:53,000 og vi introdusert noe som vi ikke klapse dette navnet på forrige uke, 29 00:01:53,000 --> 00:01:56,000 men asymptotisk notasjon, Big O, the Big Omega, 30 00:01:56,000 --> 00:02:00,000 og noen ganger Big Theta notasjon, og disse var bare måter 31 00:02:00,000 --> 00:02:02,000 å beskrive kjøretiden til algoritmer, 32 00:02:02,000 --> 00:02:05,000 hvor mye tid det tar for en algoritme for å kjøre. 33 00:02:05,000 --> 00:02:08,000 >> Og du husker kanskje at du snakket om kjøretiden i forhold til størrelsen 34 00:02:08,000 --> 00:02:11,000 av input, som vi vanligvis kaller n, hva problemet kan være, 35 00:02:11,000 --> 00:02:13,000 der n er antall personer i rommet, 36 00:02:13,000 --> 00:02:17,000 antall sider i en telefonbok, og vi begynte å skrive ting ut 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 og selv når regnestykket ikke helt fungerer så perfekt 39 00:02:24,000 --> 00:02:28,000 og det var n ² - n / 2 eller noe sånt 40 00:02:28,000 --> 00:02:31,000 Vi vil i stedet bare kaste bort noen av de lavere ordens ledd, 41 00:02:31,000 --> 00:02:34,000 og motivasjonen er det at vi virkelig ønsker en 42 00:02:34,000 --> 00:02:37,000 slags objektiv måte å vurdere 43 00:02:37,000 --> 00:02:39,000 ytelsen til programmer eller ytelsen av algoritmer 44 00:02:39,000 --> 00:02:42,000 at på slutten av dagen har ingenting å gjøre, for eksempel, 45 00:02:42,000 --> 00:02:45,000 med hastigheten på datamaskinen i dag. 46 00:02:45,000 --> 00:02:47,000 >> For eksempel, hvis du implementerer boble sortere, 47 00:02:47,000 --> 00:02:50,000 eller du implementere flette sortere eller valg sorterer på dagens datamaskin, 48 00:02:50,000 --> 00:02:53,000 en 2 GHz datamaskin, og du kjører den, 49 00:02:53,000 --> 00:02:56,000 og det tar noen flere sekunder, neste år er det en 3 GHz 50 00:02:56,000 --> 00:02:59,000 eller en 4 GHz datamaskin, og du kan da hevde at "Wow, min algoritme 51 00:02:59,000 --> 00:03:03,000 er nå dobbelt så fort ", når det i realiteten det er åpenbart ikke tilfelle. 52 00:03:03,000 --> 00:03:06,000 Det er bare maskinvaren har fått raskere, men datamaskinen 53 00:03:06,000 --> 00:03:10,000 har ikke, og slik at vi virkelig ønsker å kaste bort ting som 54 00:03:10,000 --> 00:03:13,000 multipler av 2 eller multipler av 3 når det gjelder å beskrive 55 00:03:13,000 --> 00:03:17,000 hvor fort eller hvor sakte en algoritme er og egentlig bare fokusere 56 00:03:17,000 --> 00:03:20,000 på n eller noen faktor av disse, 57 00:03:20,000 --> 00:03:24,000 noe strøm derav som i tilfelle av slag fra siste uke. 58 00:03:24,000 --> 00:03:27,000 Og husker at med hjelp av flettingen slag 59 00:03:27,000 --> 00:03:31,000 vi var i stand til å gjøre så mye bedre enn boble sortere og utvalg sorter 60 00:03:31,000 --> 00:03:33,000 og selv innsetting slag. 61 00:03:33,000 --> 00:03:36,000 >> Vi kom ned til n log n, og igjen, 62 00:03:36,000 --> 00:03:39,000 huske at log n vanligvis refererer til noe som vokser 63 00:03:39,000 --> 00:03:43,000 saktere da n, så n log n så langt var bra 64 00:03:43,000 --> 00:03:45,000 fordi det var mindre enn n ². 65 00:03:45,000 --> 00:03:47,000 Men for å oppnå n log n med fletting slags 66 00:03:47,000 --> 00:03:51,000 hva var den grunnleggende kimen til en idé om at vi måtte utnytte 67 00:03:51,000 --> 00:03:54,000 at vi også leveraged tilbake i uke 0? 68 00:03:54,000 --> 00:03:58,000 Hvordan gjorde vi takle sortering problemet cleverly med fletting slags? 69 00:03:58,000 --> 00:04:04,000 Hva var nøkkelen innsikt, kanskje? 70 00:04:04,000 --> 00:04:07,000 Noen i det hele tatt. 71 00:04:07,000 --> 00:04:09,000 Ok, la oss ta et skritt tilbake. 72 00:04:09,000 --> 00:04:11,000 Beskriv flette sortere i dine egne ord. 73 00:04:11,000 --> 00:04:15,000 Hvordan fungerte det? 74 00:04:15,000 --> 00:04:17,000 Ok, vi ro tilbake til uken 0. 75 00:04:17,000 --> 00:04:19,000 Ok, ja. 76 00:04:19,000 --> 00:04:22,000 [Uhørlig-student] 77 00:04:22,000 --> 00:04:26,000 Ok, bra, så vi delte rekke tall i 2 deler. 78 00:04:26,000 --> 00:04:29,000 Vi sortert hver av disse bitene, og da vi fusjonerte dem, 79 00:04:29,000 --> 00:04:33,000 og vi har sett denne ideen før å ta et problem som er så stor 80 00:04:33,000 --> 00:04:36,000 og hakking den opp i et problem som er så stor eller så stor. 81 00:04:36,000 --> 00:04:38,000 >> Husker telefonboken eksempel. 82 00:04:38,000 --> 00:04:42,000 Husker selv-telling algoritme fra uker siden, 83 00:04:42,000 --> 00:04:45,000 så flette sort ble oppsummert av denne pseudokode her. 84 00:04:45,000 --> 00:04:48,000 Når du får n elementer, først det var sunn fornuft sjekk. 85 00:04:48,000 --> 00:04:51,000 Hvis n <2 så ikke gjør noe i det hele tatt 86 00:04:51,000 --> 00:04:55,000 fordi hvis n <2 deretter n er åpenbart 0 eller 1, 87 00:04:55,000 --> 00:04:57,000 og så hvis det er enten 0 eller 1 er det ingenting å sortere. 88 00:04:57,000 --> 00:04:59,000 Du er ferdig. 89 00:04:59,000 --> 00:05:01,000 Listen er allerede trivially sortert. 90 00:05:01,000 --> 00:05:04,000 Men ellers hvis du har to eller flere elementer gå videre og dele dem 91 00:05:04,000 --> 00:05:06,000 i 2 halvdeler, venstre og høyre. 92 00:05:06,000 --> 00:05:09,000 Sortere hver av disse halvdeler, og deretter flette sortert halvdeler. 93 00:05:09,000 --> 00:05:13,000 Men problemet her er at ved første øyekast dette føles som om vi punting. 94 00:05:13,000 --> 00:05:17,000 Dette er en sirkulær definisjon i at hvis jeg har bedt deg om å sortere disse n elementer 95 00:05:17,000 --> 00:05:22,000 og du forteller meg "All right, fine, vil vi sortere de n / 2 og de n / 2 elementer," 96 00:05:22,000 --> 00:05:27,000 så mitt neste spørsmål kommer til å være "Fine, hvordan du sortere n / 2 elementer?" 97 00:05:27,000 --> 00:05:30,000 >> Men på grunn av strukturen av dette programmet, 98 00:05:30,000 --> 00:05:33,000 fordi det er denne base case, så å si, 99 00:05:33,000 --> 00:05:39,000 dette spesielle tilfellet som sier at hvis n er 00:05:42,000 Ikke svar med det samme sirkulære svar. 101 00:05:42,000 --> 00:05:46,000 Denne prosessen, vil dette syklisitet slutt ende. 102 00:05:46,000 --> 00:05:50,000 Hvis jeg spør deg "Sorter disse n elementer", og sier du, "Fine, sortere disse n / 2," 103 00:05:50,000 --> 00:05:53,000 så du sier, "Fine, sort disse n / 4, n / 8, n/16," 104 00:05:53,000 --> 00:05:56,000 til slutt vil du dele med en stor nok antall 105 00:05:56,000 --> 00:05:59,000 at du vil ha bare 1 element venstre, og da kan du si, 106 00:05:59,000 --> 00:06:02,000 "Her, her er en sortert enkelt element." 107 00:06:02,000 --> 00:06:06,000 Da glans av denne algoritmen opp her er å komme fra det faktum 108 00:06:06,000 --> 00:06:09,000 at når du har alle disse individuelt sorterte lister, 109 00:06:09,000 --> 00:06:12,000 som alle er av størrelse 1, som synes å være ubrukelig, 110 00:06:12,000 --> 00:06:15,000 når du begynner å flette dem og flette dem 111 00:06:15,000 --> 00:06:19,000 du bygge opp til slutt som Rob gjorde i videoen en endelig sortert liste. 112 00:06:19,000 --> 00:06:22,000 >> Men denne ideen strekker seg langt utover sortering. 113 00:06:22,000 --> 00:06:26,000 Det er denne ideen som er innebygd i dette programmet kjent som rekursjon, 114 00:06:26,000 --> 00:06:29,000 ideen der du er et program, 115 00:06:29,000 --> 00:06:32,000 og for å løse noen problemer du kaller deg selv, 116 00:06:32,000 --> 00:06:36,000 eller sette i sammenheng med programmeringsspråk du er en funksjon, 117 00:06:36,000 --> 00:06:39,000 og for å løse et problem, du funksjonen kaller deg selv 118 00:06:39,000 --> 00:06:42,000 igjen og igjen og igjen, men du funksjonen 119 00:06:42,000 --> 00:06:44,000 kan ikke kalle deg uendelig mange ganger. 120 00:06:44,000 --> 00:06:47,000 Til slutt må du bunnen ut, så å si, 121 00:06:47,000 --> 00:06:49,000 og har noen hardkodet basen tilstand som sier 122 00:06:49,000 --> 00:06:53,000 på dette punktet slutte å kalle deg selv slik at hele prosessen 123 00:06:53,000 --> 00:06:56,000 endelig stopper faktisk. 124 00:06:56,000 --> 00:06:58,000 Hva betyr dette egentlig, å Recurse? 125 00:06:58,000 --> 00:07:01,000 >> La oss se, hvis vi kan gjøre en enkel, trivielt eksempel med, sier 126 00:07:01,000 --> 00:07:03,000 3 personer med meg her oppe på scenen, hvis noen er komfortable. 127 00:07:03,000 --> 00:07:06,000 1, kom opp, 2 og 3. 128 00:07:06,000 --> 00:07:09,000 Hvis du tre ønsker å komme opp her. 129 00:07:09,000 --> 00:07:12,000 Hvis du ønsker å stå rett ved siden av meg her i en linje, antar at problemet for hånden 130 00:07:12,000 --> 00:07:15,000 er telle svært trivially antall personer som er her. 131 00:07:15,000 --> 00:07:18,000 Men ærlig, jeg er lei av alle disse telling eksempler. 132 00:07:18,000 --> 00:07:21,000 Dette kommer til å ta litt tid, 1, 2, og prikk, prikk, prikk. 133 00:07:21,000 --> 00:07:23,000 Det kommer til å ta en evighet. 134 00:07:23,000 --> 00:07:25,000 Jeg vil heller bare punt dette problemet helt ved hjelp av-hva heter du? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, all right. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly og? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly, og Willy. 138 00:07:31,000 --> 00:07:34,000 Akkurat nå har jeg blitt bedt om spørsmålet av noen 139 00:07:34,000 --> 00:07:37,000 hvor mange mennesker er oppe på dette stadiet, og jeg har ingen anelse. 140 00:07:37,000 --> 00:07:40,000 Dette er en veldig lang liste, og så i stedet jeg kommer til å gjøre dette trikset. 141 00:07:40,000 --> 00:07:43,000 Jeg kommer til å be personen ved siden av meg å gjøre det meste av arbeidet, 142 00:07:43,000 --> 00:07:46,000 og når hun er ferdig gjør det meste av arbeidet 143 00:07:46,000 --> 00:07:49,000 Jeg kommer til å gjøre minst mulig arbeid mulig og bare legge en 144 00:07:49,000 --> 00:07:51,000 til hva hennes svar er, så her vi går. 145 00:07:51,000 --> 00:07:54,000 Jeg har blitt spurt om hvor mange personer som er på scenen. 146 00:07:54,000 --> 00:07:57,000 Hvor mange mennesker er på scenen til venstre for deg? 147 00:07:57,000 --> 00:08:00,000 Venstre for meg? >> Ok, men ikke jukse. 148 00:08:00,000 --> 00:08:04,000 Det er bra, det er riktig, men hvis vi ønsker å fortsette denne logikken 149 00:08:04,000 --> 00:08:08,000 la oss anta at du på samme måte vil punt dette problemet til venstre for deg, 150 00:08:08,000 --> 00:08:11,000 så heller enn svar direkte gå videre og bare overlate oppgaven. 151 00:08:11,000 --> 00:08:14,000 Å, hvor mange mennesker er til venstre for meg? 152 00:08:14,000 --> 00:08:16,000 Hvor mange mennesker er til venstre? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Latter] 155 00:08:27,000 --> 00:08:30,000 Ok, så 0, så hva nå Willy har gjort 156 00:08:30,000 --> 00:08:33,000 er du har returnert svaret denne retningen sier 0. 157 00:08:33,000 --> 00:08:36,000 Nå, hva skal du gjøre? >> 1. 158 00:08:36,000 --> 00:08:39,000 Ok, så du er en, så sier du, "All right, jeg kommer til å legge en 159 00:08:39,000 --> 00:08:41,000 til hva Willy telling var, "så 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Du er nå en så svaret på akkurat nå er- 161 00:08:43,000 --> 00:08:45,000 1. >> Og mine ville være 2. 162 00:08:45,000 --> 00:08:48,000 Bra, så du tar det forrige svaret på 1, 163 00:08:48,000 --> 00:08:51,000 legge minimalt med arbeid du ønsker å gjøre, som er en. 164 00:08:51,000 --> 00:08:55,000 Du har nå to, og du deretter gi meg hvilken verdi? 165 00:08:55,000 --> 00:08:57,000 3, mener jeg, beklager, 2. 166 00:08:57,000 --> 00:08:59,000 Bra. 167 00:08:59,000 --> 00:09:02,000 >> Vel, vi hadde 0 til venstre. 168 00:09:02,000 --> 00:09:05,000 Da vi hadde en, og så legger vi til 2, 169 00:09:05,000 --> 00:09:07,000 og nå er du levere meg nummer 2, 170 00:09:07,000 --> 00:09:10,000 og så jeg sier, ok, +1, 3. 171 00:09:10,000 --> 00:09:13,000 Det er faktisk tre mennesker som står ved siden av meg på dette stadiet, 172 00:09:13,000 --> 00:09:16,000 slik at vi kunne ha åpenbart gjort dette veldig lineært, 173 00:09:16,000 --> 00:09:19,000 veldig mye i det åpenbare mote, men hva gjorde vi egentlig gjøre? 174 00:09:19,000 --> 00:09:21,000 Vi tok et problem av størrelse 3 i utgangspunktet. 175 00:09:21,000 --> 00:09:24,000 Vi brøt det ned i et problem med størrelse 2, 176 00:09:24,000 --> 00:09:27,000 deretter et problem av størrelse 1, og deretter endelig base case 177 00:09:27,000 --> 00:09:29,000 var virkelig, oh, det er ingen der, 178 00:09:29,000 --> 00:09:33,000 på hvilket punkt Willy returnerte effektivt en hardkodet svar et par ganger, 179 00:09:33,000 --> 00:09:36,000 og den andre ble deretter boblet opp, boblet opp, boblet opp, 180 00:09:36,000 --> 00:09:39,000 og deretter ved å legge i denne ytterligere 1 181 00:09:39,000 --> 00:09:41,000 Vi har implementert denne grunnleggende ideen om rekursjon. 182 00:09:41,000 --> 00:09:44,000 >> Nå, i dette tilfellet det ikke virkelig løse et problem 183 00:09:44,000 --> 00:09:46,000 noe mer effektivt da vi har sett så langt. 184 00:09:46,000 --> 00:09:48,000 Men tenk om algoritmer vi har gjort på scenen så langt. 185 00:09:48,000 --> 00:09:51,000 Vi hadde 8 stykker av papir på tavla, 186 00:09:51,000 --> 00:09:55,000 på video når Sean var på utkikk etter nummer 7, og hva gjorde han egentlig gjøre? 187 00:09:55,000 --> 00:09:58,000 Vel, han gjorde ikke gjøre noen form for splitt og hersk. 188 00:09:58,000 --> 00:10:01,000 Han gjorde ikke noen form for rekursjon. 189 00:10:01,000 --> 00:10:03,000 Heller han bare gjorde dette lineære algoritme. 190 00:10:03,000 --> 00:10:07,000 Men da vi introduserte ideen om sortert tall på scenen leve forrige uke 191 00:10:07,000 --> 00:10:09,000 da vi hadde dette instinktet for å gå til midten, 192 00:10:09,000 --> 00:10:13,000 på hvilket punkt vi hadde en mindre liste av størrelse 4 eller en annen liste over størrelse 4, 193 00:10:13,000 --> 00:10:17,000 og da vi hadde nøyaktig samme problem, så vi gjentok, gjentatt, gjentatt. 194 00:10:17,000 --> 00:10:19,000 Med andre ord, recursed vi. 195 00:10:19,000 --> 00:10:24,000 Tusen takk til våre 3 frivillige her for å demonstrere rekursjon med oss. 196 00:10:24,000 --> 00:10:28,000 >> La oss se om vi ikke kan gjøre dette nå litt mer konkret, 197 00:10:28,000 --> 00:10:30,000 løse et problem som igjen vi kunne gjøre ganske enkelt, 198 00:10:30,000 --> 00:10:34,000 men vi vil bruke det som et springbrett til å implementere denne grunnleggende ideen. 199 00:10:34,000 --> 00:10:37,000 Hvis jeg ønsker å beregne summering av en haug med tall, 200 00:10:37,000 --> 00:10:39,000 for eksempel, hvis du passerer i nummer 3, 201 00:10:39,000 --> 00:10:42,000 Jeg ønsker å gi deg verdien av sigma 3, 202 00:10:42,000 --> 00:10:46,000 slik at summen av 3 + 2 + 1 + 0. 203 00:10:46,000 --> 00:10:48,000 Jeg ønsker å komme tilbake svaret 6, 204 00:10:48,000 --> 00:10:51,000 så vi vil implementere denne sigma funksjonen, denne oppsummeringen funksjonen 205 00:10:51,000 --> 00:10:54,000 som, igjen, tar i inngang, og deretter returnerer summering 206 00:10:54,000 --> 00:10:57,000 av dette nummeret hele veien ned til 0. 207 00:10:57,000 --> 00:10:59,000 Vi kunne gjøre dette ganske enkelt, ikke sant? 208 00:10:59,000 --> 00:11:01,000 Vi kunne gjøre dette med en slags looping struktur, 209 00:11:01,000 --> 00:11:04,000 så la meg gå videre og få dette i gang. 210 00:11:04,000 --> 00:11:07,000 >> Inkluder stdio.h. 211 00:11:07,000 --> 00:11:09,000 La meg komme meg inn viktigste å jobbe med her. 212 00:11:09,000 --> 00:11:12,000 La oss lagre dette som sigma.c. 213 00:11:12,000 --> 00:11:14,000 Så jeg kommer til å gå inn her, og jeg kommer til å erklære en int n, 214 00:11:14,000 --> 00:11:18,000 og jeg kommer til å gjøre følgende mens brukeren ikke samarbeider. 215 00:11:18,000 --> 00:11:22,000 Mens brukeren ikke har gitt meg et positivt tall 216 00:11:22,000 --> 00:11:26,000 la meg gå videre og be dem for n = GetInt, 217 00:11:26,000 --> 00:11:28,000 og la meg gi dem noen instruksjoner om hva du skal gjøre, 218 00:11:28,000 --> 00:11:33,000 så printf ("Positiv heltall please"). 219 00:11:33,000 --> 00:11:39,000 Bare noe relativt enkelt som dette slik at etter den tid traff vi linje 14 220 00:11:39,000 --> 00:11:42,000 Vi har nå et positivt heltall antagelig i n. 221 00:11:42,000 --> 00:11:44,000 >> Nå la oss gjøre noe med det. 222 00:11:44,000 --> 00:11:50,000 La meg gå videre og beregne summering, så int sum = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma er bare summering, så jeg bare skrive det i mer avansert måte. 224 00:11:54,000 --> 00:11:56,000 Vi vil bare kalle det sigma der. 225 00:11:56,000 --> 00:11:58,000 Det er summen, og nå skal jeg skrive ut resultatet, 226 00:11:58,000 --> 00:12:08,000 printf ("Summen er% d \ n", sum). 227 00:12:08,000 --> 00:12:11,000 Og så skal jeg tilbake 0 for godt mål. 228 00:12:11,000 --> 00:12:15,000 Vi har gjort alt som dette programmet krever unntatt den interessante delen, 229 00:12:15,000 --> 00:12:18,000 som er å faktisk implementere sigma funksjonen. 230 00:12:18,000 --> 00:12:22,000 >> La meg gå ned hit til bunnen, og la meg erklære funksjon sigma. 231 00:12:22,000 --> 00:12:26,000 Det er nødt til å ta en variabel som er av typen heltall, 232 00:12:26,000 --> 00:12:30,000 og hva datatype ønsker jeg å returnere antagelig fra sigma? 233 00:12:30,000 --> 00:12:34,000 Int, fordi jeg vil at den skal matche mine forventninger på linje 15. 234 00:12:34,000 --> 00:12:37,000 Her la meg gå videre og gjennomføre dette 235 00:12:37,000 --> 00:12:41,000 i en ganske grei måte. 236 00:12:41,000 --> 00:12:45,000 >> La oss gå videre og si int sum = 0, 237 00:12:45,000 --> 00:12:47,000 og nå skal jeg gå har litt for loop her 238 00:12:47,000 --> 00:12:50,000 som kommer til å si noe sånt som dette, 239 00:12:50,000 --> 00:13:01,000 for (int i = 0; I <= antall; i + +) sum + = i. 240 00:13:01,000 --> 00:13:05,000 Og så skal jeg komme tilbake summen. 241 00:13:05,000 --> 00:13:07,000 Jeg kunne ha gjennomført dette i en rekke måter. 242 00:13:07,000 --> 00:13:09,000 Jeg kunne ha brukt en stund loop. 243 00:13:09,000 --> 00:13:11,000 Jeg kunne ha hoppet med summen variabel hvis jeg virkelig ville, 244 00:13:11,000 --> 00:13:15,000 men kort sagt, vi bare har en funksjon som hvis jeg ikke tabbe erklærer sum er 0. 245 00:13:15,000 --> 00:13:18,000 Så det itererer fra 0 på opp gjennom antall, 246 00:13:18,000 --> 00:13:23,000 og på hver iterasjon legger det at dagens verdi til sum og deretter returnerer sum. 247 00:13:23,000 --> 00:13:25,000 >> Nå er det en liten optimalisering her. 248 00:13:25,000 --> 00:13:29,000 Dette er trolig en bortkastet trinn, men det får så være. Det er greit for nå. 249 00:13:29,000 --> 00:13:32,000 Vi er minst å være grundig og gå 0 hele veien videre opp. 250 00:13:32,000 --> 00:13:34,000 Ikke veldig hardt og ganske grei, 251 00:13:34,000 --> 00:13:37,000 men det viser seg at med sigma-funksjonen har vi samme mulighet 252 00:13:37,000 --> 00:13:39,000 som vi gjorde her på scenen. 253 00:13:39,000 --> 00:13:42,000 På scenen vi bare telles hvor mange som var ved siden av meg, 254 00:13:42,000 --> 00:13:47,000 men i stedet hvis vi ønsket å telle antall 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 ned til 0 kunne vi likeledes punt til en funksjon 256 00:13:51,000 --> 00:13:55,000 at jeg vil i stedet beskrive som rekursiv. 257 00:13:55,000 --> 00:13:57,000 Her la oss sjekke en rask sunn fornuft gjør og sørge for at jeg ikke tabbe. 258 00:13:57,000 --> 00:14:00,000 >> Jeg vet det er minst én ting i dette programmet at jeg gjorde feil. 259 00:14:00,000 --> 00:14:04,000 Da jeg traff inn kommer jeg til å få noen form for roping på meg? 260 00:14:04,000 --> 00:14:06,000 Hva skal jeg bli skreket til om? 261 00:14:06,000 --> 00:14:11,000 Ja, jeg glemte prototypen, så jeg bruker en funksjon kalt sigma på linje 15, 262 00:14:11,000 --> 00:14:16,000 men det er ikke erklært før linje 22, så jeg best proaktivt gå opp her 263 00:14:16,000 --> 00:14:22,000 og erklære en prototype, og jeg vil si int sigma (int tall), og det er det. 264 00:14:22,000 --> 00:14:24,000 Det er implementert i bunnen. 265 00:14:24,000 --> 00:14:27,000 >> Eller en annen måte jeg kunne løse dette, 266 00:14:27,000 --> 00:14:30,000 Jeg kunne flytte funksjonen der oppe, som ikke er dårlig, 267 00:14:30,000 --> 00:14:32,000 men minst når programmene dine begynner å bli lang, ærlig, 268 00:14:32,000 --> 00:14:35,000 Jeg tror det er noen verdi i å alltid ha hoved øverst 269 00:14:35,000 --> 00:14:38,000 slik at du i leseren kan åpne filen og deretter umiddelbart se 270 00:14:38,000 --> 00:14:40,000 hva programmet gjør uten å måtte søke gjennom det 271 00:14:40,000 --> 00:14:42,000 på jakt etter den viktigste funksjonen. 272 00:14:42,000 --> 00:14:49,000 La oss gå ned til min terminal-vinduet her, kan du prøve å lage sigma gjør sigma, 273 00:14:49,000 --> 00:14:51,000 og jeg skrudd opp her også. 274 00:14:51,000 --> 00:14:55,000 Implisitt deklarasjon av funksjon GetInt betyr at jeg har glemt å gjøre hva annet? 275 00:14:55,000 --> 00:14:57,000 [Uhørlig-student] 276 00:14:57,000 --> 00:15:00,000 Bra, så tilsynelatende en vanlig feil, så la oss sette dette opp her, 277 00:15:00,000 --> 00:15:04,000 cs50.h, og nå la oss gå tilbake til min terminal-vinduet. 278 00:15:04,000 --> 00:15:08,000 >> Jeg vil tømme skjermen, og jeg skal kjøre lage sigma. 279 00:15:08,000 --> 00:15:11,000 Det synes å ha utarbeidet. La meg nå kjøre sigma. 280 00:15:11,000 --> 00:15:15,000 Jeg skal skrive inn nummer 3, og jeg fikk 6, så ikke en streng sjekk, 281 00:15:15,000 --> 00:15:18,000 men minst det synes å bli arbeider ved første øyekast, men la oss nå rive den fra hverandre, 282 00:15:18,000 --> 00:15:21,000 og la oss utnytte faktisk ideen av rekursjon, igjen, 283 00:15:21,000 --> 00:15:24,000 på en svært enkel sammenheng slik at om noen ukers tid 284 00:15:24,000 --> 00:15:27,000 når vi begynner å utforske mer avansert datastrukturer enn arrays 285 00:15:27,000 --> 00:15:30,000 Vi har et annet verktøy i verktøykasse med å 286 00:15:30,000 --> 00:15:33,000 manipulere disse datastrukturer som vi skal se. 287 00:15:33,000 --> 00:15:36,000 Dette er iterativ tilnærming, loopen tilnærming. 288 00:15:36,000 --> 00:15:39,000 >> La meg i stedet nå gjøre dette. 289 00:15:39,000 --> 00:15:44,000 La meg i stedet si at summering av tall 290 00:15:44,000 --> 00:15:48,000 ned til 0 er virkelig det samme som 291 00:15:48,000 --> 00:15:53,000 nummer + sigma (antall - 1). 292 00:15:53,000 --> 00:15:57,000 Med andre ord, akkurat som på scenen punted jeg til hver av folk ved siden av meg, 293 00:15:57,000 --> 00:16:00,000 og de i sin tur holdt punting før vi endelig bunnet ut på Willy, 294 00:16:00,000 --> 00:16:03,000 som måtte returnere en hardkodet svar som 0. 295 00:16:03,000 --> 00:16:07,000 Her nå er vi på samme måte punting til sigma 296 00:16:07,000 --> 00:16:10,000 samme funksjon som egentlig heter, men nøkkelen innsikt her 297 00:16:10,000 --> 00:16:12,000 er at vi ikke kaller sigma likt. 298 00:16:12,000 --> 00:16:14,000 Vi er ikke bestått i n. 299 00:16:14,000 --> 00:16:17,000 Vi er tydelig passerer i antall - 1, 300 00:16:17,000 --> 00:16:20,000 så en litt mindre problem, litt mindre problem. 301 00:16:20,000 --> 00:16:23,000 >> Dessverre er dette ikke helt en løsning ennå, og før vi fikse 302 00:16:23,000 --> 00:16:26,000 hva som kan hoppe ut så opplagt at noen av dere 303 00:16:26,000 --> 00:16:28,000 la meg gå videre og kjøre gjør. 304 00:16:28,000 --> 00:16:30,000 Det synes å kompilere greit. 305 00:16:30,000 --> 00:16:32,000 La meg kjøre sigma med 6. 306 00:16:32,000 --> 00:16:37,000 Whoops, la meg kjøre sigma med 6. 307 00:16:37,000 --> 00:16:42,000 Vi har sett dette før, om enn utilsiktet sist gang også. 308 00:16:42,000 --> 00:16:48,000 Hvorfor fikk jeg denne kryptiske segmentering feil? Ja. 309 00:16:48,000 --> 00:16:50,000 [Uhørlig-student] 310 00:16:50,000 --> 00:16:53,000 Det er ingen base case, og mer spesifikt, hva kan ha skjedd? 311 00:16:53,000 --> 00:16:58,000 Dette er et symptom på hva slags atferd? 312 00:16:58,000 --> 00:17:00,000 Si det litt høyere. 313 00:17:00,000 --> 00:17:02,000 [Uhørlig-student] 314 00:17:02,000 --> 00:17:05,000 Det er en uendelig loop effektivt, og problemet med uendelige løkker 315 00:17:05,000 --> 00:17:08,000 når de involverer rekursjon i dette tilfellet, en funksjon ringer selv, 316 00:17:08,000 --> 00:17:10,000 hva skjer hver gang du ringer en funksjon? 317 00:17:10,000 --> 00:17:13,000 Vel, tenker tilbake til hvordan vi lagt ut minnet i en datamaskin. 318 00:17:13,000 --> 00:17:16,000 Vi sa at det er denne del av minnet som kalles stabelen som er på bunnen, 319 00:17:16,000 --> 00:17:19,000 og hver gang du ringer en funksjon litt mer minne blir satt 320 00:17:19,000 --> 00:17:24,000 på denne såkalte stack inneholder som fungerer lokale variabler eller parametere, 321 00:17:24,000 --> 00:17:27,000 så hvis sigma kaller sigma samtaler sigma kaller sigma 322 00:17:27,000 --> 00:17:29,000  kaller sigma hvor kommer denne historien ende? 323 00:17:29,000 --> 00:17:31,000 >> Vel, det til slutt overskridelsene den totale mengden 324 00:17:31,000 --> 00:17:33,000 minne som du har tilgjengelig til datamaskinen. 325 00:17:33,000 --> 00:17:37,000 Du overkjørt segmentet som du er ment å holde seg innenfor, 326 00:17:37,000 --> 00:17:40,000 og du får dette segmentering feil, dumpet kjerne, 327 00:17:40,000 --> 00:17:43,000 og hva kjernen dumpet betyr er at jeg nå har en fil som heter kjerne 328 00:17:43,000 --> 00:17:46,000 som er en fil som inneholder nuller og enere 329 00:17:46,000 --> 00:17:49,000 som faktisk i fremtiden vil være nyttig diagnostisk. 330 00:17:49,000 --> 00:17:52,000 Hvis det ikke er åpenbart for deg hvor feilen er 331 00:17:52,000 --> 00:17:54,000 du kan faktisk gjøre litt av rettsmedisinske analyser, så å si, 332 00:17:54,000 --> 00:17:58,000 på denne kjernen dump filen, som er igjen, bare en hel haug med nuller og enere 333 00:17:58,000 --> 00:18:02,000 som representerer i hovedsak staten programmet i minnet 334 00:18:02,000 --> 00:18:05,000 i det øyeblikket den krasjet på denne måten. 335 00:18:05,000 --> 00:18:11,000 >> Reparasjonen her er at vi kan ikke bare blindt returnere sigma, 336 00:18:11,000 --> 00:18:14,000 tallet + sigma av en litt mindre problem. 337 00:18:14,000 --> 00:18:16,000 Vi trenger å ha noen form for base case her, 338 00:18:16,000 --> 00:18:19,000 og hva bør base case sannsynligvis være? 339 00:18:19,000 --> 00:18:22,000 [Uhørlig-student] 340 00:18:22,000 --> 00:18:25,000 Ok, så lenge antallet er positivt vi skal faktisk tilbake dette, 341 00:18:25,000 --> 00:18:29,000 eller sagt på en annen måte, hvis tall er, sier <= til 0 342 00:18:29,000 --> 00:18:32,000 vet du hva, jeg skal gå videre og returnere 0, 343 00:18:32,000 --> 00:18:36,000 mye som Willy gjorde, og annet, jeg kommer til å gå videre 344 00:18:36,000 --> 00:18:41,000 og returnere dette, så det er ikke så mye kortere 345 00:18:41,000 --> 00:18:44,000 enn iterativ versjon som vi pisket opp først med en for loop, 346 00:18:44,000 --> 00:18:48,000 men merker at det er denne typen eleganse til det. 347 00:18:48,000 --> 00:18:51,000 I stedet for å returnere en tall og utføre alt dette regnestykket 348 00:18:51,000 --> 00:18:54,000 og legge opp ting med lokale variabler 349 00:18:54,000 --> 00:18:57,000 du i stedet sier "Ok, hvis dette er en super enkelt problem, 350 00:18:57,000 --> 00:19:01,000 som antall er <0, la meg straks tilbake 0 ". 351 00:19:01,000 --> 00:19:03,000 >> Vi kommer ikke til å bry støtte negative tall, 352 00:19:03,000 --> 00:19:05,000 så jeg kommer til hardt kode verdien 0.. 353 00:19:05,000 --> 00:19:08,000 Men ellers, for å gjennomføre denne ideen summere 354 00:19:08,000 --> 00:19:11,000 alle disse tallene sammen du effektivt kan ta en liten matbit 355 00:19:11,000 --> 00:19:14,000 ut av problemet, mye som vi gjorde her på scenen, 356 00:19:14,000 --> 00:19:18,000 deretter punt resten av problemet til neste person, 357 00:19:18,000 --> 00:19:20,000 men i dette tilfellet den neste person er selv. 358 00:19:20,000 --> 00:19:22,000 Det er en identisk navn funksjon. 359 00:19:22,000 --> 00:19:25,000 Bare gi det en mindre og mindre og mindre problem hver gang, 360 00:19:25,000 --> 00:19:28,000 og selv om vi ikke har helt formaliserte ting i koden her 361 00:19:28,000 --> 00:19:33,000 Dette er nøyaktig hva som skjer i uke 0 med telefonboken. 362 00:19:33,000 --> 00:19:36,000 Dette er akkurat hva som skjer i de siste ukene med Sean 363 00:19:36,000 --> 00:19:39,000 og med våre demonstrasjoner for å søke etter tall. 364 00:19:39,000 --> 00:19:42,000 Det tar et problem, og dele det igjen og igjen. 365 00:19:42,000 --> 00:19:44,000 >> Med andre ord, det er en måte nå med å oversette 366 00:19:44,000 --> 00:19:47,000 denne virkelige verden konstruere, dette høyere nivå konstruere 367 00:19:47,000 --> 00:19:51,000 av splitt og hersk og gjør noe igjen og igjen 368 00:19:51,000 --> 00:19:56,000 i kode, så dette er noe vi vil se igjen over tid. 369 00:19:56,000 --> 00:20:00,000 Nå, som en side, hvis du er ny på rekursjon du bør i det minste forstå nå 370 00:20:00,000 --> 00:20:02,000 hvorfor dette er morsomt. 371 00:20:02,000 --> 00:20:05,000 Jeg kommer til å gå til google.com, 372 00:20:05,000 --> 00:20:17,000 og jeg kommer til å søke etter noen tips og triks på rekursjon, skriver. 373 00:20:17,000 --> 00:20:21,000 Fortelle personen ved siden av deg hvis de ikke var ler akkurat nå. 374 00:20:21,000 --> 00:20:23,000 Mente du rekursjon? 375 00:20:23,000 --> 00:20:25,000 Mente du-ah, der vi går. 376 00:20:25,000 --> 00:20:28,000 Ok, nå som resten av alle. 377 00:20:28,000 --> 00:20:30,000 En liten påske egg innebygd sted der i Google. 378 00:20:30,000 --> 00:20:33,000 Som en side, en av lenkene vi legger på kursets hjemmeside 379 00:20:33,000 --> 00:20:36,000 for i dag er bare dette rutenettet av ulike sortering algoritmer, 380 00:20:36,000 --> 00:20:39,000 noen som vi så på i forrige uke, men hva er fint om dette visualisering 381 00:20:39,000 --> 00:20:43,000 som du prøver å vikle tankene dine rundt ulike ting knyttet til algoritmer 382 00:20:43,000 --> 00:20:46,000 vet at du kan veldig lett nå starte med ulike typer innganger. 383 00:20:46,000 --> 00:20:50,000 Inngangene alle reversert, inngangene meste sortert, inngangene tilfeldig og så videre. 384 00:20:50,000 --> 00:20:53,000 Som du prøver å igjen, skille disse tingene i tankene dine 385 00:20:53,000 --> 00:20:57,000 innse at denne nettadressen på kurset hjemmeside på Forelesninger siden 386 00:20:57,000 --> 00:21:00,000 kan hjelpe deg grunn gjennom noen av disse. 387 00:21:00,000 --> 00:21:05,000 >> I dag har vi endelig får til å løse dette problemet fra en stund tilbake, 388 00:21:05,000 --> 00:21:08,000 som var at denne swap funksjonen bare ikke fungerte, 389 00:21:08,000 --> 00:21:12,000 og hva var det fundamentale problemet med denne funksjonen swap, 390 00:21:12,000 --> 00:21:15,000 målet som var igjen, for å utveksle en verdi her og her 391 00:21:15,000 --> 00:21:17,000 slik at dette skjer? 392 00:21:17,000 --> 00:21:20,000 Dette gjorde ikke faktisk fungerer. Hvorfor? 393 00:21:20,000 --> 00:21:22,000 Ja. 394 00:21:22,000 --> 00:21:28,000 [Uhørlig-student] 395 00:21:28,000 --> 00:21:31,000 Nøyaktig, forklaringen på dette bugginess 396 00:21:31,000 --> 00:21:34,000 bare var fordi når du ringer funksjoner i C 397 00:21:34,000 --> 00:21:38,000 og disse funksjoner tar argumenter, som a og b her, 398 00:21:38,000 --> 00:21:42,000 du passerer i kopier av hvilken verdi du gir til denne funksjonen. 399 00:21:42,000 --> 00:21:46,000 Du er ikke å gi de opprinnelige verdiene selv, 400 00:21:46,000 --> 00:21:49,000 så vi så dette i sammenheng med buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, som så litt noe sånt som dette. 402 00:21:52,000 --> 00:21:57,000 >> Husker at vi hadde x og y initialisert til 1 og 2, henholdsvis. 403 00:21:57,000 --> 00:21:59,000 Vi deretter skrives ut hva de var. 404 00:21:59,000 --> 00:22:03,000 Jeg deretter hevdet at jeg var å bytte dem ved å kalle swap av x, y. 405 00:22:03,000 --> 00:22:06,000 Men problemet var at bytte arbeidet, 406 00:22:06,000 --> 00:22:10,000 men bare i omfanget av swap fungere selv. 407 00:22:10,000 --> 00:22:13,000 Så snart vi traff linje 40 de byttet verdier 408 00:22:13,000 --> 00:22:16,000 ble kastet bort, og så ingenting 409 00:22:16,000 --> 00:22:21,000 i den opprinnelige funksjon viktigste var faktisk endret i det hele tatt, 410 00:22:21,000 --> 00:22:26,000 så hvis du tenker tilbake da om hva dette ser ut i form av hukommelsen vår 411 00:22:26,000 --> 00:22:29,000 dersom venstre side av brettet representerer- 412 00:22:29,000 --> 00:22:33,000 og jeg skal gjøre mitt beste for at alle kan se dette-hvis dette venstre side av brettet 413 00:22:33,000 --> 00:22:37,000 representerer, sier RAM, og stakken kommer til å vokse på opp på denne måten, 414 00:22:37,000 --> 00:22:43,000 og vi kaller en funksjon som main, og viktigste har 2 lokale variabler, x og y, 415 00:22:43,000 --> 00:22:48,000 la oss beskrive de som x her, og la oss beskrive disse som y her, 416 00:22:48,000 --> 00:22:55,000 og la oss sette inn verdiene 1 og 2, så dette her er viktigste, 417 00:22:55,000 --> 00:22:58,000 og når viktigste kaller swap-funksjonen i operativsystemet 418 00:22:58,000 --> 00:23:02,000 gir swap-funksjonen sin egen skjærer minne på stakken, 419 00:23:02,000 --> 00:23:04,000 sin egen ramme på stakken, så å si. 420 00:23:04,000 --> 00:23:08,000 Det tildeler også 32 bits for disse ints. 421 00:23:08,000 --> 00:23:11,000 Det skjer for å kalle dem a og b, men det er helt vilkårlig. 422 00:23:11,000 --> 00:23:13,000 Det kunne ha kalt dem hva det vil, men hva skjer når main 423 00:23:13,000 --> 00:23:19,000 samtaler swap er det tar dette 1, setter en kopi der, setter en kopi der. 424 00:23:19,000 --> 00:23:23,000 >> Det er en annen lokal variabel i swap, men heter hva? >> Tmp. 425 00:23:23,000 --> 00:23:27,000 Tmp, så la meg gi meg en annen 32 biter her, 426 00:23:27,000 --> 00:23:29,000 og hva gjorde jeg i denne funksjonen? 427 00:23:29,000 --> 00:23:34,000 Jeg sa int tmp får en, så en har en, så jeg gjorde dette da vi sist spilte med dette eksempelet. 428 00:23:34,000 --> 00:23:39,000 Deretter en får b, så b er 2, så nå blir dette 2, 429 00:23:39,000 --> 00:23:42,000 og nå b får temp, så temp er 1, 430 00:23:42,000 --> 00:23:44,000 så nå b blir dette. 431 00:23:44,000 --> 00:23:46,000 Det er flott. Det fungerte. 432 00:23:46,000 --> 00:23:49,000 Men deretter så snart funksjonen returnerer 433 00:23:49,000 --> 00:23:52,000 swap minne forsvinner effektivt, slik at det kan brukes på nytt 434 00:23:52,000 --> 00:23:58,000 av en annen funksjon i fremtiden, og viktigste er selvsagt helt uforandret. 435 00:23:58,000 --> 00:24:00,000 Vi trenger en måte fundamentalt løse dette problemet, 436 00:24:00,000 --> 00:24:03,000 og i dag skal vi endelig ha en måte å gjøre dette der 437 00:24:03,000 --> 00:24:06,000 Vi kan innføre noe som kalles en peker. 438 00:24:06,000 --> 00:24:09,000 Det viser seg at vi kan løse dette problemet 439 00:24:09,000 --> 00:24:12,000 ikke ved å passere i kopier av x og y 440 00:24:12,000 --> 00:24:18,000 men i stedet ved å passere i det, tror du, til swap-funksjonen? 441 00:24:18,000 --> 00:24:20,000 Ja, hva med adresse? 442 00:24:20,000 --> 00:24:22,000 Vi har egentlig ikke snakket om adresser i mye detalj, 443 00:24:22,000 --> 00:24:25,000 men hvis dette tavle representerer mitt datamaskinens minne 444 00:24:25,000 --> 00:24:28,000 Vi kunne sikkert begynne nummereringen bytes i RAM min 445 00:24:28,000 --> 00:24:31,000 og si dette er byte # 1, er denne byte # 2, byte # 3, 446 00:24:31,000 --> 00:24:35,000 byte # 4, byte # ... 2000000000 hvis jeg har 2 GB RAM, 447 00:24:35,000 --> 00:24:38,000 slik at vi kunne sikkert komme opp med noen vilkårlig nummerering ordning 448 00:24:38,000 --> 00:24:41,000 for alle de individuelle bytes i datamaskinens minne. 449 00:24:41,000 --> 00:24:43,000 >> Hva om stedet når jeg kaller swap 450 00:24:43,000 --> 00:24:47,000 stedet for å passere på kopier av x og y 451 00:24:47,000 --> 00:24:51,000 hvorfor ikke jeg i stedet passere i adressen x her, 452 00:24:51,000 --> 00:24:55,000 adressen til y her, i hovedsak den postadresse 453 00:24:55,000 --> 00:24:59,000 av x og y fordi da bytte, hvis han er informert 454 00:24:59,000 --> 00:25:01,000 av adressen i minnet av x og y, 455 00:25:01,000 --> 00:25:04,000 deretter bytte, hvis vi trent ham litt, 456 00:25:04,000 --> 00:25:07,000 han kunne potensielt kjøre til den adressen, så å si, 457 00:25:07,000 --> 00:25:11,000 x, og endre antall der, og deretter kjøre til adressen y, 458 00:25:11,000 --> 00:25:16,000 endre antall der, selv mens faktisk ikke får kopier av disse verdiene selv, 459 00:25:16,000 --> 00:25:19,000 så selv om vi snakket om dette som viktigste minne 460 00:25:19,000 --> 00:25:23,000 og dette som swap minne den kraftige og farlige delen av C 461 00:25:23,000 --> 00:25:28,000 er at hvilken som helst funksjon kan røre minnet overalt i datamaskinen, 462 00:25:28,000 --> 00:25:32,000 og dette er kraftig i at du kan gjøre veldig fancy ting med dataprogrammer i C. 463 00:25:32,000 --> 00:25:36,000 Dette er farlig fordi du kan også skru opp veldig enkelt. 464 00:25:36,000 --> 00:25:39,000 Faktisk, for å en av de vanligste måtene for programmer disse dager utnyttes 465 00:25:39,000 --> 00:25:42,000 fortsatt er for en programmerer ikke å innse 466 00:25:42,000 --> 00:25:45,000 at han eller hun er slik en data 467 00:25:45,000 --> 00:25:49,000 å være skrevet på et sted i minnet som ikke er beregnet. 468 00:25:49,000 --> 00:25:51,000 >> For eksempel, erklærer han eller hun en rekke størrelse 10 469 00:25:51,000 --> 00:25:56,000 men da prøver uhell å sette 11 bytes inn i den rekke minne, 470 00:25:56,000 --> 00:25:59,000 og du begynner å berøre deler av minnet som ikke lenger er gyldige. 471 00:25:59,000 --> 00:26:02,000 Bare for å kontekstuell dette, kan noen av dere vet at 472 00:26:02,000 --> 00:26:06,000 programvaren ber ofte for serienumre eller registrering nøkler, 473 00:26:06,000 --> 00:26:08,000 Photoshop og Word og programmer som dette. 474 00:26:08,000 --> 00:26:12,000 Det finnes sprekker, som noen av dere vet, på nettet hvor du kan kjøre et lite program, 475 00:26:12,000 --> 00:26:14,000 og voila, ikke mer forespørsel om et serienummer. 476 00:26:14,000 --> 00:26:16,000 Hvordan er det å jobbe? 477 00:26:16,000 --> 00:26:21,000 I mange tilfeller er disse tingene er ganske enkelt å finne i datamaskiner 478 00:26:21,000 --> 00:26:24,000 tekst segmenter i datamaskinens faktiske nuller og enere 479 00:26:24,000 --> 00:26:28,000 hvor er den funksjonen hvor serienummeret er forespurt, 480 00:26:28,000 --> 00:26:31,000 og du overskrive den plassen, eller mens programmet kjører 481 00:26:31,000 --> 00:26:33,000 du kan finne ut hvor nøkkelen er faktisk lagret 482 00:26:33,000 --> 00:26:37,000 bruke noe som kalles en debugger, og du kan knekke programvare på den måten. 483 00:26:37,000 --> 00:26:40,000 Dette er ikke å si at dette er vårt mål for de neste par dagene, 484 00:26:40,000 --> 00:26:42,000 men det har svært reelle konsekvenser. 485 00:26:42,000 --> 00:26:45,000 At man tilfeldigvis omfatte tyveri av programvare, 486 00:26:45,000 --> 00:26:47,000 men det er også kompromiss av hele maskiner. 487 00:26:47,000 --> 00:26:50,000 >> Faktisk, når nettsteder i disse dager er utnyttet 488 00:26:50,000 --> 00:26:53,000 og kompromittert og data lekkasje og passord er stjålet 489 00:26:53,000 --> 00:26:58,000 dette svært ofte knyttet til dårlig styring av ens minne, 490 00:26:58,000 --> 00:27:01,000 eller, i tilfelle av databaser, unnlatelse forutse 491 00:27:01,000 --> 00:27:03,000 motstandere inngang, så mer om det i ukene som kommer, 492 00:27:03,000 --> 00:27:07,000 men for nå bare en sniktitt på hva slags skade du kan gjøre 493 00:27:07,000 --> 00:27:11,000 ved ikke helt forstå hvordan ting fungerer under panseret. 494 00:27:11,000 --> 00:27:14,000 La oss gå om å forstå hvorfor dette er brutt 495 00:27:14,000 --> 00:27:17,000 med et verktøy som vil bli mer og mer nyttige 496 00:27:17,000 --> 00:27:19,000 som våre programmer får mer komplisert. 497 00:27:19,000 --> 00:27:21,000 Så langt når du har hatt en feil i programmet 498 00:27:21,000 --> 00:27:23,000 hvordan har dere gått feilsøkt? 499 00:27:23,000 --> 00:27:25,000 Hva har dine teknikker vært så langt, enten undervist av TF din 500 00:27:25,000 --> 00:27:27,000 eller bare selvlært? 501 00:27:27,000 --> 00:27:29,000 [Student] printf. 502 00:27:29,000 --> 00:27:31,000 Printf, så printf har trolig vært din venn i at hvis du ønsker å se 503 00:27:31,000 --> 00:27:33,000 hva som skjer på innsiden av programmet 504 00:27:33,000 --> 00:27:36,000 du bare sette printf her, printf her, printf her. 505 00:27:36,000 --> 00:27:38,000 Så du kjører den, og du får en hel haug med ting på skjermen 506 00:27:38,000 --> 00:27:43,000 som du kan bruke til da utlede hva som faktisk går galt i programmet. 507 00:27:43,000 --> 00:27:45,000 >> Printf en tendens til å være en veldig mektig ting, 508 00:27:45,000 --> 00:27:47,000 men det er en svært manuell prosess. 509 00:27:47,000 --> 00:27:49,000 Du må sette en printf her, en printf her, 510 00:27:49,000 --> 00:27:51,000 og hvis du setter den inne i en løkke du kan få 100 linjer 511 00:27:51,000 --> 00:27:53,000 av produksjonen som du deretter å sile gjennom. 512 00:27:53,000 --> 00:27:58,000 Det er ikke en veldig brukervennlig eller interaktive mekanisme for debugging programmer, 513 00:27:58,000 --> 00:28:00,000 men heldigvis finnes det alternativer. 514 00:28:00,000 --> 00:28:03,000 Det er et program, for eksempel, heter GDB, GNU Debugger, 515 00:28:03,000 --> 00:28:06,000 som er en liten uforståelige i hvordan du bruker den. 516 00:28:06,000 --> 00:28:08,000 Det er litt komplisert, men ærlig, 517 00:28:08,000 --> 00:28:11,000 dette er en av de tingene der hvis du putter i denne uken og neste 518 00:28:11,000 --> 00:28:14,000 den ekstra timen til å forstå noe som GDB 519 00:28:14,000 --> 00:28:18,000 det vil spare deg sannsynligvis flere titalls timer i det lange løp, 520 00:28:18,000 --> 00:28:21,000 Så med det, la meg gi deg en teaser på hvordan dette ting fungerer. 521 00:28:21,000 --> 00:28:23,000 >> Jeg er i min terminal-vinduet. 522 00:28:23,000 --> 00:28:26,000 La meg gå videre og kompilere programmet, buggy3. 523 00:28:26,000 --> 00:28:28,000 Det er allerede oppdatert. 524 00:28:28,000 --> 00:28:31,000 La meg kjøre den akkurat som vi gjorde en stund tilbake, og faktisk er det brutt. 525 00:28:31,000 --> 00:28:34,000 Men hvorfor er dette? Kanskje jeg skrudd opp swap-funksjon. 526 00:28:34,000 --> 00:28:37,000 Kanskje det er a og b. Jeg er ikke helt flytte dem rundt riktig. 527 00:28:37,000 --> 00:28:39,000 La meg gå videre og gjøre dette. 528 00:28:39,000 --> 00:28:43,000 Snarere enn å bare kjøre buggy3 la meg i stedet kjøre dette programmet GDB, 529 00:28:43,000 --> 00:28:48,000 og jeg kommer til å fortelle den til å kjøre buggy3, 530 00:28:48,000 --> 00:28:52,000 og jeg kommer til å inkludere en kommandolinje argument,-tui, 531 00:28:52,000 --> 00:28:55,000 og vi vil sette dette i fremtidige problemer på spec å minne. 532 00:28:55,000 --> 00:28:57,000 Og nå svart og hvitt grensesnitt dukket opp som, igjen, 533 00:28:57,000 --> 00:28:59,000 er litt overveldende i starten, fordi det er alt dette 534 00:28:59,000 --> 00:29:02,000 garantiinformasjon her nede, men minst det er noe kjent. 535 00:29:02,000 --> 00:29:04,000 I toppen av vinduet er min faktiske koden, 536 00:29:04,000 --> 00:29:08,000 og hvis jeg blar opp her la meg bla til toppen av filen min, 537 00:29:08,000 --> 00:29:11,000 og ja, det er buggy3.c, og legg merke til nederst i dette vinduet 538 00:29:11,000 --> 00:29:13,000 Jeg har denne GDB ledeteksten. 539 00:29:13,000 --> 00:29:16,000 >> Dette er ikke det samme som min normale John Harvard spørsmål. 540 00:29:16,000 --> 00:29:19,000 Dette er et spørsmål som kommer til å tillate meg å kontrollere GDB. 541 00:29:19,000 --> 00:29:21,000 GDB er et feilsøkingsverktøy. 542 00:29:21,000 --> 00:29:24,000 En debugger er et program som lar deg gå gjennom 543 00:29:24,000 --> 00:29:27,000 gjennomføring av programmet linje for linje for linje, 544 00:29:27,000 --> 00:29:30,000 underveis gjør noe du vil programmet, 545 00:29:30,000 --> 00:29:33,000 selv ringe funksjoner, eller ser, enda viktigere, 546 00:29:33,000 --> 00:29:35,000 på ulike variable verdier. 547 00:29:35,000 --> 00:29:37,000 La oss gå videre og gjøre dette. 548 00:29:37,000 --> 00:29:40,000 Jeg kommer til å gå videre og skrive kjøre på GDB prompt, 549 00:29:40,000 --> 00:29:43,000 så merker nederst til venstre på skjermen jeg har skrevet løpe, 550 00:29:43,000 --> 00:29:45,000 og jeg har truffet inn, og hva gjorde det gjøre? 551 00:29:45,000 --> 00:29:50,000 Det bokstavelig talt kjørte mitt program, men jeg gjorde ikke faktisk se mye gå på her 552 00:29:50,000 --> 00:29:55,000 fordi jeg har faktisk ikke fortalt debugger 553 00:29:55,000 --> 00:29:57,000 til pause på et bestemt tidspunkt. 554 00:29:57,000 --> 00:29:59,000 Bare å skrive løp kjører programmet. 555 00:29:59,000 --> 00:30:01,000 Jeg vet faktisk ikke se noe. Jeg kan ikke manipulere det. 556 00:30:01,000 --> 00:30:03,000 >> I stedet la meg gjøre dette. 557 00:30:03,000 --> 00:30:08,000 På dette GDB spørsmål la meg isteden skrive pause, inn. 558 00:30:08,000 --> 00:30:10,000 Det er ikke det jeg mente å skrive. 559 00:30:10,000 --> 00:30:13,000 La oss isteden skrive pause viktigste. 560 00:30:13,000 --> 00:30:15,000 Med andre ord, jeg vil sette noe som kalles et stoppunkt, 561 00:30:15,000 --> 00:30:18,000 som er treffende navn fordi det vil bryte eller pause 562 00:30:18,000 --> 00:30:21,000 gjennomføring av programmet på det aktuelle stedet. 563 00:30:21,000 --> 00:30:23,000 Viktigste er navnet på funksjonen min. 564 00:30:23,000 --> 00:30:25,000 Legg merke til at GDB er ganske smart. 565 00:30:25,000 --> 00:30:28,000 Det regnet ut at main skjer for å starte omtrent på linje 18 566 00:30:28,000 --> 00:30:32,000 av buggy3.c, og deretter legge merke til her øverst til venstre 567 00:30:32,000 --> 00:30:34,000 b + er rett ved siden av linje 18. 568 00:30:34,000 --> 00:30:38,000 Det er minner meg om at jeg har satt et stoppunkt på linje 18. 569 00:30:38,000 --> 00:30:42,000 Denne gangen når jeg skriver løp, jeg kommer til å kjøre mitt program 570 00:30:42,000 --> 00:30:45,000 inntil den treffer den stoppunkt, 571 00:30:45,000 --> 00:30:48,000 så vil programmet pause for meg på linje 18. 572 00:30:48,000 --> 00:30:50,000 Here we go, kjøre. 573 00:30:50,000 --> 00:30:53,000 Ingenting ser ut til å ha skjedd, men varsel nederst til venstre 574 00:30:53,000 --> 00:30:58,000 starter programmet, buggy3, stoppunkt 1 i hovedvinduet til buggy3.c linje 18. 575 00:30:58,000 --> 00:31:00,000 Hva kan jeg gjøre nå? 576 00:31:00,000 --> 00:31:03,000 >> Merker jeg kan begynne å skrive ting som print, 577 00:31:03,000 --> 00:31:08,000 ikke printf, print x, og nå er det rart. 578 00:31:08,000 --> 00:31:11,000 $ 1 er bare en kuriositet, som vi skal se 579 00:31:11,000 --> 00:31:14,000 hver gang du skriver ut noe du får en ny $ verdi. 580 00:31:14,000 --> 00:31:18,000 Det er slik at du kan se tilbake på tidligere verdier i tilfelle, 581 00:31:18,000 --> 00:31:21,000 men for nå hva print forteller meg er at verdien av x på dette punktet i historien 582 00:31:21,000 --> 00:31:26,000 er tilsynelatende 134514032. 583 00:31:26,000 --> 00:31:29,000 Hva? Hvor ble det selv kommer fra? 584 00:31:29,000 --> 00:31:31,000 [Uhørlig-student] 585 00:31:31,000 --> 00:31:34,000 Faktisk, dette er hva vi kaller en søppel verdi, og vi har ikke snakket om dette ennå, 586 00:31:34,000 --> 00:31:37,000 men grunnen til at du initialisere variabler 587 00:31:37,000 --> 00:31:40,000 er åpenbart at de har noen verdi som du vil de skal ha. 588 00:31:40,000 --> 00:31:44,000 Men fangsten er huske at du kan erklære variabler 589 00:31:44,000 --> 00:31:46,000 som jeg gjorde et øyeblikk siden i min sigma eksempel 590 00:31:46,000 --> 00:31:48,000 uten egentlig å gi dem en verdi. 591 00:31:48,000 --> 00:31:50,000 Huske hva jeg gjorde over her i sigma. 592 00:31:50,000 --> 00:31:52,000 Jeg erklærte n, men hvilken verdi har jeg gi det? 593 00:31:52,000 --> 00:31:56,000 Ingen, fordi jeg visste at i de neste par linjer 594 00:31:56,000 --> 00:31:59,000 GetInt ville ta seg av problemet med å sette en verdi på innsiden av n. 595 00:31:59,000 --> 00:32:02,000 >> Men på dette punktet i historien om linje 11 596 00:32:02,000 --> 00:32:05,000 og linje 12 og linje 13 og linje 14 597 00:32:05,000 --> 00:32:08,000 gjennom de flere linjer hva er verdien av n? 598 00:32:08,000 --> 00:32:10,000 I C bare du ikke vet. 599 00:32:10,000 --> 00:32:14,000 Det er generelt litt søppel verdi, noen helt tilfeldige tall 600 00:32:14,000 --> 00:32:17,000 som er igjen i hovedsak fra noen tidligere funksjon 601 00:32:17,000 --> 00:32:21,000 etter å ha blitt kjørt, slik som programmet kjører 602 00:32:21,000 --> 00:32:24,000 huske at funksjonen blir funksjon, funksjon, funksjon. 603 00:32:24,000 --> 00:32:27,000 Alle disse rammene blir satt på minnet, og de returnerer, 604 00:32:27,000 --> 00:32:31,000 og akkurat som jeg foreslo med viskelæret deres minne er slutt gjenbrukes. 605 00:32:31,000 --> 00:32:37,000 Vel, det bare skjer, slik at denne variabelen x i dette programmet 606 00:32:37,000 --> 00:32:41,000 synes å ha inneholdt noen søppel verdi som 134514032 607 00:32:41,000 --> 00:32:44,000 fra noen tidligere funksjon, ikke en som jeg skrev. 608 00:32:44,000 --> 00:32:47,000 Det kan være noe som kommer effektivt med operativsystemet, 609 00:32:47,000 --> 00:32:49,000 noen funksjon under panseret. 610 00:32:49,000 --> 00:32:52,000 >> Ok, det er greit, men la oss nå gå videre til neste linje. 611 00:32:52,000 --> 00:32:55,000 Hvis jeg skriver "neste" på min GDB spørsmål, og jeg traff inn, 612 00:32:55,000 --> 00:32:58,000 merke til at uthevingen trekk ned til linje 19, 613 00:32:58,000 --> 00:33:01,000 men den logiske konsekvensen er at linje 18 614 00:33:01,000 --> 00:33:06,000 er nå ferdig utfører, så hvis jeg igjen skrive "print x" 615 00:33:06,000 --> 00:33:10,000 Jeg skal nå se en, og faktisk, det gjør jeg. 616 00:33:10,000 --> 00:33:14,000 Igjen er $ ting en måte GDB minner deg 617 00:33:14,000 --> 00:33:17,000 hva historien utskrifter er at du har gjort. 618 00:33:17,000 --> 00:33:21,000 Nå la meg gå videre og skrive ut y, og faktisk er y noen sprø verdi så vel, 619 00:33:21,000 --> 00:33:24,000 men ikke så farlig fordi i linje 19 er vi i ferd med å tildele det 620 00:33:24,000 --> 00:33:27,000 verdien 2, så la meg skrive "neste" igjen. 621 00:33:27,000 --> 00:33:29,000 Og nå er vi på printf linje. 622 00:33:29,000 --> 00:33:31,000 La meg gjøre print x. 623 00:33:31,000 --> 00:33:34,000 La meg gjøre print y. Oppriktig, jeg får litt lei av å skrive ut dette. 624 00:33:34,000 --> 00:33:38,000 La meg i stedet skrive "skjerm x" og "display y," 625 00:33:38,000 --> 00:33:41,000 og nå hver gang jeg skriver en kommando i fremtiden 626 00:33:41,000 --> 00:33:45,000 Jeg vil bli minnet på hva som er x og y, hva er x og y, hva er x og y. 627 00:33:45,000 --> 00:33:48,000 >> Jeg kan også, som en side, skriv inn "info lokalbefolkningen." 628 00:33:48,000 --> 00:33:50,000 Info er en spesiell kommando. 629 00:33:50,000 --> 00:33:52,000 Lokalbefolkningen betyr det viser meg de lokale variabler. 630 00:33:52,000 --> 00:33:55,000 Bare i tilfelle jeg glemmer eller er dette en gal, komplisert funksjon 631 00:33:55,000 --> 00:33:57,000 at jeg eller noen andre skrev info lokalbefolkningen vil fortelle deg 632 00:33:57,000 --> 00:34:00,000 hva er alle lokale variabler inne denne lokale funksjonen 633 00:34:00,000 --> 00:34:03,000 som du kanskje bryr seg om hvis du ønsker å rote rundt. 634 00:34:03,000 --> 00:34:07,000 Nå er printf om å utføre, så la meg gå videre og bare skrive "neste". 635 00:34:07,000 --> 00:34:10,000 Fordi vi er i dette miljøet vi ikke egentlig se det 636 00:34:10,000 --> 00:34:14,000 utføre her nede, men merker det blir litt mangled her. 637 00:34:14,000 --> 00:34:17,000 Men merker det overordnede skjermen der, 638 00:34:17,000 --> 00:34:21,000 så det er ikke en perfekt program her, men det er greit fordi jeg alltid kan rote rundt 639 00:34:21,000 --> 00:34:23,000 ved hjelp av print hvis jeg vil. 640 00:34:23,000 --> 00:34:26,000 >> La meg skrive neste gang, og nå her er den interessante delen. 641 00:34:26,000 --> 00:34:29,000 På dette punktet i historien y er 2, og x er 1, 642 00:34:29,000 --> 00:34:32,000 som foreslått her, og igjen, 643 00:34:32,000 --> 00:34:35,000 Årsaken til dette er automatisk visning nå er fordi jeg brukte kommandoen 644 00:34:35,000 --> 00:34:40,000 Displayet x og Y vises, så det øyeblikket jeg skriver neste 645 00:34:40,000 --> 00:34:43,000 i teorien x og y skal bli byttet. 646 00:34:43,000 --> 00:34:45,000 Nå vet vi allerede at ikke kommer til å være tilfelle, 647 00:34:45,000 --> 00:34:49,000 men vi får se i et øyeblikk hvor vi kan dykke dypere for å finne ut hvorfor det er sant. 648 00:34:49,000 --> 00:34:54,000 Neste, og dessverre er y fortsatt 2 og x er fortsatt en, og jeg kan bekrefte så mye. 649 00:34:54,000 --> 00:34:56,000 Print x, print y. 650 00:34:56,000 --> 00:34:59,000 Faktisk har ingen bytte faktisk skjedde, så la oss starte dette over. 651 00:34:59,000 --> 00:35:01,000 Klart swap er brutt. 652 00:35:01,000 --> 00:35:04,000 La oss isteden skrive "run" igjen. 653 00:35:04,000 --> 00:35:07,000 La meg si ja, jeg vil starte det fra begynnelsen, skriver. 654 00:35:07,000 --> 00:35:09,000 >> Nå er jeg tilbake opp på linje 18. 655 00:35:09,000 --> 00:35:11,000 Nå legge merke x og y er søppel verdiene igjen. 656 00:35:11,000 --> 00:35:15,000 Neste, neste, neste, neste. 657 00:35:15,000 --> 00:35:17,000 Hvis jeg får lei jeg kan også bare skrive n for neste. 658 00:35:17,000 --> 00:35:21,000 Du kan forkorte det til kortest mulig sekvens av tegn. 659 00:35:21,000 --> 00:35:23,000 Swap er nå brutt. 660 00:35:23,000 --> 00:35:25,000 La oss dykke i, så i stedet for å skrive neste, 661 00:35:25,000 --> 00:35:30,000 nå skal jeg til å skrive trinn, slik at jeg stepping innsiden av denne funksjonen 662 00:35:30,000 --> 00:35:33,000 slik at jeg kan gå gjennom det, så jeg traff trinn og deretter inn. 663 00:35:33,000 --> 00:35:37,000 Legg merke til at de fremhever hopper ned lavere i mitt program til linje 36. 664 00:35:37,000 --> 00:35:39,000 Nå hva er de lokale variabler? 665 00:35:39,000 --> 00:35:41,000 Info lokalbefolkningen. 666 00:35:41,000 --> 00:35:43,000 Ingenting ennå fordi vi ikke har fått til den linjen, 667 00:35:43,000 --> 00:35:47,000 så la oss gå videre og si "Next". 668 00:35:47,000 --> 00:35:50,000 Nå synes vi å ha tmp, print tmp. 669 00:35:50,000 --> 00:35:52,000 Søppel verdi, ikke sant? Jeg tror det. 670 00:35:52,000 --> 00:35:55,000 Hva med ut en, print b, 1 og 2? 671 00:35:55,000 --> 00:35:58,000 I et øyeblikk, så snart jeg skriver neste gang 672 00:35:58,000 --> 00:36:02,000 tmp kommer til å ta på en verdi på 1, forhåpentligvis, 673 00:36:02,000 --> 00:36:05,000 fordi tmp kommer til å bli tildelt verdien av en. 674 00:36:05,000 --> 00:36:08,000 >> Nå la oss gjøre ut en, print b, 675 00:36:08,000 --> 00:36:11,000 men nå ut tmp, og det er faktisk en. 676 00:36:11,000 --> 00:36:14,000 La meg gjøre videre. La meg gjøre videre. 677 00:36:14,000 --> 00:36:16,000 Jeg er ferdig med swap-funksjonen. 678 00:36:16,000 --> 00:36:19,000 Jeg er fortsatt inne i den på linje 40, så la meg skrive en, 679 00:36:19,000 --> 00:36:22,000 print b, og jeg bryr meg ikke hva tmp er. 680 00:36:22,000 --> 00:36:27,000 Det ser ut som swap er riktig når det gjelder å bytte a og b. 681 00:36:27,000 --> 00:36:31,000 Men hvis jeg nå skrive neste, jeg hoppe tilbake til linje 25, 682 00:36:31,000 --> 00:36:34,000 og selvfølgelig, hvis jeg skriver i x og print y 683 00:36:34,000 --> 00:36:38,000 de er fortsatt uendret, så vi har ikke løst problemet. 684 00:36:38,000 --> 00:36:41,000 Men diagnostisk nå kanskje med denne GDB program 685 00:36:41,000 --> 00:36:44,000 Vi har i det minste fått ett skritt nærmere å forstå 686 00:36:44,000 --> 00:36:47,000 hva som går galt uten å søppel vår kode ved å sette en printf her, 687 00:36:47,000 --> 00:36:50,000 printf her, printf her og deretter kjøre den igjen og igjen 688 00:36:50,000 --> 00:36:52,000 prøver å finne ut hva som går galt. 689 00:36:52,000 --> 00:36:55,000 >> Jeg kommer til å gå videre og avslutte ut av dette helt med å slutte. 690 00:36:55,000 --> 00:36:57,000 Det kommer til å så si: "Quit likevel?" Ja. 691 00:36:57,000 --> 00:37:00,000 Nå er jeg tilbake på mitt normale spørsmål, og jeg er ferdig med GDB. 692 00:37:00,000 --> 00:37:03,000 Som en side, trenger du ikke å bruke denne-tui flagg. 693 00:37:03,000 --> 00:37:07,000 Faktisk, hvis du utelater det du får i hovedsak den nederste halvdelen av skjermen. 694 00:37:07,000 --> 00:37:11,000 Hvis jeg skriver pause viktigste og deretter kjøre 695 00:37:11,000 --> 00:37:15,000 Jeg kan fremdeles kjøre mitt program, men hva det vil gjøre er mer ordrett 696 00:37:15,000 --> 00:37:18,000 bare vise meg den aktuelle linjen, ett om gangen. 697 00:37:18,000 --> 00:37:21,000 The-tui, tekstlig brukergrensesnitt, 698 00:37:21,000 --> 00:37:25,000 bare viser deg mer av programmet på en gang, noe som er nok litt konseptuelt enklere. 699 00:37:25,000 --> 00:37:27,000 Men faktisk, jeg kan bare gjøre neste, neste, neste, 700 00:37:27,000 --> 00:37:30,000 og jeg kommer til å se en linje av gangen, og hvis jeg virkelig ønsker å se hva som skjer 701 00:37:30,000 --> 00:37:35,000 Jeg kan skrive listen og se en hel haug med nabokommunene linjer. 702 00:37:35,000 --> 00:37:39,000 >> Det er en video som vi har bedt om at du ser for problem sett 3 703 00:37:39,000 --> 00:37:43,000 der Nate dekker noen av vanskelighetene med GDB, 704 00:37:43,000 --> 00:37:46,000 og dette er en av de tingene, ærlig, der noen ikke-triviell andel av dere 705 00:37:46,000 --> 00:37:49,000 vil aldri røre GDB, og som vil være en dårlig ting 706 00:37:49,000 --> 00:37:53,000 fordi bokstavelig vil du ende opp med å tilbringe mer tid senere dette semesteret 707 00:37:53,000 --> 00:37:56,000 jakte ned bugs så du ville gjort hvis du satt i det halv time / time 708 00:37:56,000 --> 00:38:00,000 denne uken og neste læring å bli komfortabel med GDB. 709 00:38:00,000 --> 00:38:02,000 Printf var din venn. 710 00:38:02,000 --> 00:38:05,000 GDB skal nå være din venn. 711 00:38:05,000 --> 00:38:08,000 >> Eventuelle spørsmål om GDB? 712 00:38:08,000 --> 00:38:12,000 Og her er en rask liste over noen av de mest kraftfulle og nyttige kommandoer. 713 00:38:12,000 --> 00:38:15,000 Ja. >> Kan du skrive ut en streng? 714 00:38:15,000 --> 00:38:17,000 Kan du skrive ut en streng? Absolutt. 715 00:38:17,000 --> 00:38:19,000 Det trenger ikke å bare være heltall. 716 00:38:19,000 --> 00:38:22,000 Hvis en variabel s er en streng skriver du bare inn i print s. 717 00:38:22,000 --> 00:38:24,000 Den vil vise deg hva som strengvariabel er. 718 00:38:24,000 --> 00:38:26,000 [Uhørlig-student] 719 00:38:26,000 --> 00:38:28,000 Det vil gi deg adresse og selve strengen. 720 00:38:28,000 --> 00:38:32,000 Den vil vise deg begge deler. 721 00:38:32,000 --> 00:38:34,000 Og en siste ting, bare fordi disse er godt å vite også. 722 00:38:34,000 --> 00:38:37,000 Backtrace og ramme, la meg dykke inn i dette siste gang, 723 00:38:37,000 --> 00:38:39,000 nøyaktig samme program med GDB. 724 00:38:39,000 --> 00:38:44,000 La meg gå videre og kjøre den tekstlige brukergrensesnitt versjon, 725 00:38:44,000 --> 00:38:46,000 bryte viktigste. 726 00:38:46,000 --> 00:38:49,000 La meg gå videre og kjøre igjen. Her er jeg. 727 00:38:49,000 --> 00:38:55,000 Nå la meg gå neste, neste, neste, neste, neste, step, skriver. 728 00:38:55,000 --> 00:39:00,000 >> Og nå antar jeg er nå i swap bevisst, men jeg liker "Damn, hva var verdien av x?" 729 00:39:00,000 --> 00:39:02,000 Jeg kan ikke gjøre x lenger. 730 00:39:02,000 --> 00:39:05,000 Jeg kan ikke gjøre y fordi de ikke er i omfang. 731 00:39:05,000 --> 00:39:07,000 De er ikke i sammenheng, men ikke noe problem. 732 00:39:07,000 --> 00:39:09,000 Jeg kan skrive tilbakesporing. 733 00:39:09,000 --> 00:39:13,000 Som viser meg alle de funksjonene som har utført opp til dette tidspunktet. 734 00:39:13,000 --> 00:39:16,000 Legg merke til at en på bunnen, viktigste, på linje med hoved 735 00:39:16,000 --> 00:39:18,000 være på bunnen av bildet her. 736 00:39:18,000 --> 00:39:22,000 Det faktum at swap er over det på linje med swap være over den i minnet her, 737 00:39:22,000 --> 00:39:26,000 og hvis jeg ønsker å komme tilbake til hovedsiden midlertidig jeg kan si "frame". 738 00:39:26,000 --> 00:39:30,000 Hvilket nummer? Viktigste er rammen # 1. 739 00:39:30,000 --> 00:39:32,000 Jeg kommer til å gå foran og si "frame 1". 740 00:39:32,000 --> 00:39:36,000 >> Nå er jeg tilbake i viktigste, og jeg kan skrive ut x, og jeg kan skrive ut y, 741 00:39:36,000 --> 00:39:40,000 men jeg kan ikke skrive ut en eller b. 742 00:39:40,000 --> 00:39:43,000 Men jeg kan hvis jeg sier: "OK, vent litt. Hvor var swap?" 743 00:39:43,000 --> 00:39:46,000 La meg gå videre og si "frame 0". 744 00:39:46,000 --> 00:39:48,000 Nå er jeg tilbake der jeg ønsker å være, og som en side, 745 00:39:48,000 --> 00:39:52,000 det er andre kommandoer også, som om du virkelig får lei skrive neste, neste, neste, neste, 746 00:39:52,000 --> 00:39:56,000 du kan generelt si ting som "neste 10", og som vil gå gjennom de neste 10 linjene. 747 00:39:56,000 --> 00:39:59,000 Du kan også skrive "fortsett" når du virkelig får lei stepping gjennom den. 748 00:39:59,000 --> 00:40:05,000 Fortsett vil kjøre programmet uten avbrudd til den treffer en annen stoppunkt, 749 00:40:05,000 --> 00:40:07,000 enten i en sløyfe eller senke ned i programmet. 750 00:40:07,000 --> 00:40:11,000 >> I dette tilfellet fortsatte vi til slutten, og programmet gått som normalt. 751 00:40:11,000 --> 00:40:13,000 Dette er en fancy måte, dårligere prosess. 752 00:40:13,000 --> 00:40:16,000 Bare programmet gått som normalt. 753 00:40:16,000 --> 00:40:24,000 Mer om det i videoen og i debugging økter fremover. 754 00:40:24,000 --> 00:40:26,000 Det var mye. 755 00:40:26,000 --> 00:40:35,000 La oss ta vår 5-minutters pause her, og vi vil komme tilbake med structs og filer. 756 00:40:35,000 --> 00:40:38,000 >> Hvis du har dykket inn i denne ukens pset allerede 757 00:40:38,000 --> 00:40:41,000 du vet at vi bruker i fordelingen koden, 758 00:40:41,000 --> 00:40:45,000 kildekoden som vi leverer til deg som et utgangspunkt, noen nye teknikker. 759 00:40:45,000 --> 00:40:50,000 Spesielt introduserte vi denne nye nøkkelordet kalt struct, for struktur, 760 00:40:50,000 --> 00:40:53,000 slik at vi kan lage tilpassede variabler sorterer. 761 00:40:53,000 --> 00:40:57,000 Vi har også innført begrepet fil I / O, fil inngang og utgang, 762 00:40:57,000 --> 00:41:00,000 og dette er, slik at vi kan spare staten 763 00:41:00,000 --> 00:41:03,000 av Scramble bord til en fil på disk 764 00:41:03,000 --> 00:41:06,000 slik at undervisningen stipendiater og jeg kan forstå 765 00:41:06,000 --> 00:41:09,000 hva som skjer på innsiden av programmet uten å måtte manuelt spille 766 00:41:09,000 --> 00:41:11,000 dusinvis av spill av Scramble. 767 00:41:11,000 --> 00:41:13,000 Vi kan gjøre dette mer automatedly. 768 00:41:13,000 --> 00:41:18,000 >> Denne ideen om en struct løser en ganske overbevisende problem. 769 00:41:18,000 --> 00:41:21,000 Anta at vi ønsker å gjennomføre noen program 770 00:41:21,000 --> 00:41:25,000 som holder liksom styr på informasjon om studenter, 771 00:41:25,000 --> 00:41:28,000 og studenter kan ha, for eksempel en ID, et navn 772 00:41:28,000 --> 00:41:31,000 og et hus på et sted som Harvard, så disse er 3 stykker av informasjon 773 00:41:31,000 --> 00:41:34,000 Vi ønsker å holde rundt, så la meg gå videre og begynne å skrive et lite program her, 774 00:41:34,000 --> 00:41:38,000 inkludere stdio.h. 775 00:41:38,000 --> 00:41:42,000 La meg gjøre inkludere cs50.h. 776 00:41:42,000 --> 00:41:44,000 Og deretter starte min viktigste funksjon. 777 00:41:44,000 --> 00:41:46,000 Jeg vil ikke bry deg med noen kommandolinjeargumenter, 778 00:41:46,000 --> 00:41:49,000 og her jeg vil ha en student, så jeg kommer til å si 779 00:41:49,000 --> 00:41:54,000 en student har et navn, så jeg kommer til å si "string navn." 780 00:41:54,000 --> 00:41:59,000 Så jeg kommer til å si en student har også en ID, så int id, 781 00:41:59,000 --> 00:42:03,000 og en student har et hus, så jeg også kommer til å si "string hus." 782 00:42:03,000 --> 00:42:06,000 Så jeg skal bestille disse litt mer renslig som dette. 783 00:42:06,000 --> 00:42:11,000 Ok, nå har jeg tre variabler som å representere en student, så "en student." 784 00:42:11,000 --> 00:42:15,000 >> Og nå vil jeg fylle disse verdiene, så la meg gå videre og si noe sånt 785 00:42:15,000 --> 00:42:18,000 "Id = 123". 786 00:42:18,000 --> 00:42:21,000 Navnet kommer til å bli David. 787 00:42:21,000 --> 00:42:24,000 La oss si huset kommer til å få Mather, 788 00:42:24,000 --> 00:42:31,000 og da kommer jeg til å gjøre noe vilkårlig som printf ("% s, 789 00:42:31,000 --> 00:42:37,000 hvis ID er% d, bor i% s. 790 00:42:37,000 --> 00:42:41,000 Og nå, hva jeg ønsker å plugge inn her, den ene etter den andre? 791 00:42:41,000 --> 00:42:47,000 Navn, id, hus, return 0. 792 00:42:47,000 --> 00:42:50,000 Ok, med mindre jeg skrudd opp et sted her 793 00:42:50,000 --> 00:42:54,000 Jeg tror vi har en ganske god program som lagrer én student. 794 00:42:54,000 --> 00:42:57,000 Selvfølgelig, dette er ikke alle som interessant. Hva om jeg ønsker å ha to studenter? 795 00:42:57,000 --> 00:42:59,000 Det er ingen big deal. Jeg kan støtte 2 personer. 796 00:42:59,000 --> 00:43:03,000 La meg gå videre og markere dette og gå ned her, 797 00:43:03,000 --> 00:43:09,000 og jeg kan si "id = 456" for en som Rob som bor i Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Ok, vent, men jeg kan ikke kalle disse den samme, 799 00:43:12,000 --> 00:43:15,000 og det ser ut som jeg er nødt til å kopiere dette, 800 00:43:15,000 --> 00:43:19,000 så la meg si at disse vil være Davids variabler, 801 00:43:19,000 --> 00:43:23,000 og la meg få noen eksemplarer av disse for Rob. 802 00:43:23,000 --> 00:43:27,000 Vi vil kalle disse Rob, men dette er ikke til å fungere nå 803 00:43:27,000 --> 00:43:33,000 fordi jeg har-vent, la oss endre meg til ID1, navn1 og House1. 804 00:43:33,000 --> 00:43:35,000 Rob vil være 2, 2. 805 00:43:35,000 --> 00:43:42,000 Jeg har fått til å endre dette her, her, her, her, her, her. 806 00:43:42,000 --> 00:43:45,000 Vent, hva om Tommy? La oss gjøre dette igjen. 807 00:43:45,000 --> 00:43:49,000 Selvfølgelig hvis du fortsatt tror dette er en god måte å gjøre dette på, er det ikke, 808 00:43:49,000 --> 00:43:52,000 så kopiere / lime dårlig. 809 00:43:52,000 --> 00:43:55,000 Men vi løste dette for en uke siden. 810 00:43:55,000 --> 00:43:59,000 >> Hva var vår løsning når vi ønsket å ha flere forekomster av samme datatype? 811 00:43:59,000 --> 00:44:01,000 [Studenter] En rekke. 812 00:44:01,000 --> 00:44:03,000 En matrise, så la meg prøve å rydde opp. 813 00:44:03,000 --> 00:44:07,000 La meg gjøre noen plass for meg selv på toppen, og la meg i stedet gjøre dette her. 814 00:44:07,000 --> 00:44:12,000 Vi vil kalle disse menneskene, og i stedet skal jeg si "int IDer," 815 00:44:12,000 --> 00:44:14,000 og jeg kommer til å støtte tre av oss for nå. 816 00:44:14,000 --> 00:44:18,000 Jeg kommer til å si "strengnavn," så skal jeg støtte 3 av oss, 817 00:44:18,000 --> 00:44:22,000 og da kommer jeg til å si "streng hus," og jeg kommer til å støtte tre av oss. 818 00:44:22,000 --> 00:44:26,000 Nå i her i stedet for David få sine egne lokale variabler 819 00:44:26,000 --> 00:44:28,000 Vi kan bli kvitt dem. 820 00:44:28,000 --> 00:44:30,000 Det føles bra at vi rengjøring dette opp. 821 00:44:30,000 --> 00:44:35,000 Da kan jeg si David kommer til å være [0] og navn [0] 822 00:44:35,000 --> 00:44:38,000 og hus [0]. 823 00:44:38,000 --> 00:44:41,000 Og så Rob vi kan tilsvarende spare på dette. 824 00:44:41,000 --> 00:44:46,000 La oss sette dette ned her, så han kommer til å vilkårlig være ids [1]. 825 00:44:46,000 --> 00:44:50,000 Han kommer til å være navn [1], 826 00:44:50,000 --> 00:44:53,000 og deretter til slutt, hus [1]. 827 00:44:53,000 --> 00:44:57,000 >> Fortsatt litt kjedelig, og nå må jeg finne ut av dette, 828 00:44:57,000 --> 00:45:03,000 så la oss si "navn [0], id [0], hus [0], 829 00:45:03,000 --> 00:45:06,000 og la oss pluralize dette. 830 00:45:06,000 --> 00:45:09,000 Ids, IDS, IDer. 831 00:45:09,000 --> 00:45:12,000 Og igjen, jeg gjør det, så igjen, jeg er allerede ty til å kopiere / lime igjen, 832 00:45:12,000 --> 00:45:14,000 så oddsen er det er en annen løsning her. 833 00:45:14,000 --> 00:45:18,000 Jeg kan sikkert rydde opp videre med en sløyfe eller noe sånt, 834 00:45:18,000 --> 00:45:21,000 så kort sagt, er det litt bedre, men fortsatt føles som 835 00:45:21,000 --> 00:45:24,000 Jeg ty til å kopiere / lime, men selv dette, hevder jeg, 836 00:45:24,000 --> 00:45:27,000 er egentlig ikke fundamentalt riktig løsning fordi 837 00:45:27,000 --> 00:45:29,000 hva om en gang vi bestemmer vet du hva? 838 00:45:29,000 --> 00:45:32,000 Vi virkelig burde ha blitt lagring e-postadresser for David og Rob 839 00:45:32,000 --> 00:45:34,000 og alle andre i dette programmet. 840 00:45:34,000 --> 00:45:36,000 Vi bør også lagre telefonnumre. 841 00:45:36,000 --> 00:45:39,000 Vi bør også lagre nødtelefon tall. 842 00:45:39,000 --> 00:45:41,000 Vi har alle disse delene av data som vi ønsker å lagre, 843 00:45:41,000 --> 00:45:43,000 så hvordan kan du gå om du gjør det? 844 00:45:43,000 --> 00:45:46,000 >> Du erklærer en annen rekke på toppen, og deretter manuelt legge 845 00:45:46,000 --> 00:45:49,000 en e-postadresse [0], e-postadresse [1] 846 00:45:49,000 --> 00:45:51,000 for David og Rob og så videre. 847 00:45:51,000 --> 00:45:56,000 Men det er egentlig bare en antagelse bak denne designen 848 00:45:56,000 --> 00:45:59,000 at jeg bruker ære systemet å vite at 849 00:45:59,000 --> 00:46:03,000 [I] i hver av de flere matriser 850 00:46:03,000 --> 00:46:06,000 bare så skjer for å referere til den samme personen, 851 00:46:06,000 --> 00:46:10,000 så [0] i ids er nummer 123, 852 00:46:10,000 --> 00:46:13,000 og jeg kommer til å anta at navnene [0] 853 00:46:13,000 --> 00:46:16,000 er den samme personens navn og hus [0] 854 00:46:16,000 --> 00:46:21,000 er den samme person hus og så videre for alle de ulike matriser som jeg skaper. 855 00:46:21,000 --> 00:46:24,000 Men merker at det er ingen fundamental sammenheng 856 00:46:24,000 --> 00:46:27,000 blant de tre biter av informasjon, id, navn og hus, 857 00:46:27,000 --> 00:46:32,000 selv om foretaket vi prøver å modellere i dette programmet er ikke arrays. 858 00:46:32,000 --> 00:46:35,000 Arrays er nettopp dette programmatiske måte å gjøre dette. 859 00:46:35,000 --> 00:46:38,000 Hva vi egentlig ønsker å modellere i vårt program er en person 860 00:46:38,000 --> 00:46:41,000 som David, en person som Rob innsiden av som 861 00:46:41,000 --> 00:46:46,000 eller innkapsle er et navn og ID og et hus. 862 00:46:46,000 --> 00:46:49,000 >> Kan vi noe uttrykke denne ideen om innkapsling 863 00:46:49,000 --> 00:46:52,000 hvor en person har en ID, et navn og et hus 864 00:46:52,000 --> 00:46:55,000 og ikke ty til virkelig dette hack der vi bare 865 00:46:55,000 --> 00:46:58,000 stole på at braketten noe 866 00:46:58,000 --> 00:47:02,000 refererer til samme menneskelige enhet i hver av disse uensartede arrays? 867 00:47:02,000 --> 00:47:04,000 Vi kan faktisk gjøre dette. 868 00:47:04,000 --> 00:47:08,000 La meg gå over main for nå, og la meg lage min egen datatype 869 00:47:08,000 --> 00:47:10,000 for egentlig første gang. 870 00:47:10,000 --> 00:47:14,000 Vi brukte denne teknikken i Scramble, 871 00:47:14,000 --> 00:47:17,000 men her jeg kommer til å gå videre og lage en datatype, 872 00:47:17,000 --> 00:47:19,000 og vet du hva, jeg kommer til å kalle det student eller person, 873 00:47:19,000 --> 00:47:23,000 og jeg kommer til å bruke typedef for definere en type. 874 00:47:23,000 --> 00:47:25,000 Jeg kommer til å si at dette er en struktur, 875 00:47:25,000 --> 00:47:29,000 og så denne strukturen kommer til å være av typen student, vil vi si, 876 00:47:29,000 --> 00:47:31,000 selv om det er litt datert nå for meg. 877 00:47:31,000 --> 00:47:33,000 Vi vil si "int id." 878 00:47:33,000 --> 00:47:35,000 Vi vil si "string navn." 879 00:47:35,000 --> 00:47:37,000 Så får vi si "string huset," 880 00:47:37,000 --> 00:47:40,000 så nå i slutten av disse få linjer med kode 881 00:47:40,000 --> 00:47:45,000 Jeg har nettopp lært clang at det eksisterer 882 00:47:45,000 --> 00:47:49,000 en datatype foruten ints, foruten strenger, foruten dobler, foruten flyter. 883 00:47:49,000 --> 00:47:54,000 >> Som i dette øyeblikk i tid linje 11, er det nå en ny datatype kalt studenter, 884 00:47:54,000 --> 00:47:58,000 og nå kan jeg erklære en student variabel hvor jeg vil, 885 00:47:58,000 --> 00:48:01,000 så la meg bla nedover her til folk. 886 00:48:01,000 --> 00:48:05,000 Nå kan jeg bli kvitt dette, og jeg kan gå tilbake til David her, 887 00:48:05,000 --> 00:48:10,000 og for David kan jeg faktisk si at David, 888 00:48:10,000 --> 00:48:13,000 Vi kan bokstavelig talt kalle variabelen etter meg selv, 889 00:48:13,000 --> 00:48:16,000 kommer til å være av typen student. 890 00:48:16,000 --> 00:48:18,000 Dette kan se litt rart, men dette er ikke så forskjellig 891 00:48:18,000 --> 00:48:22,000 fra å erklære noe som int eller en streng eller en flåte. 892 00:48:22,000 --> 00:48:24,000 Det bare så skjer for å bli kalt student nå, 893 00:48:24,000 --> 00:48:28,000 og hvis jeg ønsker å sette noe på innsiden av denne strukturen 894 00:48:28,000 --> 00:48:31,000 Jeg har nå å bruke et nytt stykke av syntaks, men det er ganske grei, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" i hovedstaden D, 896 00:48:39,000 --> 00:48:42,000 og david.house = "Mather," 897 00:48:42,000 --> 00:48:46,000 og nå kan jeg bli kvitt denne ting her. 898 00:48:46,000 --> 00:48:51,000 Merker vi nå har redesignet vårt program i virkelig en mye bedre måte 899 00:48:51,000 --> 00:48:54,000 i at nå vårt program gjenspeiler den virkelige verden. 900 00:48:54,000 --> 00:48:57,000 >> Det er en reell oppfatningen av en person eller en student. 901 00:48:57,000 --> 00:49:02,000 Her har vi nå en C-versjon av en person eller mer spesifikt en student. 902 00:49:02,000 --> 00:49:05,000 Innsiden av den personen er disse relevante egenskaper, 903 00:49:05,000 --> 00:49:10,000 ID, navn og hus, så Rob blir i hovedsak de samme her nede, 904 00:49:10,000 --> 00:49:14,000 så student rob, og nå 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 at variabelen kalles Rob er liksom meningsløst. 907 00:49:20,000 --> 00:49:22,000 Vi kunne ha kalt det x eller y eller z. 908 00:49:22,000 --> 00:49:25,000 Vi kalte det Rob å være semantisk konsekvent, 909 00:49:25,000 --> 00:49:28,000 men egentlig navnet er inne i feltet selv, 910 00:49:28,000 --> 00:49:30,000 så nå har jeg denne. 911 00:49:30,000 --> 00:49:33,000 Dette også føles ikke som den beste designen i at jeg har hardkodet David. 912 00:49:33,000 --> 00:49:35,000 Jeg har hardkodet Rob. 913 00:49:35,000 --> 00:49:39,000 Og jeg har fortsatt å ty til noen kopier og lim hver gang jeg vil ha nye variabler. 914 00:49:39,000 --> 00:49:43,000 Videre har jeg til tilsynelatende gi hver av disse variablene et navn, 915 00:49:43,000 --> 00:49:46,000 selv om jeg vil mye heller beskrive disse variablene 916 00:49:46,000 --> 00:49:48,000  mer generelt som studenter. 917 00:49:48,000 --> 00:49:52,000 >> Nå kan vi slå sammen ideene som har jobbet godt for oss 918 00:49:52,000 --> 00:49:56,000 og i stedet si: "Vet du hva, gi meg en variabel kalt studenter, 919 00:49:56,000 --> 00:50:01,000 og la oss være det har med størrelse 3, "så nå jeg kan gjøre dette videre, 920 00:50:01,000 --> 00:50:04,000 bli kvitt den manuelt erklærte David, 921 00:50:04,000 --> 00:50:08,000 og jeg kan i stedet si noe sånt studenter [0] her. 922 00:50:08,000 --> 00:50:11,000 Da kan jeg si studenter [0] her, 923 00:50:11,000 --> 00:50:14,000 studenter [0] her, og så videre, og jeg kan gå rundt 924 00:50:14,000 --> 00:50:16,000 og rydde opp for Rob. 925 00:50:16,000 --> 00:50:19,000 Jeg kan også gå om nå kanskje legge en sløyfe 926 00:50:19,000 --> 00:50:23,000 og bruke GetString og GetInt å faktisk få disse verdiene fra brukeren. 927 00:50:23,000 --> 00:50:27,000 Jeg kunne gå om å legge en konstant fordi dette er generelt dårlig praksis 928 00:50:27,000 --> 00:50:29,000 til hardt kode noen vilkårlig antall som 3 her 929 00:50:29,000 --> 00:50:33,000 og så bare husk at du bør sette mer enn 3 studenter i den. 930 00:50:33,000 --> 00:50:36,000 Det ville trolig være bedre å bruke # define på toppen av filen min 931 00:50:36,000 --> 00:50:40,000 og faktor det ut, så ja, la meg gå videre og generalisere dette. 932 00:50:40,000 --> 00:50:43,000 >> La meg åpne opp et eksempel som er blant dagens 933 00:50:43,000 --> 00:50:46,000 eksempler på forhånd, structs1. 934 00:50:46,000 --> 00:50:49,000 Dette er en mer komplett program som bruker # define opp her 935 00:50:49,000 --> 00:50:51,000 og sier at vi kommer til å ha tre studenter som standard. 936 00:50:51,000 --> 00:50:54,000 Her jeg erklære en klasse verdt av studenter, 937 00:50:54,000 --> 00:50:57,000 så et klasserom med elever, og nå er jeg bruke en løkke 938 00:50:57,000 --> 00:51:00,000 bare for å gjøre koden litt mer elegant, fylle klassen 939 00:51:00,000 --> 00:51:05,000 med brukerens input, så iterate fra i = 0 på opp til studenter, som er tre. 940 00:51:05,000 --> 00:51:07,000 Og da jeg be brukeren i denne versjonen 941 00:51:07,000 --> 00:51:10,000  hva er studentens ID, og ​​jeg får det med GetInt. 942 00:51:10,000 --> 00:51:13,000 Hva er studentens navn, og da får jeg den med GetString. 943 00:51:13,000 --> 00:51:15,000 Hva er studentens huset? Jeg får det med GetString. 944 00:51:15,000 --> 00:51:19,000 Og så nederst her bare jeg besluttet å endre 945 00:51:19,000 --> 00:51:22,000 hvordan jeg skriver disse ut og å faktisk bruke en loop, 946 00:51:22,000 --> 00:51:24,000 og hvem er jeg skriver ut? 947 00:51:24,000 --> 00:51:27,000 Ifølge kommentaren jeg skriver noen i Mather, 948 00:51:27,000 --> 00:51:30,000 og det er det så Rob og Tommy og så videre-faktisk Tommy i Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy og David ville bli trykt i dette tilfellet, men hvordan er dette fungerer? 950 00:51:34,000 --> 00:51:40,000 Vi har ikke sett denne funksjonen før, men ta en gjetning på hva dette betyr. 951 00:51:40,000 --> 00:51:42,000 Sammenligner strenger. 952 00:51:42,000 --> 00:51:45,000 >> Det er litt ikke-innlysende hvordan det sammenligner strenger fordi det viser seg 953 00:51:45,000 --> 00:51:49,000 hvis den gir 0 som betyr at strengene er like. 954 00:51:49,000 --> 00:51:53,000 Hvis den gir en -1 som betyr en kommer alfabetisk før den andre, 955 00:51:53,000 --> 00:51:57,000 og hvis det returnerer en som betyr at den andre ord kommer alfabetisk 956 00:51:57,000 --> 00:52:00,000 før den andre, og du kan se på nettet eller på mannen siden 957 00:52:00,000 --> 00:52:04,000 for å se nøyaktig hvilken vei som er, men alt dette er nå gjør er det å si 958 00:52:04,000 --> 00:52:09,000 hvis [i]. huset er lik "Mather" 959 00:52:09,000 --> 00:52:13,000 deretter gå videre og skrive ut så og så er i Mather. 960 00:52:13,000 --> 00:52:16,000 Men her er noe vi ikke har sett før, og vi vil komme tilbake til dette. 961 00:52:16,000 --> 00:52:21,000 Jeg kan ikke huske noen gang å måtte gjøre dette i noen av mine programmer. 962 00:52:21,000 --> 00:52:24,000 Gratis er tilsynelatende refererer til minnet, frigjør minne, 963 00:52:24,000 --> 00:52:31,000 men hva minne er jeg tydeligvis frigjør i denne sløyfen nederst i dette programmet? 964 00:52:31,000 --> 00:52:34,000 Det ser ut som jeg befri en persons navn 965 00:52:34,000 --> 00:52:37,000 og en person i huset, men hvorfor er det? 966 00:52:37,000 --> 00:52:41,000 >> Det viser seg alle disse ukene du har brukt GetString 967 00:52:41,000 --> 00:52:45,000 Vi har slags vært innføre en bug i hver eneste en av dine programmer. 968 00:52:45,000 --> 00:52:51,000 GetString av design tildeler minne slik at den kan gå tilbake til deg en streng, 969 00:52:51,000 --> 00:52:55,000 som David, eller Rob, og du kan deretter gjøre hva du vil 970 00:52:55,000 --> 00:52:59,000 med strengen i programmet fordi vi har reservert minne for deg. 971 00:52:59,000 --> 00:53:02,000 Problemet er hele tiden hver gang du ringer GetString 972 00:53:02,000 --> 00:53:05,000 vi, forfatterne av GetString, har vært å spørre operativsystemet 973 00:53:05,000 --> 00:53:07,000 å gi oss en bit av RAM for denne strengen. 974 00:53:07,000 --> 00:53:09,000 Gi oss litt av RAM for dette neste streng. 975 00:53:09,000 --> 00:53:11,000 Gi oss litt mer RAM for dette neste streng. 976 00:53:11,000 --> 00:53:13,000 Hva du, programmerer, har aldri gjort 977 00:53:13,000 --> 00:53:15,000 er å gi oss at hukommelsen tilbake, 978 00:53:15,000 --> 00:53:17,000 så for disse flere uker alle programmene du har skrevet 979 00:53:17,000 --> 00:53:20,000 har hatt det som kalles en minne sprang der de fortsette å bruke 980 00:53:20,000 --> 00:53:24,000 mer og mer minne hver gang du ringer GetString, og det er fint. 981 00:53:24,000 --> 00:53:27,000 Vi bevisst gjøre det i de første ukene fordi det ikke er så interessant 982 00:53:27,000 --> 00:53:29,000 å måtte bekymre deg om hvor strengen kommer fra. 983 00:53:29,000 --> 00:53:34,000 Alt du ønsker er ordet Rob å komme tilbake når brukeren skriver det i. 984 00:53:34,000 --> 00:53:38,000 >> Men fremover vi nå må begynne å få mer sofistikerte om dette. 985 00:53:38,000 --> 00:53:42,000 Hver gang vi allokere minne vi bedre til slutt levere det tilbake. 986 00:53:42,000 --> 00:53:45,000 Ellers i den virkelige verden på din Mac eller PC kan du ha behov opplevd 987 00:53:45,000 --> 00:53:50,000 symptomer der datamaskinen er sliping til å stoppe opp etter hvert 988 00:53:50,000 --> 00:53:54,000 eller dum spinnende badeball er bare opptar datamaskinens 989 00:53:54,000 --> 00:53:56,000 Hele oppmerksomhet og du kan ikke gjøre ting. 990 00:53:56,000 --> 00:54:00,000 Som kan forklares av en rekke bugs, men blant de mulige feilene 991 00:54:00,000 --> 00:54:03,000 er ting som kalles minnelekkasjer der noen som skrev at stykke programvare 992 00:54:03,000 --> 00:54:07,000 du bruker ikke huske å frigjøre minne 993 00:54:07,000 --> 00:54:10,000 at han eller hun spurte operativsystemet for, 994 00:54:10,000 --> 00:54:14,000 ikke bruker GetString, fordi det er en CS50 ting, men med lignende funksjoner 995 00:54:14,000 --> 00:54:16,000 som spør operativsystemet for minne. 996 00:54:16,000 --> 00:54:19,000 Hvis du eller de skru opp og aldri komme tilbake som minne 997 00:54:19,000 --> 00:54:24,000 et symptom på at kan være at et program bremser og bremser og bremser ned 998 00:54:24,000 --> 00:54:26,000 med mindre du huske å ringe gratis. 999 00:54:26,000 --> 00:54:28,000 >> Vi vil komme tilbake til når og hvorfor du vil ringe gratis, 1000 00:54:28,000 --> 00:54:32,000 men la oss gå videre bare for godt mål, og prøve å kjøre dette programmet. 1001 00:54:32,000 --> 00:54:35,000 Dette ble kalt structs1, skriver. 1002 00:54:35,000 --> 00:54:40,000 La meg gå videre og kjøre 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, og vi ser Davids i Mather, Tommy i Mather. 1005 00:54:50,000 --> 00:54:53,000 Dette er bare et lite sunn fornuft sjekk at programmet fungerer. 1006 00:54:53,000 --> 00:54:56,000 Nå, dessverre, er dette programmet litt frustrerende i det 1007 00:54:56,000 --> 00:55:00,000 Jeg gjorde alt det arbeidet, skrev jeg i 9 forskjellige strenger, trykk enter, 1008 00:55:00,000 --> 00:55:04,000 ble fortalt som var i Mather, men åpenbart jeg visste hvem var i Mather allerede fordi jeg skrev den. 1009 00:55:04,000 --> 00:55:07,000 Det ville være minst fint om dette programmet er mer som en database 1010 00:55:07,000 --> 00:55:10,000 og det husker faktisk hva jeg har skrevet i 1011 00:55:10,000 --> 00:55:12,000 så jeg aldri igjen å legge inn disse studentene poster. 1012 00:55:12,000 --> 00:55:15,000 Kanskje det er som en registrarial system. 1013 00:55:15,000 --> 00:55:21,000 >> Vi kan gjøre dette ved hjelp av denne teknikken kalles fil I / O, fil inngang og utgang, 1014 00:55:21,000 --> 00:55:24,000 en svært generisk måte å si når du ønsker å lese filer eller skrive filer 1015 00:55:24,000 --> 00:55:26,000 du kan gjøre dette med et bestemt sett av funksjoner. 1016 00:55:26,000 --> 00:55:29,000 La meg gå videre og åpne dette eksempelet structs2.c, 1017 00:55:29,000 --> 00:55:33,000 som er nesten identisk, men la oss se hva den nå gjør. 1018 00:55:33,000 --> 00:55:36,000 På toppen av filen erklærer jeg en klasse av studenter. 1019 00:55:36,000 --> 00:55:38,000 Jeg så fylle den klassen med brukerens input, 1020 00:55:38,000 --> 00:55:41,000 så disse linjene med kode er akkurat som før. 1021 00:55:41,000 --> 00:55:45,000 Så hvis jeg ruller nedover her skriver jeg ut alle som er i Mather vilkårlig som før, 1022 00:55:45,000 --> 00:55:47,000 men dette er en interessant ny funksjon. 1023 00:55:47,000 --> 00:55:51,000 Disse linjene med kode er ny, og introdusere de noe her, 1024 00:55:51,000 --> 00:55:55,000 Fil, alle caps, og det har * i her også. 1025 00:55:55,000 --> 00:55:58,000 La meg flytte dette over her, en * over her også. 1026 00:55:58,000 --> 00:56:00,000 >> Denne funksjonen har vi ikke sett før, fopen, 1027 00:56:00,000 --> 00:56:03,000 men det betyr fil åpen, så la oss skumme gjennom disse, 1028 00:56:03,000 --> 00:56:05,000 og dette er noe vi vil komme tilbake til i fremtidige psets, 1029 00:56:05,000 --> 00:56:10,000 men denne linjen her åpner egentlig en fil som heter database, 1030 00:56:10,000 --> 00:56:13,000 og det åpner spesielt det på en slik måte at det kan gjøre det til det? 1031 00:56:13,000 --> 00:56:15,000 [Uhørlig-student] 1032 00:56:15,000 --> 00:56:19,000 Høyre, så "w" betyr bare det forteller operativsystemet 1033 00:56:19,000 --> 00:56:21,000 åpne denne filen på en slik måte at jeg kan skrive til den. 1034 00:56:21,000 --> 00:56:23,000 Jeg ønsker ikke å lese den. Jeg ønsker ikke å bare se på det. 1035 00:56:23,000 --> 00:56:26,000 Jeg ønsker å endre den og legge ting potensielt til det, 1036 00:56:26,000 --> 00:56:28,000 og filen kommer til å bli kalt database. 1037 00:56:28,000 --> 00:56:30,000 Dette kan kalles noe. 1038 00:56:30,000 --> 00:56:32,000 Dette kan være database.txt. Dette kan være. Db. 1039 00:56:32,000 --> 00:56:37,000 Dette kan være et ord som foo, men jeg vilkårlig valgte å navngi filen database. 1040 00:56:37,000 --> 00:56:42,000 Dette er en liten sunn fornuft sjekk at vi vil komme tilbake til i stor detalj over tid, 1041 00:56:42,000 --> 00:56:47,000 Hvis fp, for filpekeren, ikke lik NULL som betyr alt er vel. 1042 00:56:47,000 --> 00:56:51,000 >> Lang historie kort, funksjoner som fopen noen ganger mislykkes. 1043 00:56:51,000 --> 00:56:53,000 Kanskje filen ikke eksisterer. Kanskje du er ute av diskplass. 1044 00:56:53,000 --> 00:56:55,000 Kanskje du ikke har tillatelse til denne mappen, 1045 00:56:55,000 --> 00:56:58,000 så hvis fopen returnerer null noe dårlig skjedde. 1046 00:56:58,000 --> 00:57:02,000 Derimot, hvis fopen ikke returnerer null alt er bra 1047 00:57:02,000 --> 00:57:04,000 og jeg kan begynne å skrive til denne filen. 1048 00:57:04,000 --> 00:57:06,000 Her er et nytt triks. 1049 00:57:06,000 --> 00:57:08,000 Dette er en for løkke som er iterating over hver av mine studenter, 1050 00:57:08,000 --> 00:57:10,000 og dette ser så likt det vi har gjort før, 1051 00:57:10,000 --> 00:57:15,000 men denne funksjonen er en fetter av printf kalt fprintf for fil printf, 1052 00:57:15,000 --> 00:57:18,000 og merker det er annerledes i bare 2 måter. 1053 00:57:18,000 --> 00:57:20,000 One, begynner det med f stedet for p, 1054 00:57:20,000 --> 00:57:23,000 men da er det første argumentet er tilsynelatende hva? 1055 00:57:23,000 --> 00:57:25,000 [Studenter] File. >> Det er en fil. 1056 00:57:25,000 --> 00:57:30,000 Denne tingen kalt fp, som vi vil til slutt erte hverandre hva en filpekeren er, 1057 00:57:30,000 --> 00:57:35,000 men for nå fp representerer bare filen som jeg har åpnet, 1058 00:57:35,000 --> 00:57:41,000 så fprintf her sier skrive denne brukerens ID til filen, ikke til skjermen. 1059 00:57:41,000 --> 00:57:44,000 Skriv ut brukerens navn til filen, ikke til skjermen, 1060 00:57:44,000 --> 00:57:47,000 huset til filen, ikke til skjermen, og deretter ned her, selvsagt, 1061 00:57:47,000 --> 00:57:50,000 lukke filen, og deretter ned her gratis minnet. 1062 00:57:50,000 --> 00:57:53,000 >> Den eneste forskjellen mellom denne versjon 2 og 1 1063 00:57:53,000 --> 00:57:58,000 er innføring av fopen og denne filen med * 1064 00:57:58,000 --> 00:58:01,000 og denne oppfatningen av fprintf, så la oss se hva sluttresultatet er. 1065 00:58:01,000 --> 00:58:03,000 La meg gå inn i min terminal-vinduet. 1066 00:58:03,000 --> 00:58:06,000 La meg kjøre structs2, skriver. 1067 00:58:06,000 --> 00:58:09,000 Ser ut som alt er bra. La oss kjøre 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 oppførte det samme, men hvis jeg gjør nå ls 1071 00:58:23,000 --> 00:58:28,000 merke til hva filen er her blant alle koden min, database, 1072 00:58:28,000 --> 00:58:32,000 så la oss åpne det, gedit av databasen, og se på det. 1073 00:58:32,000 --> 00:58:34,000 Det er ikke den mest sexy av filformater. 1074 00:58:34,000 --> 00:58:38,000 Det er virkelig en del av data linje per linje per linje, 1075 00:58:38,000 --> 00:58:42,000 men de av dere som bruker Excel eller CSV-filer, kommaseparert verdier, 1076 00:58:42,000 --> 00:58:47,000 Jeg kunne sikkert ha brukt fprintf til stedet kanskje gjøre noe som dette 1077 00:58:47,000 --> 00:58:50,000 slik at jeg kunne faktisk lage tilsvarende en Excel-fil 1078 00:58:50,000 --> 00:58:53,000 ved å skille ting med komma, ikke bare nye linjer. 1079 00:58:53,000 --> 00:58:56,000 >> I dette tilfellet hvis jeg hadde i stedet brukt komma i stedet for nye linjer 1080 00:58:56,000 --> 00:59:01,000 Jeg kunne bokstavelig talt åpne denne databasen i Excel hvis jeg i stedet gjorde det ser slik ut. 1081 00:59:01,000 --> 00:59:03,000 Kort sagt, nå som vi har makt til å skrive til filer 1082 00:59:03,000 --> 00:59:07,000 Vi kan nå begynne vedvarende data, holde den rundt på plate 1083 00:59:07,000 --> 00:59:10,000 slik at vi kan holde informasjon rundt igjen og igjen. 1084 00:59:10,000 --> 00:59:14,000 Merke til et par andre ting som er nå litt mer kjent. 1085 00:59:14,000 --> 00:59:16,000 På toppen av dette C-filen har vi en typedef 1086 00:59:16,000 --> 00:59:21,000 fordi vi ønsket å lage en datatype som representerer et ord, 1087 00:59:21,000 --> 00:59:25,000 så denne typen kalles ord, og innsiden av denne strukturen 1088 00:59:25,000 --> 00:59:27,000 det er litt mer avansert nå. 1089 00:59:27,000 --> 00:59:30,000 Hvorfor er et ord består av tilsynelatende en array? 1090 00:59:30,000 --> 00:59:33,000 Hva er et ord bare intuitivt? 1091 00:59:33,000 --> 00:59:35,000 >> Det er en rekke tegn. 1092 00:59:35,000 --> 00:59:37,000 Det er en rekke tegn rygg mot rygg mot rygg. 1093 00:59:37,000 --> 00:59:41,000 Alle store bokstaver skjer for å være vi vilkårlig si maksimal lengde 1094 00:59:41,000 --> 00:59:44,000 av hvilket som helst ord i ordboken som vi bruker for Scramble. 1095 00:59:44,000 --> 00:59:46,000 Hvorfor har jeg en en? 1096 00:59:46,000 --> 00:59:48,000 Null karakter. 1097 00:59:48,000 --> 00:59:51,000 Husker når vi gjorde Bananagrams eksempel vi trengte en spesiell verdi 1098 00:59:51,000 --> 00:59:55,000 på slutten av ordet for å holde styr 1099 00:59:55,000 --> 00:59:59,000 hvor ordene faktisk avsluttet, og som oppgavesettet spesifikasjonen sier 1100 00:59:59,000 --> 01:00:03,000 her vi assosiere med et gitt ord en boolsk verdi, 1101 01:00:03,000 --> 01:00:05,000 et flagg, så å si, sant eller usant. 1102 01:00:05,000 --> 01:00:09,000 Har du funnet dette ordet allerede, fordi vi innser 1103 01:00:09,000 --> 01:00:13,000 vi virkelig trenger en måte å huske ikke bare hva et ord er i Scramble 1104 01:00:13,000 --> 01:00:15,000 men hvorvidt du, menneske, har funnet det 1105 01:00:15,000 --> 01:00:20,000 slik at hvis du finner ordet "the" du kan ikke bare skrive, skriver, det, enter,, skriver 1106 01:00:20,000 --> 01:00:23,000 og få 3 poeng, 3 poeng, 3 poeng, 3 poeng. 1107 01:00:23,000 --> 01:00:26,000 Vi ønsker å være i stand til å svarteliste det ordet ved å sette en bool 1108 01:00:26,000 --> 01:00:29,000 til true hvis du allerede har funnet den, og så det er derfor vi 1109 01:00:29,000 --> 01:00:31,000 innkapslet det i denne strukturen. 1110 01:00:31,000 --> 01:00:35,000 >> Nå, her nede i Scramble det er denne andre struct kalt ordbok. 1111 01:00:35,000 --> 01:00:39,000 Fraværende her er ordet typedef fordi i dette tilfellet 1112 01:00:39,000 --> 01:00:43,000 vi trengte å kapsle ideen om en ordbok, 1113 01:00:43,000 --> 01:00:46,000 og en ordbok inneholder en hel haug med ord, 1114 01:00:46,000 --> 01:00:49,000 som følger av denne matrisen, og hvor mange av disse ordene er det? 1115 01:00:49,000 --> 01:00:51,000 Vel, uansett hva dette variabel kalt størrelsen sier. 1116 01:00:51,000 --> 01:00:53,000 Men vi trenger bare en ordbok. 1117 01:00:53,000 --> 01:00:55,000 Vi trenger ikke en datatype som heter ordbok. 1118 01:00:55,000 --> 01:00:58,000 Vi trenger bare en av dem, så det viser seg i C 1119 01:00:58,000 --> 01:01:03,000 at hvis du ikke sier typedef, du bare si struct, så inne i klammeparentes 1120 01:01:03,000 --> 01:01:05,000 du sette variabler, så du satte navnet. 1121 01:01:05,000 --> 01:01:09,000 Dette er å erklære en variabel kalt ordbok 1122 01:01:09,000 --> 01:01:11,000 som ser slik ut. 1123 01:01:11,000 --> 01:01:16,000 Derimot, er disse linjene skaper en gjenbrukbar datastruktur kalt ordet 1124 01:01:16,000 --> 01:01:19,000 at du kan lage flere kopier av, akkurat som vi opprettet 1125 01:01:19,000 --> 01:01:22,000 flere kopier av studenter. 1126 01:01:22,000 --> 01:01:24,000 >> Hva betyr dette i siste instans tillate oss å gjøre? 1127 01:01:24,000 --> 01:01:30,000 La meg gå tilbake til, la oss si, en enklere eksempel fra enklere tider, 1128 01:01:30,000 --> 01:01:34,000 og la meg åpne opp, la oss si, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 Problemet her på hånden er å faktisk skrelle tilbake 1130 01:01:38,000 --> 01:01:41,000 laget av en streng og begynne å ta av disse opplæring hjul 1131 01:01:41,000 --> 01:01:44,000 fordi det viser seg at en streng hele tiden 1132 01:01:44,000 --> 01:01:47,000 er som vi lovet i uke 1 egentlig bare et kallenavn, 1133 01:01:47,000 --> 01:01:51,000 et synonym fra CS50 bibliotek for noe som ser litt mer kryptisk, 1134 01:01:51,000 --> 01:01:53,000 char *, og vi har sett denne stjernen før. 1135 01:01:53,000 --> 01:01:55,000 Vi så det i sammenheng med filer. 1136 01:01:55,000 --> 01:01:59,000 >> La oss nå se hvorfor vi har gjemt denne detaljen i noen tid nå. 1137 01:01:59,000 --> 01:02:02,000 Her er en fil som heter compare1.c, 1138 01:02:02,000 --> 01:02:07,000 og den ber tilsynelatende brukeren for 2 strenger, s og t, 1139 01:02:07,000 --> 01:02:11,000 og da er det prøver å sammenligne de strenger for likestilling i linje 26, 1140 01:02:11,000 --> 01:02:14,000 og hvis de er like står det: "Du skrev det samme," 1141 01:02:14,000 --> 01:02:17,000 og hvis de ikke er like står det: "Du har skrevet forskjellige ting." 1142 01:02:17,000 --> 01:02:19,000 La meg gå videre og kjøre dette programmet. 1143 01:02:19,000 --> 01:02:23,000 La meg gå inn i min kilde katalog, lage en compare1. Det samlet greit. 1144 01:02:23,000 --> 01:02:25,000 La meg kjøre compare1. 1145 01:02:25,000 --> 01:02:27,000 Jeg zoome inn, inn. 1146 01:02:27,000 --> 01:02:29,000 Si noe. HELLO. 1147 01:02:29,000 --> 01:02:32,000 Jeg vil si noe nytt. HELLO. 1148 01:02:32,000 --> 01:02:34,000 Jeg definitivt ikke skrive forskjellige ting. 1149 01:02:34,000 --> 01:02:37,000 >> La meg prøve dette igjen. BYE BYE. 1150 01:02:37,000 --> 01:02:40,000 Definitivt ikke annerledes, så hva er det som skjer her? 1151 01:02:40,000 --> 01:02:44,000 Vel, er det som virkelig blir sammenlignet på linje 26? 1152 01:02:44,000 --> 01:02:46,000 [Uhørlig-student] 1153 01:02:46,000 --> 01:02:49,000 Ja, så det viser seg at en streng, datatype, er en slags hvit løgn. 1154 01:02:49,000 --> 01:02:53,000 En streng er en char *, men hva er en char *? 1155 01:02:53,000 --> 01:02:56,000 En char *, som de sier, er en peker, 1156 01:02:56,000 --> 01:03:00,000 og en peker er effektivt en adresse, 1157 01:03:00,000 --> 01:03:05,000 en sum sted i minnet, og hvis du tilfeldigvis har skrevet inn et ord som HELLO, 1158 01:03:05,000 --> 01:03:08,000 husker fra tidligere diskusjoner strenger 1159 01:03:08,000 --> 01:03:16,000 dette er som ordet HELLO. 1160 01:03:16,000 --> 01:03:19,000 Husk at et ord som HELLO kan representeres 1161 01:03:19,000 --> 01:03:22,000 som en rekke tegn som dette 1162 01:03:22,000 --> 01:03:25,000 og deretter med en spesiell karakter ved enden kalles null karakter, 1163 01:03:25,000 --> 01:03:27,000 som \ betegner. 1164 01:03:27,000 --> 01:03:29,000 Hva er egentlig en streng? 1165 01:03:29,000 --> 01:03:32,000 Legg merke til at dette er flere biter av minne, 1166 01:03:32,000 --> 01:03:36,000 og faktisk er slutten av det eneste kjente når du ser gjennom hele strengen 1167 01:03:36,000 --> 01:03:38,000 på jakt etter den spesielle null karakter. 1168 01:03:38,000 --> 01:03:41,000 Men hvis dette er en del av minne fra min datamaskinens minne, 1169 01:03:41,000 --> 01:03:44,000 la oss vilkårlig si at denne strengen bare hadde flaks, 1170 01:03:44,000 --> 01:03:47,000 og det fikk plassert helt i begynnelsen av min datamaskinens RAM. 1171 01:03:47,000 --> 01:03:54,000 Dette er 0 byte, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> Når jeg sier noe sånt som GetString og jeg streng s = GetString 1173 01:04:02,000 --> 01:04:04,000 hva som virkelig blir returnert? 1174 01:04:04,000 --> 01:04:08,000 For disse siste ukene, er det som virkelig blir lagret i s 1175 01:04:08,000 --> 01:04:13,000 er ikke denne strengen per se, men i dette tilfellet hva som blir lagret, er 1176 01:04:13,000 --> 01:04:18,000 tallet 0 fordi det GetString faktisk gjør 1177 01:04:18,000 --> 01:04:20,000 er det ikke tilbake fysisk en streng. 1178 01:04:20,000 --> 01:04:22,000 Som ikke engang virkelig gjøre konseptuelle forstand. 1179 01:04:22,000 --> 01:04:24,000 Hva det retur er et tall. 1180 01:04:24,000 --> 01:04:28,000 At antallet er adressen HELLO i minnet, 1181 01:04:28,000 --> 01:04:32,000 og streng s da, hvis vi skrelle tilbake dette laget, ikke streng egentlig ikke eksisterer. 1182 01:04:32,000 --> 01:04:35,000 Det er bare en forenkling i CS50 biblioteket. 1183 01:04:35,000 --> 01:04:38,000 >> Dette er virkelig noe som heter char *. 1184 01:04:38,000 --> 01:04:41,000 Char er fornuftig fordi det er et ord, som HELLO? 1185 01:04:41,000 --> 01:04:44,000 Vel, det er en rekke tegn, en rekke tegn. 1186 01:04:44,000 --> 01:04:47,000 Char * betyr adressen til en karakter, 1187 01:04:47,000 --> 01:04:50,000 så hva betyr det å returnere en streng? 1188 01:04:50,000 --> 01:04:53,000 En fin og enkel måte å returnere en streng 1189 01:04:53,000 --> 01:04:57,000 er heller enn å prøve å finne ut hvordan jeg kommer tilbake til 5 eller 6 forskjellige byte 1190 01:04:57,000 --> 01:05:01,000 la meg gå tilbake til adressen som byte? 1191 01:05:01,000 --> 01:05:03,000 Den første. 1192 01:05:03,000 --> 01:05:06,000 Med andre ord, la meg gi deg adressen til en karakter i minnet. 1193 01:05:06,000 --> 01:05:10,000 Det er det char * representerer, er adressen til en enkelt tegn i minnet. 1194 01:05:10,000 --> 01:05:12,000 Ring den variabelen s. 1195 01:05:12,000 --> 01:05:15,000 Butikk i s den aktuelle adressen, som jeg vilkårlig sagt er 0, 1196 01:05:15,000 --> 01:05:19,000 bare for å holde ting enkelt, men i virkeligheten er det generelt et større antall. 1197 01:05:19,000 --> 01:05:21,000 >> Vent litt. 1198 01:05:21,000 --> 01:05:23,000 Hvis du bare gi meg adressen til det første tegnet, hvordan vet jeg hva adressen er 1199 01:05:23,000 --> 01:05:25,000 for neste tegn, den tredje, fjerde og femte? 1200 01:05:25,000 --> 01:05:27,000 [Uhørlig-student] 1201 01:05:27,000 --> 01:05:31,000 Du bare vet hvor slutten av strengen er ved hjelp av denne praktiske triks, 1202 01:05:31,000 --> 01:05:35,000 så når du bruker noe som printf, hva printf tar bokstavelig talt som argument sin, 1203 01:05:35,000 --> 01:05:39,000 husker at vi bruker denne% s plassholder, og du passerer i 1204 01:05:39,000 --> 01:05:41,000 variabelen som er å lagre en streng. 1205 01:05:41,000 --> 01:05:47,000 Hva du egentlig passerer er adressen til den første tegnet strengen. 1206 01:05:47,000 --> 01:05:50,000 Printf bruker deretter en for loop eller en stund loop ved mottak som adresse, 1207 01:05:50,000 --> 01:05:53,000 for eksempel, 0, så la meg gjøre dette nå, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n", s); 1209 01:06:02,000 --> 01:06:07,000 Når jeg ringer printf ("% s \ n", s), hva jeg egentlig gi printf med 1210 01:06:07,000 --> 01:06:13,000 er adressen for det første tegnet i s, som i dette tilfellet er vilkårlig H. 1211 01:06:13,000 --> 01:06:16,000 >> Hvordan vet printf hva som skal vises på skjermen? 1212 01:06:16,000 --> 01:06:19,000 Personen som gjennomføres printf implementert en stund løkke eller en for loop 1213 01:06:19,000 --> 01:06:23,000 som sier ikke lik denne karakteren den spesielle null karakter? 1214 01:06:23,000 --> 01:06:25,000 Hvis ikke, skrive det ut. Hva med denne? 1215 01:06:25,000 --> 01:06:28,000 Hvis ikke skrive det, skrive det ut, skrive det ut, skrive det ut. 1216 01:06:28,000 --> 01:06:32,000 Å, dette er en spesiell. Stopp trykkteknikker og gå tilbake til brukeren. 1217 01:06:32,000 --> 01:06:35,000 Og det er bokstavelig talt alt som har skjedd under panseret, 1218 01:06:35,000 --> 01:06:38,000 og det er mye å fordøye i den første dagen av en klasse, 1219 01:06:38,000 --> 01:06:43,000 men for nå er det virkelig byggestein forstå alt 1220 01:06:43,000 --> 01:06:46,000 som har pågått på innsiden av våre datamaskinens minne, 1221 01:06:46,000 --> 01:06:49,000 og til slutt vil vi erte dette fra hverandre med litt hjelp 1222 01:06:49,000 --> 01:06:51,000 fra en av våre venner på Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> Professor Nick Parlante ved Stanford har gjort denne fantastiske videosekvens 1224 01:06:56,000 --> 01:06:58,000 fra alle slags forskjellige språk som introduserte 1225 01:06:58,000 --> 01:07:00,000 denne lille Claymation karakter Binky. 1226 01:07:00,000 --> 01:07:03,000 Stemmen du er i ferd å høre på bare noen få andre sniktitt 1227 01:07:03,000 --> 01:07:05,000 er at av en Stanford professor, og du får 1228 01:07:05,000 --> 01:07:07,000 bare 5 eller 6 sekunder av dette akkurat nå, 1229 01:07:07,000 --> 01:07:09,000 men dette er notatet som vi vil konkludere i dag 1230 01:07:09,000 --> 01:07:11,000 og begynne på onsdag. 1231 01:07:11,000 --> 01:07:15,000 Jeg gir deg Pointer Moro med Binky, forhåndsvisningen. 1232 01:07:15,000 --> 01:07:18,000 [♪ Music ♪] [Professor Parlante] Hei, Binky. 1233 01:07:18,000 --> 01:07:21,000 Våkn opp. Det er tid for pekeren moro. 1234 01:07:21,000 --> 01:07:24,000 [Binky] Hva er det? Lær om pekere? 1235 01:07:24,000 --> 01:07:26,000 Oh, goody! 1236 01:07:26,000 --> 01:07:29,000 >> Vi vil se deg på onsdag. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]