[Musik Spela] DAVID J. MALAN: Okej. [SKRATT] Välkommen tillbaka. Detta är CS50. Och detta i slutet av vecka fem. Och fram tills nu, har vi ganska mycket tagit för givet att det finns denna kompilator, klang, som du har varit åberopande genom detta andra verktyg som kallas Gör som på något sätt magiskt omvandlar din källkod i objektkod, nollor och ettor att datorns CPU, central behandlingsenhet, faktiskt förstår. Men det visar sig att det finns ett antal som är händer under huven på mellan ingång och utgång. Och jag skulle vilja föreslå att vi kött att i lite mer detalj i dessa fyra steg, något som kallas förbehandling, något kallas kompilering, som vi har sett, något som kallas montering, och något som kallas länkning. Så fram tills nu, i några av våra program, vi har haft kraftig ingår. På senare tid har vi haft några vassa definierar för konstanter. Så visar det sig att de saker som inleds med den hash symbol eller pundet symbolen är pre-processor direktiven. Det är bara ett finare sätt att säga att det är en kodrad som faktiskt omvandlas till något annat innan Datorn försöker även att konvertera din program till ettor och nollor. Exempelvis ingår skarp standard I / O. H, ganska mycket bara innebär att gå framåt, greppa innehållet i filerna stdio.h och klistra in dem där. Så inga ettor och nollor vid den punkten ännu. Det är egentligen bara ett byte. Och det är gjort under den så kallade förbehandling skede, när du faktiskt köra klang eller specifikt Gör i de flesta fall. Så allt detta har hänt först automatiskt hittills. Sedan kommer sammanställningen steget. Men vi har oversimplified kompilering. Sammanställa ett program verkligen innebär att ta det från något som C, den källkod som vi har skrivit, ned till något som kallas församling. Assembler är en lägre nivå språk som, tack och lov, kommer vi inte har föranleda mycket till skriva denna termin. Men det är på den lägsta nivån i meningen att du bokstavligen börja skriva addera och subtrahera och multiplicera och lasta från minnet och sparar i minnet, den mycket grundläggande instruktioner som en dator, under huven, faktiskt förstår. Slutligen tar monterar det språket till nollor och ettor som vi har varit beskriver hittills. Och verkligen Slutligen finns det så kallade länka fas, som vi kommer se på bara ett ögonblick, som kombinerar era nollor och ettor med nollor och ettor andra människor före du har skapat. Så överväga detta super enkla program. Det var från vecka 1. Det sa bara, Hello World, på skärmen. Vi körde detta genom klang. Eller vi körde igenom Gör som körde klang. Och utmatas vid den tidpunkt där några nollor och ettor. Men det visar sig att det finns ett mellanliggande steg. Om jag går hit - oops, inte vill se honom ännu. Om jag går hit till min apparat och jag öppnar upp hej.c, här är det samma program. Och vad jag ska göra i min terminal Fönstret här är jag ska kör klang snarare än att göra, vilket automatiserar alla fyra dessa steg för oss. Och jag ska göra klang-S och sedan hej.c och ange sedan. Och jag får en blinkande prompt igen, vilket är bra. Och nu i en något större fönster, Jag kommer att öppna upp gedit i här. Och jag ska öppna en fil som, visar sig, kallas hello.s detta innehåller det assembler Jag hänvisade till tidigare. Och detta är vad som kallas församling språk, tämligen låg nivå instruktioner som din Intel CPU eller vad det är som finns inuti förstår. Och mov är för drag. samtal är för ringer, en mycket låg nivå funktion. sub är för subtrahera. Så när du har en viss processor inuti av datorn, gör vad den distinkta, kontra andra processorer på marknad, är vilka anvisningar det förstår och ofta hur effektivt det är, hur snabbt det är på att genomföra några av dessa instruktioner. Nu mer om detta, kan du ta nästa höst CS61 vid högskolan. Men här har vi, till exempel, ett fåtal identifierare som kanske ser bekant. hello.c är namnet på programmet. . Text - det finns inte mycket av intresse där just nu, minns att texten segment, och med måndagen, är där i minne ditt program slutar faktiskt upp. Så det är åtminstone vagt bekanta där. Här, naturligtvis, är ett omnämnande vår huvuduppgift. Rulla ner, dessa hänvisar till saker kallade register, mycket små bitar av minne i din faktiska CPU. Och om jag rulla ner ännu vidare, ser jag någon sorts indirekt omnämnande av ASCII. Och det, faktiskt, är att strängen, hej, kommatecken, värld. Så lång historia kort, har detta varit händer för dig, automatiskt, under huven all denna tid. Och vad har hänt egentligen är en gång du har kört klang, eller genom Gör, du får första, från källkoden, den så kallade assembler. Sedan klang är att omvandla denna församling språket ner till ettor och nollor. Och detta är den bild som vi började vår diskussion i vecka 0 på - och sedan Vecka 1 på. Och sedan slutligen, dessa nollor och ettor kombineras med nollor och ettor från dessa bibliotek som vi har tagit för givet som Standard I / O eller String bibliotek eller ens den CS50 biblioteket. Så att måla denna bild mer visuellt, har vi hej.c. Och det, naturligtvis, använder printf fungera att säga, hej världen. Sammanställningen steget tar ner det till den filen såg vi bara hello.s, även men som normalt har raderats automatiskt för dig. Men det är den assemblerkod i mitten steget. Och sedan när vi monterar aggregatet språk, så att säga, det är då du få dessa nollor och ettor. Så vi har zoomat in på ett effektivt sätt i dag på vad vi har tagit för givet, innebär att gå källkod att invända kod. Men slutligen, nu när samma bild - Låt oss skjuta det över till den vänstra sidan. Och notera att i toppen finns Jag nämnde stdio.h. Det är en fil som vi har inkluderat i nästan alla av program som vi har skrivit. Och det är den fil vars innehåll får kopiera klistras, effektivt ovanpå din kod. Men det visar sig att, på en dator systemet någonstans, det finns förmodligen en stdio.c fil som någon skrev år sedan som implementerar alla funktioner som förklarades i stdio.h. Nu i verkligheten är det nog inte på din Mac eller din PC eller ens i CS50 apparaten är en rå C-kod. Någon sammanställt redan det och inkluderade . O fil för objektkod eller. En fil, som hänvisar till ett delat bibliotek som blivit förinstallerat och förkompilerade för dig. Men antar att det faktiskt existerar på vår dator stdio.c parallellt med Clang. Din kod är under utarbetande och monteras. stdio.c 's kod ska sammanställas och monteras, så att denna mycket sista steg, här nere, måste vi på något sätt länk, så att säga, dina nollor och ettor med sina ettor och nollor i en enkelt program som i slutändan är kallas bara Hej. Så det är all den magi som är har hänt hittills. Och kommer att fortsätta att ta dessa processer för givet, men inser det finns en hel del smaskiga detaljer händer under det. Och detta är vad som gör din dator med Intel Inside särskilt tydlig. Så på detta meddelande, om du vill ansluta oss till lunch på fredag, går till det vanliga stället cs50.net/rsvp, 13:15 på fredag. Och nu några tillkännagivanden. Så vi har några goda nyheter. Och vi har några dåliga nyheter. Börja med några goda nyheter här. [STÖNANDE] Okej. Tja, det är tekniskt en helgdag, så det är inte så mycket en gåva från oss. Men då den dåliga nyheten förstås. [STÖNANDE] Jag tillbringade mycket tid på dessa animationer. [SKRATT] Det kommer att finnas en översyn session denna kommande måndag. Det kommer att vara klockan 5:30. Vi kommer att påminna dig om alla dessa detaljer via e-post på kursens hemsida på bara ett par dagar tid. Det kommer att filmas och göras tillgängliga kort därefter. Så om du inte kan göra det måndag natt kortplats, oroa dig inte. Sektioner den kommande veckan kommer också fokusera på översyn för frågesport. Om din avsnitt är på måndag, vilket är indeed universitet semester, kommer vi fortfarande träffas i avsnittet. Om du helt enkelt inte kan göra det avsnitt eftersom du kommer bort, det är bra. Delta i en söndag eller tisdag avsnitt eller tune in till Jasons avsnitt, vilket är tillgängliga online. Så, mer dåliga nyheter. Så enligt kursplanen, Vi har föreläsning nästa fredag. Men de goda nyheterna - klart, jag tillbringade för mycket tid på detta. [SKRATT] Vi ska avbryta nästa fredagens föreläsningar. Så det kommer att bli en present till oss, så att du kan verkligen ha en trevlig paus i mellan denna vecka och två veckor framåt. Så ingen föreläsningar nästa vecka, bara en liten lite frågesport, som du bör vara blir allt mer upphetsad. Så låt oss nu vända vår uppmärksamhet mot något som faktiskt är mer visuell och mer spännande och att ställa scenen för vad som kommer att vara på horisonten på bara ett par veckor. Efter den första frågesporten, vi vrider fokusera på vårt problem set till en annan domän specifikt problem, som kriminalteknik och säkerhet mer allmänt. Faktum är att tradition med detta problem set är för mig en av de undervisning karl eller certifikatutfärdare för att gå över campus ta några fotografier av identifierbara men icke uppenbara människor, platser eller saker, då varje år jag på något sätt lyckas råkar radera eller korrupta digitala mediekort som är inne i vår kamera. Men ingen big deal. Jag kan gå vidare och plugga som i min dator. Jag kan göra en rättsmedicinsk bild av den, så att tala, genom att kopiera nollor och ettor off av denna minneskort, vare dess ett SD-kort eller compact flash-kort eller vad du är bekant med. Och då kan vi dela ut det. Och så utmaningen framöver, bland annat saker för dig, kommer att vara att skriva C-kod som återvinner en hel massa JPEG för mig och avslöjade blir dessa människor, platser eller saker. Och vi kommer också att prata, i detta problem ställa och i dagarna framöver, om grafik mer allmänt. Vi har använt dem, en kurs, för att bryta ut. Men du har slags tagit för givet det finns dessa höga nivå föreställningar av rektanglar och ovaler. Men under huven det finns pixlar. Och du har fått börja tänker på dem. Eller du kommer för p-set 4 måste tänka om gapet mellan dina tegelstenar, hur snabbt du bollen rör sig över skärmen för att bryta ut. Så det är denna föreställning om prickar på skärmen som är spelar in redan. Nu vad du ser, är dock vad du får på en datorskärm. Om du någonsin tittat på några bra eller dålig TV, oddsen är att de ganska mycket behandla publiken som technophobes som inte riktigt vet mycket om datorer. Och så är det väldigt lätt för polisen detektiv att säga, kan du städa upp det för mig? Eller förbättra, eller hur? Förbättra är som modeord i mest något brott relaterade show. Och verkligheten är om du tar en mycket suddig bild av en misstänkt gör något dåligt, kan du inte bara öka den. Du kan inte zooma in steglöst. Du kan inte se i glimt av någons öga som begick det särskilt brott, trots att Prevalensen av denna på TV. Och så med att vi motivera att kommande problem som med en glimt vissa visar med vilken du kan vara bekant. [VIDEO SPELA] -OK. Nu, låt oss få en bra titt på dig. -Vänta. Kör det tillbaka. -Vänta lite. Gå höger. -Där. Frys det. -Full skärm. -OK. Frys det. -Dra upp på det, kommer ya? -Vektor i den där killen av att den bakre hjulet. -Zoom in just här på denna plats. -Med rätt utrustning, det avbildade kan förstoras och skärpas. -Vad är det? -Det är en förbättring program. -Kan du klara det upp någon? -Jag vet inte. Låt oss stärka den. -Förbättra sektion A-6. -Jag förbättrade detaljer och - -Jag tror att det räcker att öka. Släpp det till min skärm. -Förbättra reflektion i hennes ögon. -Låt oss köra detta genom videoförstärkning. -Edgar, kan du förbättra detta? -Vänta. -Jag har arbetat med denna reflektion. -Någon eftertanke. -Reflection. -Det är en reflektion av mannens ansikte. -Den reflektion. -Det är en reflektion. -Zoom in på spegeln. -Du kan se en reflektion. -Kan du förbättra bilden härifrån? -Kan du förbättra honom just här? -Kan du förbättra den? -Kan du förbättra den? -Kan vi förbättra detta? -Kan du förbättra den? -Vänta lite, jag ska förbättra. -Zoom in på dörren. -X10. -Zoom. [SKRATT] -Flytta in -Vänta, sluta. -Sluta. -Paus. -Rotera en 75 grader runt den vertikala behaga. [SKRATT] -Sluta, och tillbaka till den del om dörren igen. -Fick en bild förstärkare som kan bitmap? -Vi kanske kan använda Pradeep Sen metod för att se in i windows. -Denna programvara är state of the art. -Ikonen värdet är avstängd. -Med rätt kombination av algoritmer. -Han har tagit belysning algoritmer för att nästa nivå och jag kan använda dem till förstärka detta fotografi. -Lock på och förstora den z-axeln. -Förbättra. -Förbättra. -Förbättra. -Freeze och förbättra. [END VIDEOAVSPELNING] DAVID J. MALAN: Så Problem Set 5 är vad som väntar där. Så vi kommer snart att få en bättre förståelse om när och varför du kan och vår inte kan öka på det sättet. Men först, låt oss återvända vår uppmärksamhet till några av de byggstenar vi ska måste kunna berätta den historien. Så minns att vi drog denna bild på Måndag och lite förra veckan. Och detta beskriver layouten av saker i datorns minne när kör vissa program. Den tech segment där uppe, återkallelse, hänvisar till de faktiska nollor och ettor att komponera ditt program. Det finns, under det, en del initierade eller oinitierade uppgifter, som typiskt refererar till saker som konstanter eller strängar eller globala variabler som har försatts i förväg. Det finns i högen, men vi ska komma tillbaka till det på en bit. Och sedan finns det stacken. Ungefär som en stapel av brickor i cafeteria, det är här minnet blir skiktad och skiktas när du gör vad i ett program? Vad är det stack användning för? Yeah? Ring av funktion. Varje gång du ringer en funktion, det är ges till flisa av minne för dess lokala variabler eller dess parametrar. Och bildmässigt, ser vi att med varje successiv funktion kallas, när A Parlamentet B kallar C samtal D, de få skiktas på stapeln. Och inom varje av dessa skivor minnet är i huvudsak en unik räckvidd för denna funktion, vilken, naturligtvis, är problematiskt om du vill lämna från en funktion till en annan En bit av data som du vill ha det att mutera eller ändra. Så vad var vår lösning för att möjliggöra En funktion som representeras av en stapel rama ändra det minne inuti av en annan stack ram? Hur gör de två prata med varandra? Så med hjälp av pekare eller adresser, vilket, återigen, bara beskriva var i minne, i form av en specifik bita nummer, den speciella värde kan hittas. Så minns förra gången också vi fortsatte berättelsen och tittade på en ganska buggig program. Och detta program är buggyn för ett fåtal skäl, men det mest oroande en är eftersom den inte kontrollera vad? Ja, misslyckas det att kolla in. Förlåt? Om det är mer än 12 tecken. Så mycket smart, när du ringer memcopy, vilket, som namnet antyder, precis kopior minne från sitt andra argument in i sitt första argument. Det tredje argumentet, mycket smart, är kontrolleras för att säkerställa att du inte kopiera mer än, i det här fallet, längden av bar, antal tecken, in i destinationsvektorn, är vilken denna array C. Men problemet är att det om C själv är inte stor nog att hantera det? Du kommer att kopiera det antal byte som du har fått. Men vad har du egentligen mer byte än du har utrymme för? Nåväl, det här programmet är mycket dumt bara blint fortsätter att ta vad det är givet, är hej backslash 0 bra om strängen är kort nog, liksom fem tecken. Men om det är faktiskt 12 tecken eller 1.200 tecken, såg vi förra gången att du bara kommer att helt överskrivning minne som tillhör inte dig. Och värsta fall, om du skriver att röda delen där som vi kallade returadress - detta är precis där datorn automatiskt, för dig, bakom scener, stoppas undan ett 32-bitars värde som påminner den till vilken adress det ska tillbaka när foo, denna andra funktion, görs verkställande. Det är ett bröd smula slags till vilken den återvänder. Om du skriver det, potentiellt, om du är den onde, kan kunde potentiellt ta över någons dator. Och du kommer säkerligen krascha det i de flesta fall. Nu är detta problem var bara förvärrat när vi började prata om minnet förvaltningen mer generellt. Och malloc, för minnesallokering, är en funktion som vi kan använda för att fördela minnet när vi inte vet i förväg att vi kanske behöver. Så, till exempel, om jag går tillbaka till apparaten här. Och jag öppnar upp från förra gången hello2.c, minns detta program här, som såg lite ungefär så här, bara tre rader - uppge ditt namn, sedan string namn, till vänster, lika getString. Och då kan vi skriva ut det, användarens namn. Så detta var ett super enkelt program. För att vara tydlig, låt mig gå vidare och göra hello-2. Jag kommer att göra dot slash hello-2. Uppge ditt namn - David. Enter. Hej David. Det verkar fungera OK. Men vad som verkligen händer under huven här? Först ska vi skära ner några lager. String är bara en synonym vi har insåg för vad? Char stjärna. Så låt oss göra det lite mer svårbegripliga men mer tekniskt korrekt att detta är en röding stjärna, vilket innebär att namn, ja, är en variabel. Men vad namn butiker är adressen en röding, vilket känns lite konstigt eftersom jag får tillbaka en sträng. Jag får tillbaka flera tecken inte en röding. Men naturligtvis behöver du bara den första röding adress att komma ihåg när Hela strängen är därför varför? Hur tror du ut där i slutet av strängen är att veta i början? Det omvända snedstrecket noll. Så med dessa två ledtrådar du räkna ut före början och slutet av varje sträng är, så länge de är korrekt utformad med den null terminator, som omvänt snedstreck noll. Men detta kräver getString. Och det visar sig att getString hela denna tid har varit lite fusk för oss. Det har gjort detta arbete, för att vara säker, få en sträng från användaren. Men var är det minne kommit från? Om vi ​​går tillbaka till bilden här och tillämpa definitionen från bara en stund sedan, att stapeln är där minne går när funktioner kallas, med den logiken, när du ringer getString, och då jag skriver in D-A-V-I-D Enter, där är D-A-V-I-D omvänt snedstreck noll lagras, baserat på den Historien har vi berättat för oss långt? Det verkar vara i stapeln, rätt? När du ringer får sträng får du en liten del av minnet på traven. Så det är självklart att D-A-V-I-D omvänt snedstreck noll lagras det i stapeln. Men vänta lite, getString avkastning den strängen, så att säga, vilket betyder Det är magasinet från cafeterian tas bort från stapeln. Och vi sade förra gången att så fort en returnerar funktionen, och du tar det bricka, så att säga, av stapeln, vad kan du anta om resterna av att minnet? Jag sorts ritade dem som frågetecken eftersom de blir effektivt okända värden. De kan återanvändas när vissa nästa funktion kallas. Med andra ord, om vi råkar att lagra - Jag drar en snabb bild här i bunten. Om vi ​​råkar dra ned av mitt minne segmentet, och vi ska säga att detta är platsen för minnet ockuperat av huvud och kanske arg c och arg v och allt annat i programmet, när getString kallas, förmodligen getString blir en bit av minnet här. Och sedan D-A-V-I-D somehow hamnar i denna funktion. Och jag ska förenklingarna. Men låt oss anta att dess D-A-V-I-D omvänt snedstreck noll. Så här många bytes som används i ramen för getString. Men så fort getString avkastning, vi sade förra gången att detta minne över här hela blir - Woops! - allt blir effektivt raderas. Och vi kan tänka på det nu som frågan varumärken för vem vet vad som kommer att bli av det minnet. Sannerligen, jag ofta kallar funktioner andra än getString. Och så fort jag kallar någon annan funktion än getString, kanske inte i detta särskilda program vi bara såg på men någon annan, säkert någon annan Funktionen kan hamna givet denna nästa plats i stapeln. Så det kan inte vara så att getString butiker D-A-V-I-D på stacken eftersom jag skulle omedelbart förlora tillgången till den. Men vi vet att de getString bara tillbaka vad? Det är inte återvänder till mig sex tecken. Vad är det återvänder verkligen gjorde vi sluta förra gången? Adressen för den första. Så på något sätt, när du ringde getString, det fördela en del av minnet för strängen som användarna skriver och sedan återvänder adress av det. Och det visar sig att när du vill fungera för att allokera minne i detta sätt och återgå till den som ringt den funktionen, adressen till att bit av minnet, absolut du kan inte sätta det i stapeln vid botten, eftersom funktionellt är det bara ska inte bli ert mycket snabbt, så du kan nog gissa var Vi kommer förmodligen att slänga det istället, den så kallade högen. Så mellan botten av ditt minne är layout och toppen av ditt minne är layout är en hel massa segment. En är stacken, och höger ovan är det i högen. Och högen är bara en annan del av minne som inte används för funktioner när de kallas. Den används för längre sikt minne, när du vill ha en funktion för att få tag i minne och kunna hänga på det utan att förlora kontrollen över det. Nu kan du kanske omedelbart se att detta inte är nödvändigtvis en perfekt design. När ditt program tilldelas minne på stacken, eller som du kallar mer och fler funktioner, eller som du tilldelar minne på högen med malloc ut som getString gör, vad tydligt verkar vara oundvikligt problem? Rätt. Liksom det faktum att dessa pilar pekar mot varandra bådar inte gott. Och faktiskt, skulle vi mycket snabbt krascha ett program i en rad olika sätt. I själva verket tror jag att vi kan ha gjort detta misstag en gång. Eller om inte, låt oss göra det medvetet nu. Låt mig gå vidare och skriva super snabbt ett program som heter dontdothis.c. Och nu ska jag gå in här och gör skarp inkluderar stdio.h. Låt oss förklara funktionen foo tar inga argument, är som betecknas som väl av ogiltiga. Och det enda foo kommer att göra är samtal foo, vilket förmodligen inte är den smartaste idé, men så var det. Ent main tomrum. Nu är det enda huvud går göra är att ringa foo också. Och bara för sparkar, jag kommer att gå framåt här och säga printf "Hej från foo ". OK. Så om jag inte gör några misstag, Gör dontdothis dot snedstreck. Och låt oss göra det i ett större fönster - dot snedstreck, dontdothis. Kom igen. Uh oh. Tydligen kan du göra det här. Fan också. OK. Vänta. Stand by. Gjorde vi - Vi använde det med Make. [Suckar] Jag vet, men jag tror att vi bara bort det. Öh, ja. Fan också. Lös det här Rob. Vad? Det är väldigt enkelt. Ja, vände vi optimering av. OK, stand bye. Nu känner jag mig bättre. OK. Okej. Så låt oss kompilera här - Gör du dontdothis. Du kanske måste byta namn här till dothis.c på bara ett ögonblick. Där vi går. Tack. OK. Så det faktum att jag skriver något var faktiskt bara bromsa den process genom vilken vi skulle ha nått den punkten. OK. Phew! Så vad som verkligen händer? Anledningen till det, precis som en åt sidan, är göra något i form av insatser och produktionen tenderar att vara långsammare eftersom du måste skriva tecknen till skärm, har den att rulla. Så lång historia kort, jag hade faktiskt hände så otålig, skulle vi ha sett denna slutresultatet också. Nu när jag fick rida på tryck-ups, Vi ser det genast. Så varför händer detta. Tja, den enkla förklaringen, naturligtvis, är att foo troligen inte att kalla sig. Nu i allmänna termer, detta är rekursion. Och vi trodde att ett par veckor sedan rekursivt är bra. Rekursion är denna magiska sätt uttrycka dig super kortfattat. Och det fungerar bara. Men det är en viktig del av alla de rekursiva program som vi har pratat om och såg på hittills, vilket var att de hade vad? Ett basfall, vilket var lite hårt kodad fall som sägs i vissa situationer inte kalla foo, vilket är klart inte fallet här. Så vad som verkligen händer i termer av denna bild? Tja, då main anropar foo, det får en bit av minnet. När foo anropar foo, blir det en bit av minnet. När foo anropar foo, blir det en bit. Det blir en skiva. Det blir en skiva. Eftersom foo aldrig återvänder. Vi kommer aldrig radera en av dem ramar från stacken. Så vi blåser igenom högen, inte att nämna vem vet vad, och vi att överskrida vår så kallade segment av minnet. Fel gå segmentering falskt. Så lösningen finns det uppenbarligen gör inte detta. Men den större innebörden är att, ja, det absolut finns en viss gräns, även om den inte är väl definierade, om hur många funktioner som du kan ringa i en program, hur många gånger en funktion kan kalla sig. Så även om vi predikade rekursion eftersom detta potentiellt magisk sak en par veckor sedan för sigma funktion, och när vi får de uppgifter strukturer och CS50, kommer du att se andra applikationer för det, det är inte nödvändigtvis det bästa. För om en funktion kallar sig, kallar sig, även om det finns en bas fall, om du inte träffar det basfall för 1.000 samtal eller 10.000 samtal, genom Då kanske du har slut på utrymme på din sk stack och hit vissa andra delar av minnet. Så det är också en design trade-off mellan elegans och mellan robusthet din genomförande. Så det finns en annan nackdel eller annan Gotcha vad vi har gjort hittills. När jag ringde getString - Låt mig gå tillbaka till hello-2. Lägg märke till att jag ringer getString, som återvänder en adress. Och vi hävdar idag att adress är från högen. Och nu är jag skriva ut sträng på den adressen. Men vi har aldrig kallat motsatsen till getString. Vi har aldrig haft att calll en funktion som ungetstring, där du lämnar tillbaka detta minne. Men ärligt talat vi förmodligen borde ha varit. För om vi frågar datorn för minnet, i form av någon som getString men aldrig ge det tillbaka, säkerligen även det är säkert leda till problem där vi får slut på minne. Och i själva verket kan vi leta efter dessa problem med nya verktyg vars användning är lite kryptiskt att skriva. Men låt mig gå vidare och stänka upp på skärmen på bara ett ögonblick. Jag ska gå vidare och köra Valgrind med parametern vars första kommandot line argument är namnet av det programmet hello-2. Och tyvärr är det utgången är atrociously komplex utan goda skäl. Så vi ser alla att röra. David är uppge mitt namn. Så det är det programmet faktiskt kör. Och nu får vi denna utgång. Så Valgrind liknar i anden till GDB. Det är inte en debugger i sig. Men det är ett minne checker. Det är ett program som kommer att köra programmera och berätta för dig om du frågade en dator för minne och aldrig räckte det tillbaka, vilket innebär att du har en minnesläcka. Och minnesläckor tenderar att vara dåligt. Och du är användare av datorer har förmodligen kände detta, oavsett om du har en Mac eller en PC. Har du någonsin använt din dator för samtidigt och inte startas om flera dagar, eller om du har precis fått en hel del program som körs, och den förbannade saken saktar till ett tvärstopp, eller åtminstone det är super irriterande att använda, eftersom allt blev bara super slow. Nu som kan vara någon av flera skäl. Det kan vara en oändlig loop, en bugg i någons kod, eller, mer helt enkelt, det kan betyda att du använder mer minne, eller försöker, än din Datorn har faktiskt. Och kanske finns det en bugg i vissa program att hålla ber om minnet. Webbläsare för åren var ökänd för detta, ber om mer och mer minne men aldrig lämnar tillbaka. Visst, om du bara har en ändlig mängd minne, kan du inte begära oändligt många gånger för några av detta minne. Och så det du ser här, även om igen Valgrind produktion är onödigt komplicerat att titta på först, detta är den intressanta delen. Heap - i bruk vid avfart. Så här är hur mycket minne var i bruk i högen på tid mitt program lämnat - tydligen sex byte i ett block. Så jag kommer att vifta mina händer på vad ett block är. Tänk på det är bara en bit, en mer tekniska ordet för bit. Men sex bytes - vad är de sex byte som var fortfarande i bruk? Exakt. D-A-V-I-D backslash noll, fem brev namn plus null terminator. Så det här programmet Valgrind märkte att jag bad om sex byte, tydligen, med sätt att getString, men aldrig gav dem tillbaka. Och i själva verket kan detta inte vara så uppenbart om mitt program är inte tre linjer, men det är 300 linjer. Så vi kan faktiskt ge en annan kommando line argument att Valgrind till göra den mer utförlig. Det är lite irriterande att minnas. Men om jag gör - låt oss se. Läcka - Var det läcka - även jag minns inte vad det är utanför sidan. - Läckage-kontroll är lika fullt. Japp, tack. - Läckage-kontroll är lika fullt. Enter. Samma program körs. Skriv in David igen. Nu ser jag lite mer detalj. Men under högen sammanfattning, som är identisk med fyra - ah, Detta är ganska trevligt. Nu Valgrind är faktiskt ute lite hårdare i min kod. Och det är att säga att, tydligen, malloc på rad - vi zooma ut. På linjen - Vi kan inte se vilken linje det är. Men malloc är den första gärningsmannen. Det finns en blogg i malloc. Okej? OK, ingen. Rätt? Jag ringde getString. getString kallar tydligen malloc. Så vad kodrad är tydligen vid fel för att ha tilldelas detta minne? Låt oss anta att den som skrev malloc har funnits så länge att det är inte deras fel. Så det är nog mitt. getString i cs50.c - så det är en fil någonstans på datorn - i linje 286 verkar vara den skyldige. Låt oss nu anta att CS50 har runt för anständig tid, så vi är för ofelbar. Och så det är nog inte i getString att felet ligger, utan i hello-2.C linje 18. Så låt oss ta en titt på vad den linjen 18 var. Oh. På något sätt denna linje är inte nödvändigtvis buggy, per se, men det är anledningen bakom denna minnesläcka. Så super enkelt, vad skulle intuitivt vara lösningen här? Om vi ​​ber om minnet, var aldrig ge tillbaka, och det verkar vara en problem eftersom tiden min dator kan få slut på minne, kan bromsa ner, kan dåliga saker hända, ja, vad är den enkla intuitiva lösningen? Bara ge det tillbaka. Hur frigöra dig att minnet? Jo, tack och lov är det ganska enkelt att bara säga fri namn. Och vi har aldrig gjort det här förut. Men du kan i princip tänka fri som motsatsen till malloc. gratis är motsatsen till allokering av minne. Så låt mig nu kompilera detta. Gör hello-2. Låt mig köra den igen. hello-2 David. Så det verkar fungera i exakt samma sätt. Men om jag går tillbaka till Valgrind och kör samma kommando på min nyligen kompilerat program, maskinskrivning i mitt namn som tidigare - trevligt. Heap Sammanfattning - i bruk vid avfart - noll byte i noll block. Och det är super trevligt, alla heap block frigavs. Inget läckage är möjliga. Så kommer upp, inte med Problem Set 4, men med problem 5 set, kriminalteknik och framåt, även detta kommer att bli en mått på riktigheten av din program, oavsett om du har eller inte har minnesläckor. Men tack och lov, kan du inte bara resonera genom dem intuitivt, vilket är, utan tvekan, lätt för små program men svårare för större program, Valgrind, för de större programmen, kan hjälpa dig att identifiera det aktuella problemet. Men det finns ett annat problem som kan uppstå. Låt mig öppna denna fil här, vilket är, igen, en något enkelt exempel. Men låt oss fokusera på vad detta program gör. Detta kallas memory.c. Vi kommer att lägga ut senare i dag i zip av dagens källkod. Och märker att jag har en funktion som kallas f som tar inga argument och returnerar ingenting. I linje 20, jag förklara tydligen en pekare till en int och kalla det x. Jag tilldelar är avkastningen värdet av malloc. Och bara för att vara tydlig, hur många bytes am Jag får förmodligen tillbaka från malloc i den här situationen? Förmodligen 40. Var får du det ifrån? Tja, om du minns att en int är ofta 4 byte, det är åtminstone i Apparaten är 10 gånger 4 uppenbarligen 40. Så malloc återvänder en adress en bit av minne och lagring som itu slutligen i x. Så för att vara tydlig, det då händer? Nåväl, låt mig byta tillbaka till vår bild här. Låt mig inte bara dra ner på mitt datorns minne, låt mig gå vidare och rita hela rektangel som representerar hela mitt RAM. Vi säger att stapeln är på botten. Och det finns en text segment i de oinitierade uppgifter. Men jag ska bara abstrakta dem annat bort som dot, dot dot. Jag kommer bara att hänvisa till detta som högen på toppen. Och sedan längst ner på denna bild, att representera huvud, jag ska att ge det ett segment minne på stacken. För f, jag ska ge det en bit av minne på stacken. Nu fick jag höra min källkoden igen. Vilka är de lokala variablerna för huvud? Uppenbarligen ingenting, så att skivan är effektivt tom eller inte ens så stor som jag har ritat det. Men i f, har jag en lokal variabel, som kallas x. Så jag kommer att gå vidare och ge f en bit av minnet, kalla det x. Och nu malloc av 10 gånger 4, Så 40 malloc, där det är minne kommer från? Vi har inte ritat en bild liknande förut. Men låt oss anta att det är ett effektivt sätt kommer från här, så en, två, tre, fyra, fem. Och nu behöver jag 40 av dessa. Så jag ska bara göra prick, prick, prick att föreslå att det finns ännu mer minne kommer tillbaka från högen. Nu vad är adressen? Låt oss välja vår godtyckliga behandla som alltid - Ox123, även om det förmodligen kommer att vara något helt annat. Det är adressen till första byten i minne som jag ber minnesallokera för. Så kort sagt, när ledningen 20 exekverar, vad är bokstavligen förvaras inuti av x här? Ox123. Ox123. Och oxen är ointressant. Det betyder bara att här är en hexadecimalt tal. Men vad som är avgörande är att det jag har butik i x, som är en lokal variabel. Men dess datatyp, igen, är en adress till en int. Tja, jag ska lagra Ox123. Men återigen, om det är lite för kompliceras i onödan, om jag bläddra tillbaka, kan vi abstrakta detta bort helt rimligt och bara säga att x är en pekare till bit av minnet. OK. Nu frågan till hands är följande - linje 21, visar det sig, är buggig. Varför? Förlåt? Det har inte - säga att en gång till. Jo, det gör det inte gratis. Så det är den andra utan. Så det finns en annan, men särskilt vid ledningen 21. Exakt. Denna enkla kodrad är bara en buffer overflow, en buffertöverskridning. En buffert betyder bara en bit av minnet. Men den del av minnet är av storlek 10, 10 heltal, vilket innebär att om vi index till det med hjälp av syntaktiska socker av array notation, torget konsoler, har du tillgång till x konsol 0 x konsol 1 x, fäste prick, prick, prick. x konsol 9 är den största. Så om jag gör x fäste 10, där Jag faktiskt går i minnet? Tja, om jag har 10 int - Låt oss rita faktiskt alla av dessa ut här. Så det var det första fem. Här är de övriga fem ints. Så x konsol 0 är här. x bracket 1 är här. x konsol 9 är här. x konsol 10 är här, vilket betyder att jag säger, i linje 21, till datorn sätta nummer där? Antalet 0 där? Tja, det är 0, ja. Men bara det faktum att dess 0 är lite av en slump. Det kan vara det antal 50, för alla vi bryr oss. Men vi försöker att uttrycka det på x konsol 10, som är där detta frågetecken ritas, vilket är inte en bra sak. Detta program kan mycket väl krascha som följd. Nu, låt oss gå vidare och se om detta är verkligen vad som händer. Gör minne, eftersom filen kallas memory.c. Låt oss gå vidare och köra programminnet. Så fick vi tur, faktiskt, verkar det. Vi hade tur. Men låt oss se om vi nu kör Valgrind. Vid första anblicken, mitt program kanske verkar vara helt rätt. Men låt mig springa Valgrind med - Läckage-kontroll är lika fullt på minnet. Och nu när jag kör här - intressant. Ogiltig skriva av storlek 4 på line 21 av memory.c. Linje 21 i memory.c är vilken? Åh, intressant. Men vänta. Storlek 4, vad är det att hänvisa till? Jag bara gjorde en skriva, men det är av storlek 4. Varför är det 4? Det är för att det är en int, vilket är återigen fyra bytes. Så Valgrind hittat en bugg som jag, blick på min kod, inte. Och kanske din TF skulle eller skulle inte. Vad Men Valgrind säkert funnit att Vi har gjort ett misstag där, även om vi har tur, och datorn beslutat, eh, jag kommer inte att krascha bara för att du rörde en byte, en int värde av minne som du inte faktiskt äger. Tja, vad annat är buggigt här. Adress - detta är en galen tittar adress i hexadecimal. Det betyder bara någonstans i högen är noll byte efter ett block av storlek 40 allokeras. Låt mig zooma ut här och se om Detta är en lite mer hjälp. Intressant. 40 bytes är definitivt förlorade i förlust rekord 1 av 1. Återigen, är mer ord än nytta här. Men baserat på de markerade linjerna, där ska jag fokusera förmodligen min uppmärksamhet för en bugg? Ser ut som en linje 20 i memory.c. Så om vi går tillbaka till rad 20, det är det en som du identifierade tidigare. Och det är inte nödvändigtvis buggy. Men vi har redan vänt dess effekter. Så hur löser jag åtminstone en av dessa misstag? Vad kan jag göra efter rad 21? Jag kunde göra utan x, så att ge tillbaka det minnet. Och hur kan jag fixa detta fel? Jag ska definitivt gå inte längre än 0. Så låt mig försöka och kör detta. Tyvärr, definitivt gå inte längre än 9. Gör minne. Låt mig köra Valgrind i ett större fönster. Och nu ser. Trevligt. Alla heap block frigavs. Inget läckage är möjliga. Och upp över här, det finns inget omnämnande något mer av det ogiltiga höger. Bara för att få giriga, och låt oss se om en annan demonstration går inte som planerat - Jag fick tur för en stund sedan. Och det faktum att detta är 0 är kanske onödigt vilseledande. Låt oss bara göra 50, en något godtycklig antal, fabrikat minne dot slash minne - fortfarande ha tur. Ingenting krascha. Anta att jag bara göra något riktigt dumt, och jag gör 100. Låt mig remake minne, dot slash minne - got lucky igen. Vad sägs om 1000? ints utanför, ungefär, där jag borde vara? Gör minne - fan det. [SKRATT] OK. Låt oss inte röra runt längre. Rerun minne. Där vi går. Okej. Så uppenbarligen du index 100.000 ints bortom där du borde ha varit i minne, dåliga saker hända. Så det här är naturligtvis inte en hård, snabb regel. Jag var typ av hjälp rättegång och fel att komma dit. Men detta beror på, lång historia kort, datorns minne är också indelad in i dessa saker som kallas segment. Och ibland, datorn faktiskt har gett dig lite mer minne än du ber om. Men för effektivitet, det är bara lättare att få mer minne, men bara berätta att du får en del av det. Och om du har tur ibland, Därför kanske du kan röra minne som inte tillhör dig. Du har ingen garanti för att det värde du sätter det kommer att stanna där, eftersom datorn tycker fortfarande att det är inte er, men det är inte nödvändigtvis kommer att slå en annan del av minnet i dator och framkalla ett misstag som detta här. Okej. Några frågor så på minnet? Okej. Låt oss ta en titt här, då, vid något som vi har tagit för beviljas under ganska lång tid, vilket är i denna fil som heter cs50.h. Så detta är en fil. Dessa är bara en massa av kommentarer där uppe. Och du kanske har tittat på detta om du petade runt på apparaten. Men det visar sig att hela tiden, när vi brukade använda sträng som synonym, det medel genom vilket vi förklarade som synonym var med detta nyckelordet typedef, för typ definition. Och vi i huvudsak säger, gör sträng en synonym för röding stjärna. Att de medel som stapeln skapat dessa stödhjul kallas strängen. Nu här är bara en prototyp för getchar. Vi kanske har sett det förut, men det är faktiskt vad den gör. getchar tar inga argument, returnerar en röding. getdouble tar inga argument, returnerar en dubbel. getFloat tar inga argument, returer en flottör, och så vidare. getInt är här. getlonglong är här. Och getString är här. Och det är det. Denna lila linjen är en annan preprocessor direktivet på grund av hashtag i början av den. Okej. Så låt mig nu gå in cs50.c. Och vi kommer inte att prata för länge på det här. Men för att ge dig en glimt av vad som finns pågått hela detta tid, låt mig gå till - låt oss göra getchar. Så getchar är mestadels kommentarer. Men det ser ut så här. Så detta är den verkliga funktionen getchar att vi har varit tar för givet existerar. Och även om vi har använder inte denna som ofta, om någonsin, är det åtminstone relativt enkel. Så det är värt att ta en snabb titt på här. Så getchar har en oändlig loop, medvetet så tydligen. Det kräver då - och det är lite av en trevlig återanvändning av kod vi själva skrev. Det kallar getString. För vad gör det innebära att få en röding? Tja, kan man lika gärna försöka få ett hel textrad från användaren och sedan bara titta på en av dessa tecken. I linje 60, är ​​här en liten bit av en sanity check. Om getString återvände null, låt oss inte gå vidare. Något gick fel. Nu är det här något irriterande men konventionellt i C. röding max förmodligen representerar vad just baserat på dess namn? Det är en konstant. Det är som det numeriska värdet av största röding du kan representera med en tugga, vilket sannolikt är den 255, vilket är det största antalet du representerar åtta bitar, med början på noll. Så jag har att använda detta, i denna funktion, när skriva denna kod, bara för att om något går fel i getchar men sitt syfte i livet är att returnera en röding, måste du på något sätt kunna att signalera till användaren att något gick fel. Vi kan inte returnera null. Det visar sig att null är en pekare. Och återigen, har getchar att returnera en röding. Så konventionen, om något går fel, är du, programmeraren, eller i detta fall mig med biblioteket, hade jag en bestämmer bara godtyckligt, om något går fel, kommer jag att returnera antalet 255, som verkligen är innebär att vi inte kan, kan användaren inte skriver tecknet representeras av nr 255 eftersom vi hade en stjäla det som en så kallad sentinel värde till representera ett problem. Nu visar det sig att karaktären 255 är inte något man kan skriva om tangentbordet, så det är ingen big deal. Användaren märker inte att Jag har stulit denna karaktär. Men om du ser någonsin i man-sidorna på en datorsystem någon hänvisning till en versaler konstant som denna som säger, i fall av misstag denna konstanta kraft returneras, det är allt en del människor gjorde år sedan var godtyckligt beslutat att returnera denna speciella värde och kalla det en konstant i fall något går fel. Nu det magiska händer här nere. Först, jag förklarar i linje 67 två karaktärer, C1 och C2. Och sedan i linje 68, det finns faktiskt en kodrad som är som påminner om vår vän printf, med tanke på att det har procent Cs inom citationstecken. Men märker vad som händer här. sscanf betyder sträng scan - innebär skanna ett formaterat sträng, ergo sscanf. Vad betyder det? Det betyder att du passerar till sscanf en sträng. Och linjen är vad användaren skriver i. Du passerar till sscanf ett format sträng som detta som berättar scanf vilka är Hoppas du att användaren har skrivit i. Du passerar in då adresserna för två bitar av minnet, i det här fallet, eftersom jag har två platshållare. Så jag kommer att ge den adressen C1 och adressen till C2. Och minns att du ger en funktion av adress viss variabel, vad är innebörden? Vad kan denna funktion gör som ett resultat för att ge den en adress till en variabel, i motsats till variabeln själv? Det kan ändra det, eller hur? Om du hade någon en karta till en fysisk adress, kan man gå dit och göra vad de vill på den adressen. Samma idé här. Om vi ​​övergår till sscanf, adressen till två bitar av minnet, även dessa små små bitar av minne, C1 och C2, men Vi berättar det adressen till dem, sscanf kan ändra det. Så sscanf syfte i livet, om vi läser mannen sida, är att läsa vad användaren har skrivit in, hoppas på att användaren behöver skrev i en karaktär och kanske annan karaktär, och vad användaren skrivit, går det första tecknet här, går det andra tecknet här. Nu, som en parentes, detta, och du skulle bara vet detta från dokumentationen, det faktum att jag sätter ett tomt utrymme där betyder bara att jag inte bryr mig om användaren slår på mellanslagstangenten några gånger innan han eller hon tar en karaktär, kommer jag att ignorera alla blanktecken. Så att, jag vet från dokumentationen. Det faktum att det finns en andra% c följt av blanktecken är faktiskt avsiktlig. Jag vill kunna detektera om användaren skruvas upp eller inte samarbetade. Så jag hoppas att användaren endast skrivit i ett tecken, därför hoppas jag att sscanf kommer bara att returnera värde 1, eftersom, återigen, om jag läser dokumentationen, sscanf syfte i liv är att återvända till det antal variabler som är fyllda med indata från användaren. Jag gick i två variabler adresser, C1 och C2. Jag hoppas dock att endast en av dem blir dödad för om sscanf returnerar 2, vad är förmodligen implikationen logiskt? Att användaren inte bara ge mig en karaktär som jag sa till honom eller henne. De skrev förmodligen på minst två tecken. Så om jag istället hade inte den andra % C, hade jag bara en, vilket uppriktigt sagt skulle vara mer intuitivt tillvägagångssätt, jag tror att en första anblick, du kommer inte att kunna upptäcka Om användaren har gett dig mer input än vad du egentligen ville. Så detta är en implicit form av felkontroll. Men märker vad jag gör här. När jag är säker på att användaren gav mig en karaktär, fri jag linjen, gör motsatsen till getString, vilket i sin tur använder malloc, och sedan återvänder jag C1, karaktären som jag hoppats på användaren tillhandahålls och endast tillhandahålls. Så en snabb skymt bara, men några frågor om getchar? Vi ska återkomma till några av de andra. Nåväl, låt mig gå vidare och göra detta - Antag nu, bara för att motivera vår diskussion i en vecka plus tid, detta är en fil som heter structs.h. Och återigen, detta är bara ett smakprov av något som ligger framför oss. Men märker att en hel på detta är kommentarer. Så låt mig belysa endast de intressant del för nu. typedef - Det är det samma sökord igen. typedef vi använder för att förklara sträng som en speciell datatyp. Du kan använda typedef för att skapa helt nya datatyper som inte fanns när C uppfanns. Till exempel kommer int med C. röding kommer med C. dubbel levereras med C. Men det finns ingen föreställning om en elev. Och ändå skulle det vara ganska bra att vara kunna skriva ett program som lagrar i en variabel, en student ID-nummer, deras namn, och deras hus. Med andra ord, tre stycken av data, som en int och en sträng och en annan sträng. Med typedef, är det ganska stark om detta och sökord sturct för struktur, dig, programmeraren under 2013, kan faktiskt definiera din egen att datatyper som inte existerade år sedan men som passar dina syften. Och så här i raderna 13 till 19, vi förklara en ny datatyp, som en int, men kalla det student. Och inne i denna variabel kommer att vara tre saker - en int, en sträng, och en sträng. Så du kan tänka på vad som verkligen är hände här, trots att detta är en lite av en förenkling för idag, en elev är i huvudsak går att se ut så här. Det kommer att bli en del av minne med ett ID, ett namn fält, och ett hus fält. Och vi kommer att kunna använda dessa bitar av minne och komma åt dem enligt följande. Om jag går in struct0.c, är här en relativt lång, men efter en mönster, av kod som använder denna nya trick. Så först, låt mig fästa er uppmärksamhet till de intressanta delarna där uppe. Sharp definierar studenter 3, förklarar en konstant kallas studenter och övertagare det godtyckligt numret 3, precis så jag har tre elever som använder detta program nu. Här kommer Main. Och lägg märke till hur jag deklarerar en samling av elever? Tja, jag använder precis samma syntax. Ordet elev är uppenbarligen nya. Men deltagare, klassificera, fäste studenter. Så tyvärr finns det en hel del av återanvändning av termer här. Detta är bara ett nummer. Så detta är som att säga tre. Class är precis vad jag vill att ringa variabeln. Jag skulle kalla det studenter. Men klass, detta är inte en klass i en objektorienterad Java typ av väg. Det är bara en klass elever. Och datatypen för varje element i matrisen är student. Så det här är lite annorlunda och från att säga något så här, det är bara - Jag säger ge mig tre elever och kallar den arrayen klassen. Okej. Nu här är en fyra loop. Den här killen är bekant - iterate från noll på upp till tre. Och här är den nya bit syntax. Programmet kommer att uppmana mig, människan, för att ge det en elev ID, som är en int. Och här är den syntax som du kan använda förvara något i ID-fältet vid plats klass bracket I. Så denna syntax är inte ny. Det betyder bara ge mig den åttonde elev i klassen. Men denna symbol är ny. Fram tills nu har vi inte kan användas prick, åtminstone i koden så här. Detta innebär att gå till struct som kallas en elev och sätta något där. Även i detta nästa rad, 31, går vidare och sätta vad användaren skriver för ett namn här och vad de gör för en hus, samma sak, gå vidare och lägga den i. huset. Så vad gör detta program slutändan göra? Du kan se en liten teaser där. Låt mig gå vidare och gör structs 0 dot slash struct 0, student ID 1, säger David Mather, student-ID 2. Rob Kirkland, student-ID 3. Lauren Leverit - och det enda programmet gjorde, vilket är bara helt godtyckligt, är Jag ville göra något med dessa data, nu när jag har lärt oss hur man använda structs, är jag bara tvungen denna extra slinga här. Jag iterera över gruppen av elever. Jag använde vår, kanske nu välbekanta vän, sträng jämföra, stircomp till kontrollen är 8th studentens hus lika med Mather? Och i så fall, bara skriva ut något godtyckligt gillar, ja, är det. Men återigen, bara ge mig möjligheter att använda och återanvända och återanvända denna nya dot notation. Så vem bryr sig, eller hur? Kommer upp med en elev programmet är något godtyckligt, men det visar sig att vi kan göra nyttiga saker med här till exempel enligt följande. Detta är en mycket mer komplicerad struct i C. Den har ett dussin eller fler områden, något kryptiskt heter. Men om du någonsin hört talas om en grafik filformat som kallas bitmapp, BMP, det visar sig att den bitmapp filformat ganska mycket ser ut som det. Det är en dum liten Smiley face. Det är en liten bild som jag har zoomat in på ganska stora så att jag kunde se varje av de enskilda punkter eller pixlar. Nu visar det sig att vi kan representera en svart prick med, säg, numret 0. Och en vit prick med nummer 1. Så med andra ord, att om du vill rita en Smiley face och spara den bilden på en dator, räcker det att lagra nollor och de som ser ut så här, där, igen, dessa är vita och nollor är svarta. Och tillsammans, om du har ett effektivt en omgjorda av ettor och nollor, har du en rutnät av pixlar, och om du lägger dem, har du en söt lilla Smiley face. Nu är bitmapp filformat, BMP, effektivt att under huven, men med fler pixlar sot som du kan faktiskt representera färger. Men när du har mer sofistikerade filformat som BMP och JPEG och GIF som du kanske känner, de filer på hårddisken vanligen inte bara ha nollor och ettor för pixlarna, men de har vissa metadata samt - meta i den meningen att är inte riktigt uppgifter men det är bra att ha. Så dessa områden här antyder, och vi får se detta mer i detalj i P-set 5, att innan de nollor och ettor som representerar pixlar i en bild, det finns en massa metadata som storleken på bilden och bredden på bilden. Och märker jag plocka upp några godtyckliga saker här - bredd och höjd. Biträkningen och några andra saker. Så det finns vissa metadata i en fil. Men genom att förstå hur filer läggs ut på detta sätt, kan du faktiskt sedan manipulera bilder, återhämta bilder från disk, ändra storlek på bilder. Men du kan inte nödvändigtvis förbättra dem. Jag behövde ett fotografi. Så jag gick tillbaka till RJ hit, vem du såg på skärmen ganska länge sedan. Och om jag öppnar Keynote här, är detta vad händer om du försöker att zooma in och förbättra RJ. Han blir inte bättre egentligen. Nu Keynote är slags oskärpa det en lite, bara för att släta över faktum att RJ inte blir särskilt förbättrad när du zoomar in Och om att göra det här sättet, se rutorna? Ja, kan du se definitivt rutorna på en projektor. Det är vad du får när du förbättra. Men att förstå hur vår RJ eller Smiley face genomförs kommer att låta oss faktiskt skriva kod som manipulerar dessa saker. Och jag trodde att jag skulle sluta på denna anmärkning, med 55 sekunder av ett förhöja det är, Jag vågar säga ganska missvisande. [VIDEO SPELA] -Han ljuger. Om vad, vet jag inte. -Så vad vet vi? -Det at 9:15 Ray Santoya var på ATM. -Så frågan är vad gjorde han vid 9:16? -Inspelningen nio millimeter på något. Kanske såg han prickskytt. -Eller jobbade med honom. -Vänta. Gå tillbaka en. -Vad ser du? -Ta med ansiktet uppåt, helskärm. -Hans glasögon. -Det är en reflektion. -Det är Neuvitas basketlag. Det är deras logotyp. -Och han pratar med den som är bär den jackan. [END VIDEOAVSPELNING] David J. MALAN: Detta kommer vara Problem Set 5. Vi kommer att se dig nästa vecka. HANE SPEAK: Vid nästa CS50. [Syrsor som gnisslar] [Musik Spela]