JASON Hirschhorn: Välkommen, alla, till vecka 6. Jag är glad att se er alla lever och mår bra efter Quiz 0, för jag vet att var lite grov. Men tack och lov, ni alla gjorde otroligt bra. Och så det är underbart. Om du är i min avdelning, har jag gett mest om du säkerhets redan dina frågesporter. Ett par av er, jag träffa efter lektionen. Och om du är en förlängning student och du inte har fått din frågesport tillbaka Ännu är din TF förmodligen jobbar på det och examination det, och kommer att få tillbaka till dig inom kort. Så mina förlängnings studenter som är tittar just nu - förhoppningsvis leva - Jag kommer att få dina frågesporter inom kort också. Vår agenda för idag är följande. Först kommer vi att gå igenom några resurser som CS50 ger till dig. Vi kommer att gå över Quiz 0 nästa, och Jag ska svara på alla frågor någon har om särskilda problem. Och då kommer vi att gå över fil-I / O och problem set 5. De sista två ämnen kommer att ta upp den största delen av avsnittet idag. Jag sätter denna lista upp varje vecka som en påminnelse till er alla, men av kärnan avsnitt, vi har bara 90 minuter - vi inte kan täcka allt som jag skulle älska att täcka för er. Men vi har massor av resurser för dig att dra på som du lär känna materialet och arbetet genom ditt problem sätter. En påminnelse om att jag har nätet en text box, ställa upp för dig att fylla i om du har synpunkter för mig, både positiva och konstruktiv, om avsnitt. Den webbadress ligger här ända ner. Så snälla, ta en stund om du har någon feedback, vare sig under avsnitt, eller efter, eller efter att du titta på videon på nätet, för att ge mig din återkoppling. Jag uppskattar verkligen alla och allt. Så jag har haft små konversationer med en hel del av min eleverna under hela veckan - som jag lämnar ryggfrågesporter, talar om naturligtvis, att se hur du gör. Och ett tema har kommit över och över att tala om - i särskilt - Problemet ställer. Och jag har inkapslade det temat på bordet just nu. I huvudsak finns det en skillnad mellan att slå in något som är görs på rätt sätt och något det är gjort bra. De flesta människor har gjort fantastiska i fråga om korrekthet - 5 s eller 4 s på alla psets. De flesta människor blir dem hela tiden. Men bara för att du har gjort något rätt betyder inte att du har gjort något så elegant, eller effektivt, eller så rent som du kunde ha gjort det. Och det är vad designen - och i mindre grad, stil - axlar är för. Så jag skjuta er alla, och andra TF driver ni, att inte bara tur i saker som är rätt, men vänder på de saker som är kodade väl. Att inte göra onödiga FÖR loopar, inte räkna om variabler Om du behöver inte. Till exempel, ser tillbaka till problembild 4, när du placerar blocken på skärm, varje varv - varje tegelsten i en given rad har samma y-koordinat - samma höjd-koordinaten. Så att y-koordinaten inte behövde beräknas i det inre kapslade FOR loop som du troligen använt att sätta dessa tegelstenar på skärmen. Det behöver bara beräknas varje gången du slog en rad, eller flyttas ned en rad. Så att säga, om det finns 10 tegelstenar i en rad, kan varje tegelsten ha samma y-koordinat, och att y-koordinat kan bara beräknas en gång för alla av dem. Det behöver inte beräknas 10 gånger, inte heller denna beräkning behöver att hända i den färdiga funktionsanrop - den nya gracked samtalsfunktionen. Så om det var lite förvirrande för dig, mer allmänt, det som behöver inte ske varje gång du går igenom en FOR loop ska inte vara läggs innanför FOR loop, och bör inte händer varje gång du går genom FOR loop. Ett annat bra design exempel såg vi i vecka 3 för 15, skulle du kunna hålla spåret av noll. Så när du initierar styrelsen, du spara - i en global variabel, kanske - x-och y-koordinat för noll. Och sedan när du - i ditt drag funktion, när du gör ett lyckat drag, uppdatera dig på Placeringen av noll. Det skulle rädda dig från att behöva göra kapslade FÖR loopar att titta igenom ombord varje gång i ditt drag funktion och hitta noll, eller hitta kakel, och sedan kontrollera vad som händer med det. Istället har du platsen för noll, kan du bara se över, under, och till vänster och höger om det, för att hitta kakel du letade efter. Så när det gäller de program som vi är skriva, de är aldrig tillräckligt stor att vissa av dessa designbeslut verkligen kommer att hindra din program, eller göra det köras långsammare, eller kanske till och med slut på minne. Men vi är fortfarande driver er att skriva så elegant och effektiv kod som möjligt. Så om du sluta skriva saker som har en betydligt större omfattning, kommer de att skrivas med god utforma förutom att vara korrekt. Så många av er har förde det ut. Det är något som vi är ute efter - något som vi kommer att fortsätta att pressa er på. Om du någonsin har några frågor om den utformningen av ditt program, välkommen att nå ut till mig, och jag är glad att gå igenom ditt program med dig, och peka på några av konstruktionen beslut som du gjort, och ger dig några förslag på hur man gör med bättre designbeslut. Så vi kommer att gå vidare att prata om Quiz 0. Innan vi gör det, gör någon har några frågor om vad Jag har täckt hittills? [Prasslande NOISE] JASON Hirschhorn: Sju sekunder. OK. Låt oss tala om Quiz 0 för lite. De flesta av er har din Quiz 0 rygg. Om du inte gör det, förhoppningsvis du kommer ihåg det lite. Men om du har tagit Quiz 0, då du också ha tillgång till PDF-nätet i provlösning. Är det någon som har några frågor innan Vi hoppar in i veckans material om ett särskilt problem på Quiz 0 - varför svaret är vad det är? Är det någon förvirrad om vad som helst? Även om du fick problemet rätt, men bara vill att jag ska förklara det lite mer, jag är glad att göra det nu. Så jag har bett er att komma förberedda med några tankar om Quiz 0. Så vem skulle vilja få oss började med en fråga eller kommentera om Quiz 0? [PAPER PRASSEL] JASON Hirschhorn: Inte alla gjorde perfekt. Så jag vet [skratt] måste det finnas några frågor om Quiz 0. OK. Ja. Ompica. OMPICA: Number 10. JASON Hirschhorn: Number 10. Vilken var nummer 10? OMPICA: The - JASON Hirschhorn: Jag Har inte - OMPICA: Den omfattar - JASON Hirschhorn: Number 10 var åtta till i - att skriva åtta till jag? OMPICA: Ja. JASON Hirschhorn: OK. Så en annan fråga som du kan ha frågade var jag förutseende? Svaret är ja. I avsnitt innan testet, frågade jag ni att koda både Sterling och åtta till i.. Båda råkade visas på frågesport. Så förhoppningsvis, du betalat uppmärksamhet på det. Och om du hade, då du skulle ha förmodligen gjort väl på dessa två. Men åtta till mig, det gjorde vi faktiskt inte koden det i klassen, men det var, återigen, frågade på frågesport. Så ett par saker att ta notera när kodning åtta till i.. Det första, per den frågan, var att du behövs för att kontrollera om strängen var lika med noll. Ett par personer försökte kolla senare i programmet, om s fäste jag var - så ett visst tecken i det sträng - var lika med noll. Men kom ihåg, att null är väsentligt - det är bra att tänka på null som ett noll pekare - en pekare till noll - någonstans i minnet där du kan aldrig komma åt. Så om något är lika med noll, du vet att det inte har initierats, eller det finns inget där. Så s är en röding stjärna, s fäste i är en röding. Så det är klokt att jämföra s till null, men inte s fäste jag på null. Men återigen - så det var det första att du skulle göra - kontrollerar du att du faktiskt fick en riktig sträng. Därefter ville att du skulle gå igenom varje tecken i strängen. Och så det skulle vara som ett s fäste i, till exempel, om i är din iterator. Och ta det tecknet, och få sitt verkliga värde. Du har det lagras som en röding, men ASCII-värdet för noll - noll som en karaktär - är faktiskt inte heltalet noll. Det är något annat nummer som du kan slå upp i ASCII-tabellen. Så ett sätt att rätta till det - förmodligen det bästa sättet för att korrigera för som - är subtrahera från det teckenvärdet - noll som ett tecken. Så minus enda anbud, nolla, annan enda anbud. Det kommer att vidta de nummer du har som en röding, och få det lika med numret som en faktisk heltal. Och det är mycket lik den metod en massa människor tog i Problemet set 2, med Caesar och Viginere - dessa chiffer, när du var rotera dem. Så efter att du har det som ett tal från noll till nio, sedan - beroende på där det går i den slutliga antalet - du behöver för att multiplicera den med en kraft av 10. Vissa människor flyttade från baksidan till front, och multiplicerat den enskilde nummer genom en effekt på 10. Vissa människor flyttade från den framifrån och bakåt - och så tog den högsta beställa siffror först - och skulle spara dem i en global räknevariabeln. Och sedan varje gång genom FOR slinga, multiplicera det jätte globala motverka variabel genom 10, för att göra utrymme för nästa tecken. Så det var lite förvirrande utan mig att skriva det på tavlan. Men provlösningen är tillgänglig för dig. Men de var de stora sakerna vi sökte. Även en kontroll för att se till att varje särprägel var verkligen en karaktär mellan noll och nio, och inte något annat tecken, som en A, till exempel. Det var det vi var ute för i den frågan. Besvarar det din fråga? OMPICA: Ja. JASON Hirschhorn: OK. Finns det några andra frågor om Quiz 0? Hur är det att sammanställa? Alla sammanställa rätt? Nej. Det fanns en - [Skratt] Eventuella frågor om sammanställning process? Wow. [PAPER PRASSEL] JASON Hirschhorn: Ja. Michael. MICHAEL: Är nummer 7 - random? JASON Hirschhorn: Number 7. Nummer 7 var få ett slumpmässigt heltal. Utmärkt. Så du gett ett heltal a och en heltal b, och du vill ha en slumpmässig heltal mellan a och b.. Vi kan faktiskt skriva en på styrelsen, eftersom detta var en rad kod - ett sätt att göra det. Så vi gett drand som en funktion som vi skulle kunna använda. Och vad betyder drand - förutsatt att det har varit seedad - vad drand tillbaka? MICHAEL: En flottör mellan 0,0 och 1,0. JASON Hirschhorn: Ett nummer - ja. Ett tal mellan 0 och 1. Och så vi har b och en. Och sedan har vi vår slump mellan 0 och 1 ges till oss av drand. Vissa människor försökte sätta b, eller b minus a, eller något inom de parentes. Det skulle betyda att de är argument till denna funktion. drand tar inga argument - liknande getString gör inte tar några argument. Så det är bara öppna föräldra, nära Paren - och att det, i sig, är funktionsanropet. Och det ger dig ett nummer mellan 0 och 1. Naturligtvis har vi en hel rad att siffrorna kan vara i. Säg, om b är 10 och en är 5, vi verkligen intresserad av ett tal med ett intervall av 5. Så nästa sak vi behöver göra är multiplicera med intervallet b minus en. Så antar att är multipliceras. Och det kommer att ge oss ett nummer inom ett givet intervall. Och det specifikt område är den skillnaden mellan b minus en. Och slutligen, kommer att bara ge den från - säga området mellan b minus en är 5, som ska ge oss en nummer 0-5. Men om en är i själva verket 5, måste vi öka detta intervall upp till där det är faktiskt tänkt att vara, genom att lägga till en. Så det blir logiken höger. Och då skulle du ha en annan fråga? MICHAEL: Nej. Jag känner mig riktigt dum just nu. [Skratt] JASON Hirschhorn: Nej. Känn dig inte riktigt dum. Ett antal personer kämpade med denna fråga. Och sedan, är den andra frågan, drand, du sa, ger dig en flottör - returnerar en float. Men denna funktion faktiskt frågade för ett heltal som skall returneras. Du behöver inte kasta detta uttryckligen till ett heltal, eftersom dessa verksamheten kommer att behandla det som allt en flyta - som ett flyttal. Gillar du vilja - även om detta är ett heltal, kommer detta multipliceras fullständigt. Allt multiplikation fungerar. Du behöver inte kasta det här. I själva verket bör du inte kasta den. Det skulle - om du skulle kasta ett nummer det är mellan 0 och 1 - ett slumptal, ett flyttal - då det kommer att antingen vara enbart 0 eller 1, så du förlorar allt detta precision. Men i slutet, när du kommer tillbaka, det blir automatiskt skickas tillbaka som ett heltal. Så du behöver inte göra att gjuta själv. Så detta var svaret på den frågan, nummer 7. Alla andra frågor om Quiz 0? Ja, Annie. ANNIE: När vi använder rekursiv - När vi använder iterativa loopar? JASON Hirschhorn: När ni använder rekursiv - så mer allmänt, och nackdelar av rekursion kontra en iterativ metod. Kan någon ge ett proffs eller en kon? Snälla? Inte kan någon. Vem kan erbjuda ett proffs eller en kon? [PAPER PRASSEL] STUDENT 1: Rekursivt är mindre kodning - mindre skriva? JASON Hirschhorn: Så i allmänhet, rekursion speciellt, en funktion - eller en algoritm som merge sort - som lämpar sig till en rekursiv metod - skulle kunna vara enklare att koda rekursivt. Och bara vettigare att göra det rekursivt. Så det skulle vara ett proffs för att rekursion. Andra? Yeah? STUDENT 2: Con till rekursion - Den använder mer minne. JASON Hirschhorn: Så exakt rätt. En rekursiv funktion kommer att fortsätta att lägga till stack ramar till stacken. Så om du arbetar på en hel del siffror, och måste ringa detta fungera en hel del, då du kommer säkert tar upp mer minne, medan en iterativ metod kommer bara parkera ett stapla ram på stacken, eftersom allt händer inom en funktion. Alla andra för-och nackdelar? Yeah. STUDENT 3: Fördelar för rekursion. Du behöver inte bestämma i avancera hur många gånger koden måste upprepas. Du kan ha ett förutbestämt antal tider som du måste iterera, då rekursion är bättre, eftersom det tar det resultatet. JASON Hirschhorn: Jag tror det är sant. Men jag tror att i båda fallen du skulle aldrig - skulle du förmodligen få lite inmatning från användaren. Eller denna funktion skulle ha lite input som skulle avgöra hur många gånger det ska köras. Så i allmänhet, skulle du inte svårt kod - även i en iterativ metod - hur många gånger att slingan ska köras. Hade du en annan du var tänker på, Annie? OK. Så de är förmodligen de två - den största pro och den största con till en rekursiv kontra en iterativ metod. OK. Något annat på Quiz 0? Låt oss gå vidare. File I / O. Det är ett underbart kort denna vecka på fil-I / O som förhoppningsvis du har sett flera gånger, och beundrad. En hel del arbete gick in i det, och jag har hörde det är vansinnigt bra. Jag ingår också länken på denna bild, om du inte har haft en chans att titta på det 10 gånger. Så kommer vi att kortfattat gå igenom de viktiga steg för att öppna och arbeta med filer, och då kommer vi att dyka in i en kodningsproblem innan undersöka problemet set. Så återigen, jag kommer att sätta upp detta på skärmen, men jag ska prata om bara en minut om vad vi är gör här med fil I/O-- vad betyder det? Det innebär att vi kan skapa vår program, och sedan har våra program exit, och inte har gjort någon inverkan på världen utanför vårt program. Men när vi börjar arbeta med filer - både läsa dem och skapa dem - kan vi ha viss effekt på den värld utanför vårt program. Precis som om Microsoft Word inte kunde göra några Word-dokument, sedan när Microsoft Word sluta, alla dina Arbetet skulle vara borta, och det skulle verkligen vara värdelös. Vi vill i slutändan vill kunna skriva program som kan påverka världen omkring dem, både genom att ta in komplexa ingångar - i form av filer och via filer, och även skapa intressanta och övertygande utgångar - i form av olika typer av filer. Så det är därför vi börjar lära sig att arbeta med filer. Mer specifikt vad vi gör är följande. Det är väldigt enkelt. Det finns bara ett par steg, och de är listade här på denna kod. Så vi kommer att gå igenom denna kod rad för rad. Först ser du markerat - När du arbetar med en fil, oavsett vilken typ av fil det är, du behöver för att öppna den. Och det är med en uppmaning till fopen - här. Du innehålla namnet på filen. Om filen inte finns i din katalog, eller den mapp där programmet liv, då måste du också inkludera en väg till där filen finns. Vi kommer att anta att detta fil som heter "text.txt" - ett enkelt textdokument - är i samma mapp som programmet är. Så det är en annan sak att hålla i sinne - att om du vill öppna en fil någon annanstans, du faktiskt behöver att inkludera dess plats. För det andra kan du skicka ett argument till fopen, och det är vad du vill göra med filen. Det finns tre huvudargument som du kommer att passera till fopen. Vem kan ge mig dessa tre? Vem kan ge mig en av dem? Ja. STUDENT 4: Filnamnet? JASON Hirschhorn: Förlåt. Tre huvudargument som du kan passera som det andra argumentet till fopen. Du har rätt - filnamnet är det första argumentet. Men det andra argumentet till fopen är allmänhet tre strängar, och - ja. Aleja. Aleja: A för append. JASON Hirschhorn: A, om du vill lägga till en fil som redan finns. STUDENT 5: R för läsning. JASON Hirschhorn: R, om du vill läsa från en fil. STUDENT 6: W för skrivning. JASON Hirschhorn: Och w, om du vill skriva till en fil. Så i det här fallet, vi skriver till filen, så vi har w. Du öppnar den, måste du också spara fil någonstans, och det är med den kod till den vänstra sidan av uppdraget operatören - Jag skapar en pekare till en fil heter, i det här fallet, fil. Vi kommer inte att oroa sig vad detta versaler FIL sak är. Det räcker att säga, det är en lång ström av ettor och nollor. Och det är hur vi ska driva det och förstå det. Nästa sak vi behöver göra - och Detta är oerhört viktigt - varje gång du öppnar en fil - faktiskt, när du kallar malloc, för exempel, och få lite minne och försök och spara den i en pekare, som du alltid vill kontrollera att se till att det funktionen inte returnera null. Så i detta fall, vi kontrollera för att se till att vi verkligen öppnat filen på rätt sätt, och det fanns inget fel i vårt program. Sedan när vi har kontrollerat att se till att vi har en fungerande fil, kan vi skriva till eller läsa från, eller lägga till filen. I det här fallet är jag helt enkelt skriva ut en rad till den här filen. Hur vet jag det? Tja, jag använder denna funktion heter fprintf. Alla funktioner som du kommer att använda när du skriver till eller läser från, eller manipulera filer kommer att likna funktioner som du har sett förut, men börjar med bokstaven F, står för filen. Och fprintf, till skillnad från vår normala tryck app, tar ytterligare ett argument, och det är den fil där du vill skriva ut den här raden till. Jag har inte något att höger om ohai. Jag har inte den tredje argument till printf - eller det andra argumentet till printf, den tredje argumentet till fprintf, eftersom jag har inga platshållare här. Jag är inte med några variabler. Men återigen, fprintf och alla dessa filer funktioner som fungerar med filer i allmänhet kommer att behöva filen där de är verksamma. Slutligen, den sista viktiga att göra är att avsluta ärendet, precis som med - när vi malloc något, Vi vill befria något, så att vi har en minnesläcka - vi vill att avsluta vår fil. Om detta program lämnat utan stängning filen, oddsen är ingenting skulle gå fel, särskilt om det var en liten fil. Men det är säkert bra kodning stil och träna för att alltid avsluta din fil när du är klar med den. Så det är grunderna i fil-I / O. Du har säkert sett det förut, eller såg det i den fantastiska kort. Är det någon som har några frågor, innan vi går in lite träning kodning problem, om fil-I / O eller steg jag bara gick över? [SKRIVANDE LÅTER] JASON Hirschhorn: Har du har en fråga, Avi? AVI: Nej. JASON Hirschhorn: OK. Jag kommer att vänta en sju sekunder. [Skratt] Det är ett riktigt bra tips. Ni bara inte gillar ställa frågor. Det är bra. OK. Så vår första praktik Problemet är att vi är kommer att duplicera funktionen hos ett kommandoradsverktyg som du antagligen använt tidigare - kopia - kopieringsverktyget. Om du skriver cp och sedan ge det två argument i din terminal kan du kopiera en fil. Och det är vad vi kommer att skriva just nu. Så återigen, läsning av av denna bild, skulle jag dig att skriva ett program som tar två och endast två kommandoraden argument - en källfil och en målfil - och kopierar innehållet i källan filen till målfilen en byte i taget. Så det är mycket att be om. Återigen, är en bra metod för att detta ska inte gå direkt till C-kod, men dela upp det i ett par steg. Först, tänk på logiken - precis vad jag ber dig att göra - och förstå alla de steg på detta problem. Inte i C, bara i några pseudo, eller ens en mental modell av vad som händer. Nästa gång du har den pseudokod ner, räkna ut hur pseudo kartor på verktyg och saker som vi har lärt sig att använda i C. Och slutligen, när du har allt som tillsammans, kan du koda problemet. Ta 5 till 10 minuter att arbeta med detta problem. Jag lägger instruktionerna tillbaka upp på en sekund. Och då kommer vi att gå över pseudokoden, och kod den lever som en grupp. Om du har några frågor när du är arbetar med detta, tveka inte att ta upp din hand, och jag kommer att komma runt och svara på dem. STUDENT 7: Kan jag dra ett papper? JASON Hirschhorn: Vad händer? [SKRIVANDE LÅTER] JASON Hirschhorn: OK. Låt oss gå över pseudokod först, och då jag ska ge dig ett par mer minuter för att avsluta kodning. Vem vill börja mig med den första raden i pseudokod för denna funktion? STUDENT 8: Kontrollera att se till att du fick två filer. JASON Hirschhorn: OK. Och om vi inte? STUDENT 8: Jag skulle återvända 0. JASON Hirschhorn: Bör vi gå tillbaka 0? STUDENT 8: tillbaka en - blanking. Ursäkta. JASON Hirschhorn: Ja. Förmodligen inte 0. Eftersom 0 betyder att allt var bra. OK. Så det är den första raden av pseudokod. Vem har den andra raden i pseudokod? STUDENT 9: Öppna båda filerna? JASON Hirschhorn: Öppna båda filerna. OK? STUDENT 10: Kontrollera om filen är NULL? JASON Hirschhorn: Kontrollera att Se till varken är NULL. Som en parentes - slash 0 - är att NULL? STUDENT 11: Nej. JASON Hirschhorn: Det är inte NULL. Det kallas NULL terminator. Det är faktiskt stavas med bara en liter. Så kontrollerar något emot det - det är faktiskt ett tecken - så kontrollera något emot det är inte samma som kontroll för att se om det är lika med NULL. Och en del människor - på sina frågesporter och deras problem satser - har fått två av dem förvirrade. Men två av dessa är i själva verket är olika. Man avslutar en sträng - en är en pekare till 0. STUDENT 12: Varför skulle inte du kontrollera att se till att filerna inte är NULL innan du öppnar dem? JASON Hirschhorn: Så öppna sparar något i den filen. Och om du går tillbaka hit - så denna linje - fopen - kommer att ge dig en adress och lagra den adressen i filen om det fungerar. Om det inte fungerar, det kommer att lagra NULL - STUDENT 12: Oh. OK. Fick dig. JASON Hirschhorn: I filen. Så du kan inte kontrollera om NULL innan du har öppnat dem. NULL betyder något inte fungera korrekt. OK. Så kontrollera att varken säga? Eller är? Vad tror vi? Vi ska gå med det. STUDENT 13: Är. JASON Hirschhorn: Är? Inte heller är? STUDENT 13: Är. JASON Hirschhorn: OK. Vi verkar ha en del enighet om det. Inte heller är NULL. OK, nästa rad av pseudokod. Vem har inte gett mig en rad ännu? Vi kommer att vänta på dig. Yeah. STUDENT 14: Du måste läsa från den första filen? JASON Hirschhorn: OK. STUDENT 14: Eller vi använder fscanf eller något liknande den första filen? JASON Hirschhorn: Så vi vill läsa från den första filen och - låt oss sätta det här. Läs från källfilen. Och sedan, vad gör vi efter att vi läsa från källfilen? Någon annan? STUDENT 15: Skriv in målfilen? JASON Hirschhorn: Vi skriver till målfilen, och - OK. Vad vi saknar? Någon annan som inte har gett mig en kodrad ännu - av pseudokod. Yeah. STUDENT 16: Kanske kan du alltid kontrollera om det finns något att läsa om, som nästa rad? Det är som nästa rad, se om den finns. [ELEKTRONISK BEEP] JASON Hirschhorn: Oj. Det är mitt journal programvara. Yeah? STUDENT 16: Yeah. JASON Hirschhorn: Så ge det till mig en gång till. STUDENT 16: Kontrollera om det finns ännu en nästa linje från källfilen att läsa. JASON Hirschhorn: OK. Så vi inte läsa rader - läste byte här - men du är rätt. Vi önskar att läsa och skriva till dess det finns inga fler bytes. OK. Och så dessa borde egentligen vara indragen lite, eftersom de är under där. Rätt? Tills vi är av byte, kommer vi att läses från källfilen och skriva till målfilen. Och då, vad är det sista linje pseudokod? Någon som inte gett mig något ännu. STUDENT 17: Stäng filerna? JASON Hirschhorn: Exakt. Stäng filerna. Så det är vår pseudokod. Jag kommer att sätta den pseudo in gedit, och i ett par minuter som vi kommer att koda detta tillsammans. OK. Låt oss komma igång som en grupp. Nishant, jag har min nya filen. Jag har precis öppnat upp detta. Untitled dokument 1. Vad är det första jag ska göra? Nishant: Inkludera biblioteken? JASON Hirschhorn: OK. Vilka bibliotek? Nishant: stdio.h, stdlib.h, tror jag? JASON Hirschhorn: OK. Vad är stdlib för? Nishant: Jag glömde. JASON Hirschhorn: OK. Så inkluderar stdio. Vad ska jag göra med innan Jag börja koda? Nishant: Skriv en rubrik? JASON Hirschhorn: Hur får jag det färgade? [inplacering UTTRYCKER] Nishant: Hur får du det färgade? JASON Hirschhorn: Hur får jag färgkoder? Nishant: Jag vet inte. Oh. Spara. JASON Hirschhorn: Save. Ja. Jag ska spara den som en. C.. Så spara den på skrivbordet som cp.c. Söt. Och om jag vill få fullt stil poäng, vad ska jag omfatta högst upp? Nishant: Du kan skriva ditt namn, namn av programmet, och syftet av programmet också? JASON Hirschhorn: Ser bra ut. Utmärkt. Så du har börjat oss perfekt. # Include - Vi kommer också skriva - OK. Så jag tror att jag är redo att gå. Vem har den första kodraden för mig - eller de första kodrader som det kommer att ta för att tillfredsställa vår första comment i pseudokod? Du. STUDENT 18: Borde inte det vara int argc, och sedan char * argv? JASON Hirschhorn: Jag tror du har rätt. Låt oss ändra det till int viktigaste, öppna föräldra, int argc, kommatecken, char * argv? Så? STUDENT 18: Brackets. JASON Hirschhorn: Brackets. Öppet fäste, nära fästet, nära förälder. Perfect. Nu kan jag ta kommandoradsargument. OK. Se till att vi gett två filer. Du kan ge mig det också. STUDENT 18: Om argc - detta inte lika 3. JASON Hirschhorn: Om öppna föräldra argc inte lika 3? STUDENT 18: Ja, du tillbaka 1 eller något. JASON Hirschhorn: Förlåt. STUDENT 18: Return 1 eller något. JASON Hirschhorn: Tillbaka 1. OK? Bra. Öppna båda filerna. Vem kan hjälpa mig att öppna båda filerna? Vem har inte gett mig koden ännu? Kurt? KURT: Så alla caps F-I-L-E stjärna källa. JASON Hirschhorn: Jag tänker att ta ut vokalerna. De är coola. Det är som Tumblr. STUDENT 18: Lika fopen - JASON Hirschhorn: Lika med fopen? STUDENT 18: Öppna Paren, argv, öppna konsolen. JASON Hirschhorn: Vänta. Ursäkta. Öppen föräldra. OK. STUDENT 18: Yeah. Argv sub 1. JASON Hirschhorn: Sub 1? STUDENT 18: Yeah. Argv öppna fäste 1 - Ja. Och sedan komma och öppna sedan dubbel citat, r, dubbla citat, nära paren, semikolon. JASON Hirschhorn: Sweet. Och hur är det med andra? STUDENT 18: Mycket lik, men i stället S-R-C, skulle du kalla det D-S-T. JASON Hirschhorn: Oo! Det gillar jag. STUDENT 18: Just D-S-T. Yeah. Och sedan argv, öppna konsolen, 2. Yeah. Och sedan w istället för r.. Yeah. JASON Hirschhorn: Great. Nästa par rader. Dessutom, om någon har saker att lägga till linjer som vi har gjort, gärna lägga till dem också. Kontrollera att ingen är NULL. Vem kan ge mig koden jag behöver tillfredsställa den linjen av pseudokod? Archer. ARCHER: Om src lika jämlikar NULL eller dst lika jämlikar NULL, då du kommer tillbaka - JASON Hirschhorn: Vad? ARCHER: Return 2? JASON Hirschhorn: Return 2. Så om öppna föräldra src lika är lika med NULL, eller - vad det thing's - pipe? Pipe? Vi kallar det röret. Rör, rör, dst lika likar NULL, avkastning 2. OK? Tills vi är av byte - vi liksom hoppade över detta steg från den pseudo del att gå till här. Men tills vi har slut på byte - vad låter det som? Vilken typ av C-struktur - men jag använder inte ordet struktur, eftersom vi kommer att börja använda att i andra fall - men C-verktyg låter det som? STUDENT 19: En slinga. JASON Hirschhorn: En ögla. Låter som en slinga. Så vem kan ge mig den första raden av sling koden här? Du kan också välja vilken typ av slinga som du vill, om du ger mig denna kodrad. Det finns tre typer. Du får välja. Jag skulle vilja föreslå en av dem. Avi. Vilken vill du ha? AVI: FOR. JASON Hirschhorn: FOR. AVI: int i lika med noll. JASON Hirschhorn: OK. AVI: Denna del är jag inte säker på. Men jag är mindre än storlek av stjärn källa? Jag är inte säker på det. JASON Hirschhorn: OK. AVI: Eftersom du vill ha den storleken på en fil, eller hur? JASON Hirschhorn: Så det här förmodligen inte ge oss storleken av den faktiska fil i byte. Så vad kan vi göra? Vad är en annan typ av loop? Eller ska vi hålla fast vid FOR loop? STUDENT 20: Kan du göra en while-slinga? Och då, vad du skulle göra är att Du skulle - eftersom vi har en char * för filen. Så om vi håller just uppräkning som tills vi skulle hitta den NULL tecken på I slutet av det? Eller nej, det är inte hur filer fungerar? JASON Hirschhorn: Så vi kan hålla uppräkning av char * tills vi hittar NULL - STUDENT 20: I huvudsak hålla igång tecken för tecken tills vi hit i slutet av filen. JASON Hirschhorn: Ja. Så det är vad vi vill göra. Vi vill fortsätta läsa, tecken med karaktär, tills vi kommer till i slutet av filen. STUDENT 20: Yeah. Sök - vad är slutet eller stoppskylt vid slutet av en textfil. JASON Hirschhorn: OK. Så när vi kommer till slutet av filen - hur vet vi att vi har nått slutet på en fil? Om jag ringer - så låt oss ta ett steg tillbaka. Vad är en funktion? Låt oss gå till denna linje här. Läs från källfilen. Vem kan ge mig den kodrad? STUDENT 21: fscanf? JASON Hirschhorn: fscanf. OK. Vad händer om jag vill läsa, mycket specifikt, en bitgrupp? STUDENT 21: Jag vet inte. JASON Hirschhorn: OK. Ännu enklare än fscanf - vad är en - Jag vill läsa från en källfilen? Läs från en källfil. Vad är en funktion - ja. STUDENT 22: Det är fread? JASON Hirschhorn: fread. Jag tror låt oss hålla fast vid som man för nu. Vilken typ av argument gör fread ta? STUDENT 22: Förmodligen den filtyp, och sedan plats i filen? JASON Hirschhorn: Vad kan jag skriva här att räkna ut vilken typ av argument fread tar? FLERA STUDENTER: Man fread. JASON Hirschhorn: Man fread och fwrite. Ser ut som de umgås tillsammans. Så fread tar hur många argument? STUDENT 23: Fyra. JASON Hirschhorn: Det tar fyra argument. Det tar en pekare, en storlek, och att sak, vilket är konstigt, och lite fil. OK? Låt oss läsa om det här. "Funktionen fread läser n memb delar av data, varje storlek byte långa, från strömmen som utpekas av streama, lagra dem på plats ges av pekare. " Så fyra argument. Varför kan jag inte kopiera just detta, och klistra in den här. OK. Så vem kan börja fylla i dessa argument för mig? Avi. AVI: Ta ut tomrummet. Sätt bara src. Ta ut pekaren och stjärnan. Sätt src. Då - JASON Hirschhorn: Så jag kommer att sluta dig där, eftersom det är felaktigt. Du har rätt med src, men där ska src gå? [inplacering UTTRYCKER] JASON Hirschhorn: Det bör gå hit. Det är src - vår src är en typ. Låt oss titta här. Detta är att be om en filtyp *, vi faktiskt brukar se dem så. Så det här är att be om ett argument för filtyp * kallas bäck som är src. OK? Vilken storlek på saker att göra vi vill läsa? Jag gav dig det här i problembeskrivning. STUDENT 24: En byte i taget. JASON Hirschhorn: En byte. Hur stor är en byte? Dess storlek är i byte, så vad kan jag rätta till det? STUDENT 25: One. JASON Hirschhorn: One. Rätt. Dess storlek är i enhetsbyte, så 1 är 1 byte. Hur många vill jag läsa på en gång. STUDENT 26: en? JASON Hirschhorn: En sak. Jag vill läsa en sak av storlek 1, en tugga i taget. Och var ska jag uttrycka det, när jag läste det? STUDENT 27: Destination? JASON Hirschhorn: Så jag kan inte sätta det rakt in destinationen. STUDENT 28: Du är gonna put den till en tredje pekare? STUDENT 27: Att destinationen. JASON Hirschhorn: OK. Yeah. STUDENT 29: Du kan deklarera något till fungera som en tillfällig lagring tidigare. JASON Hirschhorn: OK. Ge mig det. STUDENT 29: En annan fil pekare, kanske? JASON Hirschhorn: OK. Så detta är ogiltig stjärna - det är en typ void stjärna, så det gör det inte måste vara en fil pekare. Och om jag läser en byte, där skulle vara en bra plats att lagra en byte-? STUDENT 29: En array? JASON Hirschhorn: En array. OK. Och vad mer är något som är bara storleken ett byte? STUDENT 30: En char *? STUDENT 29: Yeah. JASON Hirschhorn: En char * är inte en byte. STUDENT 29: En röding. JASON Hirschhorn: En char är en byte. Rätt? Så låt oss kalla denna buffert är en generisk namn används för dessa saker för att lagra något tillfälligt. Så jag skapar en buffert. Rätt? Men det tar en void *. Så kanske du har rätt, att det bör vara en buffert av storlek 0. Så det lagrar en - höger. Eftersom denna rätt här - röding bufferten är en karaktär, men detta tar ett tomrum * - en pekare. Så jag skulle kunna göra det här och nu bufferten är en pekare. Vad skulle jag göra? STUDENT 31: Sätt en stjärna bredvid char. JASON Hirschhorn: jag kunde har skapat den char *. OK. Vad är en annan sak som jag skulle kunna göra? Eller låt oss gå med här. Char * buffer, så vad lägger jag in här? STUDENT 31: Buffer. JASON Hirschhorn: Buffert. Buffert är en pekare till en röding. Och på den platsen, vi sätter en byte av något som vi har läst. Yeah. Avi. AVI: Bara en snabb fråga. Vill du malloc buffert? JASON Hirschhorn: Vem kan svara på den frågan? STUDENT 32: Tja, det spelar egentligen ingen peka på någonting just nu, så - JASON Hirschhorn: Men gör Vi vill att malloc det? STUDENT 32: Om du skulle göra det på det sätt, antar jag, ja, eftersom du skulle behöva någon plats för den att peka på. JASON Hirschhorn: Vill vi måste malloc det? STUDENT 33: Om du ska använda det utanför slingan. JASON Hirschhorn: Kommer vi att använda det utanför slingan? STUDENT 34: Ja. STUDENT 35: Vänta. Vill vi att förklara den i slingan till okända? JASON Hirschhorn: Så jag antar att vi har vissa pseudo WHILE loop här att vi är försöka lista ut, att Vi har inte kommit till ännu. Vi behöver inte malloc det. Vi arbetar i huvud, det kommer bara som kan användas i denna slinga. Det behöver inte föreligga utanför denna. Så det kan vara en lokal variabel. Du har en pekare till en lokal variabel. STUDENT 36: Men det är inte pekar på någonting. JASON Hirschhorn: Nej, det är inte initieras till någonting. Men vi kommer inte att använda den också. Vi kommer att sätta något i det första gången vi använder den. Så det verkar OK. Så vi behöver inte malloc här. Och jag tycker det är OK som det är. OK. Vi har den fread linje. Låt oss göra det nästa rad. Om vi ​​vill skriva till en fil, vad är en bra funktion att använda för att göra det? STUDENT 37: fwrite? STUDENT 38: fprintf? JASON Hirschhorn: fprintf är ett. Vad är en till? STUDENT 39: fwrite. JASON Hirschhorn: fwrite. Och för våra syften, fwrite, som vi såg här, är förmodligen ett bättre val. Det tar fyra argument också. Nishant, kan du ge mig argumenten? Nishant: Det första som händer vara bara buffert. JASON Hirschhorn: OK. Nishant: Den andra är bara kommer att bli 1. Tredje man kommer att bli 1. Och den fjärde kommer att bli dst. JASON Hirschhorn: Är det någon som har några frågor om den linjen? Det ser bra ut. OK. Så nu ser det ut som det enda vi är saknas - faktiskt, låt oss skriva denna sista raden. Stäng filerna. Vem kan avsluta upp oss skrivande de två sista raderna? Ja. Förlåt, vad heter du? LUCY: Lucy. JASON Hirschhorn: Lucy. LUCY: fclose src och sedan fclose destination. JASON Hirschhorn: fclose, öppen föräldra, src, nära föräldra, semikolon. Och fclose - ja? LUCY: Öppna parenteser, dst och sedan semikolon. JASON Hirschhorn: Great. Och vad ska jag ta i slutet? LUCY: Return 0. JASON Hirschhorn: Return 0. Måste jag? Bara en fråga. Måste vi inkludera retur 0? FLERA STUDENTER: Nej. JASON Hirschhorn: Nej. Huvud gör det automatiskt om du kommer till slutet. Men jag tycker det är trevligt att inkludera det uttryckligen. Speciellt när vi återvänder andra saker under hela programmet. OK. Detta är vad vi saknar - MEDAN vad? Vem kan komma på något - har en känsla av hur det kunde gå in där? Även om det bara är i vissa pseudo liknande språk? Vad är vi egentligen - vad vill vi gå till? Ja, Lucy. LUCY: Slutet på filen. JASON Hirschhorn: Slutet på filen. Så vad menar du med slutet av filen? LUCY: När du når slutet av filen, sluta. JASON Hirschhorn: OK. Så när vi kommer till slutet av filen. Hur vet vi när vi har nått i slutet av filen? STUDENT 40: Jag tror buffert sätts till NULL. STUDENT 41: Buffert förklaras inuti slingan. JASON Hirschhorn: Så du tror bufferten ska vara inställd på NULL. Varför skulle buffert sättas till NULL? STUDENT 40: För när du fread, du försöker sätta ingenting in i bufferten. JASON Hirschhorn: OK. Så du tänker fread - När vi har kommit till slutet av den fil, vad fread göra? Jag tror att det är frågan Vi måste ta reda på. Vad betyder fread göra? Är det ett noll i buffert, eller gör den något annat? Hur kan vi räkna ut vad det betyder? STUDENT 42: Man. JASON Hirschhorn: Man. Så låt oss titta hit. Retur värde. På framgång, fread och fwrite returnera Antalet poster läsas eller skrivas. Detta antal är lika med antalet bytes överföras endast när storleken är 1. Om ett fel uppstår, eller i slutet av filen har nåtts, är returvärdet kort posträkning eller 0. Så för våra syften, om fread når slutet på filen, och läser ur slutet av filen, det finns inget kvar att läsa, vad det kommer att återvända? STUDENT 43: Zero? JASON Hirschhorn: Vad? STUDENT 43: Zero? JASON Hirschhorn: Zero. Det kommer att återvända noll. Så vi vet att fread, när vi har nått slutet på filen, går att returnera noll. Hur kan vi använda det till vår fördel? AVI: Du kan deklarera en variabel utanför av slingan kallas check. Om kryss lika - för nu - en. JASON Hirschhorn: OK. AVI: Och sedan kan du lägga en IF uttalande direkt efter fread säger om fread lika med noll - nr. JASON Hirschhorn: Vem kan hjälpa Avi ut? AVI: Vad är värdet returneras av fread? JASON Hirschhorn: Vi bara gick över det. AVI: Hur står det? JASON Hirschhorn: Så det tillbaka - låt oss se upp här - den returnerar en size_t, som huvudsakligen är ett heltal. Så det returnerar ett heltal. Och i vårt fall kommer den tillbaka 1 eller 0 - 1 om det läste en sak - en byte, och 0 om vi har kommit till slutet. Så om fread - ja? STUDENT 45: Kan du inte bara sätta den fulla fread (buffer, 1, 1, src) i while-slinga? JASON Hirschhorn: Så du föreslår att göra detta in dit? [inplacering UTTRYCKER] JASON Hirschhorn: Vänta. Så vi befria det. Så du föreslår att sätta fread in där? Vad ska vi också flytta om du vill göra det? STUDENT 45: Bufferten utanför. JASON Hirschhorn: Vi bör också flytta ut det här. STUDENT 45: Men gör det hela tiden flytta den framåt? [inplacering UTTRYCKER] JASON Hirschhorn: OK. Så detta är vad Okshar föreslås. Vi skapar vår buffert. Vi MEDAN fread, då fwrite vi. Tankar om detta? STUDENT 46: Min enda fråga är, skulle det faktiskt köra kommandot fread? JASON Hirschhorn: Bra fråga. När du lägger ett funktionsanrop inne i ett tillstånd, gör att funktionsanrop köra? Vi har sett exempel på detta tidigare. Rätt? STUDENT 46: OK. Yeah. Så det gör exekvera. JASON Hirschhorn: Vi har sett saker så förut, där vi har en funktionsanrop inne i ett tillstånd. Betyder det funktionsanrop köra? Ja. Så svaret är ja. Funktionen samtal kommer att utföra. Men återigen, är det vad vi vill? Vad är ett sätt som vi kunde räkna ut om det är det vi vill? FLERA STUDENTER: Kör det? JASON Hirschhorn: Vi skulle kunna köra det. Men innan vi gör det, vi kunde också resonera igenom det här. Om - säga att vi har en byte i vår fil, vi kommer till här, vi kommer till denna kod. Detta kommer att köras. fread återgår en bitgrupp och förvara den i bufferten. Och detta kommer att utvärderas till 1, höger, efter att han återvänder 1. Så medan 1. Betyder det att koden inuti WHILE-slingan kommer att utföra? STUDENT 47: Yeah. Det är sant. JASON Hirschhorn: Ja. 1 är sant. Det är inte 0. Så koden inuti här kommer att utföra. Så vi ska skriva det. Vi ska gå tillbaka till denna linje igen. Nu har vi - vi är i slutet av vår fil. Vi läser från slutet av vår fil, eftersom vi bara hade en byte i den. Fread returnerar 0, butiker något i buffert. Jag vet ärligt talat inte vad den lagrar i buffert. Vi kan nog se upp för att se vad det gör. Att jag vet ärligt talat inte. Vi vet inte, vem bryr sig om vad den lagrar i buffert? Men det återvänder 0. Och kommer medan 0 exekvera? MEDAN 0 inte kommer att utföra. Så då ska vi flytta ner hit. Så låt oss få en handuppräckning om detta är koden vi ska köra, eller om vi bör göra förändringar först. Så om du tror - du måste rösta. Om du tycker att vi ska köra den här koden som är, räck upp handen. OK. Det finns en - har du en fråga, oro? Yeah. STUDENT 48: När vi flyttar buffert utsidan av slingan, gör vi måste malloc det? JASON Hirschhorn: Bra fråga. När vi flyttar buffert utanför loop, måste vi malloc det? Detta är ett utrymme fråga. Om vi ​​initiera buffert utanför av denna slinga, kommer det att existera insidan av slingan? FLERA STUDENTER: Ja. JASON Hirschhorn: Ja. Dess räckvidd täcker insidan av slingan, och, egentligen, allt under det inne av denna kod, inklusive saker inne här. Så vi behöver inte malloc det. Det är en lokal variabel, och dess omfattning fortfarande innehåller slingan. STUDENT 49: Behöver vi att befria det? JASON Hirschhorn: Vill vi behöver buffert? STUDENT 49: Ja, om vi inte malloc. JASON Hirschhorn: Vill vi behöver buffert? Vi gör inte. Återigen är det en lokal variabel, så vi inte behöver för att befria den. OK. Låt oss se vad som händer. Därför är det ej initierad. Det var det något som Marcus föreslog tidigare. Så vi har detta fel, variabel buffert är icke initierat när den används här. Hur kan vi åtgärda detta? STUDENT 50: malloc det? STUDENT 51: Lika NULL? STUDENT 52: Säg buffert lika NULL. JASON Hirschhorn: OK. Ser bra ut. Vi har det nu. Låt oss skapa något för att försöka kopiera. Så vi har vår textfil. Hur kan vi köra det här programmet? Yeah. STUDENT 53: Du kan göra punkt slash cp, test.txt. Och då kan du namnge en annan fil som det kommer att lagra in. JASON Hirschhorn: OK. Vi kallar det out.txt. Cool? Seg fel. Tankar om seg felet? Det här är bra. Hur kan vi ta reda på var den seg felet är? Vad? STUDENT 54: GDB. JASON Hirschhorn: GDB. Vi kör gdb genom att skriva gdb dot snedstreck, namnet på vårt program. Inga kommandoradsargument där. Vi kommer att ställa en brytpunkt i main. Om jag vill börja gdb, vad gör jag? STUDENT 55: R. JASON Hirschhorn: R. Och sen då? STUDENT 55: Argumenten? JASON Hirschhorn: Då kommandoradsargument. Låt oss gå igenom. N är bara ta mig rad för rad. Jag ska gå till Jag får min seg fel. Det är mitt seg fel. Det ser ut som fread orsakade mitt seg fel. Jag vet fread orsakade mitt seg fel, eftersom det var den linje vi bara avrättades. Och det enda som var händer i den linjen - två saker hände. Fread gick, och sedan var vi göra lite medan checkar. Jag är villig att satsa att MEDAN kontroll inte orsakar min seg fel. Troligtvis var fread orsakar min seg fel. Jag ser också något här, memcopy. Memory kopia. Låter som att flytta minnet från en plats till en annan. Låter som något som skulle hända i fread, kanske lite minne flyttar härifrån till här. Låt oss gå igenom det här igen. Hur startar jag den över och köra den igen? Yeah. STUDENT 56: Behöver du lägga ett et-tecken före buffert? JASON Hirschhorn: Så et-tecken före buffert skulle ge mig adressen till buffert, som är en char *. Låt oss gå igenom det här en gång till. Hur kör jag igenom det en gång till? STUDENT 57: Kan du bara typ köra igen? JASON Hirschhorn: Skriv bara springa igen. Så vi kommer inte att verkställa denna linje. Så buffert är en NULL-pekare. Rätta? Det pekar på - låt oss se. Om vi ​​har vår - rita en snabb bild av detta. Kan alla se om Jag skriver här borta? Så i stacken, har vi en lokal variabel och det kallas buffert, och det är en pekare till en char. Vilken adress är det röding på? STUDENT 58: 0x0. JASON Hirschhorn: Höger. Det är vad det här är. Här inne, inne buffert, lagras 0x0. Det är det vi har - det inställning vi har just nu. Så här linjen, fread, lägger något från källa där? In i denna box eller rutan? Vilken låda? Vänster ruta eller höger låda? Denna rätt ruta. Det följer pekaren, och placerar det i här. När vi försöker och beröring minne på läge 0, vad får vi? En segmentering fel. Det är fel att vi har just nu. Yeah. STUDENT 59: Har inte du har att sätta stjärna buffert? Eller nej? För fread? JASON Hirschhorn: Så fread tar en pekare. Så den passerar i buffert. Och så kommer det de-referens den någonstans inne fread. Men återigen, som vi såg, tar det en pekare. Vi behöver inte passera det stjärn buffert. Det skulle kunna passera det vad det här. Och det skulle förmodligen ge oss ett fel eftersom vi är de-refererar det. Rätt? När vi de-referens här pekaren, när Vi försöker komma åt den här platsen, vi får ett fel - vår segmentering fel. Så - oops. Vi kommer att sluta av gdb. Vår linje - vårt problem - är rätt här på denna linje. Och det är ett problem eftersom på denna linje. Hur kan vi skapa en ruta som är tillgänglig i fread. Rätt? Vi måste skapa en ruta som är en byte stora, storleken på en röding. Men vi behöver att rutan för att vara tillgänglig när funktionen körs. Så var - ja. Några idéer? STUDENT 60: Ställ bara in det som någon slumpmässig karaktär. Bara gör char buffert jämlikar tecknet. Och sedan, när du har buffert där - JASON Hirschhorn: Vänta. Char buffert? Så ingen stjärna? STUDENT 60: Yeah. Ta ut stjärnan. Lika med en slumpmässig karaktär. JASON Hirschhorn: OK. Så ge mig en. STUDENT 60: Like a eller något. Och sedan när du har buffert där använder du en - STUDENT 61: Star? Åh nej, et-tecknet. STUDENT 60: Använd et-tecknet. JASON Hirschhorn: OK. Och hur är det i fwrite? STUDENT 60: Använd et-tecknet igen. JASON Hirschhorn: Okej. Så din idé är, vi skapar en röding och sätta något i det, och sedan skriva till den röding. STUDENT 60: Yeah. JASON Hirschhorn: Vad tror folk tycker? STUDENT 62: Det är invecklade. JASON Hirschhorn: OK. Låt oss dra ut det. Så den här gången kommer jag att göra detta i rött på stacken här, och då kan vi kommer att ha - ooh! Ursäkta. Så den här gången har vi något som kallas buffert, och det är på stacken. Rätta? Och vi sparar på det en, till en början. Sedan har vi vår uppmaning till fread. Vad fread gör är det tar ett byte från vår fil och placerar den någonstans. Det sätter den i oavsett sak är att peka på. Nåväl, innan vi hade den här adressen - 0x0. Nu vad adress har vi? STUDENT 63: Allt vad adressbufferten är. JASON Hirschhorn: Allt vad adressbufferten är. Det kommer förmodligen att bli något liknande. Förmodligen kommer att börja med en b och ett f, och sedan har sex andra hexadecimala siffror. Spelar ingen roll. Vissa adress. Och vi passerar den adressen i. Och vi ska sätta vår en byte sak på den adressen. Så vi kommer att sätta vår en byte sak inne här. Och sedan ska vi skriva från vad är någonsin inne här. Är det någon som har några frågor om det? Vem tror att denna kod kommer att fungera? Räck upp handen om du tror denna kod kommer att fungera. Du måste ta ställning. Och vem tror denna kod inte kommer att fungera? Räck upp handen. Alla andra ska vara höja sin hand. OK. Michael, var står du? MICHAEL: Jag kan inte bestämma mig. Typ av i mitten. JASON Hirschhorn: Du är i mitten. Välj en. MICHAEL: Jag måste tro och säger att det kommer att fungera. JASON Hirschhorn: OK. Du har tro och säger att det fungerar? Vad hände? [inplacering UTTRYCKER] JASON Hirschhorn: Nej seg fel. Hur kan vi kontrollera om två saker är lika? Två filer är lika. STUDENT 64: Diff. JASON Hirschhorn: Diff. Diff kontroller för skillnaderna mellan två filer, och om den återvänder ingenting, de är identiska. Och om vi öppnar upp, vi får vår fil. Så det var den rätta lösningen. Låt oss titta tillbaka på det en gång till. Vi gjorde faktiskt inte ens måste initiera den. Det skulle antagligen se lite renare om du inte lägger något slumpmässigt i det. Poängen är, du behövs för att skapa lite utrymme för att lagra något från fread och ta något slut fwrite. Och det där måste vara antingen en lokal variabel på stacken - du kunde ha malloc'd lite utrymme. Så vi kunde faktiskt ha skriftlig malloc här, och som skulle ha fungerat. Och då skulle vi ha förvaring våra saker någonstans på högen. Men detta är faktiskt sannolikt, den mest eleganta lösningen. Bara skapa utrymme på stacken för dessa saker att gå. Jag skulle ha två andra kommentarer. Om du skulle ta sin tur i detta, och sedan få poäng på detta, mina kommentarer skulle vara som följer. Dessa 1 är här, för mig, titta som magic numbers. Denna 1, i termer av fread, vettigt. Det är många saker att läsa eller skriva. Men här en här bör förmodligen vara något annat. Så vad är en lösning? STUDENT 65: Storlek på byte. JASON Hirschhorn: Gillar det? STUDENT 65: Storlek på röding. JASON Hirschhorn: Storlek på röding. Ja, är byte inte en typ. Så storleken på röding verk. Vi skulle kunna ha, på toppen av vår kod, # definierat det. Kallade något BYTE och det är verkligen en röding. Egentligen en ännu bättre metod kan ha varit här - uint. Någon som vet vad det är? Ursäkta. Jag har det bakåt. Vänta, nej. Vilken väg tar det vägen? Någon som vet vad det är? Yeah. STUDENT 67: Tänkt att hjälpa standardisera över system saker som har - som heltal utan tecken som har 8 byte? JASON Hirschhorn: Det är exakt rätt. På olika maskiner, storleken på en röding - vanligtvis inte en röding. Tecken är vanligtvis en bitgrupp. Men storleken på andra datatyper är olika storlekar på en 32-bitars maskin jämfört med en 64-bitars maskin. En uint8_t är alltid 8 bitar - alltid en bitgrupp. Och jag måste inkludera att standard int header-fil. Så nu, det hade förmodligen varit det bästa sättet att skriva den här koden. Så jag bli av med de magiska siffrorna. Och jag har också en mer logisk skriver för buffert. Det är inte bara en röding, det är ett byte, vilket är vad vi förväntar oss att det ska vara. Och här uppe, vi har faktiskt varit lite mer robust. Vi ska inte kalla det en röding, som - kanske, vem vet - kan vara en annan storleken på olika maskiner. Vi är faktiskt säger det är precis en byte, alltid, oavsett vad. Och om vi ser här, vi gör cp. Uh-oh. Vad hände? STUDENT 68: Det kan vara påslagen. JASON Hirschhorn: Vad? STUDENT 69: Är det? STUDENT 70: Du gjorde inte definiera det som en typ. STUDENT 71: Men det ska definieras i standarden. STUDENT 72: Vad händer? STUDENT 73: Bör definiera vara versaler? JASON Hirschhorn: Så det är inte # define. Faktiskt, i detta fall, är jag kommer att använda typedef. Eftersom vi använder det som en typ på en plats. Så i det här fallet, vi faktiskt vill typedef som vi skriver ut en ny typ byte, och det är i huvudsak detta. Det är lite annorlunda än # define. Och nu, fungerar vår kod perfekt. Så, återigen, # define tar något, ersätter det överallt med den andra saken. Det är bara ett makro - stenografi för att bli av magic numbers. Men i detta fall, eftersom vi är använder den som en typ - just här - För att detta ska fungera, vi behöver att typedef vad byte är. Och vi definiera det här. Det är inte en struct, det är faktiskt bara ett heltal utan tecken. Det är en byte långt. Denna kod kommer att finnas tillgängliga på nätet, och ni alla borde ha det just nu. Så vi har - perfekt - 13 minuter kvar att gå över problemet set 5. Jag vill gå igenom copy.c tillsammans, och sedan ska vi tala kort om de andra delarna av problemet inställd. Så låt mig dra upp copy.c. Och det häftiga är, vi har faktiskt redan skrivit en hel del av denna kod. Koden skrev vi bokstavligen bara kom ut här när jag var skriver detta på min egen. Men detta är copy.c, är grunden för de två första delarna av problemet set till whodunit.c, vilket du behöver för att skriva, och resize.c. Recover.c, som är den tredje och sista del av problemet set, är inte baserad bort av denna fil. Du kommer att behöva skriva den filen, Vi ger dig en mall för att fil, men det har ingenting att göra med copy.c. Men eftersom copy.c är grunden för de två första delarna, vi ska för att gå igenom det nu, så att du har en bra känsla för vad den gör. Och kommentarerna ger en del av det bort. Vi har redan skrivit en del av detta. Först ska vi se till vi får tre argument. Därefter ska vi komma ihåg filnamnet. Så vi hoppade över detta steg när Vi kodade vår sak - när vår cp. Men här, de gör det lite renare. De kontrollerar att båda filerna är bra, i Förutom att öppna dem. Vi skrev all denna kod just nu, så jag är kommer inte att uppehålla mig vid denna kod. Nästa är en del saker som är specifika för de typer av filer som vi använder, som är bitmap filer. Bitmap-filer har en del metadata associerade med dem. Så de första byte berätta om filen. De är inte färgerna i pixeln i den bilden. De berätta om filen. Och om du läser igenom problemet set, du har mycket mer information om vilka typer av metadata strukturer ingår med bitmappar. Men det är därför vi har denna första uppsättning - denna kod här. Vi läser metadata - två bitar av metadata - filen rubriken och informationen rubriken. Och vi kontrollerar vissa delar av det till se till att det är en sann bitmappfil innan du fortsätter. Och återigen, det är detaljer som vi behöver inte gå in på nu. Om du läser igenom problemet set, kommer du att förstå dessa. Lång historia kort, de är bara att säga, detta är en bitmap-fil, och bekräftar att. Nästa, vi skriver dem till ut filen. Vi ser det här. Vi skriver den ut pekaren. Därefter ska vi bestämma stoppning. Så återigen, som är egenhet med en bitmap-fil, några rader inkluderar stoppning i slutet. Och om du läser igenom problemet set, du kommer att lära dig mer om utfyllnad. Detta är formeln för att hitta stoppning. Viktigt att komma ihåg - när du ändrar storlek på en bitmapp fil, stoppningen ändras. När du ändrar storlek på en fil, stoppningen ändras. Det kommer aldrig att bli större än 3 - det ska vara 0 till 3, inkluderande. Men när du ändrar storlek på något, stoppningen ändringar. Om jag bara har en pixel i den raden, jag behöver tre byte av stoppning, eftersom varje rad måste vara multipler av fyra bytes länge i en bitmap-fil. Men om jag dubbla det, att gå från en pixel att två pixel, som var och en, låt oss säga, är ett byte, då jag behöver två byte av stoppning för att göra som är lika med fyra. Så när jag ändra storleken på något, Jag behöver ändra beloppet av stoppning jag har. Är det vettigt att alla? Därefter iterera vi över varje rad, eller genom alla rader. Och sedan iterera vi igenom varje kolumn i varje rad. Vi ska behandla denna bitmapp som ett rutnät, som vi har behandlat styrelsen i 15. Som vi behandlade blocken när vi tryckt dem på skärmen. Ett rutnät med rader och kolumner. Då - vi såg detta. Vi har faktiskt bara kodat detta. Vi skapade en tillfällig lagring. Vi läser in där, och sedan Vi skriver ut det. Detta är precis vad vi just gjorde. Nästa, eftersom jag sa varje rad slutar i några stoppning, vi hoppa över den utfyllnad - den gamla stoppning. Och då kan vi lägga till den igen. I det här fallet skapar vi exakt samma fil. Vi bara kopiera den. Så denna linje är ganska dumt. Vi kunde bokstavligen bara sätta stoppningen i. Men om du ändrar storleken på filen, Vill du fortfarande här linjen? Så om vi ändrar storleken på en fil, vill vi ändå vill hoppa över den gamla stoppning? STUDENT 74: Ja. JASON Hirschhorn: Så vi gör. Eftersom denna, återigen, erbjudanden med källfilen. Vi bryr oss inte om utfyllnaden från källfilen. Vi vill gå till nästa rad. Men vi vill inte bara sätta tillbaka den gamla mängden stoppning. Vi måste sätta tillbaka den ny mängd stoppning. Så när vi ändrar storleken på en fil, ändå vill vi att hoppa över stoppning i den gamla filen - vad Vi läser in från. Men det vi skriver till, kommer vi att behöva lägga tillbaka några olika antal vaddering som vi har fastställt. Yeah. STUDENT 75: Ordningen på dessa två linjer ingen roll, eller hur? Eftersom du hanterar olika filer. JASON Hirschhorn: Exakt. Ordningen för dessa två linjer spelar ingen roll. Vi skriver den här raden. Det är här för filen vi skriver till. Det är viktigt, så att vi får rätt mängd fyllning. Detta har att göra med den i filen. Vi vill hoppa över stoppningen. Vi vill inte läsa - Om vi ​​läser en byte i taget, vi bryr sig inte om de stoppning byte. Vi vill flytta till nästa rad. Slutligen precis som Lucy gav för oss, vi stänger filerna och återgå 0. Så detta är copy.c. Och vi skrev faktiskt - vi tillbringade större delen av avsnitt skriver detta, i grunden. Du gjorde det här. Så förhoppningsvis har du en bra känsla av vad som händer här. Den stora skillnaden, ärligt talat, är bara denna första del som behandlar egenheter i bitmap-filer. Så jag har som min nästa bild, vad behöver vi göra? Nåväl, låt oss tänka på deckare. Och för någon som läser igenom problemet satt, vad gör vi behöver göra DECKARE? Simply. Aleja. Aleja: Kan du ta ut den del för varje pixel som betecknar rött. Och sedan - slags? JASON Hirschhorn: OK. Så ta ut den del av varje pixel som markerar rött. Det är nära, men inte alla av det. STUDENT 76: Tja, det finns olika sätt att göra det. JASON Hirschhorn: OK. Ge mig ett sätt. STUDENT 76: Ta ut alla röda, och sedan betona blått och grönt. JASON Hirschhorn: OK. Så med tanke på båda dessa sätt - det låter som vi ger det en bildpunkt, det har en röd, blå och grön nivå. Vi vill förändra de relativa nivåerna av den röda, blå och grön, beroende på detta bildelement. Var i denna kod bör vi ändra den relativa rött, blått och grönt nivåer av en given pixel. Efter att vi har läst den - innan vi skriva det? Ge mig radnumret. FLERA STUDENTER: 83. JASON Hirschhorn: 83. Så just här. För deckare, den kod du behöver för att skrivning borde alla gå där. Och det är den enda kod du behöver för att skriva. Därför att, som vi hört, allt du behöver för att göra är att ändra dessa relativt blå, röda och gröna nivåer från varje pixel. Du har läst det på, och nu är du kommer att skriva ut det. Hur får jag - om jag har den här grejen kallad triple, just här, och det är av skriver RGBTRIPLE - väl, om vi såg i bmp.h, vad är RGBTRIPLE? STUDENT 77: Det är en struct. JASON Hirschhorn: RGBTRIPLE är en struct. Vi ser att här ända ner. Och så om jag ville tillgång till, säg, röd nivå av struct, hur gör jag komma åt den röda nivån på denna struct? [KLASS Sorl] STUDENT 78: RGBTRIPLE.rgbtred? JASON Hirschhorn: Är det korrekt? STUDENT 79: Det bör vara trippel punkt, i stället för RGBTRIPLE prick? JASON Hirschhorn: Triple. Triple är den lokala variabeln, så här, det finns inga tips här. Så vi bara använda punktnotation. Detta kommer att ge mig den nivå av rött. Om jag vill ändra det, jag bara ställa det lika med något annat. Så återigen, denna kodrad åtkomst denna variabel inuti denna struct, och Vi kan ställa in den på något nytt. Så för deckare, återigen, är det, i grund och botten vad vi behöver göra. Mycket enkelt. Ändra precis några relativa nivåer, och det är där den koden går. Ändra storlek, å andra sidan, är lite knepigare. I själva verket är omformate förmodligen svåraste delen av detta problem inställd. Vi har tre minuter att gå över den. Men återigen, vi har redan skrivit de flesta av denna kod, så vi borde vara ganska bekant. Vad är några saker som vi vill göra i ändra storlek, om du har läst över problem set? Om du ger dem till mig, vi kan prata om dem. Vad är några saker som vi vill göra? STUDENT 80: Vertikalt - så du måste vågrätt ändra storlek på den, men vertikalt ändra storlek på den också? JASON Hirschhorn: Så om vi får en pixel, och vi vill ändra storlek på den genom en faktor på två, måste det nu vara storleksändras vågrätt och ändra storlek vertikalt. Låter det vettigt? Yeah. Så det är nog största utmaningen. Och vi ska prata om det i en sekund. Yeah. STUDENT 81: Som jag tänkte på det var du behövde skriva ut den - JASON Hirschhorn: Vänta. Tala inte om för oss vad du gjorde. Vi kommer att prata i logik. STUDENT 81: OK. Vad var frågan? JASON Hirschhorn: Du bara höjde handen. Det var ingen fråga. Låt mig presentera den. Låt mig bara diskutera detta kort. Så vi har en pixel, vill vi kopiera den, både horisontellt och vertikalt. Så idealt vad vi gör här är att vi Läs i vår pixel, vi skriver det men många gånger. Men sedan har vi våra knep här, eftersom då vill vi att hoppa till nästa rad och skriva den på början av nästa rad. Så om vi vill att replikera både horisontellt och vertikalt, vad som är ett bra sätt att göra det - en bra men för att göra det? Så vi behöver inte ständigt söka runt vår fil att placera saker. Den frågan kanske inte har var vettigt, men jag tror att en svara för det kommer att hjälpa. STUDENT 82: Skapa en array? JASON Hirschhorn: Så låt oss tänka av varje fil som en rad. Låt oss tänka i termer av rader. Om vi ​​har vår första raden från vår lilla bild, kan vi göra den raden i en stor rad från en stor bild, och sedan kopiera den raden dock många gånger som behövs för att replikeras, snarare än att gå pixel för pixel, vilket blir förvirrande när hantera filer. För om vi hade - Jag kör ut i rymden. Om detta är vår fil, och vi har som en pixel där, och vi vill lägga den just där, har vi fortfarande en del saker att behöva gå dit när vi är skriva och skapa vår nya fil - vår fil som är dubbelt så stor. Men det är verkligen svårt med filfunktioner att hoppa runt till nya linjer så där, och sedan gå tillbaka hit och lägga saker där. Det är nästan omöjligt att göra något så, om det är vettigt. Så om vi tänker i termer av rader, kan vi ta vår rad, och sedan lägga den - replikera rader vertikalt. Och det är hur vi handskas med storleksändring vertikalt istället för horisontellt. Det var typ av snabb, och lite förvirrande. Tyvärr vår tid är slut. Jag kommer att stå utanför för dig här som har frågor om Problemet set, inklusive återhämta sig. Så låt oss skjuta för nu. Och igen, om du har några frågor, vi kan prata utanför.