1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [DEL 5: mindre komfortable] 2 00:00:02,730 --> 00:00:05,180 [Nate Hardison, Harvard University] 3 00:00:05,180 --> 00:00:08,260 [Dette er CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Så velkommen tilbake, folkens. 5 00:00:11,690 --> 00:00:16,320 Velkommen til § 5. 6 00:00:16,320 --> 00:00:20,220 På dette punktet, etter å ha fullført quiz 0 og etter å ha sett hvordan du har gjort, 7 00:00:20,220 --> 00:00:25,770 forhåpentligvis du føler deg virkelig bra fordi jeg var veldig imponert resultatet i denne delen. 8 00:00:25,770 --> 00:00:28,050 For våre online seere, har vi hatt et par spørsmål 9 00:00:28,050 --> 00:00:33,680 om de to siste problemene på oppgavesettet - eller på quiz, heller. 10 00:00:33,680 --> 00:00:39,690 Så vi kommer til å gå over dem veldig raskt, slik at alle ser hva som skjedde 11 00:00:39,690 --> 00:00:45,060 og hvordan du skal gå gjennom selve løsningen i stedet for bare å se på løsningen selv. 12 00:00:45,060 --> 00:00:50,330 Vi kommer til å gå over de siste par problemer veldig raskt, 32 og 33. 13 00:00:50,330 --> 00:00:53,240 Bare, igjen, kan slik at online seere se dette. 14 00:00:53,240 --> 00:00:59,080 >> Hvis du slår til problemet ditt 32, som er på side 13, 15 00:00:59,080 --> 00:01:02,730 13 av 16, er problemet 32 ​​om bytteavtaler. 16 00:01:02,730 --> 00:01:05,010 Det var alt om å bytte to heltall. 17 00:01:05,010 --> 00:01:08,740 Det er problemet at vi hadde gått over et par ganger i forelesningen. 18 00:01:08,740 --> 00:01:13,590 Og her, hva vi ber deg om å gjøre en rask minne spor. 19 00:01:13,590 --> 00:01:17,000 Å fylle ut verdiene til variablene som de er på stakken 20 00:01:17,000 --> 00:01:20,250 som koden går gjennom denne swap-funksjon. 21 00:01:20,250 --> 00:01:24,500 Spesielt det vi ser på - jeg kommer til å sette dette iPad ned - 22 00:01:24,500 --> 00:01:29,650 i særdeleshet, hva vi ser på er denne linjen nummerert 6 her. 23 00:01:29,650 --> 00:01:36,740 Og det er nummerert 6 for bare contiguity med forrige problemet. 24 00:01:36,740 --> 00:01:41,720 Hva vi ønsker å gjøre er å vise eller merke staten minne 25 00:01:41,720 --> 00:01:46,090 som det er på den tiden da vi utføre denne linjen nummer 6, 26 00:01:46,090 --> 00:01:52,540 som er effektivt en retur fra vår swap-funksjon her. 27 00:01:52,540 --> 00:01:59,450 Hvis vi bla nedover her, så vi at adressene til alt i minnet ble levert for oss. 28 00:01:59,450 --> 00:02:02,540 Dette er svært viktig, vi vil komme tilbake til det i løpet av et øyeblikk. 29 00:02:02,540 --> 00:02:09,240 Og deretter ned her på bunnen, hadde vi et lite minne diagram som vi kommer til å referere til. 30 00:02:09,240 --> 00:02:12,490 Jeg har faktisk gjort dette ut på min iPad. 31 00:02:12,490 --> 00:02:20,720 Så jeg kommer til å veksle frem og tilbake mellom iPad og denne koden bare for referanse. 32 00:02:20,720 --> 00:02:26,540 >> La oss starte. Først, la oss fokusere på de første par linjer av viktigste akkurat her. 33 00:02:26,540 --> 00:02:30,220 Hvis du vil starte, vi kommer til å starte x til 1 og y 2. 34 00:02:30,220 --> 00:02:33,040 Så vi har to heltall variabler, de begge kommer til å bli plassert på stakken. 35 00:02:33,040 --> 00:02:36,050 Vi kommer til å sette en 1 og en 2 i dem. 36 00:02:36,050 --> 00:02:43,150 Så hvis jeg snur over til min iPad, forhåpentligvis, la oss se - 37 00:02:43,150 --> 00:02:48,660 Apple TV speiling, og der vi går. Okay. 38 00:02:48,660 --> 00:02:51,670 Så hvis jeg snur over til min iPad, 39 00:02:51,670 --> 00:02:56,220 Jeg ønsker å starte x til 1 og y 2. 40 00:02:56,220 --> 00:03:00,580 Vi gjør det ganske enkelt ved å skrive en 1 i boksen merket x 41 00:03:00,580 --> 00:03:07,730 og en 2 i boksen merket y. Ganske enkel. 42 00:03:07,730 --> 00:03:11,620 Så nå la oss gå tilbake til den bærbare datamaskinen, se hva som skjer videre. 43 00:03:11,620 --> 00:03:15,810 Så dette neste linjen er der ting blir vanskelig. 44 00:03:15,810 --> 00:03:28,110 Vi passerer adressen x og adressen y som parametrene a og b til swap-funksjonen. 45 00:03:28,110 --> 00:03:32,380 Adressen x og adressen y er ting som vi ikke kan beregne 46 00:03:32,380 --> 00:03:36,360 uten å referere til disse punktene rett ned her. 47 00:03:36,360 --> 00:03:39,750 Og heldigvis, de to første punktene forteller oss nøyaktig hva svarene er. 48 00:03:39,750 --> 00:03:44,740 Adressen til x minne er 10, og adressen y i minnet er 14. 49 00:03:44,740 --> 00:03:51,870 Så de er verdier som blir vedtatt i som a og b opp toppen i vår swap-funksjon. 50 00:03:51,870 --> 00:04:00,760 Så igjen, bytte tilbake til diagrammet vårt, kan jeg skrive en 10 i en 51 00:04:00,760 --> 00:04:07,400 og en 14 i b. 52 00:04:07,400 --> 00:04:11,610 Nå er dette punktet hvor vi fortsette med swap. 53 00:04:11,610 --> 00:04:14,520 Så blar tilbake til laptop igjen, 54 00:04:14,520 --> 00:04:21,079 Vi ser at måten swap fungerer er jeg først dereferanse A og lagrer resultatet i tmp. 55 00:04:21,079 --> 00:04:27,650 Så dereferanse operatør sier "Hei. Unn innholdet i variabel en som en adresse. 56 00:04:27,650 --> 00:04:33,830 Gå til det du har lagret på denne adressen, og bruke det. " 57 00:04:33,830 --> 00:04:41,720 Hva du legger ut på variabelen skal lagres i vår tmp variabel. 58 00:04:41,720 --> 00:04:45,150 Bla tilbake til iPad. 59 00:04:45,150 --> 00:04:51,690 Hvis vi går for å ta 10, vet vi at adressen 10 er varible x 60 00:04:51,690 --> 00:04:55,480 fordi vi ble fortalt av vår punktet at adressen x minne er 10. 61 00:04:55,480 --> 00:05:00,180 Så vi kan gå dit, få verdien av det, som er 1, som vi ser på iPad vår, 62 00:05:00,180 --> 00:05:06,300 og laste det inn tmp. 63 00:05:06,300 --> 00:05:08,250 Igjen, dette er ikke den endelige innholdet. 64 00:05:08,250 --> 00:05:14,350 Vi kommer til å gå gjennom, og vi vil komme til vårt endelige tilstanden til programmet på slutten. 65 00:05:14,350 --> 00:05:17,210 Men akkurat nå har vi verdien 1 er lagret i tmp. 66 00:05:17,210 --> 00:05:19,210 >> Og det er en rask spørsmål over her. 67 00:05:19,210 --> 00:05:23,980 [Alexander] Er dereferanse operatør - det er bare stjernen rett foran variabel? 68 00:05:23,980 --> 00:05:27,600 >> Ja. Så dereferanse operatør, som vi vende tilbake til vår laptop igjen, 69 00:05:27,600 --> 00:05:33,780 er denne stjernen rett foran. 70 00:05:33,780 --> 00:05:37,460 I den forstand er det - du kontrast det med multiplikasjonsoperatoren 71 00:05:37,460 --> 00:05:42,400 som krever to ting, den dereferanse operatør er en unary operatør. 72 00:05:42,400 --> 00:05:46,130 Bare brukt til en verdi som i motsetning til en binær operator, 73 00:05:46,130 --> 00:05:48,810 hvor du søker på to forskjellige verdier. 74 00:05:48,810 --> 00:05:52,080 Så det er hva som skjer i denne linjen. 75 00:05:52,080 --> 00:05:58,390 Vi lastet verdien 1 og lagret den i vår midlertidige heltallsvariabel. 76 00:05:58,390 --> 00:06:05,800 Neste linje, lagrer vi innholdet i b inn - 77 00:06:05,800 --> 00:06:12,630 eller snarere, lagrer vi innholdet som b peker til på plassen der en peker til. 78 00:06:12,630 --> 00:06:17,690 Hvis vi analyserer dette fra høyre til venstre, skal vi dereferanse b, 79 00:06:17,690 --> 00:06:23,580 vi kommer til å ta 14, skal vi ta tak i heltallet som er der, 80 00:06:23,580 --> 00:06:26,900 og vi kommer til å gå til adressen 10, 81 00:06:26,900 --> 00:06:34,240 og vi kommer til å kaste et resultat av vår dereferanse av b inn i det rommet. 82 00:06:34,240 --> 00:06:40,080 Bla tilbake til vår iPad, hvor vi kan gjøre dette litt mer konkret, 83 00:06:40,080 --> 00:06:44,070 det kan hjelpe hvis jeg skriver tallene på alle adressene her. 84 00:06:44,070 --> 00:06:53,820 Så vi vet at y, er vi på adressen 14, x på adressen 10. 85 00:06:53,820 --> 00:07:00,180 Når vi starter på b, vi dereferanse b, skal vi ta verdien 2. 86 00:07:00,180 --> 00:07:08,320 Vi kommer til å ta denne verdien fordi det er den verdien som bor på adressen 14. 87 00:07:08,320 --> 00:07:15,700 Og vi kommer til å sette det inn i den variabelen som bor på adressen 10, 88 00:07:15,700 --> 00:07:19,160 som er rett der, tilsvarende våre variable x. 89 00:07:19,160 --> 00:07:21,810 Så vi kan gjøre litt for å overskrive her 90 00:07:21,810 --> 00:07:35,380 hvor vi blir kvitt vår 1 og i stedet vi skriver en 2. 91 00:07:35,380 --> 00:07:39,560 Så alt er vel og bra i verden, selv om vi har overskrevet x nå. 92 00:07:39,560 --> 00:07:44,890 Vi har lagret x gamle verdi i vår tmp variabel. 93 00:07:44,890 --> 00:07:50,210 Så vi kan fullføre swap med neste linje. 94 00:07:50,210 --> 00:07:53,030 Bla tilbake til vår laptop. 95 00:07:53,030 --> 00:07:58,150 Nå er alt som gjenstår er å ta innholdet ut av vår midlertidige heltallsvariabel 96 00:07:58,150 --> 00:08:05,630 og lagre dem i den variabelen som bor på den adressen som b holder. 97 00:08:05,630 --> 00:08:10,230 Så vi kommer til å effektivt dereferanse b for å få tilgang til variabelen 98 00:08:10,230 --> 00:08:14,340 som er på den adressen som b holder i det, 99 00:08:14,340 --> 00:08:19,190 og vi kommer til å stappe den verdien som tmp holder i den. 100 00:08:19,190 --> 00:08:23,280 Bla tilbake til iPad gang. 101 00:08:23,280 --> 00:08:31,290 Jeg kan slette denne verdien her, 2, 102 00:08:31,290 --> 00:08:41,010 og i stedet vil vi kopiere en rett inn i den. 103 00:08:41,010 --> 00:08:43,059 Deretter neste linje som utfører, selvfølgelig - 104 00:08:43,059 --> 00:08:47,150 hvis vi vende tilbake til den bærbare - er dette punkt 6, 105 00:08:47,150 --> 00:08:52,500 som er det punktet hvor vi ønsket å ha vår diagram fylt ut. 106 00:08:52,500 --> 00:08:58,940 Så blar tilbake til iPad enda en gang, bare så du kan se det ferdige diagrammet, 107 00:08:58,940 --> 00:09:06,610 du kan se at vi har en 10 i en, en 14 i b, en 1 i tmp, en 2 i x, og en 1 i y. 108 00:09:06,610 --> 00:09:11,000 Er det noen spørsmål om dette? 109 00:09:11,000 --> 00:09:14,640 Betyr dette mer fornuftig, etter å ha vandret gjennom det? 110 00:09:14,640 --> 00:09:24,850 Gjøre mindre fornuftig? Forhåpentligvis ikke. Okay. 111 00:09:24,850 --> 00:09:28,230 >> Pekere er en veldig vanskelig emne. 112 00:09:28,230 --> 00:09:33,420 En av gutta vi jobber med har en svært vanlig ordtak: 113 00:09:33,420 --> 00:09:36,590 "For å forstå pekere, må du først forstå pekere." 114 00:09:36,590 --> 00:09:40,530 Som jeg tror er veldig sant. Det tar en stund å bli vant til det. 115 00:09:40,530 --> 00:09:45,360 Loddtrekning av bilder, er loddtrekning av minne diagrammer som dette svært nyttig, 116 00:09:45,360 --> 00:09:49,480 og når du går gjennom eksempel etter eksempel etter eksempel, 117 00:09:49,480 --> 00:09:54,450 det vil begynne å gjøre litt mer fornuftig og litt mer fornuftig og litt mer fornuftig. 118 00:09:54,450 --> 00:10:01,560 Endelig, en dag, vil du ha det hele helt mestret. 119 00:10:01,560 --> 00:10:13,800 Eventuelle spørsmål før vi går videre til neste problem? OK. 120 00:10:13,800 --> 00:10:18,840 Så vende tilbake til den bærbare datamaskinen. 121 00:10:18,840 --> 00:10:23,300 Det neste problemet vi har er problem nummer 33 på fil I / O. 122 00:10:23,300 --> 00:10:26,350 Zoome inn på dette litt. 123 00:10:26,350 --> 00:10:28,710 Oppgave 33 - Ja? 124 00:10:28,710 --> 00:10:32,110 >> [Daniel] Jeg hadde bare en rask spørsmål. Denne stjernen, eller stjerne, 125 00:10:32,110 --> 00:10:35,590 det heter dereferencing når du bruker en stjerne før. 126 00:10:35,590 --> 00:10:38,820 Hva heter det når du bruker tegnet før? 127 00:10:38,820 --> 00:10:43,140 >> Tegnet er før adressesøk av operatør. 128 00:10:43,140 --> 00:10:45,880 Så la oss bla tilbake. 129 00:10:45,880 --> 00:10:49,310 Oops. Jeg er i zoom-modus så jeg kan egentlig ikke bla. 130 00:10:49,310 --> 00:10:52,780 Hvis vi ser på denne koden veldig raskt akkurat her, 131 00:10:52,780 --> 00:10:54,980 igjen, samme skjer. 132 00:10:54,980 --> 00:10:59,180 Hvis vi ser på denne koden her, på denne linjen hvor vi ringe for å bytte, 133 00:10:59,180 --> 00:11:10,460 tegnet er bare å si "få den adressen variable x liv." 134 00:11:10,460 --> 00:11:14,460 Når kompilatoren kompilerer koden, 135 00:11:14,460 --> 00:11:20,590 det har å faktisk fysisk markere et sted i minnet for alle variabler å leve. 136 00:11:20,590 --> 00:11:24,910 Og så hva kompilatoren kan deretter gjøre når den er utarbeidet alt, 137 00:11:24,910 --> 00:11:31,110 det vet, "Oh, la jeg x på adressen 10. jeg satt y på adressen 14." 138 00:11:31,110 --> 00:11:34,640 Det kan deretter fylle ut disse verdiene for deg. 139 00:11:34,640 --> 00:11:44,740 Så du kan da - det kan da passere dette i og pass & y i tillegg. 140 00:11:44,740 --> 00:11:50,730 Disse gutta få adressen, men de har også, når du passerer dem i swap-funksjonen, 141 00:11:50,730 --> 00:11:55,690 denne type informasjon, dette int * her, forteller kompilatoren, 142 00:11:55,690 --> 00:12:01,350 "Ok, vi kommer til å bli tolke denne adressen som en adresse for en heltallsvariabel." 143 00:12:01,350 --> 00:12:05,900 Som en adresse for en int, som er forskjellig fra adressen av et tegn variabel 144 00:12:05,900 --> 00:12:09,930 fordi en int tar opp, på en 32-bits maskin, tar opp 4 byte av plass, 145 00:12:09,930 --> 00:12:13,310 mens et tegn tar bare opp en byte plass. 146 00:12:13,310 --> 00:12:17,310 Derfor er det viktig å vite også hva er - hva som bor, hva slags verdi 147 00:12:17,310 --> 00:12:20,340 lever på adressen som ble vedtatt i. 148 00:12:20,340 --> 00:12:22,020 Eller adressen som du arbeider med. 149 00:12:22,020 --> 00:12:29,020 På den måten vet du hvor mange byte av informasjon å faktisk laste ut av RAM. 150 00:12:29,020 --> 00:12:31,780 Og så, ja, dette dereferanse operatør, som du spør, 151 00:12:31,780 --> 00:12:37,200 går og tilgang til informasjon på en bestemt adresse. 152 00:12:37,200 --> 00:12:42,820 Så det sier, med dette en variabel her, behandle innholdet i en som en adresse, 153 00:12:42,820 --> 00:12:47,880 gå til denne adressen, og trekk ut, laste inn i prosessoren, last inn i et register 154 00:12:47,880 --> 00:12:56,340 de faktiske verdiene eller innholdet som bor på denne adressen. 155 00:12:56,340 --> 00:12:59,620 Noen flere spørsmål? Dette er gode spørsmål. 156 00:12:59,620 --> 00:13:01,650 Det er mye ny terminologi også. 157 00:13:01,650 --> 00:13:09,800 Det er også slags funky, se & og * på forskjellige steder. 158 00:13:09,800 --> 00:13:13,180 >> OK. 159 00:13:13,180 --> 00:13:18,530 Så tilbake til problemet 33, fil I / O. 160 00:13:18,530 --> 00:13:22,540 Dette var en av de problemene som jeg tror et par ting skjedde. 161 00:13:22,540 --> 00:13:25,400 Ett, er det en ganske ny tråd. 162 00:13:25,400 --> 00:13:30,590 Det ble presentert ganske snart før quizen, 163 00:13:30,590 --> 00:13:33,400 og da tror jeg det var typen som en av de ord problemer i matematikk 164 00:13:33,400 --> 00:13:39,720 der de gir deg mye informasjon, men du faktisk ikke ender opp med å bruke massevis av det. 165 00:13:39,720 --> 00:13:44,060 Den første delen av dette problemet er å beskrive hva en CSV-fil er. 166 00:13:44,060 --> 00:13:50,620 Nå, et CSV-fil, i henhold til beskrivelsen, er en kommadelt fil. 167 00:13:50,620 --> 00:13:55,300 Grunnen til at disse er i det hele tatt interessant, og grunnen til at du bruker dem aldri, 168 00:13:55,300 --> 00:14:00,800 er, fordi, hvor mange av dere noen gang brukte ting som Excel? 169 00:14:00,800 --> 00:14:03,240 Figur fleste av dere har, sannsynligvis, eller vil bruke på et tidspunkt i livet ditt. 170 00:14:03,240 --> 00:14:06,430 Du bruker noe som Excel. 171 00:14:06,430 --> 00:14:10,940 For å få data ut av et Excel-regneark eller gjøre noen form for behandling med det, 172 00:14:10,940 --> 00:14:17,240 Hvis du ønsker å skrive et C-program eller Python program, Java-program, 173 00:14:17,240 --> 00:14:20,070 å håndtere dataene du har lagret der, 174 00:14:20,070 --> 00:14:23,170 en av de vanligste måtene å få det ut er i en CSV-fil. 175 00:14:23,170 --> 00:14:26,850 Og du kan åpne opp Excel og når du går til "Lagre som" dialog, 176 00:14:26,850 --> 00:14:32,840 du kan få ut en faktisk CSV-fil. 177 00:14:32,840 --> 00:14:35,890 >> Nyttig å vite hvordan man skal håndtere disse tingene. 178 00:14:35,890 --> 00:14:42,010 Måten det fungerer på er at det er lik - Jeg mener, det er egentlig etterligne et regneark, 179 00:14:42,010 --> 00:14:47,590 der, som vi ser her, i selve venstre-mest stykke, 180 00:14:47,590 --> 00:14:49,910 Vi har alle de siste navnene. 181 00:14:49,910 --> 00:14:54,670 Så vi har Malan, så Hardison, og deretter Bowden, MacWilliam, og deretter Chan. 182 00:14:54,670 --> 00:14:59,470 Alle de siste navn. Og så komma skiller de siste navnene fra de første navnene. 183 00:14:59,470 --> 00:15:02,970 David, Nate, Rob, Tommy, og Zamyla. 184 00:15:02,970 --> 00:15:06,850 Jeg har alltid blande Robby og Tom. 185 00:15:06,850 --> 00:15:10,940 Og så, til slutt, er den tredje kolonnen e-postadressene. 186 00:15:10,940 --> 00:15:18,500 Når du forstår det, er resten av programmet ganske grei å gjennomføre. 187 00:15:18,500 --> 00:15:23,850 Hva vi har gjort for å etterligne den samme strukturen i vår C program 188 00:15:23,850 --> 00:15:27,510 er vi har brukt en struktur. 189 00:15:27,510 --> 00:15:30,520 Vi vil begynne å spille med disse litt mer også. 190 00:15:30,520 --> 00:15:35,790 Vi så dem for første litt i oppgavesettet 3, da vi arbeider med ordbøker. 191 00:15:35,790 --> 00:15:40,290 Men denne ansatte struct lagrer et etternavn, fornavn, og en e-post. 192 00:15:40,290 --> 00:15:44,500 Akkurat som vår CSV-filen ble lagring. 193 00:15:44,500 --> 00:15:47,950 Så dette er bare å konvertere fra ett format til et annet. 194 00:15:47,950 --> 00:15:54,630 Vi har til å konvertere, i dette tilfellet, en stab struct inn en linje, 195 00:15:54,630 --> 00:15:59,060 en kommaseparert linje, akkurat sånn. 196 00:15:59,060 --> 00:16:01,500 Gjør det fornuftig? Dere har alle tatt quizen, 197 00:16:01,500 --> 00:16:07,680 så jeg tenke at du har minst hadde litt tid til å tenke på dette. 198 00:16:07,680 --> 00:16:16,410 >> I leie-funksjonen, spør problemet oss å ta i - vi vil zoome inn på dette litt - 199 00:16:16,410 --> 00:16:22,480 ta i en stab struktur, en stab struct, med navn s, 200 00:16:22,480 --> 00:16:30,900 og legge innholdet til vår staff.csv fil. 201 00:16:30,900 --> 00:16:34,230 Det viser seg at dette er ganske grei å bruke. 202 00:16:34,230 --> 00:16:37,430 Vi vil slags leke seg med disse funksjonene litt mer i dag. 203 00:16:37,430 --> 00:16:44,510 Men i dette tilfellet er fprintf funksjonen virkelig nøkkelen. 204 00:16:44,510 --> 00:16:51,960 Så med fprintf, kan vi skrive ut, akkurat som dere har brukt printf hele denne sikt. 205 00:16:51,960 --> 00:16:55,050 Du kan printf en linje til en fil. 206 00:16:55,050 --> 00:16:59,030 Så i stedet for bare å gjøre den vanlige printf samtale der du gi den formatstrengen 207 00:16:59,030 --> 00:17:05,380 og deretter erstatte alle variablene med følgende argumenter, 208 00:17:05,380 --> 00:17:11,290 med fprintf, er din aller første argumentet i stedet filen du ønsker å skrive til. 209 00:17:11,290 --> 00:17:21,170 Hvis vi skulle se på dette i apparatet, for eksempel, mann fprintf, 210 00:17:21,170 --> 00:17:25,980 Vi kan se forskjellen mellom printf og fprintf. 211 00:17:25,980 --> 00:17:28,960 Jeg skal zoome inn her litt. 212 00:17:28,960 --> 00:17:33,140 Så med printf, gir vi det et format streng, og deretter påfølgende argumenter 213 00:17:33,140 --> 00:17:37,580 er alle variablene for erstatning eller erstatning i vår formatstrengen. 214 00:17:37,580 --> 00:17:47,310 Mens med fprintf, er det første argumentet faktisk dette fil * kalles en bekk. 215 00:17:47,310 --> 00:17:51,800 >> Flytte tilbake hit til leie vår, 216 00:17:51,800 --> 00:17:54,550 Vi har allerede fått vår fil * stream åpnet for oss. 217 00:17:54,550 --> 00:17:57,810 Det er hva denne første linjen gjør den åpner staff.csv fil, 218 00:17:57,810 --> 00:18:01,690 det åpner det i append modus, og alt som er igjen for oss å gjøre, er 219 00:18:01,690 --> 00:18:08,640 skrive bemanningsstrukturen til filen. 220 00:18:08,640 --> 00:18:10,870 Og, la oss se, jeg ønsker å bruke iPad? 221 00:18:10,870 --> 00:18:17,900 Jeg vil bruke iPad. Vi har annullert - la oss sette dette på bordet slik at jeg kan skrive litt bedre - 222 00:18:17,900 --> 00:18:33,680 ugyldiggjøre leie og det tar i ett argument, en stab struktur kalt s. 223 00:18:33,680 --> 00:18:44,120 Fikk våre bukseseler, har vi vår fil * heter filen, 224 00:18:44,120 --> 00:18:48,380 Vi har vår fopen linjen gitt til oss, 225 00:18:48,380 --> 00:18:51,890 og jeg vil bare skrive det som prikker siden det er allerede i pedia. 226 00:18:51,890 --> 00:19:00,530 Og deretter på vår neste linje, vi kommer til å ringe til fprintf 227 00:19:00,530 --> 00:19:03,700 og vi kommer til å passere i filen som vi ønsker å skrive til, 228 00:19:03,700 --> 00:19:10,290 og deretter våre formatstrengen, som - 229 00:19:10,290 --> 00:19:14,300 Jeg skal la dere fortelle meg hva det ser ut som. 230 00:19:14,300 --> 00:19:20,500 Hva med deg, Stella? Vet du hva den første delen av formatstrengen ser ut? 231 00:19:20,500 --> 00:19:24,270 [Stella] Jeg er ikke sikker. >> Gjerne spørre Jimmy. 232 00:19:24,270 --> 00:19:27,690 Vet du, Jimmy? 233 00:19:27,690 --> 00:19:31,000 [Jimmy] Vil det bare være sist? Jeg vet ikke. Jeg er ikke helt sikker. 234 00:19:31,000 --> 00:19:39,020 >> Ok. Hva med, gjorde noen få dette riktig på eksamen? 235 00:19:39,020 --> 00:19:41,770 Nei vel. 236 00:19:41,770 --> 00:19:47,920 Det viser seg at her alt vi trenger å gjøre er vi ønsker hver del av våre ansatte struktur 237 00:19:47,920 --> 00:19:53,290 som skal skrives ut som en streng i fil vår. 238 00:19:53,290 --> 00:19:59,900 Vi bare bruke strengen substitusjon tegnet tre forskjellige tider fordi vi har et etternavn 239 00:19:59,900 --> 00:20:07,160 etterfulgt av komma, deretter en fornavn etterfulgt av et komma, 240 00:20:07,160 --> 00:20:12,430 og så til slutt e-postadressen som er fulgt - som ikke 241 00:20:12,430 --> 00:20:15,140 montering på skjermen min - men det er etterfulgt av en ny linje karakter. 242 00:20:15,140 --> 00:20:20,060 Så jeg kommer til å skrive det bare der nede. 243 00:20:20,060 --> 00:20:23,560 Og deretter følge vår formatstrengen, 244 00:20:23,560 --> 00:20:27,880 vi bare har erstatninger, som vi har tilgang til via dot notasjon 245 00:20:27,880 --> 00:20:31,370 som vi så i oppgavesettet 3. 246 00:20:31,370 --> 00:20:48,820 Vi kan bruke s.last, s.first, og s.email 247 00:20:48,820 --> 00:20:58,990 å erstatte i de tre verdiene i vår formatstrengen. 248 00:20:58,990 --> 00:21:06,190 Så hvordan gikk det gå? Fornuftig? 249 00:21:06,190 --> 00:21:09,700 Ja? Nei? Muligens? Okay. 250 00:21:09,700 --> 00:21:14,180 >> Den siste tingen som vi gjør etter at vi har skrevet ut og etter at vi har åpnet våre filen: 251 00:21:14,180 --> 00:21:17,370 når vi har åpnet en fil, har vi alltid huske å lukke den. 252 00:21:17,370 --> 00:21:19,430 Fordi ellers vil vi ende opp lekker minnet, 253 00:21:19,430 --> 00:21:22,500 bruker opp fildeskriptorer. 254 00:21:22,500 --> 00:21:25,950 Så for å lukke det, hvilken funksjon bruker vi? Daniel? 255 00:21:25,950 --> 00:21:30,120 [Daniel] fclose? >> Fclose, akkurat. 256 00:21:30,120 --> 00:21:37,520 Så den siste delen av dette problemet var å skikkelig lukke filen, ved hjelp av fclose funksjon, 257 00:21:37,520 --> 00:21:40,370 som ser akkurat sånn. 258 00:21:40,370 --> 00:21:43,880 Ikke altfor gal. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Så det er problem 33 på quiz. 261 00:21:49,520 --> 00:21:52,480 Vi vil ha definitivt mer fil I / O kommer opp. 262 00:21:52,480 --> 00:21:55,130 Vi vil gjøre litt mer i foredraget i dag, eller i § dag, 263 00:21:55,130 --> 00:22:01,710 fordi det er det som kommer til å danne hoveddelen av denne kommende pset. 264 00:22:01,710 --> 00:22:05,020 La oss gå videre fra quizen på dette punktet. Ja? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] Hvorfor fclose (fil) i stedet for fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 >> Ah. Fordi det viser seg at - så spørsmålet, som er en stor en, 267 00:22:19,100 --> 00:22:27,800 er hvorfor, når vi skriver fclose, skriver vi fclose (fil) star variabel 268 00:22:27,800 --> 00:22:33,680 i motsetning til filnavnet, staff.csv? Er det riktig? Ja. 269 00:22:33,680 --> 00:22:39,570 Så la oss ta en titt. Hvis jeg bytter tilbake til min laptop, 270 00:22:39,570 --> 00:22:45,040 og la oss se på fclose funksjonen. 271 00:22:45,040 --> 00:22:51,460 Så fclose funksjonen stenger en bekk og det tar i pekeren til bekken som vi ønsker å lukke, 272 00:22:51,460 --> 00:22:57,010 i motsetning til den faktiske filnavnet som vi ønsker å lukke. 273 00:22:57,010 --> 00:23:01,620 Og dette er fordi bak kulissene, når du ringer til fopen, 274 00:23:01,620 --> 00:23:12,020 når du åpner opp en fil, kan du faktisk tildele minne til å lagre informasjon om filen. 275 00:23:12,020 --> 00:23:16,380 Så du har filpekeren som har informasjon om filen, 276 00:23:16,380 --> 00:23:23,080 slik som det er åpent, størrelse, hvor du befinner deg i filen, 277 00:23:23,080 --> 00:23:29,100 slik at du kan gjøre lesing og skriving samtaler til dette bestemte stedet i filen. 278 00:23:29,100 --> 00:23:38,060 Du ender opp med å stenge pekeren stedet for å lukke filnavnet. 279 00:23:38,060 --> 00:23:48,990 >> Ja? [Daniel] Så for å bruke leie, vil du si - hvordan få det brukeren innspill? 280 00:23:48,990 --> 00:23:53,830 Ikke handler fprintf som GetString i den forstand at det vil bare vente på brukerens input 281 00:23:53,830 --> 00:23:57,180 og ber deg om å skrive dette - eller vente for deg å skrive disse tre tingene i? 282 00:23:57,180 --> 00:24:00,480 Eller trenger du å bruke noe til å gjennomføre leie? 283 00:24:00,480 --> 00:24:04,100 >> Ja. Så vi er ikke - spørsmålet var, hvordan vi får brukerundersøkelser 284 00:24:04,100 --> 00:24:09,220 for å gjennomføre leie? Og det vi har her er den som ringer for hire, 285 00:24:09,220 --> 00:24:17,690 vedtatt i denne ansatte struct med alle data som er lagret i struct allerede. 286 00:24:17,690 --> 00:24:22,990 Så er fprintf stand til å bare skrive at data direkte til filen. 287 00:24:22,990 --> 00:24:25,690 Det er ingen ventetid for brukerens input. 288 00:24:25,690 --> 00:24:32,110 Brukeren er allerede gitt innspill ved riktig å sette den i denne ansatte struct. 289 00:24:32,110 --> 00:24:36,510 Og ting, selvfølgelig, ville brekke hvis noen av disse pekere var null, 290 00:24:36,510 --> 00:24:40,370 så vi rulle opp her og ser vi på struct vår. 291 00:24:40,370 --> 00:24:43,640 Vi har streng sist, string først, streng e-post. 292 00:24:43,640 --> 00:24:48,530 Vi vet nå at alle de virkelig, under panseret, er char * variabler. 293 00:24:48,530 --> 00:24:53,470 Som kan eller ikke kan peke mot null. 294 00:24:53,470 --> 00:24:55,800 De kan peke mot minnet på haugen, 295 00:24:55,800 --> 00:24:59,650 kanskje minne på stakken. 296 00:24:59,650 --> 00:25:04,580 Vi vet ikke, men hvis noen av disse pekere er null eller ugyldig, 297 00:25:04,580 --> 00:25:08,120 at det vil definitivt krasje vår utleie funksjon. 298 00:25:08,120 --> 00:25:11,050 Det var noe som var litt utenfor rammen av eksamen. 299 00:25:11,050 --> 00:25:16,440 Vi er ikke bekymre det. 300 00:25:16,440 --> 00:25:22,170 Flott. Okay. Så går videre fra quiz. 301 00:25:22,170 --> 00:25:25,760 >> La oss lukke denne fyren, og vi kommer til å se på pset 4. 302 00:25:25,760 --> 00:25:34,700 Så hvis dere ser på pset spec, når du kan få tilgang til den, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 Vi kommer til å gå gjennom noen av avsnittet problemer i dag. 304 00:25:42,730 --> 00:25:52,240 Jeg rulle ned - del spørsmål begynner på den tredje siden av pset spec. 305 00:25:52,240 --> 00:25:57,800 Og første del ber deg om å gå og se kort på omdirigere og rør. 306 00:25:57,800 --> 00:26:02,820 Som var slags en kul kort, viser deg noen nye, kule kommandolinje triks som du kan bruke. 307 00:26:02,820 --> 00:26:06,050 Og så har vi et par spørsmål til deg også. 308 00:26:06,050 --> 00:26:10,860 Det første spørsmålet om bekker, som printf skriver som standard, 309 00:26:10,860 --> 00:26:15,920 Vi slags berørt bare litt et øyeblikk siden. 310 00:26:15,920 --> 00:26:22,380 Dette fprintf at vi var bare diskutere tar i en fil * strøm som argument sin. 311 00:26:22,380 --> 00:26:26,580 fclose tar i en fil * strøm også, 312 00:26:26,580 --> 00:26:32,660 og returverdien av fopen gir deg en fil * strøm også. 313 00:26:32,660 --> 00:26:36,060 Grunnen til at vi ikke har sett dem før når vi har jobbet med printf 314 00:26:36,060 --> 00:26:39,450 er fordi printf har en standard strøm. 315 00:26:39,450 --> 00:26:41,810 Og standard stream som den skriver 316 00:26:41,810 --> 00:26:45,190 du vil finne ut om på kort. 317 00:26:45,190 --> 00:26:50,080 Så definitivt ta en titt på den. 318 00:26:50,080 --> 00:26:53,010 >> I dagens avsnitt, skal vi snakke litt om GDB, 319 00:26:53,010 --> 00:26:57,720 siden mer kjent du er med det, jo mer praksis du får med det, 320 00:26:57,720 --> 00:27:01,390 bedre i stand vil være å faktisk jakte ned feil i din egen kode. 321 00:27:01,390 --> 00:27:05,540 Dette gjør prosessen med feilsøking opp enormt. 322 00:27:05,540 --> 00:27:09,230 Så ved å bruke printf, hver gang du gjør det du må rekompilere koden, 323 00:27:09,230 --> 00:27:13,000 må du kjøre den på nytt, noen ganger må du flytte printf samtale rundt, 324 00:27:13,000 --> 00:27:17,100 kommentere ut kode, tar det bare en stund. 325 00:27:17,100 --> 00:27:20,850 Vårt mål er å prøve og overbevise deg om at med GDB, kan du i hovedsak 326 00:27:20,850 --> 00:27:26,810 printf noe som helst i koden din, og du trenger aldri å rekompilere det. 327 00:27:26,810 --> 00:27:35,120 Du trenger aldri å starte og fortsette å gjette hvor du printf neste. 328 00:27:35,120 --> 00:27:40,910 Det første du må gjøre er å kopiere denne linjen og få delkoden ut av nettet. 329 00:27:40,910 --> 00:27:47,530 Jeg kopiering denne linjen med kode som sier, "wget ​​http://cdn.cs50.net". 330 00:27:47,530 --> 00:27:49,510 Jeg kommer til å kopiere den. 331 00:27:49,510 --> 00:27:55,950 Jeg kommer til å gå over til apparatet mitt, zoome ut slik at du kan se hva jeg gjør, 332 00:27:55,950 --> 00:28:01,890 lime den inn der, og når jeg trykker på Enter, dette wget kommando bokstavelig er en web får. 333 00:28:01,890 --> 00:28:06,210 Det kommer til å trekke ned denne filen ut av Internett, 334 00:28:06,210 --> 00:28:11,790 og det kommer til å spare det til gjeldende katalog. 335 00:28:11,790 --> 00:28:21,630 Nå hvis jeg listen min nåværende katalog du kan se at jeg har fått denne section5.zip fil rett der. 336 00:28:21,630 --> 00:28:25,260 Den måten å forholde seg til at fyren er å pakke den, 337 00:28:25,260 --> 00:28:27,650 som du kan gjøre i kommandolinjen, akkurat som dette. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Det vil pakke den, opprette mappen for meg, 340 00:28:36,980 --> 00:28:40,410 blåse hele innholdet, legg dem i det. 341 00:28:40,410 --> 00:28:47,410 Så nå kan jeg gå inn i min seksjon 5 katalogen ved hjelp av cd-kommandoen. 342 00:28:47,410 --> 00:28:58,310 Tømme skjermen ved hjelp av klare. Så tømme skjermen. 343 00:28:58,310 --> 00:29:02,280 Nå har jeg fått en fin ren terminal å forholde seg til. 344 00:29:02,280 --> 00:29:06,200 >> Nå hvis jeg føre opp alle filene som jeg ser i denne katalogen, 345 00:29:06,200 --> 00:29:12,270 du ser at jeg har fire filer: buggy1, buggy2, buggy3 og buggy4. 346 00:29:12,270 --> 00:29:16,180 Jeg har også fått sine tilsvarende. C-filer. 347 00:29:16,180 --> 00:29:20,400 Vi kommer ikke til å se på. C-filene for nå. 348 00:29:20,400 --> 00:29:24,140 I stedet, vi kommer til å bruke dem når vi åpner opp GDB. 349 00:29:24,140 --> 00:29:28,220 Vi har holdt dem rundt slik at vi har tilgang til selve kildekoden når vi bruker GDB, 350 00:29:28,220 --> 00:29:32,740 men målet for denne delen av seksjonen er å tinker rundt med GDB 351 00:29:32,740 --> 00:29:40,370 og se hvordan vi kan bruke det til å finne ut hva som går galt med hver av disse fire buggy programmer. 352 00:29:40,370 --> 00:29:43,380 Så vi skal bare rundt i rommet veldig raskt, 353 00:29:43,380 --> 00:29:47,000 og jeg kommer til å be noen om å kjøre en av de buggy programmer, 354 00:29:47,000 --> 00:29:54,730 og så får vi gå som en gruppe gjennom GDB, og vi får se hva vi kan gjøre for å fikse disse programmene, 355 00:29:54,730 --> 00:29:58,460 eller minst identifisere hva som går galt i hver av dem. 356 00:29:58,460 --> 00:30:04,760 La oss starte på her med Daniel. Vil du kjøre buggy1? La oss se hva som skjer. 357 00:30:04,760 --> 00:30:09,470 [Daniel] Det står at det er et program feil. >> Ja. Akkurat. 358 00:30:09,470 --> 00:30:12,460 Så hvis jeg kjører buggy1, får jeg en SEG feil. 359 00:30:12,460 --> 00:30:16,210 På dette punktet, jeg kunne gå og åpne opp buggy1.c, 360 00:30:16,210 --> 00:30:19,450 prøve og finne ut hva som går galt, 361 00:30:19,450 --> 00:30:22,000 men en av de mest motbydelige ting om dette segmentet feil feil 362 00:30:22,000 --> 00:30:27,610 er at det ikke forteller deg om hvilken linje av programmet tingene faktisk gikk galt og blakk. 363 00:30:27,610 --> 00:30:29,880 Du slags nødt til å se på koden 364 00:30:29,880 --> 00:30:33,990 og finne ut ved hjelp gjetning og sjekk eller printf for å se hva som går galt. 365 00:30:33,990 --> 00:30:37,840 En av de kuleste tingene om GDB er at det er veldig, veldig lett 366 00:30:37,840 --> 00:30:42,170 å finne ut linjen der du programmet krasjer. 367 00:30:42,170 --> 00:30:46,160 Det er helt verdt det å bruke den, selv om bare for det. 368 00:30:46,160 --> 00:30:56,190 Så for å starte opp GDB, skriver jeg GDB, og så gir jeg den banen til den kjørbare som jeg ønsker å kjøre. 369 00:30:56,190 --> 00:31:01,960 Her jeg skriver GDB ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Trykk Enter. Gir meg alt dette informasjon om opphavsrett, 371 00:31:06,600 --> 00:31:13,000 og ned her vil du se denne linjen som sier "Reading symboler fra / home / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1. " 373 00:31:17,680 --> 00:31:22,060 Og hvis alt går bra, vil du se det skrive ut en melding som ser slik ut. 374 00:31:22,060 --> 00:31:25,500 Det skal lese symboler, vil det si "Jeg leser symboler fra kjørbar fil," 375 00:31:25,500 --> 00:31:29,900 og da vil det ha denne "ferdig"-melding over her. 376 00:31:29,900 --> 00:31:35,410 Hvis du ser noen annen variant av dette, eller ser du det ikke kunne finne symbolene 377 00:31:35,410 --> 00:31:41,460 eller noe sånt, hva det betyr er at du bare ikke har kompilert din kjørbar riktig. 378 00:31:41,460 --> 00:31:49,980 Når vi kompilere programmer for bruk med GDB, må vi bruke den spesielle-g flagget, 379 00:31:49,980 --> 00:31:54,540 og det er gjort som standard hvis du kompilere programmer, bare ved å skrive gjøre 380 00:31:54,540 --> 00:31:59,320 eller gjøre buggy eller gjøre gjenopprette, noen av de. 381 00:31:59,320 --> 00:32:07,800 Men hvis du kompilere manuelt med Clang, så du må gå inn og ta det-g flagget. 382 00:32:07,800 --> 00:32:10,310 >> På dette punktet, nå som vi har våre GDB prompt, 383 00:32:10,310 --> 00:32:12,310 det er ganske enkelt å kjøre programmet. 384 00:32:12,310 --> 00:32:19,740 Vi kan enten skrive løp, eller vi kan bare skrive r. 385 00:32:19,740 --> 00:32:22,820 De fleste GDB kommandoer kan bli forkortet. 386 00:32:22,820 --> 00:32:25,940 Vanligvis til bare én eller et par bokstaver, som er ganske fin. 387 00:32:25,940 --> 00:32:30,980 Så Saad, hvis du skriver r og trykk Enter, hva skjer? 388 00:32:30,980 --> 00:32:39,390 [Saad] Jeg fikk SIGSEGV, segmentering feil, og deretter alt dette gobbledygook. 389 00:32:39,390 --> 00:32:43,650 >> Ja. 390 00:32:43,650 --> 00:32:47,990 Som vi ser på skjermen akkurat nå, og som Saad sa, 391 00:32:47,990 --> 00:32:53,430 når vi skriver kjøre eller r og trykk Enter, vi fortsatt får den samme segmentet feil. 392 00:32:53,430 --> 00:32:55,830 Så bruker GDB løser ikke vårt problem. 393 00:32:55,830 --> 00:32:59,120 Men det gir oss noen gobbledygook, og det viser seg at dette gobbledygook 394 00:32:59,120 --> 00:33:03,080 faktisk forteller oss hvor det skjer. 395 00:33:03,080 --> 00:33:10,680 Å analysere denne litt, er dette første bit funksjonen der alt som går galt. 396 00:33:10,680 --> 00:33:20,270 Det er denne __ strcmp_sse4_2, og det forteller oss at det skjer i denne filen 397 00:33:20,270 --> 00:33:29,450 kalt sysdeps/i386, alt dette, igjen, en slags rot - men linjen 254. 398 00:33:29,450 --> 00:33:31,670 Det er litt vanskelig å analysere. Vanligvis når du ser ting som dette, 399 00:33:31,670 --> 00:33:38,770 det betyr at det er SEG forkastninger i en av system-biblioteker. 400 00:33:38,770 --> 00:33:43,220 Så noe å gjøre med strcmp. Dere har sett strcmp før. 401 00:33:43,220 --> 00:33:52,730 Ikke altfor gal, men betyr dette at strcmp er ødelagt eller at det er et problem med strcmp? 402 00:33:52,730 --> 00:33:57,110 Hva tror du, Alexander? 403 00:33:57,110 --> 00:34:04,890 [Alexander] Er det - er 254 linjen? Og - ikke den binære, men det er ikke deres tak, 404 00:34:04,890 --> 00:34:10,590 og så er det et annet språk for hver funksjon. Er at 254 i denne funksjonen, eller -? 405 00:34:10,590 --> 00:34:21,460 >> Det er linje 254. Det ser ut som i denne. S fil, så det er assemblykode sannsynligvis. 406 00:34:21,460 --> 00:34:25,949 >> Men jeg antar det mer presserende ting er, fordi vi har fått en SEG feil, 407 00:34:25,949 --> 00:34:29,960 og det ser ut som det kommer fra strcmp funksjon, 408 00:34:29,960 --> 00:34:38,030 betyr dette, da, er at strcmp brutt? 409 00:34:38,030 --> 00:34:42,290 Det burde ikke, forhåpentligvis. Så bare fordi du har en segmentering feil 410 00:34:42,290 --> 00:34:49,480 i en av systemet fungerer, betyr vanligvis at du bare ikke ha kalt det riktig. 411 00:34:49,480 --> 00:34:52,440 Den raskeste tingen å gjøre for å finne ut hva som faktisk skjer 412 00:34:52,440 --> 00:34:55,500 når du ser noe sprøtt som dette, når du ser en SEG feil, 413 00:34:55,500 --> 00:34:59,800 spesielt hvis du har et program som er å bruke mer enn bare main, 414 00:34:59,800 --> 00:35:03,570 er å bruke en tilbakesporing. 415 00:35:03,570 --> 00:35:13,080 Jeg forkort tilbakesporing ved å skrive bt, i motsetning til den fullstendige tilbakesporing ordet. 416 00:35:13,080 --> 00:35:16,510 Men Charlotte, hva skjer når du skriver bt og trykk Enter? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] Det viser meg to linjer, linje 0 og 1 linje. 418 00:35:23,200 --> 00:35:26,150 >> Ja. Så linje 0 og linje 1. 419 00:35:26,150 --> 00:35:34,560 Dette er de faktiske stack rammer som var tiden i spill når programmet krasjet. 420 00:35:34,560 --> 00:35:42,230 Starter fra øverste ramme, 0 ramme, og gå til nederste, som er rammen en. 421 00:35:42,230 --> 00:35:45,140 Vår øverste rammen er strcmp ramme. 422 00:35:45,140 --> 00:35:50,080 Du kan tenke på dette som ligner på det problemet vi var bare å gjøre på quiz med pekere, 423 00:35:50,080 --> 00:35:54,890 der vi hadde bytte stabelen rammen på toppen av hoved stabelen ramme, 424 00:35:54,890 --> 00:35:59,700 og vi hadde de variablene som swap var bruker på toppen av de variablene som viktigste var med. 425 00:35:59,700 --> 00:36:08,440 Her er vår krasj skjedde i vår strcmp funksjon, som ble kalt av våre viktigste funksjon, 426 00:36:08,440 --> 00:36:14,370 og backtrace gir oss ikke bare funksjonene som ting mislyktes, 427 00:36:14,370 --> 00:36:16,440 men det er også å fortelle oss hvor alt ble kalt fra. 428 00:36:16,440 --> 00:36:18,830 Så hvis jeg ruller over en litt mer til høyre, 429 00:36:18,830 --> 00:36:26,110 Vi kan se at ja, vi var på linje 254 av denne strcmp-sse4.s fil. 430 00:36:26,110 --> 00:36:32,540 Men samtalen ble gjort på buggy1.c, 6 linje. 431 00:36:32,540 --> 00:36:35,960 Så det betyr at vi kan gjøre - er at vi kan bare gå sjekke ut og se hva som skjer 432 00:36:35,960 --> 00:36:39,930 på buggy1.c, 6 linje. 433 00:36:39,930 --> 00:36:43,780 Igjen, det er et par måter å gjøre dette på. Det ene er å gå ut av GDB 434 00:36:43,780 --> 00:36:49,460 eller har koden åpnes i et annet vindu og kryssreferanse. 435 00:36:49,460 --> 00:36:54,740 Det, i seg selv, er ganske praktisk fordi nå hvis du er på kontortid 436 00:36:54,740 --> 00:36:57,220 og du har en SEG feil og TF har lurer på hvor alt var å bryte, 437 00:36:57,220 --> 00:36:59,710 du kan bare si: "Å, linje 6. jeg vet ikke hva som skjer, 438 00:36:59,710 --> 00:37:03,670 men noe om linje 6 forårsaker mitt program for å bryte. " 439 00:37:03,670 --> 00:37:10,430 Den andre måten å gjøre det er at du kan bruke denne kommandoen kalles liste i GDB. 440 00:37:10,430 --> 00:37:13,650 Du kan også forkorte det med l.. 441 00:37:13,650 --> 00:37:18,910 Så hvis vi treffer l, hva vi får her? 442 00:37:18,910 --> 00:37:21,160 Vi får en hel haug med rare ting. 443 00:37:21,160 --> 00:37:26,030 Dette er selve monteringen koden 444 00:37:26,030 --> 00:37:29,860 som er i strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Dette ser slags funky, 446 00:37:32,440 --> 00:37:36,520 og grunnen til at vi får dette er fordi akkurat nå, 447 00:37:36,520 --> 00:37:40,160 GDB har oss i ramme 0. 448 00:37:40,160 --> 00:37:43,070 >> Så hver gang vi ser på variabler, helst vi ser på kildekoden, 449 00:37:43,070 --> 00:37:50,530 vi ser på kildekoden som gjelder stabelen rammen vi er nå i. 450 00:37:50,530 --> 00:37:53,200 Så for å få noe meningsfylt, må vi 451 00:37:53,200 --> 00:37:57,070 flytte til en stabel ramme som gjør mer fornuftig. 452 00:37:57,070 --> 00:38:00,180 I dette tilfellet, vil den viktigste stabelen rammen gjør litt mer fornuftig, 453 00:38:00,180 --> 00:38:02,680 fordi det var faktisk koden som vi skrev. 454 00:38:02,680 --> 00:38:05,330 Ikke strcmp koden. 455 00:38:05,330 --> 00:38:08,650 Måten du kan flytte mellom rammer, i dette tilfellet, fordi vi har to, 456 00:38:08,650 --> 00:38:10,430 vi har 0 og 1, 457 00:38:10,430 --> 00:38:13,650 du gjøre det med opp og ned kommandoer. 458 00:38:13,650 --> 00:38:18,480 Hvis jeg flytter opp ett bilde, 459 00:38:18,480 --> 00:38:21,770 nå er jeg i hovedsak stabelen rammen. 460 00:38:21,770 --> 00:38:24,330 Jeg kan flytte ned for å gå tilbake til der jeg var, 461 00:38:24,330 --> 00:38:32,830 gå opp igjen, gå ned igjen, og gå opp igjen. 462 00:38:32,830 --> 00:38:39,750 Hvis du noen gang gjøre programmet i GDB, du får en krasj, får du tilbakesporing, 463 00:38:39,750 --> 00:38:42,380 og du ser at det er i noen fil som du ikke vet hva som skjer. 464 00:38:42,380 --> 00:38:45,460 Du prøver listen, betyr ikke koden ser kjent ut for deg, 465 00:38:45,460 --> 00:38:48,150 ta en titt på dine rammer og finne ut hvor du er. 466 00:38:48,150 --> 00:38:51,010 Du er sannsynligvis i feil bunke rammen. 467 00:38:51,010 --> 00:38:58,760 Eller i det minste du er i en stabel ramme som ikke er en som du virkelig kan feilsøke. 468 00:38:58,760 --> 00:39:03,110 Nå som vi er i riktig stabelen rammen, vi er i hovedsak 469 00:39:03,110 --> 00:39:08,100 nå kan vi bruke list for å finne ut hva linjen var. 470 00:39:08,100 --> 00:39:13,590 Og du kan se det, det skrives det for oss her. 471 00:39:13,590 --> 00:39:19,470 Men vi kan treffe liste alle de samme, og listen gir oss denne fine utskriften 472 00:39:19,470 --> 00:39:23,920 av selve kildekoden som skjer her. 473 00:39:23,920 --> 00:39:26,420 >> Spesielt kan vi se på linje 6.. 474 00:39:26,420 --> 00:39:29,330 Vi kan se hva som skjer her. 475 00:39:29,330 --> 00:39:31,250 Og det ser ut som vi gjør en streng sammenligning 476 00:39:31,250 --> 00:39:41,050 mellom streng "CS50 rocks" og argv [1]. 477 00:39:41,050 --> 00:39:45,700 Noe om dette ble krasj. 478 00:39:45,700 --> 00:39:54,120 Så Missy, har du noen tanker om hva som kan skjer her? 479 00:39:54,120 --> 00:39:59,400 [Missy] Jeg vet ikke hvorfor det er krasj. >> Du vet ikke hvorfor det er krasj? 480 00:39:59,400 --> 00:40:02,700 Jimmy, noen tanker? 481 00:40:02,700 --> 00:40:06,240 [Jimmy] Jeg er ikke helt sikker, men siste gang vi brukte streng sammenligne, 482 00:40:06,240 --> 00:40:10,260 eller strcmp, hadde vi som tre forskjellige saker etter det. 483 00:40:10,260 --> 00:40:12,800 Vi har ikke en ==, tror jeg ikke, midt i den første linjen. 484 00:40:12,800 --> 00:40:16,700 I stedet ble det delt inn i tre, og en var == 0, 485 00:40:16,700 --> 00:40:19,910 var <0, tror jeg, og en var> 0. 486 00:40:19,910 --> 00:40:22,590 Så kanskje noe sånt? >> Ja. Så det er dette problemet 487 00:40:22,590 --> 00:40:27,200 av gjør vi sammenligningen riktig? 488 00:40:27,200 --> 00:40:31,660 Stella? Noen tanker? 489 00:40:31,660 --> 00:40:38,110 [Stella] Jeg er ikke sikker. >> Ikke sikker. Daniel? Tanker? Okay. 490 00:40:38,110 --> 00:40:44,770 Det viser seg hva som skjer akkurat her er når vi kjørte programmet 491 00:40:44,770 --> 00:40:48,370 og vi fikk SEG feil, da du kjørte programmet for første gang, Daniel, 492 00:40:48,370 --> 00:40:50,800 gjorde du gi det noen kommandolinjeargumentene? 493 00:40:50,800 --> 00:40:58,420 [Daniel] Nei >> Nei I så tilfelle, hva er verdien av argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> Det er ingen verdi. >> Høyre. 495 00:41:00,920 --> 00:41:06,120 Vel er det ingen passende strengverdi. 496 00:41:06,120 --> 00:41:10,780 Men det er noen verdi. Hva er verdien som blir lagret der inne? 497 00:41:10,780 --> 00:41:15,130 >> En søppel verdi? >> Det er enten en søppel verdi eller, i dette tilfellet, 498 00:41:15,130 --> 00:41:19,930 enden av argv matrisen avsluttes alltid med null. 499 00:41:19,930 --> 00:41:26,050 Så hva fikk faktisk lagret i det null. 500 00:41:26,050 --> 00:41:30,810 Den andre måten å løse dette, snarere enn å tenke det gjennom, 501 00:41:30,810 --> 00:41:33,420 er å prøve å skrive den ut. 502 00:41:33,420 --> 00:41:35,880 Det er der jeg sa at å bruke GDB er stor, 503 00:41:35,880 --> 00:41:40,640 fordi du kan skrive ut alle variabler, alle verdiene som du vil 504 00:41:40,640 --> 00:41:43,230 bruker denne handy-dandy p kommandoen. 505 00:41:43,230 --> 00:41:48,520 Så hvis jeg skriver p og da jeg skriver verdien av en variabel eller navnet på en variabel, 506 00:41:48,520 --> 00:41:55,320 sier argc, ser jeg at argc er en. 507 00:41:55,320 --> 00:42:01,830 Hvis jeg ønsker å skrive ut argv [0], kan jeg gjøre det akkurat sånn. 508 00:42:01,830 --> 00:42:04,840 Og som vi så, argv [0] er alltid navnet på programmet, 509 00:42:04,840 --> 00:42:06,910 alltid navnet på den kjørbare. 510 00:42:06,910 --> 00:42:09,740 Her ser du det har det fullstendige navnet. 511 00:42:09,740 --> 00:42:15,920 Jeg kan også skrive ut argv [1] og se hva som skjer. 512 00:42:15,920 --> 00:42:20,890 >> Her fikk vi denne typen mystiske verdi. 513 00:42:20,890 --> 00:42:23,890 Vi fikk denne 0x0. 514 00:42:23,890 --> 00:42:27,850 Husk på begynnelsen av begrepet når vi snakket om heksadesimale tall? 515 00:42:27,850 --> 00:42:34,680 Eller at lite spørsmål på slutten av pset 0 om hvordan å representere 50 i hex? 516 00:42:34,680 --> 00:42:39,410 Måten vi skriver hex tall i CS, bare ikke å forvirre oss 517 00:42:39,410 --> 00:42:46,080 med desimaltall, er vi alltid prefiks dem med 0x. 518 00:42:46,080 --> 00:42:51,420 Så dette 0x prefikset alltid betyr bare tolke følgende nummer som et heksadesimalt tall, 519 00:42:51,420 --> 00:42:57,400 ikke som en streng, ikke som et desimaltall, ikke som et binært tall. 520 00:42:57,400 --> 00:43:02,820 Siden antallet 5-0 er et gyldig tall i heksadesimal. 521 00:43:02,820 --> 00:43:06,240 Og det er et tall i desimal, 50. 522 00:43:06,240 --> 00:43:10,050 Så dette er bare hvordan vi disambiguate. 523 00:43:10,050 --> 00:43:14,860 Så 0x0 betyr heksadesimal 0, som også er desimal 0, binære 0. 524 00:43:14,860 --> 00:43:17,030 Det er bare verdien 0. 525 00:43:17,030 --> 00:43:22,630 Det viser seg at dette er hva null er, faktisk, i minnet. 526 00:43:22,630 --> 00:43:25,940 Null er bare 0. 527 00:43:25,940 --> 00:43:37,010 Her elementet lagret på argv [1] er null. 528 00:43:37,010 --> 00:43:45,220 Så vi prøver å sammenligne vår "CS50 rocks" strengen til en null-streng. 529 00:43:45,220 --> 00:43:48,130 Så dereferencing null, prøver å få tilgang ting på null, 530 00:43:48,130 --> 00:43:55,050 de er vanligvis kommer til å forårsake noen form for segmentering feil eller andre dårlige ting til å skje. 531 00:43:55,050 --> 00:43:59,350 Og det viser seg at strcmp ikke kontrollere 532 00:43:59,350 --> 00:44:04,340 om du har gått i en verdi som er null. 533 00:44:04,340 --> 00:44:06,370 Snarere, det bare går fremover, prøver å gjøre sine ting, 534 00:44:06,370 --> 00:44:14,640 og hvis det SEG feil, SEG det feil, og det er problemet. Du må gå fikse det. 535 00:44:14,640 --> 00:44:19,730 Veldig raskt, kan hvordan vi kan løse dette problemet? Charlotte? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Du kan sjekke med hvis. 537 00:44:23,540 --> 00:44:32,240 Så hvis argv [1] er null, == 0, og deretter gå tilbake 1, eller noe [uforståelig]. 538 00:44:32,240 --> 00:44:34,590 >> Ja. Så det er en fin måte å gjøre det, som vi kan sjekke for å se, 539 00:44:34,590 --> 00:44:39,230 verdien vi er i ferd med å passere inn strcmp, argv [1], er null det? 540 00:44:39,230 --> 00:44:45,830 Hvis det er null, så kan vi si greit, abort. 541 00:44:45,830 --> 00:44:49,450 >> En mer vanlig måte å gjøre dette på er å bruke argc verdi. 542 00:44:49,450 --> 00:44:52,040 Du kan se her i begynnelsen av viktigste, 543 00:44:52,040 --> 00:44:58,040 vi utelatt det første test som vi vanligvis gjør når vi bruker kommandolinjeargumenter, 544 00:44:58,040 --> 00:45:05,240 som er å teste hvorvidt våre argc verdi er hva vi forventer. 545 00:45:05,240 --> 00:45:10,290 I dette tilfellet, vi ventet minst to argumenter, 546 00:45:10,290 --> 00:45:13,660 navnet på program pluss en annen. 547 00:45:13,660 --> 00:45:17,140 Fordi vi er i ferd med å bruke det andre argumentet her. 548 00:45:17,140 --> 00:45:21,350 Så å ha en slags test på forhånd, før vår strcmp samtale 549 00:45:21,350 --> 00:45:37,390 at tester hvorvidt argv er minst 2, vil også gjøre det samme slags ting. 550 00:45:37,390 --> 00:45:40,620 Vi kan se om det fungerer ved å kjøre programmet på nytt. 551 00:45:40,620 --> 00:45:45,610 Du kan alltid starte program innen GDB, som er virkelig fint. 552 00:45:45,610 --> 00:45:49,310 Du kan kjøre, og når du passerer i argumentene til programmet, 553 00:45:49,310 --> 00:45:53,060 du passerer dem i når du kaller kjøre, ikke når du starter opp GDB. 554 00:45:53,060 --> 00:45:57,120 På den måten kan du holde påkalle programmet med forskjellige argumenter hver gang. 555 00:45:57,120 --> 00:46:08,080 Så kjøre, eller igjen, kan jeg skrive r, og la oss se hva som skjer hvis vi skriver "Hei". 556 00:46:08,080 --> 00:46:11,140 Det vil alltid spørre deg om du ønsker å starte det fra begynnelsen igjen. 557 00:46:11,140 --> 00:46:17,490 Vanligvis vil du starte det fra begynnelsen igjen. 558 00:46:17,490 --> 00:46:25,010 Og på dette punktet, det starter den igjen, skrives det ut 559 00:46:25,010 --> 00:46:28,920 programmet som vi kjører, buggy1, med argumentet hallo, 560 00:46:28,920 --> 00:46:32,720 og det skrives denne standarden ut, det sier "Du får et D," trist ansikt. 561 00:46:32,720 --> 00:46:37,610 Men vi gjorde ikke SEG feil. Det sies at prosessen gått som normalt. 562 00:46:37,610 --> 00:46:39,900 Så det ser ganske bra. 563 00:46:39,900 --> 00:46:43,050 Ingen flere SEG feil, gjorde vi det siste, 564 00:46:43,050 --> 00:46:48,190 så det ser ut som det var faktisk SEG feil bug som vi får. 565 00:46:48,190 --> 00:46:51,540 Dessverre, forteller det oss at vi får en D. 566 00:46:51,540 --> 00:46:54,090 >> Vi kan gå tilbake og se på koden og se hva som skjer der 567 00:46:54,090 --> 00:46:57,980 å finne ut hva som var - hvorfor det var å fortelle oss at vi fikk en D. 568 00:46:57,980 --> 00:47:03,690 La oss se, her var dette printf si at du fikk en D. 569 00:47:03,690 --> 00:47:08,540 Hvis vi skriver liste, som du fortsette å skrive liste, holder det gjentar seg gjennom programmet, 570 00:47:08,540 --> 00:47:10,940 så det vil vise deg de første linjene av programmet. 571 00:47:10,940 --> 00:47:15,450 Så det vil vise deg de neste linjene, og neste blings og neste del. 572 00:47:15,450 --> 00:47:18,240 Og det vil fortsette å prøve å gå ned. 573 00:47:18,240 --> 00:47:21,180 Og nå skal vi få til "linje nummer 16 er ute av rekkevidde." 574 00:47:21,180 --> 00:47:23,940 Fordi den har bare 15 linjer. 575 00:47:23,940 --> 00:47:30,310 Hvis du kommer til dette punktet, og du lurer på, "Hva gjør jeg?" kan du bruke kommandoen help. 576 00:47:30,310 --> 00:47:34,340 Bruk hjelp og deretter gi det navnet på en kommando. 577 00:47:34,340 --> 00:47:36,460 Og du ser GDB gir oss alle denne typen ting. 578 00:47:36,460 --> 00:47:43,870 Står det: "Uten argument, viser ti linjer etter eller rundt forrige notering. 579 00:47:43,870 --> 00:47:47,920 List - viser de ti linjer før - " 580 00:47:47,920 --> 00:47:52,960 Så la oss prøve å bruke liste minus. 581 00:47:52,960 --> 00:47:57,000 Og som viser de 10 linjene forrige, du kan spille rundt med liste litt. 582 00:47:57,000 --> 00:48:02,330 Du kan gjøre listen, listen -, kan du selv gi listen en rekke, som liste 8, 583 00:48:02,330 --> 00:48:07,500 og det vil liste de 10 linjene rundt linje 8. 584 00:48:07,500 --> 00:48:10,290 Og du kan se hva som skjer her er at du har en enkel if else. 585 00:48:10,290 --> 00:48:13,980 Hvis du skriver inn CS50 steiner, skrives det ut "Du får en A." 586 00:48:13,980 --> 00:48:16,530 Ellers er det skrives ut "Du får en D." 587 00:48:16,530 --> 00:48:23,770 Bummer byen. OK. Ja? 588 00:48:23,770 --> 00:48:26,730 >> [Daniel] Så når jeg prøvde å gjøre CS50 bergarter uten anførselstegn, 589 00:48:26,730 --> 00:48:29,290 det står "Du får en D." 590 00:48:29,290 --> 00:48:32,560 Jeg trengte anførselstegn for å få det til å fungere, hvorfor er det? 591 00:48:32,560 --> 00:48:38,490 >> Ja. Det viser seg at når - dette er en annen morsom liten godbit - 592 00:48:38,490 --> 00:48:47,900 når du kjører programmet, hvis vi kjører den og vi skriver i CS50 bergarter, 593 00:48:47,900 --> 00:48:50,800 akkurat som Daniel sa han gjorde, og du trykker på Enter, 594 00:48:50,800 --> 00:48:52,870 det står fortsatt vi får en D. 595 00:48:52,870 --> 00:48:55,580 Og spørsmålet er, hvorfor er dette? 596 00:48:55,580 --> 00:49:02,120 Og det viser seg at både vår terminal og GDB analysere disse som to separate argumenter. 597 00:49:02,120 --> 00:49:04,800 Fordi når det er en plass, som er underforstått som 598 00:49:04,800 --> 00:49:08,730 det første argumentet endte, den neste argumentet er i ferd med å begynne. 599 00:49:08,730 --> 00:49:13,260 Den måten å kombinere dem i to, eller sorry, i ett argument, 600 00:49:13,260 --> 00:49:18,510 er å bruke anførselstegn. 601 00:49:18,510 --> 00:49:29,560 Så nå, hvis vi setter det i anførselstegn og kjøre den på nytt, får vi en A. 602 00:49:29,560 --> 00:49:38,780 Så bare for å oppsummere, er ingen sitater, CS50 og steiner analyseres som to separate argumenter. 603 00:49:38,780 --> 00:49:45,320 Med sitater, er det tolket som et argument helt. 604 00:49:45,320 --> 00:49:53,070 >> Vi kan se dette med et stoppunkt. 605 00:49:53,070 --> 00:49:54,920 Så langt har vi kjørt programmet vårt, og det er kjørt 606 00:49:54,920 --> 00:49:58,230 inntil enten det SEG feil eller treff en feil 607 00:49:58,230 --> 00:50:05,930 eller til den har gått ut og alle har vært helt fint. 608 00:50:05,930 --> 00:50:08,360 Dette er ikke nødvendigvis den mest nyttige ting, fordi noen ganger 609 00:50:08,360 --> 00:50:11,840 du har en feil i programmet, men det er ikke forårsaker en segmentering feil. 610 00:50:11,840 --> 00:50:16,950 Det er ikke forårsaker programmet til å stoppe eller noe sånt. 611 00:50:16,950 --> 00:50:20,730 Måten å få GDB til pause programmet på et bestemt punkt 612 00:50:20,730 --> 00:50:23,260 er å sette et stoppunkt. 613 00:50:23,260 --> 00:50:26,520 Du kan enten gjøre dette ved å sette et stoppunkt på en funksjon navn 614 00:50:26,520 --> 00:50:30,770 eller du kan sette et stoppunkt på en bestemt linje med kode. 615 00:50:30,770 --> 00:50:34,450 Jeg liker å sette stoppunkter på funksjon navn, fordi - lett å huske, 616 00:50:34,450 --> 00:50:37,700 og hvis du faktisk gå inn og endre kildekoden opp litt, 617 00:50:37,700 --> 00:50:42,020 deretter din stoppunkt vil faktisk bo på samme sted i koden. 618 00:50:42,020 --> 00:50:44,760 Mens hvis du bruker linje tall, og linjenummer endre 619 00:50:44,760 --> 00:50:51,740 fordi du legger til eller slette noen kode, deretter din brytningspunkt er alle helt ødelagt. 620 00:50:51,740 --> 00:50:58,590 En av de vanligste tingene jeg gjør er å angi et stoppunkt på den viktigste funksjonen. 621 00:50:58,590 --> 00:51:05,300 Ofte jeg starter opp GDB, jeg skriver b viktigste, trykk på Enter, og som vil sette et stoppunkt 622 00:51:05,300 --> 00:51:10,630 på den viktigste funksjonen som bare sier, "Pause programmet så snart du begynner å kjøre," 623 00:51:10,630 --> 00:51:17,960 og på den måten, når jeg kjører mitt program med, sier CS50 bergarter som to argumenter 624 00:51:17,960 --> 00:51:24,830 og trykk Enter, blir det til den viktigste funksjonen og den stopper rett ved den aller første linje, 625 00:51:24,830 --> 00:51:30,620 rett før den vurderer strcmp funksjonen. 626 00:51:30,620 --> 00:51:34,940 >> Siden jeg er satt på pause, nå kan jeg begynne å rote rundt og se hva som skjer 627 00:51:34,940 --> 00:51:40,250 med alle de forskjellige variabler som er gått inn i programmet mitt. 628 00:51:40,250 --> 00:51:43,670 Her kan jeg skrive ut argc og se hva som skjer. 629 00:51:43,670 --> 00:51:50,030 Se at argc er 3, fordi det er fikk 3 forskjellige verdier i den. 630 00:51:50,030 --> 00:51:54,060 Det fikk navnet på programmet, det har det første argumentet og det andre argumentet. 631 00:51:54,060 --> 00:52:09,330 Vi kan skrive dem ut ved å se på argv [0], argv [1], og argv [2]. 632 00:52:09,330 --> 00:52:12,030 Så nå kan du også se hvorfor dette strcmp samtalen kommer til å mislykkes, 633 00:52:12,030 --> 00:52:21,650 fordi du ser at det gjorde dele opp CS50 og bergarter i to separate argumenter. 634 00:52:21,650 --> 00:52:27,250 På dette punktet, når du har truffet et stoppunkt, kan du fortsette å gå gjennom programmet 635 00:52:27,250 --> 00:52:32,920 linje for linje, i motsetning til å starte programmet på nytt. 636 00:52:32,920 --> 00:52:35,520 Så hvis du ikke ønsker å starte programmet på nytt og bare fortsette herfra, 637 00:52:35,520 --> 00:52:41,970 kan du bruke continue kommandoen og fortsetter vil kjøre programmet til slutt. 638 00:52:41,970 --> 00:52:45,010 Akkurat som det gjorde her. 639 00:52:45,010 --> 00:52:54,880 Men hvis jeg starter programmet, CS50 steiner, treffer det min stoppunkt igjen, 640 00:52:54,880 --> 00:52:59,670 og denne gangen, hvis jeg ikke ønsker å bare gå hele veien gjennom resten av programmet, 641 00:52:59,670 --> 00:53:08,040 Jeg kan bruke den neste kommandoen, som jeg også forkorte med n. 642 00:53:08,040 --> 00:53:12,960 Og dette vil gå gjennom programmet linje for linje. 643 00:53:12,960 --> 00:53:17,530 Så du kan se på som ting utføre, som variabler endring, som ting blir oppdatert. 644 00:53:17,530 --> 00:53:21,550 Som er ganske fin. 645 00:53:21,550 --> 00:53:26,570 Den andre kule ting er heller enn å gjenta den samme kommandoen over og over og over igjen, 646 00:53:26,570 --> 00:53:30,670 hvis du bare trykke Enter - så her ser du jeg har ikke skrevet i noe - 647 00:53:30,670 --> 00:53:33,780 hvis jeg bare trykke Enter, vil det gjenta forrige kommando, 648 00:53:33,780 --> 00:53:36,900 eller forrige GDB kommandoen at jeg bare satt i. 649 00:53:36,900 --> 00:53:56,000 Jeg kan fortsette å trekke inn og det vil holde stepping gjennom min kode linje for linje. 650 00:53:56,000 --> 00:53:59,310 Jeg vil oppfordre dere til å gå sjekke ut de andre buggy programmer også. 651 00:53:59,310 --> 00:54:01,330 Vi har ikke tid til å komme gjennom alle av dem i dag i snitt. 652 00:54:01,330 --> 00:54:05,890 Kildekoden er der, så du kan slags se hva som skjer 653 00:54:05,890 --> 00:54:07,730 bak kulissene hvis du blir virkelig stakk, 654 00:54:07,730 --> 00:54:11,940 men i det minste, bare øve starter opp GDB, 655 00:54:11,940 --> 00:54:13,940 kjører programmet før det bryter på deg, 656 00:54:13,940 --> 00:54:18,260 få backtrace, finne ut hvilken funksjon ulykken var i, 657 00:54:18,260 --> 00:54:24,450 hvilken linje det var på, skrive ut noen variable verdier, 658 00:54:24,450 --> 00:54:30,140 bare så du får en følelse for det, fordi det vil virkelig hjelpe deg fremover. 659 00:54:30,140 --> 00:54:36,340 På dette punktet, vi kommer til å slutte ut av GDB, som du gjør med slutte eller bare q. 660 00:54:36,340 --> 00:54:40,460 Hvis programmet er i midten av å kjøre fortsatt, og det har ikke gått ut, 661 00:54:40,460 --> 00:54:43,510 det vil alltid spørre deg: «Er du sikker på at du virkelig ønsker å slutte?" 662 00:54:43,510 --> 00:54:48,770 Du kan bare trykke ja. 663 00:54:48,770 --> 00:54:55,250 >> Nå skal vi se på neste problemet vi har, som er katten programmet. 664 00:54:55,250 --> 00:54:59,880 Hvis du ser på kort på omdirigere og rør, vil du se at Tommy bruker dette programmet 665 00:54:59,880 --> 00:55:07,540 som skriver utgangspunktet alle resultatet av en fil på skjermen. 666 00:55:07,540 --> 00:55:12,660 Så hvis jeg kjører cat, dette er faktisk en innebygd program til apparatet, 667 00:55:12,660 --> 00:55:16,860 og hvis du har Mac kan du gjøre dette på din Mac også, hvis du åpner opp terminalen. 668 00:55:16,860 --> 00:55:25,630 Og vi - katt, la oss si, cp.c, og trykk på Enter. 669 00:55:25,630 --> 00:55:29,640 Hva dette gjorde, hvis vi blar opp litt og se hvor vi kjørte linjen, 670 00:55:29,640 --> 00:55:40,440 eller hvor vi kjørte katten kommandoen, det bokstavelig talt bare skrives ut innholdet i cp.c til skjermen vår. 671 00:55:40,440 --> 00:55:44,140 Vi kan kjøre den på nytt, og du kan sette i flere filer sammen. 672 00:55:44,140 --> 00:55:49,880 Så du kan gjøre katten cp.c, og da kan vi også sette sammen den kategori C-filen, 673 00:55:49,880 --> 00:55:53,250 som er et program vi er i ferd med å skrive, 674 00:55:53,250 --> 00:55:58,140 og det vil skrive ut begge filene tilbake til tilbake til skjermen vår. 675 00:55:58,140 --> 00:56:05,490 Så hvis vi blar opp litt, ser vi at når vi kjørte denne katten cp.c, kategori C, 676 00:56:05,490 --> 00:56:17,110 først det skrives ut cp filen, og deretter under den, skrives det ut, kategori C filen rett ned her. 677 00:56:17,110 --> 00:56:19,650 Vi kommer til å bruke dette til å bare få våre føtter våt. 678 00:56:19,650 --> 00:56:25,930 Lek litt med enkel utskrift til terminalen, se hvordan det fungerer. 679 00:56:25,930 --> 00:56:39,170 Hvis dere åpne opp med gedit kategori C, trykk Enter, 680 00:56:39,170 --> 00:56:43,760 kan du se programmet som vi er i ferd med å skrive. 681 00:56:43,760 --> 00:56:48,980 Vi har tatt dette fint kjele plate, så vi trenger ikke å bruke tid på å skrive alt ut. 682 00:56:48,980 --> 00:56:52,310 Vi også sjekke antall argumenter gikk i. 683 00:56:52,310 --> 00:56:56,910 Vi skriver ut en fin bruk melding. 684 00:56:56,910 --> 00:57:00,950 >> Dette er den slags ting som, igjen, som vi har vært snakket om, 685 00:57:00,950 --> 00:57:04,490 det er nesten som muskel minne. 686 00:57:04,490 --> 00:57:07,190 Bare husk å holde gjør det samme slags ting 687 00:57:07,190 --> 00:57:11,310 og alltid skrive ut noen form for nyttig melding 688 00:57:11,310 --> 00:57:17,670 slik at folk vet hvordan de skal kjøre programmet. 689 00:57:17,670 --> 00:57:21,630 Med katten, er det ganske enkelt, vi bare kommer til å gå gjennom alle de forskjellige argumentene 690 00:57:21,630 --> 00:57:24,300 som ble sendt til vårt program, og vi kommer til å skrive ut 691 00:57:24,300 --> 00:57:29,950 innholdet ut til skjermen en om gangen. 692 00:57:29,950 --> 00:57:35,670 For å skrive ut filer ut til skjermen, vi kommer til å gjøre noe lignende 693 00:57:35,670 --> 00:57:38,120 til hva vi gjorde på slutten av quizen. 694 00:57:38,120 --> 00:57:45,350 På slutten av quizen, som leier program, måtte vi åpne opp en fil, 695 00:57:45,350 --> 00:57:48,490 og da måtte vi ut på den. 696 00:57:48,490 --> 00:57:54,660 I dette tilfellet, vi kommer til å åpne opp en fil, og vi kommer til å lese fra det stedet. 697 00:57:54,660 --> 00:58:00,630 Så vi kommer til å skrive ut, i stedet for til en fil, kommer vi til å skrive ut på skjermen. 698 00:58:00,630 --> 00:58:05,830 Så skriver til skjermen du har alle gjort før med printf. 699 00:58:05,830 --> 00:58:08,290 Så det er ikke så gal. 700 00:58:08,290 --> 00:58:12,190 Men å lese en fil er slags merkelig. 701 00:58:12,190 --> 00:58:17,300 Vi vil gå gjennom det en liten bit av gangen. 702 00:58:17,300 --> 00:58:20,560 Hvis dere går tilbake til det siste problemet på quiz, problemet 33, 703 00:58:20,560 --> 00:58:27,280 den første linjen som vi kommer til å gjøre her, åpne filen, er svært likt det vi gjorde der. 704 00:58:27,280 --> 00:58:36,370 Så Stella, hva betyr denne linjen ser ut, når vi åpner en fil? 705 00:58:36,370 --> 00:58:47,510 [Stella] Capital FIL *, fil - >> Ok. >> - Er lik fopen. >> Yup. 706 00:58:47,510 --> 00:58:55,980 Som i dette tilfellet er? Det er i kommentaren. 707 00:58:55,980 --> 00:59:06,930 >> Det er i kommentaren? argv [i] og r? 708 00:59:06,930 --> 00:59:11,300 >> Nettopp. Rett på. Så Stella er helt rett. 709 00:59:11,300 --> 00:59:13,720 Dette er hva linjen ser ut. 710 00:59:13,720 --> 00:59:19,670 Vi kommer til å få en filstrøm variabel, lagre den i en fil *, så alle caps, 711 00:59:19,670 --> 00:59:25,720 FIL, *, og navnet på denne variabelen vil være fil. 712 00:59:25,720 --> 00:59:32,250 Vi kan kalle det hva vi vil. Vi kan kalle det first_file, eller file_i, hva vi ønsker. 713 00:59:32,250 --> 00:59:37,590 Og så navnet på filen ble vedtatt i på kommandolinjen til dette programmet. 714 00:59:37,590 --> 00:59:44,450 Så det er lagret i argv [i,] og vi kommer til å åpne denne filen i lesemodus. 715 00:59:44,450 --> 00:59:48,100 Nå som vi har åpnet filen, er det ting som vi alltid må huske å gjøre 716 00:59:48,100 --> 00:59:52,230 når vi har åpnet en fil? Lukke den. 717 00:59:52,230 --> 00:59:57,220 Så Missy, hvordan vi lukke en fil? 718 00:59:57,220 --> 01:00:01,020 [Missy] fclose (fil) >> fclose (fil). Akkurat. 719 01:00:01,020 --> 01:00:05,340 Flott. Okay. Hvis vi ser på dette å gjøre kommentaren her, 720 01:00:05,340 --> 01:00:11,940 står det: "Åpen argv [i] og skrive ut innholdet til stdout." 721 01:00:11,940 --> 01:00:15,460 >> Standard ut er et merkelig navn. Stdout er bare vår måte å si 722 01:00:15,460 --> 01:00:22,880 vi ønsker å skrive det til terminalen, ønsker vi å skrive det til standard ut-strømmen. 723 01:00:22,880 --> 01:00:26,450 Vi kan faktisk bli kvitt denne kommentaren her. 724 01:00:26,450 --> 01:00:36,480 Jeg kommer til å kopiere den og lime den siden det er hva vi gjorde. 725 01:00:36,480 --> 01:00:41,290 På dette punktet, nå må vi lese filen bit for bit. 726 01:00:41,290 --> 01:00:46,300 Vi har diskutert et par måter å lese filer. 727 01:00:46,300 --> 01:00:51,830 Hvilke er dine favoritter så langt? 728 01:00:51,830 --> 01:00:57,960 Hvilke måter har du sett eller husker du, for å lese filer? 729 01:00:57,960 --> 01:01:04,870 [Daniel] fread? >> Fread? Så fread er én. Jimmy, vet du noen andre? 730 01:01:04,870 --> 01:01:12,150 [Jimmy] Nei >> Ok. Nope. Charlotte? Alexander? Noen andre? Okay. 731 01:01:12,150 --> 01:01:20,740 Så de andre som er fgetc, er en som vi vil bruke mye. 732 01:01:20,740 --> 01:01:26,410 Det er også fscanf, dere ser et mønster her? 733 01:01:26,410 --> 01:01:29,170 De alle begynner med f. Noe å gjøre med en fil. 734 01:01:29,170 --> 01:01:35,260 Det er fread, fgetc, fscanf. Disse er alle av lesningen funksjoner. 735 01:01:35,260 --> 01:01:49,120 For å skrive har vi fwrite, har vi fputc stedet for fgetc. 736 01:01:49,120 --> 01:01:58,250 Vi har også fprintf liker vi så på quiz. 737 01:01:58,250 --> 01:02:01,680 Siden dette er et problem som innebærer å lese fra en fil, 738 01:02:01,680 --> 01:02:04,940 vi kommer til å bruke en av disse tre funksjonene. 739 01:02:04,940 --> 01:02:10,890 Vi kommer ikke til å bruke disse funksjonene her nede. 740 01:02:10,890 --> 01:02:14,880 Disse funksjonene er alle funnet i standard I / O biblioteket. 741 01:02:14,880 --> 01:02:17,510 Så hvis du ser på toppen av dette programmet, 742 01:02:17,510 --> 01:02:24,110 du kan se at vi allerede har tatt topptekstfilen for standard I / O-bibliotek. 743 01:02:24,110 --> 01:02:27,120 Hvis vi ønsker å finne ut hvilken som vi ønsker å bruke, 744 01:02:27,120 --> 01:02:29,690 Vi kan alltid åpne opp mannen sidene. 745 01:02:29,690 --> 01:02:34,350 Så vi kan skrive mann stdio 746 01:02:34,350 --> 01:02:43,180 og lese alt om stdio input og output funksjoner i C. 747 01:02:43,180 --> 01:02:49,870 Og vi kan allerede se oh, se. Det er nevne fgetc, det å nevne fputc. 748 01:02:49,870 --> 01:02:57,220 Så du kan bore ned litt og se på, sier fgetc 749 01:02:57,220 --> 01:03:00,060 og se på sin mann siden. 750 01:03:00,060 --> 01:03:03,430 Du kan se at det går sammen med en hel haug med andre funksjoner: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, blir, ungetc, og input av tegn og strenger. 752 01:03:12,640 --> 01:03:19,180 Så dette er hvordan vi leser i tegn og strenger fra filer fra standard inngang, 753 01:03:19,180 --> 01:03:21,990 som er hovedsakelig fra brukeren. 754 01:03:21,990 --> 01:03:24,780 Og dette er hvordan vi gjør det i selve C. 755 01:03:24,780 --> 01:03:30,850 Slik at dette ikke bruker GetString og getchar funksjoner 756 01:03:30,850 --> 01:03:36,840 som vi brukte fra CS50 biblioteket. 757 01:03:36,840 --> 01:03:39,710 Vi kommer til å gjøre dette problemet i et par måter 758 01:03:39,710 --> 01:03:43,430 slik at du kan se to forskjellige måter å gjøre det. 759 01:03:43,430 --> 01:03:48,490 Både fread funksjon som Daniel nevnt og fgetc er gode måter å gjøre det. 760 01:03:48,490 --> 01:03:53,790 Jeg tror fgetc er litt enklere, fordi den bare har, som du ser, 761 01:03:53,790 --> 01:03:59,660 ett argument, FILE * at vi prøver å lese tegn fra, 762 01:03:59,660 --> 01:04:02,740 og returverdien er en int. 763 01:04:02,740 --> 01:04:05,610 Og dette er litt forvirrende, ikke sant? 764 01:04:05,610 --> 01:04:11,450 >> Fordi vi får en karakter, så hvorfor ikke denne avkastningen en røye? 765 01:04:11,450 --> 01:04:18,700 Dere har noen ideer om hvorfor dette ikke kan returnere en røye? 766 01:04:18,700 --> 01:04:25,510 [Missy svar, uforståelig] >> Ja. Så Missy er helt rett. 767 01:04:25,510 --> 01:04:31,570 Hvis det er ASCII, så dette heltall kunne kartlegges til en faktisk røye. 768 01:04:31,570 --> 01:04:33,520 Kan være et ASCII-tegn, og det er riktig. 769 01:04:33,520 --> 01:04:36,220 Det er akkurat det som skjer. 770 01:04:36,220 --> 01:04:39,190 Vi bruker en int rett og slett fordi den har flere biter. 771 01:04:39,190 --> 01:04:44,750 Det er større enn en røye, vår røye bare har 8 bits, som en byte på våre 32-bits maskiner. 772 01:04:44,750 --> 01:04:48,520 Og en int har alle fire byte igjen av plass. 773 01:04:48,520 --> 01:04:50,940 Og det viser seg at veien fgetc fungerer, 774 01:04:50,940 --> 01:04:53,940 hvis vi bla nedover i synopsis vår i denne mannen siden litt, 775 01:04:53,940 --> 01:05:05,000 bla helt ned. Det viser seg at de bruker denne spesielle verdi som kalles EOF. 776 01:05:05,000 --> 01:05:09,640 Det er en spesiell konstant som returverdien av fgetc funksjon 777 01:05:09,640 --> 01:05:14,570 når du treffer slutten av filen, eller hvis du får en feilmelding. 778 01:05:14,570 --> 01:05:18,170 Og det viser seg at å gjøre disse sammenligningene med EOF riktig, 779 01:05:18,170 --> 01:05:24,060 du vil ha det ekstra mengden av informasjon som du har i en int 780 01:05:24,060 --> 01:05:28,420 motsetning til å bruke en char variabel. 781 01:05:28,420 --> 01:05:32,130 Selv om fgetc er effektivt å få et tegn fra en fil, 782 01:05:32,130 --> 01:05:38,450 du ønsker å huske på at det er tilbake noe som er av type int til deg. 783 01:05:38,450 --> 01:05:41,360 Når det er sagt, det er ganske enkelt å bruke. 784 01:05:41,360 --> 01:05:44,960 Det kommer til å gi oss en karakter, så alt vi trenger å gjøre er å spørre filen, 785 01:05:44,960 --> 01:05:48,440 "Gi meg det neste tegnet, gi meg det neste tegnet, gi meg det neste tegnet," 786 01:05:48,440 --> 01:05:51,400 før vi kommer til slutten av filen. 787 01:05:51,400 --> 01:05:54,730 Og som vil trekke i ett tegn om gangen fra fil vår, 788 01:05:54,730 --> 01:05:56,250 og da kan vi gjøre hva vi vil med den. 789 01:05:56,250 --> 01:06:00,160 Vi kan lagre det, kan vi legge det til en streng, kan vi skrive den ut. 790 01:06:00,160 --> 01:06:04,630 Gjøre noe av det. 791 01:06:04,630 --> 01:06:09,600 >> Zoome ut igjen og går tilbake til vår kategori C program, 792 01:06:09,600 --> 01:06:16,170 hvis vi kommer til å bruke fgetc, 793 01:06:16,170 --> 01:06:21,710 hvordan kan vi nærmer oss denne neste linje av koden? 794 01:06:21,710 --> 01:06:26,020 Vi kommer til å bruke - fread vil gjøre noe litt annerledes. 795 01:06:26,020 --> 01:06:32,600 Og denne gangen, vi bare kommer til å bruke fgetc å få ett tegn om gangen. 796 01:06:32,600 --> 01:06:40,910 Å behandle en hel fil, kan hva vi har å gjøre? 797 01:06:40,910 --> 01:06:44,030 Hvor mange tegn er det i en fil? 798 01:06:44,030 --> 01:06:47,390 Det er mye. Så du sannsynligvis vil få en 799 01:06:47,390 --> 01:06:49,860 og deretter få en annen og få en annen og få en annen. 800 01:06:49,860 --> 01:06:53,330 Hva slags algoritme tror du vi kan ha til å bruke her? 801 01:06:53,330 --> 01:06:55,470 Hva slags -? [Alexander] A for loop? >> Nettopp. 802 01:06:55,470 --> 01:06:57,500 Noen type loop. 803 01:06:57,500 --> 01:07:03,380 En for løkke er faktisk stor, i dette tilfellet. 804 01:07:03,380 --> 01:07:08,620 Og som du sa, det høres ut som du vil ha en sløyfe over hele filen, 805 01:07:08,620 --> 01:07:11,820 få et tegn om gangen. 806 01:07:11,820 --> 01:07:13,850 Noen forslag på hva som kan se ut? 807 01:07:13,850 --> 01:07:22,090 [Alexander, uforståelig] 808 01:07:22,090 --> 01:07:30,050 >> Ok, bare fortell meg på engelsk hva du prøver å gjøre? [Alexander, uforståelig] 809 01:07:30,050 --> 01:07:36,270 Så i dette tilfellet, det høres ut som vi prøver bare å sløyfe over hele filen. 810 01:07:36,270 --> 01:07:45,330 [Alexander] Så I > Størrelsen -? 811 01:07:45,330 --> 01:07:49,290 Jeg antar størrelsen på filen, ikke sant? Størrelsen - vi vil bare skrive det slik. 812 01:07:49,290 --> 01:07:57,470 Størrelsen på filen for tiden, i + +. 813 01:07:57,470 --> 01:08:04,610 Så det viser seg at den måten du gjør dette ved hjelp av fgetc, og dette er nytt, 814 01:08:04,610 --> 01:08:10,460 er at det er ingen enkel måte å bare få størrelsen på en fil 815 01:08:10,460 --> 01:08:16,979 med denne "sizeof" type konstruere som du har sett før. 816 01:08:16,979 --> 01:08:20,910 Når vi bruker det fgetc funksjon, kan vi innføre en slags 817 01:08:20,910 --> 01:08:29,069 Nye tøffe syntaks til dette for loop, der i stedet for å bruke bare en grunnleggende teller 818 01:08:29,069 --> 01:08:33,920 å gå tegn for tegn, vi kommer til å trekke ett tegn om gangen, 819 01:08:33,920 --> 01:08:37,120 ett tegn om gangen, og måten vi vet vi er på slutten 820 01:08:37,120 --> 01:08:41,290 er ikke når vi har telt et visst antall tegn, 821 01:08:41,290 --> 01:08:49,939 men når karakteren vi trekke ut er at spesiell slutten av filen karakter. 822 01:08:49,939 --> 01:08:58,689 Så vi kan gjøre dette ved å - Jeg kaller dette lm, og vi kommer til å initialisere den 823 01:08:58,689 --> 01:09:08,050 med vår første samtale for å få det første tegnet ut av filen. 824 01:09:08,050 --> 01:09:14,979 Så denne delen her, dette kommer til å få en karakter ut av filen 825 01:09:14,979 --> 01:09:20,840 og lagre den i variabelen lm. 826 01:09:20,840 --> 01:09:25,420 Vi kommer til å fortsette å gjøre dette før vi kommer til slutten av filen, 827 01:09:25,420 --> 01:09:41,170 som vi gjør ved testing for tegnet ikke er lik den spesielle EOF karakter. 828 01:09:41,170 --> 01:09:48,750 Og da i stedet for å gjøre lm + +, noe som ville bare øke verdien, 829 01:09:48,750 --> 01:09:52,710 så hvis vi lese en A ut av filen, en hovedstad A, sier 830 01:09:52,710 --> 01:09:56,810 ch + + ville gi oss b, og da ville vi få c og deretter d. 831 01:09:56,810 --> 01:09:59,310 Det er åpenbart ikke det vi ønsker. Hva vi vil her 832 01:09:59,310 --> 01:10:05,830 i denne siste biten vi ønsker å få det neste tegnet fra filen. 833 01:10:05,830 --> 01:10:09,500 >> Så hvordan kan vi få det neste tegnet fra filen? 834 01:10:09,500 --> 01:10:13,470 Hvordan får vi det første tegnet fra filen? 835 01:10:13,470 --> 01:10:17,200 [Student] fgetfile? >> Fgetc, eller, beklager, du var helt rett. 836 01:10:17,200 --> 01:10:20,470 Jeg stavet feil det der. Så ja. 837 01:10:20,470 --> 01:10:26,240 Her i stedet for å gjøre lm + +, 838 01:10:26,240 --> 01:10:29,560 vi bare kommer til å ringe fgetc (fil) igjen 839 01:10:29,560 --> 01:10:39,180 og lagre resultatet i vår samme lm variabel. 840 01:10:39,180 --> 01:10:43,730 [Student spørsmål, uforståelig] 841 01:10:43,730 --> 01:10:52,390 >> Det er der disse fil * gutta er spesielle. 842 01:10:52,390 --> 01:10:59,070 Måten de arbeider er de - når du først åpne - når du først gjør det fopen anrop, 843 01:10:59,070 --> 01:11:04,260 FILE * serverer effektivt som en peker til begynnelsen av filen. 844 01:11:04,260 --> 01:11:12,830 Og deretter hver gang du ringer fgetc, beveger det ett tegn gjennom filen. 845 01:11:12,830 --> 01:11:23,280 Så når du ringer dette, er du økes filpekeren av et tegn. 846 01:11:23,280 --> 01:11:26,210 Og når du fgetc igjen, du flytter den en annen karakter 847 01:11:26,210 --> 01:11:28,910 og en annen karakter og en annen karakter og en annen karakter. 848 01:11:28,910 --> 01:11:32,030 [Student spørsmål, uforståelig] >> Og that - Ja. 849 01:11:32,030 --> 01:11:34,810 Det er slags av denne magiske under panseret. 850 01:11:34,810 --> 01:11:37,930 Du må bare holde økes gjennom. 851 01:11:37,930 --> 01:11:46,510 På dette punktet, er du i stand til å faktisk jobbe med en karakter. 852 01:11:46,510 --> 01:11:52,150 Så hvordan kan vi skrive ut dette til skjermen, nå? 853 01:11:52,150 --> 01:11:58,340 Vi kan bruke samme printf ting som vi brukte før. 854 01:11:58,340 --> 01:12:00,330 At vi har brukt hele semesteret. 855 01:12:00,330 --> 01:12:05,450 Vi kan kalle printf, 856 01:12:05,450 --> 01:12:21,300 og vi kan passere i karakter akkurat sånn. 857 01:12:21,300 --> 01:12:27,430 En annen måte å gjøre det er stedet for å bruke printf og måtte gjøre dette formatet streng, 858 01:12:27,430 --> 01:12:29,490 Vi kan også bruke en av de andre funksjonene. 859 01:12:29,490 --> 01:12:40,090 Vi kan bruke fputc, som skriver et tegn på skjermen, 860 01:12:40,090 --> 01:12:52,580 bortsett fra hvis vi ser på fputc - la meg zoome ut litt. 861 01:12:52,580 --> 01:12:56,430 Vi ser hva som er hyggelig er det tar i karakteren som vi leser ut ved hjelp fgetc, 862 01:12:56,430 --> 01:13:05,100 men da må vi gi det en bekk å skrive ut. 863 01:13:05,100 --> 01:13:11,850 Vi kan også bruke putchar funksjonen, som vil sette direkte til standard ut. 864 01:13:11,850 --> 01:13:16,070 Så det er en hel haug med forskjellige alternativer som vi kan bruke for utskrift. 865 01:13:16,070 --> 01:13:19,580 De er alle i standard I / O-bibliotek. 866 01:13:19,580 --> 01:13:25,150 Når du vil skrive ut - så printf, som standard, vil skrive ut til den spesielle standard ut strømmen, 867 01:13:25,150 --> 01:13:27,910 som er at stdout. 868 01:13:27,910 --> 01:13:41,300 Så vi kan bare referere til det som en slags denne magiske verdi, stdout her. 869 01:13:41,300 --> 01:13:48,410 Oops. Sett semikolon utenfor. 870 01:13:48,410 --> 01:13:52,790 >> Dette er en mye ny, funky informasjon her. 871 01:13:52,790 --> 01:13:58,600 Mye av dette er svært idiomatisk, i den forstand at dette er koden 872 01:13:58,600 --> 01:14:05,700 som er skrevet på denne måten bare fordi det er rent for å lese, lett å lese. 873 01:14:05,700 --> 01:14:11,520 Det er mange forskjellige måter å gjøre det, mange forskjellige funksjoner du kan bruke, 874 01:14:11,520 --> 01:14:14,680 men vi har en tendens til å bare følge de samme mønstrene om og om igjen. 875 01:14:14,680 --> 01:14:20,180 Så ikke bli overrasket om du ser kode som dette kommer opp igjen og igjen. 876 01:14:20,180 --> 01:14:25,690 OK. På dette punktet, må vi bryte for dagen. 877 01:14:25,690 --> 01:14:31,300 Takk for at du kom. Takk for å se om du er online. Og vi vil se deg neste uke. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]