[Powered by Google Translate] [VECKA 5] [David J. Malan, Harvard University] [Detta är CS50.] [CS50.TV] [Kvinna] Han ljuger, om vad, vet jag inte. [Man] Så vad vet vi? [Kvinna] Det vid 9:15, var Ray Santoya på ATM. [Man] Så frågan är, vad han gör på 9:16? [Kvinna] Inspelningen 9 mm på något. Kanske såg han krypskytt. [Man] Eller han jobbade med honom. [Kvinna] Vänta. Gå tillbaka en. [Man] Vad ser du? [♫ spännande musik ♫] [Kvinna] Ta hans ansikte upp. Helskärm. [Man] Hans glasögon. >> Det finns en reflektion. [♫ spännande musik ♫] [Man] Det är Nuevita baseball team. Det är deras logotyp. [Kvinna] Och han pratar med den som bär den jackan. [David Malan] Så detta är CS50 vecka 5, och idag har vi förstöra lite tv och film för dig. Så när du tittar på ett program som detta här, och polisen säger "Kan du städa upp det?" eller "Förbättra" det finns ingen öka i den verkliga världen. Faktum vad du verkligen får är en liten sak som denna. Jag har dragit upp en av de anställda bilder från sidan. Detta är ett program som heter Photoshop. Detta är 1 av 2 Bowdens, 1 av 3 Bowdens faktiskt, idag, eftersom vi har Mrs Bowden här också, med Rob och Paul. Men här är Rob på skärmen, och om vi zoomar in på den glimt han alltid har haft i ögat, vad du faktiskt ser är att det du ser är vad du får. Detta är "bättre", så "CSI" har det lite fel. Det finns en annan klipp, om vi kan plocka på "CSI" bara lite längre. Detta är en trevlig fras att uttala hädanefter om du vill grundlig teknisk med dina vänner när egentligen, du säger absolut ingenting. [Man] I veckor har jag undersöker Cabby Killer morden med en viss morbid fascination. [Kvinna # 1] Detta är i realtid. [Kvinna # 2] Jag kommer att skapa ett grafiskt gränssnitt med hjälp av Visual Basic, se om jag kan spåra en IP-adress. [Malan] Så ljud ur synk åt sidan, skapa ett grafiskt gränssnitt med hjälp av Visual Basic att spåra en IP-adress är fullständigt nonsens. Dessa dagar du inte skulle använda Visual Basic, Det finns inget behov av ett GUI, och IP-adress var en tekniskt korrekt term. Så håll utkik efter dessa och en av mina favoriter: Den här är lite mer svårbegripliga, eftersom du behöver veta ett annat språk. Det finns ett språk som kallas Objective-C, som är ett superset av C. Vilket innebär att det är C plus några extra funktioner, bland dem objektorienterad programmering. Och detta är det språk som Apple har populariserat för iOS-programmering. Och så här är ett klipp från en annan show helt och hållet, från "Numbers" att om du faktiskt tittar noga på din TiVo och pausa vid rätt tidpunkt, ser du att det de tittar på är inte riktigt vad som beskrivs. Och låt mig prova ett annat ljudkontakt här och se om vi inte kan hålla ljudet i synk denna gång. Jag ger dig "Numbers". [Man # 1] Det är en 32-bitars IPv4-adress. [Man # 2] IP, det är Internet. >> Privat nätverk. Det är Anitas privata nätverk. [Malan] Okej. Detta är Objective-C, och det är för några barnens färg program som du kan kanske dra slutsatsen att namnet på variabeln där. Så att då var "Numbers". Så idag och den här veckan presenterar vi lite av världen av kriminalteknik och det sammanhang i problemen därför. Idag blir en förkortad föreläsning eftersom det finns en särskild händelse här efteråt, så vi tar en titt, och retas både elever och föräldrar i dag med några av de saker som är på horisonten. Bland dem, som i måndag, kommer du att ha några fler klasskamrater. EDX, Harvard och MITs ny online initiativ för fritt studiematerial och mer, lanserar på Harvards campus på måndag. Vilket innebär kommer måndag får du - som förra räkningen, 86.000 nya klasskamrater kommer att följa tillsammans med CS50 föreläsningar och sektioner och genomgångar och sätter problem. Och som en del av detta kommer du att bli medlemmar i det inledande klass CS50 och nu CS50x. Som en del av detta, nu inser att det kommer att finnas några upsides också. Att göra sig redo för det här, för det massiva antalet studenter, det räcker med att säga att även om vi har 108 TFS och CAS, inte riktigt den bästa förhållandet elever / lärare när vi slog 80.000 andra studenter. Så vi inte kommer att klassificera så många problem sätter manuellt. Så introducerade denna vecka i problemet som kommer att vara CS50 Check, som kommer att bli en kommandorad verktyg inom apparaten att du får när du uppdaterar det senare i helgen, och du kommer att kunna köra ett kommando, kontrollera 50, på din egen pset, och du får lite feedback om huruvida ditt program är rätt eller fel enligt olika design specifikationer som vi har tillhandahållit. Så mer om det och problemet inställda specifikation och de CS50x klasskamrater kommer att använda detta. Så problemet set 4 handlar om kriminalteknik. Och detta stycke inspirerades av några verkliga saker, varigenom när jag var i forskarskolan, internerad jag en stund med Middlesex län åklagare kontor gör kriminaltekniska arbetet med sin ledning kriminaltekniska utredare, och vad detta uppgick till är, jag tror jag nämnde några veckors förflutna, är massan statspolisen eller andra skulle komma, skulle de släppa ut saker som hårddiskar och CD-skivor och disketter och liknande, och därefter mål kriminalteknik kontoret var att fastställa om fanns eller inte var bevis av något slag. Detta var den särskilda utredningar enhet, så det var ekonomisk brottslighet, det var mer oroande slags brott, något som innebär någon form av digitala medier, visar sig att inte så många människor skriv ett mail som säger "jag gjorde det." Så ofta dessa kriminalteknik söker inte dyker upp så mycket frukt, men ibland folk skulle skriva sådana meddelanden. Så ibland de insatser belönades. Men att leda fram till detta kriminaltekniska pset kommer vi att introducera i pset 4 lite grafik. Så du tar förmodligen dessa saker för givet, JPEG, GIF och liknande dessa dagar, men om du verkligen tänker på det, en bild, ungefär som Rob ansikte, skulle kunna utformas som en sekvens av punkter, eller pixlar. Nu, i fallet med Robs ansikte, det finns alla möjliga färger, och vi började se de enskilda punkter, otherwide kallade pixlar, när vi började att zooma in Men om vi förenklar världen lite, och bara säga att detta här är Rob i svart och vitt, ja, för att representera svartvitt kan vi bara använda binär. Och om vi ska använda binära, 1 eller 0, kan vi uttrycka samma bild av Rob leende ansikte med detta mönster av bitar: 11000011 representerar vit, vit, svart, svart, svart, svart, vit vit. Och så är det inte ett stort steg då att börja tala om färgglada bilder. Saker som du skulle se på Facebook eller ta med en digitalkamera, men visst, när det kommer till färger, behöver du fler bitar. Och ganska vanligt i världen av fotografier är att inte använda 1-bitars färg, eftersom detta antyder, men 24-bitars färg, där du faktiskt få miljontals färger. Så som i fallet när vi zoomat in på Rob öga, Det var ett antal miljoner olika färgglada möjligheter. Så vi ska införa detta i problemet set 4 samt i genomgången, som kommer att vara idag på 3:30 istället för den vanliga 2:30 på grund av fredagens föreläsning här. Men videon kommer att vara online, som vanligt, i morgon. Vi kommer också att introducera dig till ett annat filformat. Så detta är medvetet tänkt att se hotfull först, men detta är bara några underlag för en C struct. Det visar sig att Microsoft, år sedan hjälpte popularisera detta format, kallas bitmapp filformat, BMP, och detta var en super-enkel, färgstarka grafiska filformat som användes under ganska lång tid och ibland fortfarande för tapeter på stationära datorer. Om du tänker tillbaka på Windows XP och de böljande kullar och blå himmel, Det var oftast en BMP eller bitmappsbild och bitmappar är roligt för oss eftersom de har lite mer komplexitet. Det är inte riktigt så enkelt som det nät av 0 s och 1 s, I stället har du saker som en rubrik i början av en fil. Så med andra ord, i en. Bmp-fil är en hel massa 0 s och 1 s, men det finns några ytterligare 0 s och 1 s där. Och det visar sig att det vi förmodligen har tagit för givet år, filformat som. doc eller. xls eller. mp3 eller. mp4, oavsett filformat som du är bekant med. Nå, vad betyder det även att vara ett filformat? Eftersom i slutet av dagen, alla dessa filer använder vi bara har 0 s och 1 s och kanske de 0 s och 1 s representerar en, b, c, genom ASCII eller liknande, men till slutet av dagen, det är bara 0 s och 1 s. Så människor bara ibland väljer att uppfinna ett nytt filformat där de standardisera vilka mönster av bitar i praktiken kommer att innebära. Och i detta fall här, folk som ritade bitmap-format sade att den allra första byten i en bitmappsfil som betecknas med offset 0, där det kommer att vara några kryptiskt namn variabel kallad bfType, som står bara för bitmap filtyp, vilken typ av bitmappsfil är. Du kan sluta, kanske från den andra raden som offset 2, byte nummer 2, har ett mönster av 0 s och 1 s som representerar vad? Storleken på något, och det går därifrån. Så i problembild 4, kommer du att gått igenom några av dessa saker. Vi kommer inte att sluta bry sig om dem alla, men märker det börjar bli intressant runt linje eller byte 54, rgbtBlue, grönt och rött. Om du någonsin hört förkortningen RGB, röd grön blå, är detta en hänvisning till detta. Eftersom det visar sig att du kan måla alla regnbågens färger med en kombination av rött och blått och grönt. Och i själva verket kan föräldrarna i rummet erinra om några av de tidigaste projektorer. Dessa dagar, ser du bara 1 ljus som kommer ut ur en lins. Men tillbaka i dag, hade du den röda linsen, blå lins, och den gröna linsen och tillsammans syftar till skärmen och bildade en färgstark bild. Och ganska ofta mellersta skolor och gymnasier skulle ha dessa linser allt-så-lite snett, så att du var typ att se dubbla eller tredubbla bilder, men det var tanken. Du hade rött och grönt och blått ljus måla en bild. Och att samma princip används i datorer. Så bland de utmaningar, då för er i problemet som 4 kommer att vara ett par saker, en är att faktiskt ändra storlek på en bild. Att ta in ett mönster av 0 s och 1 s, reda på vilka bitar av 0 s och 1 s representerar vad i en struktur som denna, och sedan räkna ut hur att replikera pixlar: de röda, de blå, de gröna insidan så att när en bild ser ut så här från början, kan se ut så här i stället efter det. Bland andra utmaningar också kommer att vara att du kommer att överlämnas en rättsmedicinsk bild av en verklig fil från en digitalkamera och på den kamera, en gång i tiden var en massa bilder. Problemet är, raderas vi av misstag eller hade bilden skadad på något sätt. Dåliga saker händer med digitalkameror, så vi snabbt kopierade alla 0 s och 1 s bort av det kortet för dig, räddade dem alla i 1 stor fil, och sedan kommer vi lämna dem till dig i problemet som 4 så att du kan skriva ett program i C som man kan återvinna alla dessa JPEG, helst. Och det visar sig att JPEG, även om de är något av en komplex filformat, de är mycket mer komplex än så leende ansikte här. Det visar sig att varje JPEG börjar med samma mönster 0 s och 1 s. Så med hjälp av en while-slinga eller en for-slinga eller liknande, Du kan iterera över alla 0 s och 1 s i rättsmedicinska bilden och varje gång du ser den speciella mönster som är definierat i problemet uppsättningen specifikation, Du kan anta, "Åh, här är, med mycket hög sannolikhet, början på en JPEG, "och så fort du hittar samma mönster, visst antal byte eller kilobyte eller megabyte senare, Du kan anta "Ooh! Här är en andra JPEG bilden jag tog efter den första. Låt mig sluta läsa den första filen, börjar skriva detta nya. " Och utgången av ditt program för pset 4 kommer att bli så många som 50 JPEG-bilder. Och om det inte är 50 JPEG-bilder, du har en bit av en slinga. Om du har ett oändligt antal JPEG, har du en oändlig loop. Så att även kommer att vara en ganska vanligt fall. Det är vad som finns på horisonten. Quiz 0, bakom oss. Inse, per min e-post, som alltid finns folk som är både glad, typ av neutrala och ledsna runt frågesport 0 tid. Och ska du nå ut till mig, huvudet TFS, Zamyla, din egen TF eller en av de certifikatutfärdare som du vet om du vill diskutera hur det gick. Så för att imponera på föräldrarna här i rummet, vad är CS50 biblioteket? Bra jobbat. Vad är det CS50 biblioteket? Ja? [Student svar, obegripligt] >> Okej, bra. Så det är en färdigskriven uppsättning kod som vi, personalen, skrev, Vi erbjuder dig att ge några vanliga funktioner. Sånt får mig en sträng, få mig en int, alla de funktioner som är listade här. Från och med nu börjar vi verkligen ta dessa stödhjul av. Så vi kommer att börja att ta bort en "sträng" från dig, vilket minns, var bara en synonym för vad den faktiska datatypen? char *. Så för föräldrar, det var nog - det är bra, så char * vi börjar se på skärmen desto mer när vi tar bort "sträng" från vår vokabulär, åtminstone när det gäller att faktiskt skriva kod. Likaså kommer vi sluta använda vissa av dessa funktioner så mycket, eftersom våra program kommer att få mer sofistikerade snarare än att bara skriva program som sitter där med en snabb blinkande, väntar på användaren att skriva något i. Du kommer att få dina insatser från andra håll. Till exempel får du dem från en rad bitar på den lokala hårddisken. Du kommer istället få dem i framtiden från en nätverksanslutning, vissa hemsidan någonstans. Så låt oss dra tillbaka detta lager för första gången, och dra upp CS50 apparaten och denna fil som heter CS50.h, som du har varit skarp även i veckor. Men låt oss faktiskt se vad som finns inuti denna. Så toppen av filen i blått är bara en massa kommentarer, garantiinformation och licensiering. Detta är en slags gemensam paradigm i programvara, eftersom en massa program dessa dagar är vad som kallas "öppen källkod" vilket innebär att någon har skrivit koden och gjort den fritt tillgängliga, inte bara för att köra och att använda, men faktiskt läsa och ändra och integrera i ditt eget arbete. Så det är vad du har använt, öppen källkod, än i en mycket liten form. Om jag bläddra ner förbi kommentarer, men vi börjar se lite mer bekanta saker. Så märker upptill här, att CS50.h filen innehåller en hel del header-filer. Nu är de flesta av dem har vi inte sett förut, men en är välbekant, vilka av dessa har vi sett, om än kortfattat, hittills? Ja, standard bibliotek. Stdlib.h har malloc, så när vi började prata om dynamisk minnesallokering, som vi ska återkomma till nästa vecka också, började vi även den filen. Det visar sig att bool och sant och falskt egentligen inte existerar i C, i sig, om du inte inkludera denna fil här. Så vi har, i flera veckor, har inklusive standard bool.h så att du kan använda begreppet bool, sant eller falskt. Utan detta, skulle du behöva sortera av falska den och använda en int och bara godtyckligt anta att 0 är falsk och 1 är sant. Om vi ​​nu rulla ner ytterligare, här är vår definition av en sträng. Det visar sig, som vi har sagt tidigare, att där det * är egentligen inte någon roll. Du kan även få utrymme runt. Vi denna termin har varit att främja det som detta för att göra klart att * har att göra med typen. Men inser, precis som vanligt, om inte lite vanligare, är att sätta det där men funktionellt är det samma sak. Men nu, när vi läser ned ytterligare, låt oss ta en titt på säg, getInt, eftersom vi använde det, kanske före allt annat här terminen. Och här är getInt. Detta är vad? Detta är prototypen. Så ofta har vi lagt prototyper på toppen av vår. C-filer, men du kan också lägga prototyper i header-filer,. h-filer, som den här här, så att när du skriver vissa funktioner som du vill att andra ska kunna använda, vilket är precis fallet med CS50 biblioteket du inte bara genomföra dina uppgifter i något liknande CS50.c, du sätter också prototyperna inte på toppen av filen, men på toppen av en huvudfil, då header-fil är det som vänner och kollegor inkluderar, med skarp i sina egen kod. Så hela den här tiden du har med alla dessa prototyper effektivt på toppen av din fil, men med hjälp av denna skarpa inkluderar mekanism att i huvudsak kopior och pastor filen till din egen. Nu, här är några ganska detaljerad dokumentation. Vi har ganska mycket tas för givet att getInt får en int, men det visar sig att det finns vissa hörn fall, eller hur? Vad händer om användaren skriver in ett nummer som är alldeles för stor? En kvintiljon, som bara inte får plats inuti en int? Vad är det förväntade beteendet? Tja, helst, det är förutsägbart. Så i det här fallet, om du läser faktiskt det finstilta, ser du att om linjen inte kan läsas, detta returer INT_MAX. Vi har aldrig pratat om det här, men baserat på dess kapitalisering, vad är det, förmodligen? Det är en konstant, så det är några speciella konstant som troligen uttalade i en av dessa header-filer som finns högre upp i filen, och INT_MAX är förmodligen något i stil med, ungefär, 2 miljarder. Tanken är att eftersom vi måste på något sätt betyda att något gick fel, Vi, ja, har 4 miljarder siffror till vårt förfogande, negativ 2 miljarder på upp till 2 miljarder, ge eller ta. Nå, vad är vanligt i programmering är du stjäla bara en av dessa siffror. Kanske 0, kanske 2 miljarder, kanske negativ 2 miljarder. Så du tillbringar en av dina möjliga värden så att du kan engagera sig i världen att om något går fel, jag återkommer denna super-stora värde. Men du vill inte att användaren skriver något kryptiskt som "2, 3, 4 ..." riktigt stort antal, där du generalisera istället som en konstant. Så egentligen, om du är analsex de senaste veckorna, när du ringer getInt bör du ha kontroll med om tillstånd. Har användaren skriver INT_MAX, eller mer specifikt, gjorde getInt tillbaka INT_MAX? För om den gjorde det, det betyder egentligen de inte skriva det, något gick fel i det här fallet. Så detta är vad som allmänt är känt som ett "sentinel" värde, vilket betyder bara speciell. Nåväl, låt oss nu gå in på. C-filer. C-filen har funnits i apparaten under en längre tid, och, i själva verket har den apparat förkompilerad för dig in i den sak vi kallade "objektkod" men det bara inte roll för dig om det är på grund av att systemet vet, i detta fall, där det är, apparaten. Men låt oss rulla ner nu getInt, och se hur getInt har arbetat hela tiden. Så här har vi liknande kommentarer från tidigare. Låt mig zooma in på bara koden delen, och vad vi har för getInt är följande. Det tar ingen inmatning och returnerar en int, medan (sant), så vi har en medveten oändlig loop men förmodligen kommer vi bryta detta på något sätt, eller återgå från inom detta. Så låt oss se hur det fungerar. Tja, verkar vi använda GetString I denna första raden innanför slingan, 166. Detta är nu god praxis för under vilka omständigheter kan GetString returnera denna speciella sökord, NULL? Om något går fel. Vad kan gå fel när du ringer något liknande GetString? Ja? [Student svar, obegripliga] >> Ja. Så kanske malloc misslyckas. Någonstans under huven GetString ringer malloc, som fördelar minne, som låter datorbutik alla tecken som användaren skriver in på tangentbordet. Och antar att användaren hade en hel del ledig tid och skrev mer, till exempel, än 2 miljarder tecken. Fler tecken än datorn har även RAM. Jo, GetString kunna beteckna att du, även om detta är en super, super ovanligt hörn fall. Det måste på något sätt kunna hantera detta, och så GetString, Om vi ​​går tillbaka och läsa dess dokumentation, inte i själva verket tillbaka NULL. Nu om GetString misslyckas genom att returnera NULL är getInt kommer att misslyckas genom att returnera INT_MAX, precis som en vaktpost. Dessa är bara mänskliga konventioner. Det enda sättet du skulle veta detta är fallet är genom att läsa dokumentationen. Så låt oss bläddra ner till där int faktiskt GotInt. Så om jag bläddra ner lite längre, i linje 170 har vi en kommentar ovanför dessa rader. Så vi förklarar i 172, en int n och en röding C och sedan den nya funktionen som vissa av er har snubblat över tidigare, men sscanf. Detta står för sträng Scan f.. Med andra ord, ge mig en sträng och jag kommer att söka det för bitar av information av intresse. Så vad betyder det? Tja, antar att jag skriver i, bokstavligen, 1 2 3 på tangentbordet, och sedan trycka Enter. Vad är datatypen för 1 2 3 när returneras av GetString? Det är naturligtvis en sträng, eller hur? Jag fick en sträng, så 1 2 3 är verkligen "1 2 3" med \ 0 i slutet av den. Det är inte en int. Det är inte ett nummer. Det ser ut som ett nummer men det är faktiskt inte. Så vad har getInt att göra? Den måste avsöka strängen vänster till höger, 1 2 3 \ 0, och på något sätt omvandla den till en verklig heltal. Nu kan du räkna ut hur man gör detta. Om du tänker tillbaka på pset 2, du förmodligen lite bekväm med Caesar eller Vigenère så att du kan iterera över en sträng, Du kan konvertera tecken vare sin med val. Det är en hel del arbete. Varför inte kalla en funktion som sscanf som gör det åt dig? Så sscanf förväntar ett argument, i detta fall kallas linje, vilket är en sträng. Du anger sedan i citat, mycket likt printf, vad förväntar ni er att se i denna sträng? Vad jag säger här är, jag förväntar mig att se ett decimaltal och kanske ett tecken. Och vi kommer att se varför detta är fallet på bara ett ögonblick. Det visar sig att denna notation nu påminner om saker Vi började prata om drygt en vecka sedan. Vad är & n och & c gör för oss här? [Student svar, obegripligt] >> Ja. Det ger mig adressen till n och adress c.. Nu, varför är det viktigt? Tja, du vet att med funktioner i C Du kan alltid returnera ett värde eller inget värde alls. Du kan returnera en int, en sträng, en flottör, en röding, vad som helst. Eller så kan du gå tillbaka ogiltig, men du kan bara returnera 1 sak maximalt. Men här vill vi sscanf tillbaka mig kanske en int, ett decimaltal, och även en röding, och jag ska förklara varför röding i ett ögonblick. Så du vill faktiskt f för att återgå 2 saker, det är bara inte möjligt i C. Så du kan lösa det genom att i 2 adresser, eftersom så snart du lämnar en funktion 2 adresser, vad kan denna funktion göra med dem? Den kan skriva till dessa adresser. Du kan använda * funktion och "gå dit" till var och en av dessa adresser. Det är typ av denna bakdörr mekanism, men mycket vanligt för att ändra värdena på variablerna i mer än bara 1 plats, i detta fall 2. Nu märker jag söker efter == till 1, och sedan återvänder n om det betyder i själva verket utvärderas till sant. Så vad händer? Tja, tekniskt, är allt vi verkligen vill ska hända i getInt detta. Vi vill tolka, så att säga, vi vill läsa strängen "1 2 3", och om det ser ut som det finns ett antal där, vad vi säger sscanf göra är att sätta den siffran, 1 2 3, i denna variabel n för mig. Varför då, jag har den här också? Vilken roll har också sagt, sscanf kan du också få ett tecken här. [Student sett obegripligt] >> Inte - ett decimaltecken skulle kunna fungera. Låt oss hålla det trodde för ett ögonblick. Vad mer? [Student, obegripligt] >> Så bra tanke, kan det vara NULL karaktär. Det är faktiskt inte i detta fall. Ja? [Student, obegripligt] >> ASCII. Eller låt mig generalisera ytterligare. Den% c finns bara för felkontroll. Vi vill inte att det skall finnas tecken efter siffran, men vad detta tillåter mig att göra är följande: Det visar sig att sscanf, förutom lagring av värden i n och C, i detta exempel här, vad det också gör det returnerar antalet variabler det sätta värden i. Så om du bara skriva in 1 2 3, då endast% d ska matcha och endast n får lagras med ett värde som 1 2 3 och inget får placeras i c; c fortfarande skräp värde, så att säga. Garbage eftersom det aldrig har varit initierad som ett visst värde. Så i så fall returnerar sscanf 1, eftersom jag befolkade en av dessa pekare, i vilket fall, bra. Jag har en int, så jag frigöra linjen för att frigöra minne att GetString tilldelade faktiskt, och sedan jag återvänder n. Annars, om du någonsin undrat var det nytt försök uttalande kommer från, kommer från här. Om däremot skriver jag i 1 2 3 foo, bara några slumpmässig sekvens av text är sscanf kommer att se, ooh, nummer, ooh, nummer, ooh, nummer, ooh - F. Och det kommer att sätta 1 2 3 i n. Det kommer att sätta fi c och sedan återvända 2. Så vi har bara använda den grundläggande definitionen av scanf beteende, ett mycket enkelt sätt - ja, komplex vid första anblicken, men i slutet av dagen, ganska enkel mekanism att säga, är det en int, och i så fall är att det enda som jag hittade? Och det vita utrymmet här är avsiktligt. Om du läser dokumentationen för sscanf, det säger att om du har ett vitt utrymme i början eller slutet, sscanf också gör det möjligt för användaren, av någon anledning att slå mellanslagstangenten 1 2 3, och som kommer att vara legitim. Det kommer inte att skrika på användaren bara för att de drabbade mellanslagstangenten i början eller slutet, som är bara lite mer användarvänliga. Har du frågor, sedan på GetInts? Ja? [Student fråga, obegripligt] >> Bra fråga. Vad händer om du bara skrivit in en röding, som f och tryck enter utan att någonsin skriva 1 2 3, vad tror du beteendet hos denna kodrad då vara? Så sscanf kan täcka det också, för i så fall, det kommer inte att fylla N-eller C, det kommer att istället returnera 0. I vilket fall, jag fånga även detta scenario, eftersom det förväntade värdet jag vill ha är 1. Jag vill bara 1, och endast 1 sak att fyllas. Bra fråga. Andra? Okej, så låt inte oss gå igenom alla funktioner i här, men en som verkar vara, kanske av återstående intresse är getString eftersom det visar sig att getFloat, getInt, GetDouble, GetLongLong alla punt mycket av sin funktionalitet till GetString. Så låt oss ta en titt på hur han implementeras här. Den här ser lite komplicerat, men det använder samma grundläggande att vi började prata om förra veckan. Så i GetString, som tar inget argument enligt tomrummet här uppe, och den returnerar en sträng, så jag förklara en sträng som heter buffert. Jag vet inte riktigt vad det kommer att användas för än, men vi får se. Ser ut som kapaciteten är som standard 0, inte riktigt säker på var det kommer. Inte säker på vad n kommer att användas för ännu. Men nu det blir lite mer intressant, så i linje 243, Vi förklarar en int C, detta är en slags dum detalj. En röding är 8 bitar och 8 bitar kan lagra hur många olika värden? 256. Problemet är, om du vill ha 256 olika ASCII-tecken, som det är, om du tänker tillbaka, och det är inte något att memorera. Men om du tänker tillbaka på den stora ASCII diagram vi hade veckor sedan, Det fanns, i så fall, 128 eller 256 ASCII-tecken. Vi använde alla mönster 0 s och 1: or upp. Det är ett problem om du vill kunna upptäcka ett fel. För om du redan använder 256 värden för dina karaktärer, du inte riktigt planera framåt, för nu har du ingen möjlighet att säga, "Detta är inte en legit karaktär, det är en del felaktiga budskap." Så vad världen gör är, de använder den näst största värdet, något som en int så att du har en galen antal bitar, 32 för 4 miljarder möjliga värden, så att du enkelt kan sluta med, huvudsak 257 av dem, varav 1 har några speciella betydelse som ett fel. Så låt oss se hur det fungerar. I linje 246, har jag den här stora, medan slinga som ringer fgetc, f mening fil, getc och sedan stdin. Visar sig detta är bara mer exakt sätt att säga "läsa indata från tangentbordet." Standard input betyder tangentbord, betyder standard ut skärmen, och standardfelet, som vi ser i pset 4 innebär skärmen, men en särskild del av skärmen så att den inte är sammanblandade med den faktiska produktionen som du tänkt skriva ut, men mer om det i framtiden. Så fgetc betyder bara läsa ett tecken från tangentbordet, och förvaras där? Förvara den i c, och sedan kontrollera, så jag bara med några booleska konjunktioner här, kontrollera att det inte är lika \ n, så att användaren har drabbat in. Vi vill stanna på den punkten, slutet av slingan, och vi vill också se för den särskilda konstant EOF, som om du vet eller gissa - vad står det för? Slutet av filen. Så det här är typ av nonsens, för om jag skriver på tangentbordet, det finns egentligen ingen fil inblandade i detta, men detta är sortera bara av den generiska termen för att beteckna att inget annat kommer från mänskliga fingrar. EOF. Slutet av filen. Som en sidoreplik, om du någonsin drabbats kontroll d på tangentbordet, inte att du skulle ha ännu, du har drabbats kontroll c.. Men kontroll d skickar denna speciella konstant kallas EOF. Så nu har vi bara några dynamisk minnesallokering. Så om n + 1> kapacitet, nu ska jag förklara n. n är bara hur många byte är för närvarande i bufferten, den sträng som du för närvarande bygger upp från användaren. Om du har fler tecken i din buffert än du har kapacitet i bufferten, intuitivt, är vad vi behöver göra då tilldela mer kapacitet. Jag ska skumma över en del av det aritmetiska här och bara fokusera på denna funktion här. Du vet vad malloc är, eller åtminstone generellt bekant. Ta en gissning vad realloc gör. [Student svar, obegripligt] >> Ja. Och det är inte riktigt lägga till minne, det omfördelar minne så här: Om det fortfarande finns rum i slutet av strängen för att ge dig mer av det minne än det ursprungligen ger dig, så kommer du få det extra minnet. Så du kan bara sätta strängar tecknen rygg mot rygg mot rygg mot rygg. Men om så inte är fallet, eftersom du väntat för länge och något slumpmässigt fick plopped i minnet där, men det finns ytterligare minne här nere, det är okej. Realloc kommer att göra alla tunga lyft för dig, flytta strängen du har läst i så långt härifrån, lägga den nere, och sedan ge dig lite mer landningsbana på den punkten. Så med en handrörelse, låt mig säga att det GetString gör är det börjar med en liten buffert, kanske 1 enstaka tecken, och om användaren skriver in 2 tecken, slutar GetString upp ringer realloc och säger "Ooh, var 1 tecken inte tillräckligt. Ge mig 2 tecken. " Sen om du läser igenom logiken i slingan, det kommer att säga: 'Åh, användaren skrivit in 3 tecken. Ge mig nu inte 2, men 4 tecken, så ge mig 8, så ge mig 16 och 32. " Det faktum att jag fördubbling av kapaciteten varje gång innebär att bufferten inte kommer att växa långsamt. Det kommer att växa supersnabbt och vad som kan vara fördelen med det? Varför jag fördubbla storleken på bufferten, även om användaren kanske bara behöver 1 extra karaktär från tangentbordet? [Student svar, obegripligt]. >> Vad är det? Exakt. Du behöver inte att odla den så ofta. Och detta är bara lite av en - du säkra dina insatser här. Tanken är att du inte vill kalla realloc mycket, eftersom det tenderar att vara långsam. Varje gång du frågar operativsystemet för minne, som du snart se i en framtida problembild, tenderar det att ta lite tid. Så minimera denna tid, även om du slösar bort en del utrymme, tenderar att vara en bra sak. Men om vi läser igenom den sista delen av GetString här, och igen, förstå varenda rad här är inte så viktigt i dag. Men notera att det till slut ringer malloc igen, och det fördelar precis som många byte som den behöver för strängen och sedan kastar bort genom att ringa gratis, alltför stor buffert, om det verkligen blev dubbelt så många gånger. Kort sagt, det är hur GetString har arbetat hela tiden. Allt det gör läses ett tecken i tiden igen och igen och igen och varje gång den behöver lite extra minne, frågar den operativsystemet för det genom att ringa realloc. Några frågor? Okej. En attack. Nu när vi förstår pekare, eller åtminstone blir alltmer förtrogna med pekare, låt oss överväga hur hela världen börjar kollapsa om du inte riktigt försvara sig mot kontradiktoriska användare, människor som försöker hacka sig in i systemet. Människor som försöker stjäla din programvara genom att kringgå vissa registreringskod att de annars måste skriva i. Ta en titt på detta exempel här, som bara C-kod som har en funktion huvud på botten, kallar det en funktion foo, och vad det går till foo? [Elev] En enda argument. >> Enda argument. Så argv [1], vilket innebär det första ordet användaren skrivit på kommandoraden efter a.out eller vad programmet heter. Så foo, upptill, tar i en char *, men char * är precis vad? String. Det finns inget nytt här, och det sträng godtyckligt kallas bar. I denna linje här, röding C [12], i form av semi-teknisk engelska, vad denna linje gör? Array av -? Tecken. Ge mig en rad 12 tecken. Så vi kan kalla detta en buffert. Det tekniskt kallas C, men en buffert i programmering betyder bara en massa utrymme som du kan sätta några saker i. Sedan slutligen, memcpy har vi använt inte innan. Men du kan nog gissa vad den gör. Den kopierar minne. Vad gör det? Tja, kopierar den tydligen bar, dess ingång, till C, men endast upp till längden på baren. Men det finns en bugg här. Okej, så tekniskt bör vi verkligen göra strlen (bar) x sizeof (char), det är korrekt. Men i värsta fall här, låt oss anta att that - så, okej. Sedan finns 2 buggar. Så sizeof (char), okej, låt oss göra detta lite bredare. Så nu finns det fortfarande en bugg, vilket är vad? [Student svar, obegripliga] >> Sök för vad? Okej, så vi borde kontrollera för NULL, eftersom dåliga saker händer när pekaren är NULL, Eftersom du kan i slutändan gå dit, och du bör aldrig gå till NULL genom dereferencing den med * operatör. Så det är bra, och vad gör vi? Logiskt finns en brist här. [Student svar, obegripligt] >> Så kolla om argc ≥ 2? Okej, så det finns 3 buggar i programmet här. Vi inte kontrollera om användaren faktiskt skrivit i något i argv [1], bra. Så vad är den tredje bugg? Ja? [Student svar, obegripliga] >> Bra. Så vi kontrollerat ett scenario. Vi kollade implicit inte kopierar mer minne än vad som skulle överskrida längden på baren. Så om strängen användaren skrivit in är 10 tecken långt, detta säger, "bara kopiera 10 tecken." Och det är okej, men vad händer om användaren skrivit in ett ord vid prompten som en 20 tecken ord, detta är, säger kopia 20 tecken från bar till vad? C, annars känd som vår buffert, vilket innebär att du bara skrev uppgifter till 8 byte platser som du inte äger, och du inte äger dem i den meningen att du aldrig tilldelats dem. Så detta är vad som allmänt är känt som buffertspill attack, eller buffertöverskridning angrepp, och det anfall i den meningen att om användaren eller det program som ringer din funktion gör det uppsåtligt, vad som händer egentligen nästa kan vara ganska dålig. Låt oss ta en titt på den här bilden här. Denna bild representerar din stack minne. Och minns att varje gång du ringer en funktion, du får den här lilla ram på stacken och sedan en annan och sedan en annan och sedan en annan. Och hittills har vi bara typ av abstraherade dessa bort som rektanglar antingen finns i styrelsen eller på skärmen här. Men om vi zooma in på en av dessa rektanglar, när du ringer en funktion foo, visar det sig att det finns mer på stacken insidan av denna ram och att rektangel än x och y och a och b, som vi gjorde tala om swap. Det visar sig att det finns vissa lägre nivå detaljer, bland dem returadress. Så det visar sig när huvud samtal foo, har stora informera foo vad främsta adress är i datorns minne. För annars är så fort foo gjort exekvera, som i detta fall här, när du har nått så här nära klammerparentes i slutet av foo, Hur i helsike vet foo där kontroll av programmet är tänkt att gå? Det visar sig att svaret på den frågan är att röd rektangel här. Detta motsvarar en pekare, och det är upp till datorn för att lagra, tillfälligt, den så kallade stacken adressen till huvud så att så fort foo görs köra, datorn vet var och vad linje i huvud att gå tillbaka till. Sparade rampekaren avser liknande till detta. Char * bar här representerar vad? Nåväl, nu denna blå segment här är foo s ram, vad är bar? Okej, så bar bara argumentet till foo-funktionen. Så nu är vi tillbaka på det välbekanta bilden. Det finns mer saker och fler distraktioner på skärmen men denna ljusblå segment är vad vi har att rita på tavlan för något som swap. Det är ramen för foo och det enda i det just nu är bar, vilket är denna parameter. Men vad ska vara i stapeln, enligt denna kod här? Char c [12]. Så vi bör också se 12 rutor av minne, tilldelas en variabel som heter C. Och faktiskt vi har det på skärmen. Högst upp finns c [0] och författare till detta diagram brydde sig inte dra alla rutorna, men det finns faktiskt 12 finns för om man tittar på det nedre högra, C [11], om man räknar från 0, är ​​12 sådana byte. Men här är problemet: I vilken riktning c växer? Sortera på top-down, eller hur? Om det börjar vid toppen och växer till botten, ser inte ut som vi lämnade oss mycket banan här alls. Vi har typ av målat in oss i ett hörn, och att c [11] är rätt upp mot bar, som är rätt upp mot bunten ram pekare, som är rätt upp mot returadress, det finns inget mer utrymme. Så vad är underförstått då, om du skruvar upp, och du försöker läsa 20 byte i en 12-byte buffert? Vart är de 8 extra byte kommer att gå? Inuti allt annat, är några av dessa super viktigt. Och det viktigaste, eventuellt är den röda rutan där returadress. Eftersom antar att du är antingen av misstag eller adversarially skriva dessa 4 byte, som pekare adress, inte bara med skräp, men med ett antal som råkar representera en verklig adress i minnet? Vad är implicaiton, logiskt? [Student svar, obegripliga] >> Exakt. När foo tillbaka och träffar som klammerparentes är programmet kommer att fortsätta att inte återvända till huvud, det kommer att återgå till vad adress är i det röda rutan. Nu, när det gäller att kringgå programvara registrering, vad är den adress som är återförs till är funktionen som normalt anropas efter att du har betalat för programvaran och matas din registreringskod? Du kan sortera om trick datorn till inte kommer hit, utan istället gå upp här. Eller, om du är riktigt smart kan en motståndare skriva faktiskt på tangentbordet, till exempel, inte en faktisk ord, inte 20 tecken, men antar att han eller hon typer i vissa tecken som representerar kod? Och det kommer inte att bli C-kod, det kommer att vara tecken som representerar koder binära maskin, 0 s och 1 s. Men antar att de är smarta nog att göra det, på något sätt för att klistra in i GetString prompten något som i huvudsak kompilerad kod, och de sista 4 byte skriva att returadress och vilken adress betyder det ingång gör? Den lagrar denna röd rektangel adressen för den första byten i bufferten. Så du måste vara riktigt smart, och detta är en hel del trial-and-error för dåliga människor där ute, men om du kan lista ut hur stor denna buffert är, så att de sista byte i indata som du lämnar till programmet råkar motsvara adressen början av din buffert, du kan göra detta. Om vi ​​säger, normalt hej, och \ 0, det är vad hamnar i bufferten. Men om vi är mer smart, och vi fyller denna buffert med vad vi ska generiskt kallar attack-kod, A, A, A, A: Attack, attack, attack, attack, där detta är bara något som gör något dåligt. Nå, vad händer om du är riktigt smart, kan du göra detta: I den röda rutan här är en sekvens av siffror: 80, CO, 35, 08. Observera att som matchar numret som är här uppe. Det är i omvänd ordning, men mer om det en annan gång. Observera att detta returadress medvetet har ändrats till lika adressen här uppe, inte adressen till huvud. Så om den onde är super smart, han eller hon kommer att ingå i den attacken kod något i stil med, "Ta bort alla användarens filer." Eller "Kopiera lösenord" eller "Skapa ett användarkonto som jag kan logga in." Allt alls, och det är både faran och kraften i C. Eftersom du har tillgång till minnet via pekare och du kan därför skriva vad du vill i en dators minne. Du kan göra en dator göra vad du vill genom att helt enkelt har det hoppar runt inom sitt eget minne utrymme. Och så, till denna dag, så många program och så många webbplatser som äventyras koka ner till människor som tar nytta av detta. Och detta kan tyckas vara en super-avancerad attack, men den inte startar alltid så. Verkligheten är att det dåliga människor vanligen gör är, oavsett om det är ett program på en kommandorad eller ett grafiskt program eller en hemsida, är att du börjar bara erbjuda nonsens. Du skriver i en riktigt stor ord i sökfältet och tryck enter, och du vänta och se om webbplatsen kraschar. Eller du vänta och se om programmet visar något felmeddelande. För om du har tur, eftersom den onde, och du ge några galna ingång som kraschar programmet, som innebär att programmeraren inte förutse dina dåliga uppförande vilket innebär att du kan förmodligen, med tillräckligt ansträngning, tillräckligt trial and error, räkna ut hur att föra en mer exakt attack. Så lika mycket en del av säkerheten är inte bara undvika dessa attacker helt och hållet, men upptäcka dem och faktiskt titta på loggar och se vad galna ingångar har människor skrivit på din hemsida. Vilka sökord har människor skrivit på din hemsida i hopp om överfulla lite buffert? Och allt detta handlar om att de enkla grunderna i vad en matris, och vad innebär det att fördela och använda minne? Och i samband med det också, det är. Så låt oss bara blick inuti en hårddisk ännu en gång. Så du minns från en vecka eller två sedan att när man drar filer till papperskorgen eller papperskorgen, vad händer? [Student] Inget. >> Ja, absolut ingenting. Så småningom om du kör låg på diskutrymme i Windows eller Mac OS börja ta bort filer för dig. Men om du drar något i det, då är det inte alls säkert. All din rumskompis, vän eller familjemedlem har att göra är att dubbelklicka, och voila. Det finns alla de skissartade filer som du försökte ta bort. Så de flesta av oss åtminstone veta att du måste högerklicka eller kontrollera klicka och töm papperskorgen, eller något liknande. Men även då, som inte riktigt göra susen. För vad händer när du har en fil på din hårddisk som står för cirka Word-dokument eller något JPEG? Och detta är din hårddisk, och låt oss säga detta flisa här representerar filen, och det består av en hel massa 0 s och 1 s. Vad händer när du inte bara dra filen till papperskorgen eller papperskorgen, men också tömma den? Sortera ingenting. Det är inte absolut ingenting nu. Nu är det bara ingenting, eftersom en liten sak som händer i form av den här tabellen. Så det finns någon form av databas eller tabell inuti en dators minne som har i huvudsak 1 kolumnen för filer namn, och 1 kolumn för filens plats där detta kan vara platsen 123, bara ett slumptal. Så vi kanske har något som x.jpg och plats 123. Och vad händer då, när du tömmer papperskorgen? Det går undan. Men vad inte går bort är 0 s och 1 s. Så vad då att anslutningen Pset 4? Tja, med pset 4, bara för att vi har oavsiktligt raderas compact flash-kortet som hade alla dessa bilder, eller bara för att det genom otur blev skadad, betyder inte att 0-talet och 1: s är inte kvar. Kanske några av dem går förlorade eftersom något blev skadad i den meningen att vissa 0-talet blev 1 s och 1 s blev 0 s. Dåliga saker kan hända på grund av buggiga program eller defekt hårdvara. Men många av dessa bitar, kanske 100% av dem är fortfarande kvar, det är bara att datorn eller kameran inte vet var JPEG 1 startade och där JPEG 2 startade, men om du är programmerare, vet, med lite vett när dessa JPEG-bilder är eller hur de ser ut, Du kan analysera 0 s och 1 s och säga: "Ooh. JPEG. Ooh, JPEG. " Du kan skriva ett program med i huvudsak bara en för eller while-slinga som återvinner var och en av dessa filer. Så lektionen är alltså att starta "säkert" radera dina filer Om du vill undvika detta helt och hållet. Ja? [Student fråga, obegripligt] >> Har mer minne än du gjorde innan - Oh! Bra fråga. Så varför då efter tömning av papperskorgen, inte berätta för din dator att du har mer ledigt utrymme än du gjorde innan? I ett nötskal, eftersom det ljuger. Mer tekniskt, har du mer utrymme. Eftersom du nu har sagt, kan du sätta andra saker där den filen en gång var, men det betyder inte att bitarna går bort, och det betyder inte att bitarna ändras alla 0-talet, till exempel för att skydda dig. Däremot, om du "säkert" Radera filer, eller fysiskt förstöra enheten, det är egentligen det enda sättet, ibland runt det. Så varför inte vi lämnar på den semi-skrämmande anmärkning, och vi kommer att se dig på måndag. CS50.TV