JASON Hirschhorn: Velkommen, alle, til uke seks. Jeg er glad for å se dere alle lever i beste velgående etter Quiz 0, fordi jeg vet at var litt ujevn. Men heldigvis, dere alle gjorde utrolig godt. Og så det er fantastisk. Hvis du er i min del, har jeg gitt mest av dere støtt dine quizer allerede. Et par av dere, jeg møte etter klasse. Og hvis du er en forlengelse student og du ikke har mottatt din quiz tilbake ennå, er din TF trolig jobber med saken og gradering det, og vil få den tilbake til deg snart. Så min forlengelse studenter som er ser på akkurat nå - forhåpentligvis leve - Jeg vil få dine quizer kort tid også. Vår agenda for i dag er som følger. Først skal vi gå over noen ressurser som CS50 gir til deg. Vi kommer til å gå over Quiz 0 neste, og Jeg skal svare på noen spørsmål noen har om spesielle problemer. Og da vil vi gå over fil I / O og oppgavesettet fem. De to siste emnene vil ta hoveddelen av seksjonen i dag. Jeg satte denne listen opp hver uke som en påminnelse til dere alle, men av kjernen seksjon, vi har bare 90 minutter - vi er ikke i stand til å dekke alt som jeg ville elske å dekke for dere. Men vi har massevis av ressurser for du å trekke på som du blir kjent med materialet og arbeidet gjennom problemet setter. En påminnelse om at jeg har nettet en tekst boksen, satt opp for deg å fylle ut hvis du har noen tilbakemeldinger for meg, både positive og konstruktiv, om seksjonen. At URL ligger rett ned her. Så vær så snill, ta et øyeblikk hvis du har noen tilbakemelding, enten under seksjonen, eller etter, eller etter at du se videoen på nettet, for å gi meg tilbakemelding. Jeg virkelig setter pris på alle av det. Så jeg har hatt små samtaler med mye av min studenter i løpet av uken - så jeg hånden tilbake quizer, snakker om Selvfølgelig, å se hvordan du gjør. Og ett tema har kommet opp igjen og enn i å snakke om - i spesielt - oppgavesett. Og jeg har innkapslet som tema på bordet akkurat nå. I hovedsak er det en forskjell mellom å slå på noe som er gjort riktig og noe som er gjort godt. De fleste mennesker har gjort fantastisk i form av nøyaktighet - 5-er eller 4 er på alle psets. De fleste får de hele tiden. Men bare fordi du har gjort noe riktig betyr ikke at du har gjort noe så elegant, eller effektivt, eller så rent som du kunne ha gjort det. Og det er hva design - og i mindre grad, stil - aksene er for. Så jeg skyve dere alle, og andre TFs presser dere, å ikke bare turn i ting som er riktig, men slår i de tingene som er kodet godt. Ikke gjør unødvendig FOR sløyfer, ikke rekalkulerer variabler hvis du trenger ikke å. For eksempel, ser tilbake til oppgavesettet 4, når du plasserer klossene på skjermen, hver rad - hver murstein i en gitt rad har samme y-koordinaten - samme høyde koordinat. Slik at y-koordinat ikke trenger å beregnes på innsiden av indre nestet FOR løkke som du sannsynligvis brukt å sette disse murstein på skjermen. Den trenger bare skal beregnes hver gangen du slo på rad, eller beveget seg nedover en rad. Så si hvis det er 10 klosser i en rad, kan hver murstein har samme y-koordinat, og at y-koordinaten kan bare beregnes en gang for alle disse. Det trenger ikke å bli beregnet 10 tiden, og heller ikke at beregnings behov skje i selve funksjon samtale - den nye gracked funksjon samtale. Så hvis det var litt forvirrende for du, mer generelt, ting som trenger ikke å skje hver eneste gang du går gjennom en FOR løkke bør ikke være satt inne i for-løkken, og bør ikke skje hver gang du går gjennom FOR løkke. En annen god design eksempel vi så i uke 3 for 15, kunne du holde spor på null. Så når du initial brettet, du spare - i en global variabel, kanskje - x-og y-koordinaten null. Og så når du - i ditt trekk funksjon, når du gjør et vellykket trekk, oppdaterer du den Plasseringen av null. Det vil spare deg fra å måtte gjøre nestet FOR sløyfer å se gjennom borde hver gang i ditt trekk funksjon og finne null, eller finne flisen, og sjekk deretter hva som er ved siden av den. I stedet må du plasseringen av null, kan du bare se over, under, og til venstre og høyre for det, for å finne flisen du var ute etter. Så i forhold til programmene vi er skriving, de er aldri stor nok at noen av disse designbeslutninger er virkelig kommer til å hemme din program, eller at det går saktere, eller kanskje til og med gå tom for minne. Men vi er fortsatt presser dere å skrive så elegant og effektiv kode som mulig. Så hvis du ender opp med å skrive ting som har en betydelig større omfang, vil de være skrevet med god utforme i tillegg til å være korrekte. Så mange av dere har brakte det ut. Det er noe vi leter etter - noe vi kommer til å fortsette å presse deg gutta på. Hvis du har spørsmål om utformingen av programmet, gjerne å nå ut til meg, og jeg er glad for å gå gjennom programmet med deg, og peke ut noen av design beslutningene du har gjort, og gi deg noen forslag til hvordan å gjøre selv bedre design beslutninger. Så vi kommer til å gå videre å snakke om Quiz 0. Før vi gjør det, gjør noen har noen spørsmål om hva Jeg har dekket så langt? [Raslende STØY] JASON Hirschhorn: Syv sekunder. OK. La oss snakke om Quiz 0 for en bit. De fleste av dere har din Quiz 0 rygg. Hvis du ikke gjør det, forhåpentligvis Husker du den litt. Men hvis du har tatt Quiz 0, så du har også tilgang til PDF på nettet i eksempel løsninger. Er det noen som har noen spørsmål før vi hopper inn i ukens materiale om et spesielt problem på Quiz 0 - hvorfor svaret er hva det er? Er det noen forvirret om noe? Selv om du fikk problemet rett, men bare vil at jeg skal forklare det litt mer, er jeg glad for å gjøre det nå. Så jeg har bedt dere til kommer forberedt med noen tanker om Quiz 0. Så hvem ønsker å få oss startet med et spørsmål eller kommentere om Quiz 0? [PAPIR rasling] JASON Hirschhorn: Ikke alle gjorde perfekt. Så jeg vet [ler] det må være noen spørsmål om Quiz 0. OK. Ja. Ompica. OMPICA: Number 10. JASON Hirschhorn: Number 10. Hvilken var nummer 10? OMPICA: The - JASON Hirschhorn: jeg ikke har det - OMPICA: Den omfatter - JASON Hirschhorn: Nummer 10 var åtte til i - å skrive åtte til jeg? OMPICA: Yeah. JASON Hirschhorn: OK. Så et annet spørsmål du kan ha spurte var jeg forutseende? Svaret er ja. I avsnittet før quizen, spurte jeg dere å kode både Sterling og åtte til jeg. Begge skjedde med vises på quiz. Så forhåpentligvis, du har betalt oppmerksomhet til det. Og hvis du hadde, så ville du ha sannsynligvis gjort det bra på de to. Men åtte til jeg, gjorde vi ikke egentlig kode den i klassen, men det var igjen, spurte på quiz. Så et par ting å ta oppmerksom når koding åtte til jeg. Det første, per spørsmålet, var at du trengte å sjekke om strengen var lik null. Et par folk prøvde å sjekke senere i programmet hvis s brakett jeg var - slik at en bestemt karakter i den string - var lik null. Men husk, at null er egentlig - det er godt å tenke på null etter en null spisser - en peker til null - et sted i minnet hvor du kan aldri få tilgang. Så hvis noe er lik null, du vet at det ikke er blitt initialisert, eller det er ingenting der. Så s er en røye stjerne, s brakett jeg er en røye. Derfor er det fornuftig å sammenligne s til null, men ikke s brakett jeg til null. Men igjen - så det var det første at du skulle gjøre - sjekk for å forsikre deg om at du faktisk fikk en skikkelig streng. Deretter ønsket du å gå gjennom hvert tegn i strengen. Og så det ville være som en s brakett Jeg, for eksempel, hvis jeg er din iterator. Og ta det tegnet, og få sin faktiske verdien. Du har det lagret som en røye, men ASCII-verdien for null - null som et tegn - er faktisk ikke heltall null. Det er noen andre nummer som du kan slå opp i ASCII-tabellen. Så en måte å korrigere for det - sannsynligvis den beste måten for å korrigere for det - er trekke fra det tegnet verdi - null som et tegn. Så minus enkelt sitat, null, en annen enkel apostrof. Det vil ta det nummeret du har som en røye, og få det lik antall som en faktisk heltall. Og det er svært lik den tilnærmingen mange mennesker tok i Problemet satt to, med Caesar og Viginere - disse koder, når du ble rotere dem. Så etter at du har det som et nummer fra null til ni, da - avhengig av hvor det går i den ultimate nummer - du trenger å multiplisere det av en strøm av 10 år. Noen mennesker flyttet fra baksiden til front, og multiplisert den enkelte tallet med en effekt på 10. Noen mennesker flyttet fra den foran til bak - og så tok den høyeste bestille tall først - og vil lagre dem i en global tellervariabelen. Og så hver gang gjennom FOR loop, multipliserer det gigantiske globale motvirke variabel ved 10, for å gjøre plass for neste røye. Så det var litt forvirrende uten meg å skrive det på tavlen. Men prøveløsningen er tilgjengelig for deg. Men det var de store tingene vi var ute etter. Også en sjekk for å være sikker på at hver individuell karakter var faktisk en karakter mellom null og ni, og ikke en annen karakter, som en A, for eksempel. Det var de tingene vi var ute for i det spørsmålet. Besvarer det spørsmålet ditt? OMPICA: Yeah. JASON Hirschhorn: OK. Er det noen andre spørsmål om Quiz 0? Hva om kompilering? Everybody kompilering rett? Nei. Det var en - [Ler] Eventuelle spørsmål om kompilering prosessen? Wow. [PAPIR rasling] JASON Hirschhorn: Ja. Michael. MICHAEL: Er nummer syv - tilfeldig? JASON Hirschhorn: Nummer syv. Nummer 7 var få et tilfeldig heltall. Utmerket. Så du får et heltall a og en heltall b, og du vil ha en tilfeldig heltall mellom a og b. Vi kan faktisk skrive denne på styret, fordi dette var en kodelinje - én måte å gjøre det. Så vi får drand som en funksjon vi kunne bruke. Og hva betyr drand - forutsatt at det er blitt sådd - hva betyr drand tilbake? MICHAEL: En flottør mellom 0,0 og 1,0. JASON Hirschhorn: En rekke - ja. Et tall mellom 0 og 1.. Og så har vi b og en. Og så har vi vår tilfeldige tall mellom 0 og 1 gitt oss av drand. Noen prøvde å sette b, eller b minus en, eller noe inni dem parenteser. Det ville bety at de er argumenter til denne funksjonen. drand ikke tar noen argumenter - som getString gjør ikke ta noen argumenter. Så det er bare åpne paren, nær paren - og det er i seg selv funksjonskallet. Og det gir deg et nummer mellom 0 og 1. Selvfølgelig har vi en hel rekke at tallene kan være i. Si, hvis b er 10 og en er fem, vi egentlig ønsker et tall med et utvalg av fem. Så neste ting vi trenger å gjøre er multiplisere dette med utvalget b minus en. Så antar det er multiplisert. Og det vil gi oss et tall innenfor et gitt område. Og det bestemt utvalg blir Forskjellen mellom b minus en. Og til slutt, det vil bare gi den fra - si området mellom b minus er 5, som vil gi oss en nummer fra 0 til 5.. Men hvis en er faktisk fem, trenger vi å øke denne serien opp til der det er faktisk er ment å være, ved tilsetning av en. Så det blir logikken høyre. Og så, ville du ha et annet spørsmål? MICHAEL: Nei. Jeg bare føler meg veldig dum akkurat nå. [Ler] JASON Hirschhorn: Nei. Ikke føler virkelig dum. En rekke mennesker kjempet med dette spørsmålet. Og så er det andre spørsmålet, drand, du sa, gir deg en dupp - returnerer en float. Men denne funksjonen faktisk spurt for et helt tall som skal returneres. Du trenger ikke å kaste dette eksplisitt til et heltall, fordi disse operasjoner vil behandle det som alt en flyte - som et flyttall. Liker du dette vilje - selv om dette er et helt tall, vil dette multipliseres riktig. All multiplikasjon vil fungere. Du trenger ikke å kaste den her. Faktisk bør du ikke kaste det. Det ville - hvis du vil kaste en rekke det er mellom 0 og 1 - et tilfeldig tall, et flyttall - så vil det enten bare være 0 eller 1, slik at vil du miste alt dette presisjon. Men på slutten, når du kommer tilbake, det blir automatisk sendes tilbake som et heltall. Så du trenger ikke å gjøre at avstøpning selv. Så dette var svaret på det spørsmålet, nummer syv. Eventuelle andre spørsmål om Quiz 0? Ja, Annie. ANNIE: Når bruker vi rekursiv - da bruker vi iterative sløyfer? JASON Hirschhorn: Når du bruker rekursiv - så mer generelt, fordeler og ulemper med rekursjon versus en iterativ tilnærming. Kan noen gi en pro eller en con? Vennligst? Ikke kan noen. Hvem kan tilby en pro eller en con? [PAPIR rasling] STUDENT 1: Rekursiv er mindre koding - mindre å skrive? JASON Hirschhorn: Så generelt, rekursjon spesielt, en funksjon - eller en algoritme som fusjonerer sort - som gir seg til en rekursiv tilnærming - kan være mer oversiktlig å kode rekursivt. Og bare være mer fornuftig å gjøre det rekursivt. Så det ville være en proff til å rekursjon. Andre? Yeah? STUDENT 2: Con til rekursjon - Den bruker mer minne. JASON Hirschhorn: Så helt riktig. En rekursiv funksjon vil fortsette å legge stabelen rammer til bunken. Så hvis du opererer på en rekke tall, og må ringe dette fungere mye, da vil du sikkert ta opp mer minne, mens en iterativ tilnærming vil bare sette ett stable rammen på stabelen, fordi alt skjer innen én funksjon. Eventuelle andre fordeler og ulemper? Yeah. STUDENT 3: Argumenter for rekursjon. Du trenger ikke å avgjøre i forhånd hvor mange ganger kode måtte gjentas. Du kan ha et forhåndsbestemt antall ganger som du må reagere, deretter rekursjon er bedre, fordi det tar det resultatet. JASON Hirschhorn: Jeg tror det er sant. Men jeg tror i begge tilfeller du ville aldri - du vil sannsynligvis få litt input fra brukeren. Eller denne funksjonen ville ha noen innspill som ville finne ut hvor mange ganger det bør kjøre. Så generelt, du ville ikke vanskelig kode - selv i en iterativ tilnærming - hvordan mange ganger at loopen skal kjøres. Hadde du en annen du var tenker, Annie? OK. Så de er sannsynligvis de to - den største pro og den største con til en rekursiv versus en iterativ tilnærming. OK. Noe annet på Quiz 0? La oss gå videre. Fil I / O. Det er en fantastisk kort denne uken på fil I / O som forhåpentligvis du har sett flere ganger, og beundret. Mye av arbeidet gikk inn i det, og jeg har hørt det er sinnsykt nyttig. Jeg har også tatt med linken på dette lysbildet, i tilfelle du ikke har hatt en sjanse til å se den 10 ganger. Så, skal vi gå kort over store skritt til å åpne og arbeide med filer, og deretter skal vi dykke inn i en koding problem før undersøke problemet sett. Så igjen, jeg kommer til å sette dette opp på skjermen, men jeg kommer til å snakke for bare et øyeblikk om hva vi er gjør her med fil I/O-- hva betyr det? Det betyr at vi kan lage vår programmer, og da har våre programmer exit, og ikke har gjort noen innvirkning på verden utenfor vårt program. Men når vi begynner å arbeide med filer - både å lese dem inn og skape dem - kan ha en viss effekt på verden utenfor vårt program. Akkurat som om Microsoft Word var ikke i stand å gjøre noen Word-dokumenter, og deretter når Microsoft Word slutte, all din Arbeidet vil bli borte, og det ville virkelig være ubrukelig. Vi vil til syvende og sist vil kunne skrive programmer som kan påvirke verden rundt dem, både ved å ta i komplekse innganger - i form av filer og via filer, og også skape interessant og overbevisende utganger - i form av forskjellige typer filer. Så det er grunnen til at vi begynner å lære å arbeide med filer. Mer spesielt hva vi gjør er som følger. Det er veldig enkelt. Det er bare et par skritt, og de er oppført her på denne koden. Så vi kommer til å gå gjennom denne koden linje for linje. Først ser du uthevet - når du arbeider med en fil, uavhengig av hvilken type fil det er, du trenger for å åpne den. Og det er med en oppfordring til fopen - akkurat her. Du inkludere navnet på filen. Hvis filen ikke er i telefonboken, eller mappen hvor dette programmet liv, så må du også inkludere en bane til hvor filen er. Vi kommer til å anta at dette fil som heter "text.txt" - en enkelt tekstdokument - er i samme mappe som dette programmet er. Så det er en annen ting å huske på tankene - at hvis du ønsker å åpne en fil et annet sted, du faktisk trenger å omfatte plasseringen. For det andre, kan du passere et argument for å fopen, og det er det du ønsker å gjøre med filen. Det er tre hovedargumenter at du kommer til å passere til fopen. Hvem kan gi meg de tre? Hvem kan gi meg en av dem? Ja. STUDENT 4: Filnavnet? JASON Hirschhorn: Beklager. Tre hovedargumenter du kan passere som det andre argumentet til fopen. Du har rett - filnavnet er det første argumentet. Men det andre argumentet til fopen er vanligvis tre strenger, og - ja. Aleja. Aleja: A for append. JASON Hirschhorn: A, hvis du ønsker å føye til en fil som allerede eksisterer. STUDENT 5: R for lese. JASON Hirschhorn: R, hvis du ønsker å lese fra en fil. STUDENT 6: W for skriving. JASON Hirschhorn: Og w, hvis du ønsker å skrive til en fil. Så i dette tilfellet, vi skriver til filen, slik at vi har w. Du åpner den, må du også lagre fil et sted, og det er med koden til venstre side av oppdraget operatør - Jeg oppretter en peker til en fil heter, i dette tilfellet, fil. Vi kommer ikke til å bekymre hva dette alle caps FIL ting er. Det er nok å si, er det en lang strøm av nuller og enere. Og det er hvordan vi skal betjene det og forstår det. Det neste vi må gjøre - og Dette er utrolig viktig - når du åpner en fil - faktisk, når du kaller malloc, for eksempel, og få litt minne og prøv og lagre den i en peker, du alltid ønsker å sjekke for å være sikker på at det funksjon returnerte ikke null. Så i dette tilfellet, vi kontrollerer sikker på at vi faktisk åpnet filen på riktig måte, og det var ingen feil i programmet vårt. Neste, når vi har sjekket for å være sikker at vi har en fungerende fil, kan vi skrive til eller lese fra, eller føye til filen. I dette tilfellet, er jeg rett og slett å skrive ut én linje til denne filen. Hvordan vet jeg det? Vel, jeg bruker denne funksjonen kalt fprintf. Alle funksjonene du skal bruke når du skriver til eller leser fra, eller manipulere filer vil være lik funksjonene du har sett før, men starter med bokstaven F, står for filen. Og fprintf, i motsetning til våre vanlige print app, tar ett ekstra argument, og det er den filen der du ønsker å skrive ut denne linjen til. Jeg har ikke noe å rett ohai. Jeg har ikke den tredje argument for å printf - eller det andre argumentet til printf, den tredje argument til fprintf, fordi jeg har ikke noen plassholdere her. Jeg er ikke inkludert noen variabler. Men igjen, fprintf og alle disse fil funksjoner som opererer med filer er generelt kommer til å trenge filen der de opererer. Til slutt, den siste viktig ting til gjøre er å lukke filen, akkurat som med - når vi malloc noe, vi ønsker å frigjøre noe, så vi har en minnelekkasje - vi ønsker å lukke filen vår. Hvis dette programmet gått ut uten å lukke filen, oddsen er ingenting ville gå galt, spesielt hvis det ble en liten fil. Men det er absolutt god koding stil og praksis for å alltid lukke filen når du er ferdig med å bruke det. Så det er det grunnleggende fil I / O. Du har sikkert sett det før, eller så det i den fantastiske kort. Er det noen som har noen spørsmål, før vi går inn i noen praksis koding problemer, om fil I / O-eller fremgangsmåten jeg bare gikk over? [TYPING LYDER] JASON Hirschhorn: Har du har et spørsmål, Avi? AVI: Nei. JASON Hirschhorn: OK. Jeg kommer til å vente en annen sju sekunder. [Ler] Det er et veldig godt tips. Dere har bare ikke liker stille spørsmål. Det er fint. OK. Så vår første praksis problemet er, vi er kommer til å kopiere funksjonen et kommandolinje verktøy som du sannsynligvis brukt før - kopi - kopien verktøyet. Hvis du skriver cp og deretter gi det to argumenter i terminalen, kan du kopiere en fil. Og det er det vi skal å skrive akkurat nå. Så igjen, leser ut av dette lysbildet, hadde jeg du å skrive et program som tar to og bare to kommandolinje argumenter - en kildefil og målfil - og kopierer innholdet i kilden filen til målfilen en byte om gangen. Så det er mye å be om. Igjen, en god tilnærming til dette er å ikke gå rett til C-kode, men bryte det ned i et par trinn. Tenk først om logikken - nøyaktig det jeg spør deg om å gjøre - og forstå alle de trinn til dette problemet. Ikke i C, bare i noen pseudo, eller til en modell av mental hva som skjer. Neste, når du har den pseudo ned, finne ut hvordan pseudo kart på verktøy og tingene vi har lært å bruke i C. Og til slutt, når du har alt som sammen, kan du kode problemet. Ta 5 til 10 minutter til jobbe med dette problemet. Jeg skal sette instruksjonene opp igjen i et sekund. Og så kommer vi til å gå over den pseudo, og kode det leve som en gruppe. Hvis du har noen spørsmål mens du er jobber med dette, gjerne heve din hånd, og jeg vil komme rundt og svare på dem. STUDENT 7: Kan jeg sveiper et stykke papir? JASON Hirschhorn: Hva skjer? [TYPING LYDER] JASON Hirschhorn: OK. La oss gå over pseudo først, og så skal jeg gi deg et par mer minutter å fullføre koding. Hvem ønsker å starte meg av med den første linjen i pseudo for denne funksjonen? STUDENT 8: Kontroller at du fikk to filer. JASON Hirschhorn: OK. Og hvis vi ikke? STUDENT 8: Jeg vil returnere 0. JASON Hirschhorn: Bør vi tilbake 0? STUDENT 8: Gå tilbake en - blanking. Unnskyld. JASON Hirschhorn: Yeah. Sannsynligvis ikke 0. Fordi 0 betyr alt var bra. OK. Så det er den første linjen av pseudo. Hvem har den andre linjen av pseudo? STUDENT 9: Åpne begge filene? JASON Hirschhorn: Åpne begge filer. OK? STUDENT 10: Kontroller hvis filen er NULL? JASON Hirschhorn: Kontroller at verken er NULL. Som en digresjon - slash 0 - er at NULL? STUDENT 11: Nei. JASON Hirschhorn: Det er ikke NULL. Det kalles NULL terminator. Det er faktisk spelt med bare én liter. Så sjekker noe imot det - det er faktisk et tegn - så sjekker noe imot det er ikke det samme som å sjekke for å se om det lik NULL. Og noen mennesker - på sine quizer og deres problem sett - har fått to av dem forvirret. Men to av dem er faktisk forskjellige. Man ender en streng - en er en peker til 0. STUDENT 12: Hvorfor vil ikke du sjekke for å sørge for at filene ikke er NULL før du åpner dem? JASON Hirschhorn: Så åpen sparer noe i denne filen. Og hvis du går tilbake hit - så denne linjen - fopen - vil gi deg en adresse og butikk som adresse i filen hvis det fungerer. Hvis det ikke fungerer, det vil lagre NULL - STUDENT 12: Oh. OK. Fikk du. JASON Hirschhorn: I fil. Så du kan ikke sjekke for NULL før du har åpnet dem. NULL betyr noe ikke fungere korrekt. OK. Så sjekk for å kontrollere at verken si? Eller er? Hva tror vi? Vi vil gå med det. STUDENT 13: Is. JASON Hirschhorn: Er? Det er heller ikke? STUDENT 13: Is. JASON Hirschhorn: OK. Vi synes å ha noen enighet om det. Verken er NULL. OK, neste linje av pseudo. Hvem har ikke gitt meg en linje ennå? Vi vil vente på deg. Yeah. STUDENT 14: Du må lese fra den første filen? JASON Hirschhorn: OK. STUDENT 14: Eller vi bruker fscanf eller noe sånt som at den første filen? JASON Hirschhorn: Så vi ønsker å lese fra den første filen og - la oss sette det riktig her. Lese fra kildefilen. Og så, hva skal vi gjøre etter at vi lese fra kildefilen? Noen andre? STUDENT 15: Skriv inn målfilen? JASON Hirschhorn: Vi skriver til målfilen, og - OK. Hva annet skal vi mangler? Noen andre som ikke har gitt meg en linje med kode ennå - av pseudo. Yeah. STUDENT 16: Kanskje kan du alltid sjekke om det er noe å lese for, som neste linje? Det er som den neste linje, se om den finnes. [ELEKTRONISK BEEP] JASON Hirschhorn: Oops. Det er min journalføring programvare. Yeah? STUDENT 16: Yeah. JASON Hirschhorn: Så gi det til meg en gang til. STUDENT 16: Sjekk om det er fremdeles en neste linje fra kildefilen å lese. JASON Hirschhorn: OK. Så vi ikke leser linjer - leste bytes her - men du er korrekt. Vi ønsker å lese og skrive til er det ingen flere byte. OK. Og så disse bør virkelig være innrykket litt, fordi de er under der. Høyre? Inntil vi er ute av bytes, skal vi lese fra kildefilen og skrive til mål-fil. Og så, hva er den siste linje av pseudo? Noen som ikke er gitt meg noe ennå. STUDENT 17: Lukk filene? JASON Hirschhorn: Nettopp. Lukk filene. Så det er vår pseudo. Jeg kommer til å sette pseudo inn gedit, og i et par minutter vi vil kode dette sammen. OK. La oss komme i gang som en gruppe. Nishant, har jeg min nye filen. Jeg har nettopp åpnet dette opp. Untitled Document en. Hva er det første jeg bør gjøre? Nishant: Inkluder bibliotekene? JASON Hirschhorn: OK. Hva bibliotekene? Nishant: stdio.h, stdlib.h, tror jeg? JASON Hirschhorn: OK. Hva er stdlib for? Nishant: Jeg glemte. JASON Hirschhorn: OK. Så inkluderer stdio. Hva bør jeg gjøre selv før Jeg starte koding? Nishant: Skriv en header? JASON Hirschhorn: Hvordan kan jeg få det farget? [interposing VOICES] Nishant: Hvordan får du det farget? JASON Hirschhorn: Hvordan kan jeg farge koding? Nishant: Jeg vet ikke. Oh. Lagre. JASON Hirschhorn: Save. Ja. Jeg skulle lagre det som en. C.. Så lagre den på skrivebordet som cp.c. Søt. Og hvis jeg ønsker å få full stil poeng, hva skal jeg omfatter på toppen? Nishant: Du kan skrive navnet ditt, navnet av programmet, og formålet av programmet også? JASON Hirschhorn: Ser bra ut. Utmerket. Så du har startet oss perfekt. # Include - Vi vil også skrive - OK. Så jeg tror jeg er klar til start. Hvem har den første linje med kode for meg - eller de første linjer med kode som det vil ta å tilfredsstille vår første kommentere i pseudokode? Du. STUDENT 18: Burde ikke det være int argc, og deretter char * argv? JASON Hirschhorn: Jeg tror du har rett. La oss endre det til int viktigste, åpne paren, int argc, komma, char * argv? Sånn? STUDENT 18: Brak. JASON Hirschhorn: Brak. Åpen brakett, nær brakett, nær forelder. Perfekt. Nå kan jeg ta kommandolinjeargumenter. OK. Sikre at vi får to filer. Du kan gi meg det også. STUDENT 18: Hvis argc - dette ikke lik tre. JASON Hirschhorn: Hvis åpne paren argc ikke lik 3? STUDENT 18: Ja, kommer du tilbake 1 eller noe. JASON Hirschhorn: Beklager. STUDENT 18: Return 1 eller noe. JASON Hirschhorn: Return 1. OK? Flott. Åpne begge filene. Hvem kan hjelpe meg å åpne begge filene? Hvem har ikke gitt meg koden ennå? Kurt? KURT: Så alle caps F-I-L-E Star kilde. JASON Hirschhorn: Jeg kommer å ta ut vokalene. De er kule. Det er som Tumblr. STUDENT 18: Er lik fopen - JASON Hirschhorn: Er lik fopen? STUDENT 18: Åpne paren, argv, åpen brakett. JASON Hirschhorn: Vent. Unnskyld. Åpen paren. OK. STUDENT 18: Yeah. Argv sub en. JASON Hirschhorn: Sub 1? STUDENT 18: Yeah. Argv åpen brakett 1 - Ja. Og så komma, og deretter åpne dobbel sitat, r, dobbelt anførselstegn, nære paren, semikolon. JASON Hirschhorn: Søt. Og hva med den andre? STUDENT 18: Svært lik, men i stedet av S-R-C, vil du kalle det d-S-T. JASON Hirschhorn: Oo! Jeg liker det. STUDENT 18: Just D-S-T. Yeah. Og så ARGV, åpen brakett, to. Yeah. Og deretter w istedenfor r. Yeah. JASON Hirschhorn: Great. Neste par linjer. Også, hvis noen har ting å legge til linjer som vi har gjort, gjerne legge dem også. Kontroller at ingen av dem er NULL. Hvem kan gi meg koden jeg trenger for å tilfredsstille den linjen av pseudo? Archer. ARCHER: Hvis src tilsvarer likemenn NULL eller dst tilsvarer likemenn NULL, så du kommer tilbake - JASON Hirschhorn: Hva? ARCHER: Return to? JASON Hirschhorn: Return to. Så hvis åpen paren src lik lik NULL, eller - hva som thing's - rør? Pipe? Vi kaller det røret. Pipe, pipe, dst tilsvarer likemenn NULL, tilbake to. OK? Inntil vi er ute av byte - vi liksom hoppes over dette trinnet fra den pseudo del å gå på her. Men før vi er ute av byte - hva høres det ut? Hvilken type C struktur - men jeg bruker ikke ordet struktur, fordi vi kommer til å begynne å bruke som i andre tilfeller - men C verktøyet gjør det høres ut som? STUDENT 19: En løkke. JASON Hirschhorn: En løkke. Høres ut som en sløyfe. Så hvem kan gi meg den første linjen av loopen koden rett her? Du kan også velge hva slags loop du vil, hvis du gir meg denne linjen med kode. Det er tre typer. Du får velge. Jeg ville foreslå en av dem. Avi. Hvilken vil du ha? AVI: FOR. JASON Hirschhorn: FOR. AVI: int i lik null. JASON Hirschhorn: OK. AVI: Denne delen er jeg ikke sikker på. Men i er mindre enn størrelsen av stjerne kilde? Jeg er ikke sikker på det. JASON Hirschhorn: OK. AVI: Fordi du vil at størrelsen på en fil, ikke sant? JASON Hirschhorn: Så dette sannsynligvis ikke vil gi oss størrelsen av selve fil i byte. Så hva annet kan vi gjøre? Hva er en annen type løkke? Eller skal vi feste med for loop? STUDENT 20: Kan du gjøre en while-loop? Og så, hva du vil gjøre, er Hvor sterkt - fordi vi har en char * for filen. Så hvis vi bare fortsette å øke verdien for at inntil vi ville finne den NULL tegn på slutten av den? Eller nei, det er ikke hvordan filene fungerer? JASON Hirschhorn: Så vi kan holde økes røye * til vi finner NULL - STUDENT 20: I hovedsak holde det gående tegn for tegn til vi treffer slutten av filen. JASON Hirschhorn: Ja. Så det er det vi ønsker å gjøre. Vi ønsker å holde lesing, karakter av karakter, før vi kommer til slutten av filen. STUDENT 20: Yeah. Finn - hva er slutten eller stoppskilt ved enden av en tekstfil. JASON Hirschhorn: OK. Så når vi kommer til slutten av filen - hvordan vet vi vi har nådd enden av en fil? Hvis jeg ringer - så la oss ta et skritt tilbake. Hva er en funksjon? La oss gå til denne linjen her. Lese fra kildefilen. Hvem kan gi meg den linjen med kode? STUDENT 21: Fscanf? JASON Hirschhorn: Fscanf. OK. Hva om jeg ønsker å lese, veldig spesielt, en byte? STUDENT 21: Jeg vet ikke. JASON Hirschhorn: OK. Enda enklere enn fscanf - hva er en - Jeg ønsker å lese fra en kilde fil? Les fra en kilde fil. Hva er en funksjon - ja. STUDENT 22: Det er fread? JASON Hirschhorn: fread. Jeg tror la oss holde fast med at en for nå. Hva slags argumenter tar fread? STUDENT 22: Trolig filtype, og deretter plassering i fil? JASON Hirschhorn: Hva kan jeg skrive her å finne ut hva slags argumenter fread tar? FLERE STUDENTER: Man fread. JASON Hirschhorn: Man fread og fwrite. Ser ut som de henger ut sammen. Så fread tar hvor mange argumenter? STUDENT 23: Fire. JASON Hirschhorn: Det tar fire argumenter. Det tar en peker, en størrelse, og at ting, som er rare, og noen fil. OK? La oss lese om det her. "Funksjonen fread leser n medl. elementer av data, hver størrelse bytes lang, fra bekken påpekt av streame, lagre dem på stedet gitt av pekeren. " Så fire argumenter. Hvorfor kan jeg ikke bare kopiere dette, og lim det rett her. OK. Så hvem kan begynne å fylle ut disse argumentene for meg? Avi. AVI: Ta ut tomrommet. Sett bare src. Ta ut pekeren og stjernen. Sett src. Så - JASON Hirschhorn: Så jeg kommer til å slutte du det, fordi det er feil. Du har rett med src, men hvor skal src gå? [interposing VOICES] JASON Hirschhorn: Det bør gå over her. Det er src - vår src er en type. La oss se her. Dette er å be om en type fil *, vi faktisk vanligvis ser dem sånn. Så dette er å be om et argument for skriver FIL * kalles bekk som er src. OK? Hva størrelsen på ting å gjøre vi ønsker å lese? Jeg ga deg dette i problembeskrivelse. STUDENT 24: En byte om gangen. JASON Hirschhorn: En byte. Hvor stor er en byte? Størrelsen er i bytes, så hva kan jeg sette akkurat der? STUDENT 25: One. JASON Hirschhorn: One. Høyre. Størrelsen er i enhet byte, så en er en byte. Hvor mange ønsker jeg å lese på en gang. STUDENT 26: One? JASON Hirschhorn: En ting. Jeg ønsker å lese en ting av størrelse 1, en bit av gangen. Og hvor kan jeg si det, når jeg leste det? STUDENT 27: Destination? JASON Hirschhorn: Så jeg kan ikke sette det rett inn i målet. STUDENT 28: Du skal sette det inn i en tredje peker? STUDENT 27: Til bestemmelsesstedet. JASON Hirschhorn: OK. Yeah. STUDENT 29: Du kan erklære noe å virke som en midlertidig lagrings tidligere. JASON Hirschhorn: OK. Gi meg den. STUDENT 29: En annen fil pekeren, kanskje? JASON Hirschhorn: OK. Så dette er ugyldig stjerne - det er en type ugyldig stjerne, så det gjør ikke ikke å være en filpekeren. Og hvis jeg leser en byte, hvor ville være et godt sted å lagre en byte? STUDENT 29: En rekke? JASON Hirschhorn: En matrise. OK. Og hva annet er noe som er bare størrelse ett byte? STUDENT 30: En char *? STUDENT 29: Yeah. JASON Hirschhorn: En char * er ikke en byte. STUDENT 29: En røye. JASON Hirschhorn: En røye er én byte. Høyre? Så la oss kalle denne bufferen er en generisk navnet som brukes for disse tingene til å lagre noe midlertidig. Så lager jeg en buffer. Høyre? Men det tar et tomrom *. Så kanskje du har rett, at det bør være en buffer av størrelse 0. Så den lagrer ett - høyre. Fordi dette her - røye buffer er en karakter, men dette tar et tomrom * - en peker. Så jeg kunne gjøre dette og nå buffer er en peker. Hva annet kunne jeg gjøre? STUDENT 31: Sett en stjerne ved siden av røye. JASON Hirschhorn: jeg kunne har skapt det char *. OK. Hva er en annen ting jeg kunne gjøre? Eller la oss gå med denne. Char * buffer, så hva setter jeg inn her? STUDENT 31: Buffer. JASON Hirschhorn: Buffer. Buffer er en peker til en char. Og med denne plasseringen, vi setter en byte av noe vi har lest. Yeah. Avi. AVI: Bare en rask spørsmål. Ønsker du å malloc buffer? JASON Hirschhorn: Hvem kan svare på det spørsmålet? STUDENT 32: Vel, det gjør egentlig ikke punkt til noe akkurat nå, så - JASON Hirschhorn: Men gjøre vi ønsker å malloc det? STUDENT 32: Hvis du skulle gjøre det som måte, tror jeg, ja, fordi du trenger et sted for det å peke på. JASON Hirschhorn: Har vi må malloc det? STUDENT 33: Hvis du kommer til å bruke den utenfor løkken. JASON Hirschhorn: Skal vi bruke den utenfor løkken? STUDENT 34: Ja. STUDENT 35: Vent. Ønsker vi å erklære det i loopen til utover? JASON Hirschhorn: Så jeg tror vi har noen pseudo mens loop her at vi er prøver å finne ut, at vi har ikke fått til ennå. Vi trenger ikke å malloc det. Vi opererer i hovedsak er det bare å gå som skal brukes inne i denne sløyfen. Det trenger ikke å eksistere på utsiden av denne. Så det kan være en lokal variabel. Du har en peker til en lokal variabel. STUDENT 36: Men det er ikke peke på noe. JASON Hirschhorn: Nei, det er ikke initialisert til noe. Men vi kommer ikke til å bruke det også. Vi kommer til å sette noe i det første gang vi bruker den. Så det virker OK. Så vi trenger ikke malloc her. Og jeg tror det er OK som den er. OK. Vi har fread linje. La oss gjøre neste linje. Hvis vi ønsker å skrive til en fil, hva er en god funksjon for å bruke for å gjøre det? STUDENT 37: fwrite? STUDENT 38: fprintf? JASON Hirschhorn: fprintf er ett. Hva er en annen en? STUDENT 39: fwrite. JASON Hirschhorn: fwrite. Og for vårt formål, fwrite, som vi så her, er sannsynligvis et bedre valg. Det tar fire argumenter også. Nishant, kan du gi me argumentene? Nishant: Den første kommer å være bare buffer. JASON Hirschhorn: OK. Nishant: Den andre ens bare kommer til å bli en. Tredje man kommer til å bli en. Og den fjerde kommer til å være dst. JASON Hirschhorn: Er det noen som har spørsmål om den linjen? Det ser bra ut. OK. Så nå ser det ut som den ene tingen vi er mangler - faktisk, la oss skrive denne siste linjen. Lukk filene. Hvem kan fullføre oss opp skriftlig disse to siste linjene? Ja. Sorry, hva heter du? LUCY: Lucy. JASON Hirschhorn: Lucy. LUCY: fclose src og deretter fclose destinasjon. JASON Hirschhorn: fclose, åpen paren, src, nære paren, semikolon. Og fclose - ja? LUCY: Åpen parentes, dst og deretter semikolon. JASON Hirschhorn: Great. Og hva bør jeg ta med på slutten? LUCY: Return 0. JASON Hirschhorn: Return 0. Må jeg? Bare et spørsmål. Må vi være avkastning 0? FLERE STUDENTER: Nei. JASON Hirschhorn: Nei. Hoved gjør det automatisk hvis du kommer til enden. Men jeg synes det er hyggelig å inkludere det eksplisitt. Spesielt når vi er tilbake andre ting gjennom hele programmet. OK. Dette er hva vi mangler - MENS hva? Hvem kan tenke på noen - har noen følelse av hva ting kunne gå inn der? Selv om det er bare i noen pseudo som språk? Hva er vi egentlig - hva ønsker vi å gå til? Ja, Lucy. LUCY: Slutten av filen. JASON Hirschhorn: Enden på filen. Så hva mener du med slutten av filen? LUCY: Når du kommer til slutten av filen, stopp. JASON Hirschhorn: OK. Så når vi kommer til slutten av filen. Hvordan vet vi når vi har nådd slutten av filen? STUDENT 40: Jeg tror buffer vil bli satt til NULL. STUDENT 41: Buffer erklæres innenfor sløyfen. JASON Hirschhorn: Så du tror buffer vil bli satt til NULL. Hvorfor skulle buffer settes til NULL? STUDENT 40: Fordi når du fread, du prøver å sette ingenting i buffer. JASON Hirschhorn: OK. Så du tenker fread - når vi har nådd slutten av den fil, hva er fread kommer til å gjøre? Jeg tror det er spørsmålet vi må finne ut. Hva fread gjøre? Betyr det sette NULL i buffer, eller gjør den noe annet? Hvordan kan vi finne ut hva det betyr? STUDENT 42: Man. JASON Hirschhorn: Man. Så la oss se over her. Returnere verdien. På suksess, fread og fwrite returnere antall elementer lest eller skrevet. Dette tallet tilsvarer antall byte overføres bare når størrelsen er en. Hvis det oppstår en feil, eller slutten av filen er nådd, er returverdien en kort teller element eller 0. Så for vårt formål, hvis fread delene slutten av filen, og leser fra slutten av filen, det er ingenting igjen å lese, hva kommer det til å komme tilbake? STUDENT 43: Zero? JASON Hirschhorn: Hva? STUDENT 43: Zero? JASON Hirschhorn: Zero. Det kommer til å returnere null. Så vi vet at fread, når vi har nådd slutten av filen, går for å gå tilbake null. Hvordan kan vi bruke det til vår fordel? AVI: Du kan erklære en variabel utenfor av sløyfen kalt sjekken. Hvis sjekken er lik - for nå - ett. JASON Hirschhorn: OK. AVI: Og så kan du sette en IF uttalelse rett etter fread si hvis fread lik null - no. JASON Hirschhorn: Hvem kan hjelpe Avi ut? AVI: Hva er verdien returnert av fread? JASON Hirschhorn: Vi bare gikk over det. AVI: Hvordan kan du representere det? JASON Hirschhorn: Så det vender tilbake - la oss se opp her - det gir en size_t, som i hovedsak er et helt tall. Så det returnerer et heltall. Og i vårt tilfelle, vil det returnere en eller 0 - 1 hvis det lese én ting - én byte, og 0 hvis vi har nådd slutten. Så hvis fread - ja? STUDENT 45: Kan ikke du bare sette den fulle fread (buffer, 1, 1, src) i mens loop? JASON Hirschhorn: Så du foreslår gjør dette til det? [interposing VOICES] JASON Hirschhorn: Hold ut. Så vi ridding av det. Så du foreslår å sette fread inn der? Hva bør vi også flytte Hvis du ønsker å gjøre det? STUDENT 45: Buffer utenfor. JASON Hirschhorn: Vi bør også flytte dette her ut. STUDENT 45: Men gjør det stadig flytte den frem? [interposing VOICES] JASON Hirschhorn: OK. Så dette er hva Okshar foreslått. Vi skaper vår buffer. Vi MENS fread, så vi fwrite. Tanker om dette? STUDENT 46: Min eneste spørsmålet er, ville det faktisk utføre kommandoen fread? JASON Hirschhorn: Great spørsmål. Når du setter et funksjonskall innsiden av en tilstand, gjør at funksjon samtale utføre? Vi har sett eksempler på dette før. Høyre? STUDENT 46: OK. Yeah. Så det gjør utføre. JASON Hirschhorn: Vi har sett ting sånn før, hvor vi har en funksjon samtale inne i en tilstand. Betyr at funksjonskall utføre? Ja. Så svaret er ja. Denne funksjonen kaller vil utføre. Men igjen, det er det vi vil? Hva er en måte vi kunne finne ut om det er det vi vil? FLERE STUDENTER: Kjør det? JASON Hirschhorn: Vi kunne kjøre den. Men før vi gjør det, vi kunne også resonnere gjennom dette. Hvis - si at vi har én byte i vår fil, vi får til her, vi får til denne koden. Dette vil kjøre. fread kommer tilbake en byte og lagre den i bufferen. Og dette vil evaluere til en, retten, etter at han returnerer en. Så mens en. Betyr det at koden inne mens loop vil utføre? STUDENT 47: Yeah. Det er sant. JASON Hirschhorn: Ja. 1 er sant. Det er ikke 0. Så koden inne her vil utføre. Så vi skal skrive det. Vi vil flytte tilbake til dette linje igjen. Nå har vi - vi er på slutten av vår fil. Vi har lest fra slutten av filen, fordi vi bare hadde én byte i det. Fread returnerer 0, butikker noe i buffer. Jeg vet ærlig talt ikke hva den lagrer i buffer. Vi kunne sikkert slå opp for å se hva den gjør. At jeg vet ærlig talt ikke. Vi vet ikke, hvem bryr seg om hva den lagrer i buffer? Men det kommer tilbake 0. Og vil mens 0 utføre? MENS 0 vil ikke utføre. Så da vil vi flytte ned her. Så la oss få en håndsopprekning om dette er koden vi skal kjøre, eller om vi bør gjøre endringer først. Så hvis du tror - har du til å stemme. Hvis du mener vi bør kjøre denne koden som det er, kan du heve hånden. OK. Det er ett - har du et spørsmål, bekymring? Yeah. STUDENT 48: Etter at vi flytter buffer utsiden av sløyfen, gjør vi må malloc det? JASON Hirschhorn: Great spørsmål. Etter at vi flytte buffer utenfor loop, har vi å malloc det? Dette er et omfang spørsmål. Hvis vi initial buffer utenfor av denne sløyfe, vil det eksistere innsiden av løkken? FLERE STUDENTER: Ja. JASON Hirschhorn: Ja. Dens omfang dekker innsiden av løkken, og, egentlig, noe under det inne av denne kode, herunder ting inni her. Så vi trenger ikke å malloc det. Det er en lokal variabel, og dens omfang fremdeles inneholder sløyfen. STUDENT 49: Trenger vi å frigjøre det? JASON Hirschhorn: Har vi trenger å fri buffer? STUDENT 49: Ja, hvis vi ikke gjør det malloc. JASON Hirschhorn: Har vi trenger å fri buffer? Vi gjør ikke det. Igjen er det en lokal variabel, slik at vi ikke trenger å frigjøre den. OK. La oss se hva som skjer. Så det er initialisert. Det var det noe som Marcus foreslått tidligere. Så vi har denne feilen, variabel buffer er ikke-initialisert når det brukes her. Hvordan kan vi løse dette? STUDENT 50: malloc det? STUDENT 51: Er lik NULL? STUDENT 52: Si buffer lik NULL. JASON Hirschhorn: OK. Ser bra ut. Vi har det nå. La oss skape noe for å prøve å kopiere. Så vi har vår tekstfil. Hvordan kan vi kjøre dette programmet? Yeah. STUDENT 53: Du kan gjøre prikk slash cp, test.txt. Og så kan du nevne en annen fil som det vil lagre inn. JASON Hirschhorn: OK. Vi kaller det out.txt. Cool? Seg feil. Tanker om SEG feil? Dette er flott. Hvordan kan vi finne ut hvor SEG feilen er? Hva? STUDENT 54: GDB. JASON Hirschhorn: GDB. Vi kjører gdb ved å skrive gdb dot slash, navnet på programmet vårt. Ingen kommandolinjeargumentene der. Vi kommer til å sette en stoppunkt på hoved. Hvis jeg ønsker å starte gdb, hva gjør jeg? STUDENT 55: R. JASON Hirschhorn: R. Og hva så? STUDENT 55: Argumentene? JASON Hirschhorn: Da kommandolinje-argumenter. La oss gå gjennom. N er bare å ta meg linje for linje. Jeg kommer til å gå til Jeg får min SEG feil. Det er min SEG feil. Det ser ut som fread forårsaket min SEG feil. Jeg vet fread forårsaket min segmentet feil, fordi det var den linjen vi bare henrettet. Og det eneste som var skjer i den linjen - to ting skjedde. Fread skulle, og da vi var gjøre noen mens du sjekker. Jeg er villig til å satse på at den MENS sjekker var ikke årsaken til segmentet feil. Mest sannsynlig, var fread forårsaker min SEG feil. Jeg ser også noe her, memcopy. Minne kopi. Høres ut som du flytter minne fra ett sted til et annet. Høres ut som noe som ville skje i fread, kanskje noen minne flytte herfra til her. La oss gå gjennom dette igjen. Hvordan starter jeg den over og kjøre den på nytt? Yeah. STUDENT 56: Har du behov for å sette -tegnet før buffer? JASON Hirschhorn: Så Ampersand før buffer ville gi meg adressen til buffer, noe som er en char *. La oss kjøre gjennom dette en gang til. Hvordan kjører jeg gjennom det en gang til? STUDENT 57: Kan du bare skriver kjøre igjen? JASON Hirschhorn: Bare skriv løpe igjen. Så vi kommer til å utføre denne linjen. Så buffer er en NULL-peker. Korrigere? Det peker på - la oss se. Hvis vi har vår - tegne et raskt bilde av dette. Alle kan se om Jeg skriver over her? Så i bunken, har vi en lokal variabel og det heter buffer, og det er en peker til en char. Hvilken adresse er dette røye på? STUDENT 58: 0x0. JASON Hirschhorn: Høyre. Det er det dette er. I her, inne buffer, lagres 0x0. Det er det vi har - setup vi har akkurat nå. Så denne linjen, fread, setter noe fra kilden der? Inn i denne boksen eller denne boksen? Hvilken boks? Venstre boks eller høyre boksen? Denne retten boksen. Det følger pekeren, og setter det inn her. Når vi prøver og touch-minne på plassering 0, hva får vi? En segmenteringsfeil. Det er den feilen vi har akkurat nå. Yeah. STUDENT 59: Har du ikke å sette stjerne buffer? Eller nei? For fread? JASON Hirschhorn: Så fread tar en peker. Så det går i buffer. Og så får det de-referanse det et eller annet sted inne fread. Men igjen, vi så, det tar en peker. Vi trenger ikke å passere det stjerne buffer. Det ville være bestått det det som er her. Og det ville trolig gi oss en feil fordi vi er de-referering det. Høyre? Når vi de-referansen denne pekeren, når vi prøver å få tilgang til dette stedet, vi får en feilmelding - vår segmentering feil. Så - oops. Vi kommer til å slutte ut av gdb. Vår linje - vårt problem - er riktig her på denne linjen. Og det er et problem fordi av denne linjen. Hvordan kan vi skape en boks som er tilgjengelig i fread. Høyre? Vi trenger å skape en boks som er en byte stor, på størrelse med en røye. Men vi trenger den boksen til å være tilgjengelig når denne funksjonen utfører. Så der - ja. Noen ideer? STUDENT 60: Bare sett det som noe tilfeldig karakter. Bare gjør char buffer likemenn tegnet. Og så, når du har buffer der - JASON Hirschhorn: Vent. Char buffer? Så ingen stjerne? STUDENT 60: Yeah. Ta ut stjernen. Tilsvarer en tilfeldig karakter. JASON Hirschhorn: OK. Så gi meg en. STUDENT 60: Like a eller noe. Og så når du har buffer det, bruker du en - STUDENT 61: Star? Å nei, tegnet. STUDENT 60: Bruk tegnet. JASON Hirschhorn: OK. Og hva om i fwrite? STUDENT 60: Bruk tegnet på nytt. JASON Hirschhorn: Greit. Så ideen din er, vi skaper en røye og putte noe i den, og deretter skrive til at røye. STUDENT 60: Yeah. JASON Hirschhorn: Hva tror folk? STUDENT 62: Det er innviklet. JASON Hirschhorn: OK. La oss trekke den ut. Så denne gangen, kommer jeg til å trekke dette i rødt på stakken her, og da vi vil ha - ooh! Unnskyld. Så denne gangen har vi noe som heter buffer, og det er på stakken. Korrigere? Og vi sparer på det en, i utgangspunktet. Da har vi vår oppfordring til fread. Hva fread ikke er det tar en byte fra vår og plasserer den et sted. Det setter det i uansett ting peker til. Vel, før vi hadde denne adressen - 0x0. Nå hva adressen har vi? STUDENT 63: Uansett adresse buffer er. JASON Hirschhorn: Uansett adresse buffer er. Det er trolig kommer til å være noe sånt. Sannsynligvis kommer til å starte med en b og en f, og deretter ha seks andre heksadesimale siffer. Spiller ingen rolle. Noen adresse. Og vi passerer den adressen i. Og vi kommer til å sette vår ett byte ting på denne adressen. Så vi kommer til å sette vår ett byte ting inni her. Og så kommer vi til å skrive fra hva er stadig inne her. Er det noen som har noen spørsmål om det? Hvem mener denne koden vil fungere? Rekk opp hånden hvis du tror denne koden vil fungere. Du må ta et standpunkt. Og som mener denne koden ikke vil fungere? Rekk opp hånden. Alle andre bør være heve sin hånd. OK. Michael, hvor står du? MICHAEL: Jeg kan ikke bestemme. Slags i midten. JASON Hirschhorn: Du er i midten. Plukk en. MICHAEL: Jeg har tro og sier at det vil fungere. JASON Hirschhorn: OK. Du må tro og si det fungerer? Hva har skjedd? [interposing VOICES] JASON Hirschhorn: Ingen segmentet feil. Hvordan kan vi sjekke for å se om to ting er like? To filer er like. STUDENT 64: Diff. JASON Hirschhorn: Diff. Diff sjekker for forskjellene mellom to filer, og hvis den returnerer ingenting, de er identiske. Og hvis vi åpner opp, får vi vår fil. Så var den riktige løsning. La oss se tilbake på det en gang. Vi gjorde faktisk ikke engang må initialisere det. Det vil trolig se en bit renere hvis du ikke har satt noe tilfeldig i det. Poenget er, du trengte å lage noen plass til å lagre noe fra fread og ta noe ut av fwrite. Og at ting måtte være enten en lokal variable på stakken - du kunne har malloc'd noen plass. Slik at vi faktisk kunne ha skrevet malloc her, og som ville ha fungert. Og så ville vi ha vært lagring våre ting et sted på haugen. Men dette er faktisk, sannsynligvis, den mest elegante løsningen. Bare lage litt plass på stakken for disse tingene til å gå. Jeg ville ha to andre kommentarer. Hvis du var å ta igjen i dette, og deretter få scoret på dette, mine kommentarer ville være som følger. Disse en er her, til meg, se som magiske tall. Dette 1, i form av fread, er fornuftig. Det er flere ting å lese eller skrive. Men dette her bør sannsynligvis være noe annet. Så hva er en løsning? STUDENT 65: Størrelse på byte. JASON Hirschhorn: Sånn? STUDENT 65: Størrelse på røye. JASON Hirschhorn: Størrelse på røye. Ja, er byte ikke en type. Så størrelse på røye verk. Vi kan ha, på toppen av vår kode, # definert som. Heter noe BYTE og det er virkelig en røye. Egentlig en enda bedre tilnærming kan ha vært dette - UINT. Noen som vet hva det er? Unnskyld. Jeg har det bakover. Vent, nei. Hvilken vei går den? Noen som vet hva det er? Yeah. STUDENT 67: Ment for å hjelpe standardisere tvers av systemer ting som har - som usignerte heltall som har 8 byte? JASON Hirschhorn: Det er helt riktig. På forskjellige maskiner, på størrelse med en char - vanligvis ikke en røye. Tegn er vanligvis én byte. Men størrelsen på andre datatyper er forskjellige størrelser på en 32-bits maskin versus en 64-bits maskin. En uint8_t er alltid 8 bits - alltid én byte. Og jeg må ta med at standard int header-fil. Så nå, dette ville sannsynligvis vært den beste måten å skrive denne koden. Så jeg kvitt de magiske tall. Og jeg har også en mer logisk skriver for buffer. Det er ikke bare en røye, det er en byte, som er hva vi forventer at det skal være. Og her oppe, har vi faktisk vært litt mer robust. Vi kommer ikke kalle det en røye, som - kanskje, hvem vet - kan være en annen størrelse på forskjellige maskiner. Vi er faktisk sier dette er akkurat én byte, alltid, uansett hva. Og hvis vi ser her, gjør vi cp. Uh-oh. Hva har skjedd? STUDENT 68: Det kan bli slått. JASON Hirschhorn: Hva? STUDENT 69: Er det? STUDENT 70: Du gjorde ikke definere det som en type. STUDENT 71: Men det skal være definert i standarden. STUDENT 72: Hva er det som skjer? STUDENT 73: Bør definere være alle caps? JASON Hirschhorn: Så det er ikke # define. Egentlig, i dette tilfellet, er jeg kommer til å bruke typedef. Fordi vi bruker det som en type på ett sted. Så i dette tilfellet, vi faktisk ønsker å typedef som vi skriver ut en ny type byte, og det er, i det vesentlige, av dette. Det er litt annerledes enn # define. Og nå, vår koden fungerer perfekt. Så, igjen, # define tar noe, erstatter det overalt med andre ting. Det er bare en makro - stenografi for å kvitte seg med magiske tall. Men i dette tilfellet, fordi vi er bruker den som en type - akkurat her - for at det skal fungere, trenger vi å typedef uansett byte er. Og vi definerer det her. Det er ikke en struct, det er faktisk bare et usignert heltall. Det er én byte lang. Denne koden vil være tilgjengelig på nettet, og dere alle skal ha det akkurat nå. Så vi har - perfekt - 13 minutter igjen å gå løpet problem satt fem. Jeg ønsker å gå gjennom copy.c sammen, og så skal vi snakke kort om de andre deler av problemet definert. Så la meg trekke opp copy.c. Og det kule er, vi har faktisk allerede skrevet mye av denne koden. Koden vi skrev bokstavelig talt bare kom ut av her da jeg var skriver dette på min egen. Men dette er copy.c, danner grunnlaget for de to første delene av oppgavesettet for whodunit.c, som du trenger for å skrive, og resize.c. Recover.c, som er den tredje og siste en del av problemet sett, ikke er basert off av denne filen. Du kommer til å trenge å skrive denne filen, Vi gir deg en mal for at fil, men det har ingenting å gjøre med copy.c. Men fordi copy.c er grunnlaget for de to første delene, vi skal å gå gjennom det nå, så du har en god følelse av hva det gjør. Og kommentarene gi noe av det bort. Vi har allerede skrevet noe av dette. Først gjør vi sikkert vi får tre argumenter. Deretter skal vi huske filnavnet. Så vi hoppet over dette trinnet når kodet vi våre ting - når vår cp. Men her, de gjør det litt renere. De kontrollerer at begge filene er gode, i tillegg til å åpne dem. Vi skrev alt denne koden akkurat nå, så jeg er ikke kommer til å dvele ved denne koden. Neste er noen ting som er spesifikke for filtypene vi bruker, som er bitmap-filer. Bitmap-filer har noen metadata forbundet med dem. Så de første par bytes fortelle deg om filen. De er ikke fargene på pikselen i det bildet. De forteller deg om filen. Og hvis du leser gjennom problemet sett, vil du ha mye mer informasjon på hvilke typer metadata strukturer er inkludert med punktgrafikk. Men det er derfor vi har dette først satt av - denne koden her. Vi leser metadata - to stykker av metadata - Filen overskriften og informasjonen header. Og vi sjekker noen deler av det til sørge for at det er en sann bitmap fil før du fortsetter. Og igjen, dette er detaljer vi trenger ikke å gå inn nå. Hvis du leser gjennom problemet sett, du vil forstå disse. Lang historie kort, er disse bare si: dette er et bitmap-fil, og som bekrefter at. Neste, vi skriver dem til ut-filen. Vi ser at her. Vi skriver til ut pekeren. Neste, vi bestemme padding. Så igjen, er som PARTICULARITY med en bitmap fil, noen linjer inkluderer padding på slutten. Og hvis du leser gjennom problemet sett, du vil lære mer om padding. Dette er formelen for å finne padding. Viktig å huske - når du endrer størrelsen på et bitmap fil, stopp endringer. Når du endrer størrelsen på et fil, stopp endringer. Det kommer aldri til å bli større enn 3 - det vil være 0 gjennom tre, inkluderende. Men når du endrer størrelsen på noe, stopp endringer. Hvis jeg bare har ett piksel i den raden, jeg trenger tre byte med padding, fordi hver rad må være multipler av fire byte i en bitmap fil. Men hvis jeg doble det, å gå fra én piksel til to piksler, hvor hver av disse, la oss si, er en byte, så jeg trenger to byte med padding å gjøre som lik fire. Så når jeg endrer størrelsen på noe, Jeg må endre beløpet padding jeg har. Betyr det fornuftig for alle? Deretter iterere vi over hver rad, eller gjennom alle radene. Og da vi reagere gjennom hver kolonne i hver rad. Vi behandler dette bitmap som et rutenett, som vi har behandlet styret i 15.. Som vi behandlet mursteinene når vi trykket dem på skjermen. Et rutenett med rader og kolonner. Så - vi så dette. Vi har faktisk bare kodet dette. Vi skapte noen midlertidig lagring. Vi leser i det, og deretter vi skrive det ut. Dette er akkurat hva vi nettopp gjorde. Neste, fordi jeg sa hver linje ender i noen padding, vi hoppe over at padding - den gamle padding. Og så legger vi det tilbake. I dette tilfellet, skaper vi nøyaktig samme fil. Vi er bare å kopiere det. Så denne linjen er litt dumt. Vi kunne bokstavelig talt bare sette padding i. Men hvis du endrer størrelsen på filen, har du fortsatt ønsker denne linjen? Så hvis vi endre størrelsen på en fil, gjør vi fortsatt ønsker å hoppe over over den gamle padding? STUDENT 74: Ja. JASON Hirschhorn: Så vi gjør. Fordi dette, igjen, tilbud med kildefilen. Vi bryr oss ikke om padding fra kildefilen. Vi ønsker å gå til neste linje. Men vi har ikke bare satt tilbake den gamle mengde polstring. Vi trenger å sette tilbake ny mengde polstring. Så når vi endrer størrelsen på et fil, vi ønsker fortsatt å hoppe over padding i den gamle filen - hva vi leser i fra. Men hva vi skriver til, skal vi til å trenge å sette tilbake noen annen antall padding som vi har bestemt. Yeah. STUDENT 75: Rekkefølgen av disse to linjer spiller ingen rolle, ikke sant? Fordi du håndterer forskjellige filer. JASON Hirschhorn: Nettopp. Rekkefølgen av disse to linjene spiller ingen rolle. Vi skriver denne linjen. Dette er her for filen vi skriver til. Det er viktig, slik at vi får riktig mengde polstring. Dette har å forholde seg til i filen. Vi ønsker å hoppe rett over padding. Vi ønsker ikke å lese - hvis vi leser en byte om gangen, vi bryr seg ikke om de padding bytes. Vi ønsker å flytte til neste linje. Endelig akkurat som Lucy ga for oss, vi lukke filer og returnere 0. Så dette er copy.c. Og vi faktisk skrev - vi tilbrakte mesteparten av avsnitt skriver dette, egentlig. Du har gjort dette. Så forhåpentligvis du har en god følelse av hva som skjer her inne. Den store forskjellen, ærlig, er bare denne første delen som omhandler særegenheter bitmap-filer. Så jeg har som mitt neste lysbilde, hva trenger vi å gjøre? Vel, la oss tenke på whodunit. Og for noen som leser gjennom oppgavesettet, hva gjør vi trenger å gjøre i whodunit? Rett og slett. Aleja. Aleja: Kan du ta ut den delen av hver piksel som betegner rødt. Og så - slags? JASON Hirschhorn: OK. Så ta ut den delen av hvert pixel som betegner rødt. Det er tett, men ikke alle av det. STUDENT 76: Vel, det er forskjellige måter å gjøre det. JASON Hirschhorn: OK. Gi meg én måte. STUDENT 76: Ta ut alle de røde, og deretter understreke den blå og grønn. JASON Hirschhorn: OK. Så får begge disse måtene - det høres ut som vi gi den en piksel, det har en rød, blå og grønn nivå. Vi ønsker å endre den relative nivåer av de røde, blå og grønn, avhengig på at pixel. Hvor i denne koden skal vi endre den relative rød, blå og grønn nivåer i et gitt bildepunkt. Etter at vi har lest det - før vi skriver det? Gi meg den linjenummer. FLERE STUDENTER: 83. JASON Hirschhorn: 83. Så akkurat her. For whodunit, den koden du trenger for å write bør alle gå rett der. Og det er den eneste kode du trenger å skrive. Fordi, som vi har hørt, alt du trenger å gjøre er å endre disse relative blå, røde og grønne nivåer fra hver piksel. Du har lest det i, og nå er du kommer til å skrive det ut. Hvordan får jeg - hvis jeg har denne tingen kalles trippel, akkurat her, og det er av skriver RGBTRIPLE - vel, hvis vi så i bmp.h, hva er RGBTRIPLE? STUDENT 77: Det er en struct. JASON Hirschhorn: RGBTRIPLE er en struct. Vi ser at rett ned her. Og så hvis jeg ønsket å få tilgang til, si, rødt nivå av struct, hvordan gjør jeg tilgang til den røde nivået av denne strukturen? [KLASSE Murmurs] STUDENT 78: RGBTRIPLE.rgbtred? JASON Hirschhorn: Er det riktig? STUDENT 79: Det bør være trippel dot, i stedet for RGBTRIPLE dot? JASON Hirschhorn: Triple. Trippel er den lokale variable, så her, det er ingen pekere her. Så vi bare bruke dot notasjon. Dette vil gi me graden av rødt. Hvis jeg ønsker å endre det, jeg bare satt det lik noe annet. Så igjen, åpner denne linjen med kode denne variabelen inne i denne strukturen, og vi kan sette den til noe nytt. Så for whodunit, igjen, er dette, i hovedsak hva vi trenger å gjøre. Veldig enkelt. Bare endre noen relative nivåer, og det er her den koden går. Endre størrelse, på den annen side, er litt mer komplisert. Faktisk er skalerings sannsynligvis vanskeligste delen av dette problemet satt. Vi har tre minutter å gå over det. Men igjen, har vi allerede skrevet mesteparten av denne koden, så vi bør være ganske kjent. Hva er noen ting vi ønsker å gjøre i endre størrelse, hvis du har lest over oppgavesettet? Hvis du gir dem til meg, vi kan snakke om dem. Hva er noen ting vi ønsker å gjøre? STUDENT 80: Vertikalt - så du må horisontalt endre størrelse på det, men vertikalt endre størrelse på det også? JASON Hirschhorn: Så hvis vi får en pixel, og vi ønsker å endre størrelsen på det ved en faktor på to, den nå trenger å være skaleres horisontalt og skaleres vertikalt. Betyr det fornuftig? Yeah. Så det er trolig den største utfordringen. Og vi skal snakke om det i et sekund. Yeah. STUDENT 81: Måten jeg tenkte på det ble du trengte print den ut - JASON Hirschhorn: Vent. Ikke fortell oss hva du gjorde. Vi kommer til å snakke i logikk. STUDENT 81: OK. Hva var spørsmålet? JASON Hirschhorn: Du bare hevet hånden. Det var ingen tvil. La meg presentere det. La meg bare diskutere dette kort. Så vi har en piksel, vi ønsker å replikere den, både horisontalt og vertikalt. Så ideelt sett hva vi gjør her er, vi lese i vår pixel, skriver vi det imidlertid mange ganger. Men så har vi våre triks her, fordi så vi ønsker å hoppe til neste linje og skrive det på begynnelsen av neste linje. Så hvis vi ønsker å gjenskape både horisontalt og vertikalt, hva er en god måte å gjøre det - ett godt om å gjøre det? Så vi trenger ikke å stadig søke rundt vår fil å plassere ting. Det spørsmålet har kanskje ikke var fornuftig, men jeg tror en svarer til det vil hjelpe. STUDENT 82: Lag en array? JASON Hirschhorn: Så la oss tenke av hver fil som en rad. La oss tenke i form av rader. Hvis vi har vår første rad fra vår lille bilde, kan vi gjøre for at rad inn i en stor rekke av et stort bilde, og deretter gjenskape den raden imidlertid mange ganger det er behov for å bli replikert, snarere enn å gå piksel for piksel, som blir forvirrende når håndtere filer. Fordi hvis vi hadde - Jeg kjører tom for plass. Hvis dette er vår fil, og vi har som én piksel der, og vi ønsker å sette det rett der, vi har fortsatt noen ting at behovet for å gå dit når vi er å skrive og lage vår nye fil - vår fil som er dobbelt så stor. Men det er veldig vanskelig med filfunksjoner å hoppe rundt til nye linjer sånn, og så gå tilbake hit og sette ting i det. Det er nesten umulig å gjøre noe sånn, hvis det er fornuftig. Så hvis vi tenker i form av rader, kan vi ta vår rad, og deretter sette den - replikere rader vertikalt. Og det er hvordan vi håndterer resizing vertikalt i stedet for horisontalt. Det var litt rask, og litt forvirrende. Dessverre vår tid er ute. Jeg vil stå utenfor for de av dere her som har spørsmål om Oppgavesettet, inkludert gjenopprette. Så la oss utsette for nå. Og igjen, hvis du har noen spørsmål, vi kan prate utenfor.