[Powered by Google Translate] [Vecka 2, Fortsättning]
[David J. Malan, Harvard University]
[Detta är CS50. - CS50.TV]
Okej. Detta är CS50, och detta är slutet på vecka 2.
Om du räknar med att vara hungrig vid den här tiden i morgon,
vet att vi kommer att sammankalla en liten grupp i morgon, torsdag, 1:15 PM.
Det är denna URL här om du vill RSVP.
Utrymmet är begränsat, så förlåt om formuläret har fyllts upp med den tid du fylla i det här.
En annan webbadress, men som kan vara av intresse är det.
I nästan en månad, kursen kommer att göras tillgänglig
allt bredare via EDX, via vilken folk på Internet kommer att kunna följa med,
delta i kursen helt aktivt, faktiskt.
De kommer att använda CS50 Appliance och CS50 Diskutera
och de flesta av de olika mjukvaruverktyg som vi redan har använt den här terminen.
Och en av de initiativ som vi vill ta på som ett experiment i år
är att se hur mycket innehåll som vi kan översätta
i andra talade och skrivna språk.
Så om du kan ha ett intresse av att delta i projektet
där vi kommer att ge engelska avskrifter och undertexter för kursens föreläsningar
och shorts och seminarier och sektioner och liknande,
om du talar flytande eller skriva flytande ett annat språk,
Vi skulle älska att engagera dig i detta projekt där du tar på en eller flera av de videor,
översätta dem till ett språk du känner ganska väl.
>> För att ge dig en känsla av gränssnittet, det är det här webbaserade användargränssnitt
att vi kommer att använda som kommer att skapa i huvudsak en UI som denna.
Detta var jag undervisade lite Halloween sedan,
och på den högra sidan där i svart bredvid dessa tidsstämplar,
ser du de olika saker som kom ur min mun den dagen,
och sedan under det du kommer att kunna översätta till andra språk
exakt vad mappningen mellan, i detta fall, engelska och, säg, spanska.
Så det är faktiskt en mycket användarvänligt verktyg.
Du kan spola tillbaka och snabbspola mycket lätt med kortkommandon.
Så om du vill delta i detta experiment och har dina ord sett och läst
genom potentiellt tusentals människor där ute, jag är du välkommen att delta.
Ett ord om kattunge från måndag.
Så att vi har skickat en alltför skrämmande budskap, inser att som kontorstid tyder
och som sektioner antyder, är utformningen av kursen mycket
att eleverna samarbetar och pratar att arbeta igenom problemet set
och problem tillsammans, och verkligen linjen bara handlar om,
igen bör det arbete du i slutändan skicka vara din egen.
Och så helt ärligt, i kontorstid det är helt normalt,
det är helt att vänta med, att chatta med någon kompis bredvid dig.
>> Om han eller hon kämpar med något ämne och du är som,
"Åh, ja, låt mig ge er en glimt av några kodrad som jag skrev," det är bra,
det händer, och det är mycket gynnsam, tror jag, med processen för lärande.
När linjen blir korsade är när huvudet är typ av lutas hit alldeles för många sekunder
eller minuter som verkligen bara varit en frigörande möjlighet för din vän,
och säkerligen när det blir utbyts via e-post och Dropbox och liknande,
Det är också den linje.
Så med alla medel trivs och känner sig uppmuntrade att chatta med vänner
och klasskamrater om psets och fler och bara inse att det du i slutändan skicka
borde verkligen vara en produkt av din skapelse och inte någon annan.
Och så en av de domänspecifika problem för pset2,
som kommer att komma ut sent i morgon kväll, är att dyka in i världen av kryptografi,
vilket är konsten att kryptera eller förvränga information,
och detta gäller i slutändan till en värld av säkerheten.
Nu kommer säkerheten för de flesta av oss i form av tämligen vardagliga mekanismer.
Alla av oss har användarnamn och lösenord,
och alla av oss har mycket dåliga användarnamn och lösenord, troligen.
>> Om ditt lösenord är samma på flera webbplatser, det är förmodligen inte den bästa idén,
som vi kommer att diskutera mot termin slut.
Om ditt lösenord är skriven på en klisterlapp - inget skämt - på bildskärmen,
som är för inte nödvändigtvis den bästa designen men ganska vanligt fenomen.
Och om du inte använder kryptering för att kryptera dina lösenord,
de är särskilt sårbara.
Så om du tror att du är super smart genom att ha en dold Word-dokument
någonstans på din hårddisk som har alla dina lösenord
men det är i en mapp som ingen kommer att titta i, det är inte heller en mycket säker mekanism.
Och så vad pset2 kommer att införa är denna konst av kryptografi
och förvränga information så att saker som lösenord är allt säkrare.
Sammanhanget här är att med osäkra uppgifter
kommer en möjlighet att kryptera det och att förvränga den.
Och så detta, till exempel, är ett exempel på ett krypterat meddelande.
Detta säger faktiskt något på engelska, men det är uppenbarligen inte helt uppenbart.
Och vi kommer full cirkel idag att retas isär vad detta hemligt meddelande här är.
Men i den verkliga världen av datorer, saker och ting inte ens ser ut som de kan vara engelska fraser.
Till exempel, det är vad du kan hitta på en vanlig Linux-eller Mac eller UNIX-dator
i en fil som var en gång i tiden kallades lösenord filen.
>> Numera har flyttats till andra platser.
Men om man tittar på rätt plats på ett system, ser du inte bara ditt användarnamn
eller för andra människor på systemet, men du kommer att se en krypterad version av sitt lösenord.
I själva verket antyder ordet kryptan där att följande saker är krypterad,
och denna serie av till synes slumpmässiga bokstäver och tecken och siffror och så vidare
kan dekrypteras endast genom allmänt veta någon hemlighet -
ett hemligt ord, ett hemligt nummer -
och så faktiskt, till konsten att kryptografi slutligen handlar om förtroende av något slag
och veta något som någon annan inte gör det.
Så vi kommer att utforska detta i lite mer detalj i dag och i pset framöver.
Och nu några ord om Pass / Fail.
Särskilt som vissa av er har dykt in pset1, apparaten,
och en mycket ny värld för dig själv, inse att frustration och förvirring
och bara tekniska svårigheter är ganska att vänta,
särskilt med den första pset, där det finns bara så mycket nytt,
bara få känna ls och cd och alla dessa mystiska kommandon
och en ny miljö, och det är separat från själva materialet och programmering själv.
Så inser också att det finns säkert kontorstid som finns som en stödstruktur.
>> Avsnitt börjar denna kommande söndag.
Men viktigast av allt, om du känner bara att det inte är hela världen för dig,
inse att det egentligen bara tar tid.
Och om det inte vore för denna möjlighet år sedan för mig att ta en klass godkänd / underkänd,
ärligt talat, jag skulle aldrig ens satt sin fot i klassrummet.
Och du kan ändra detta fram, säger den femte måndagen i kursen,
så om du är på kanten nu inse att i stället huvudet i vissa andra vatten helt och hållet,
anser visserligen bara byta till godkänd / underkänd.
Återigen, det är inte riktigt denna kultur här på Harvard för att ta saker godkänd / underkänd
eftersom alla vill verkligen uppnå eller överträffa,
men ärligt talat, det är ett underbart sätt att försöka något
som kanske inte bekant för dig, och du kommer att sluta göra, i de flesta fall ganska bra,
kanske mycket till din förvåning.
Och i mer konkreta termer, vad jag tycker godkänd / underkänd i allmänhet gör,
särskilt som du kanske har upplevt med pset0,
Om du sätter i 10 timmar, 15 timmar, 25 timmar i någon pset
och du bara banka huvudet mot väggen och det börjar bli super sent på natten
men du har tagit pset 90% av vägen och du bara inte kan lista ut en sak,
godkänd / underkänd verkligen tar udden av en klass som denna,
där du kan sortera på glatt säga: "Okej, jag vet att det inte är perfekt,
men jag jobbade häcken av mig på detta, jag är ganska nöjd med var den hamnade, "
och som kommer att uppfylla de förväntningar på godkänt / underkänt.
Så ha det i åtanke. Okej.
>> Så de av er som har kämpat för att använda Harvard University Wi-Fi,
vet att det finns en CS50 SSID, en Wi-Fi-anslutning, flyter runt
som du kan ha bättre tur för.
Det är lite ironiskt att lösenordet för detta, om du vill försöka ansluta till denna
för bättre hastigheter - och låt oss veta om det är inte bättre - är 12345, hela vägen upp till 8
eftersom 8 är säkrare än 5.
Så om du behöver Wi-Fi-lösenord, anslut till CS50 trådlöst här, 12345678,
och inlägg på CS50 Diskutera om du fortfarande har återkommande anslutningsproblem,
och vi låter de befogenheter som ska veta detta utrymme. Okej.
Så en snabb teaser, särskilt för dem av er som är fan pojkar eller flickor i alla saker Apple.
Vad jag grävde upp från ett par år tillbaka var här filen här, iUnlock.c,
bara för att typ av göra mer konkret och mer komplexa
några av de mer grundläggande C-program som vi har skrivit.
Så jag öppnade filen, iUnlock.c. Den finns på föreläsningar sidan för idag.
På vänster sida ser du en lång lista med funktioner.
Så kolleger som skrev detta skrev upp en massa funktioner, mer än bara stora.
Han använde en massa bibliotek här, och om vi börjar rulla genom,
vad detta egentligen är är den allra första, tror jag, spricka för den ursprungliga iPhone.
>> När du ville jailbreaka den ursprungliga iPhone, vilket innebär untether den från AT & T
och faktiskt installera särskild programvara på den och göra saker som Apple inte vill att folk ska göra,
någon tog sig tid att räkna ut exakt hur de kunde utnyttja programvara brister,
misstag, buggar, i Apple-program, och därmed föddes iUnlock.c--
att om du sammanställt den på din dator och installerat den på en iPhone
som var ansluten till din dator via exempelvis en USB-kabel,
Detta skulle ge dig administrativa eller rotbehörighet på din iPhone
och låter dig göra ganska mycket vad du vill.
Och så det har varit denna fascinerande katt-och råttalek
mellan Apple och resten av världen, särskilt som de, liksom många företag,
Försök att låsa sina grejer ner så att du bara kan göra med den vad de tänker.
Men tack vare personer gillar detta och förståelsen av lågaktivt detaljer -
och i detta fall C-programmering - och en hel del av de välkända konstruktioner
att vi har börjat spela med, kan du verkligen utnyttja hårdvaran
på ett sätt som du tycker passar och inte nödvändigtvis några företagsenhet.
Så till exempel, har jag ingen aning om vad allt detta gör,
men getVersion låter ganska enkelt,
och det ser ut så här är en funktion som denna person skrev.
Det tar någon form av heltal som argument, inte återvänder något,
men verkar slinga med en for-slinga här och en om tillstånd, om tillstånd paus,
och på något sätt avser versionsnummer om vi rulla ner,
även om många av dessa sökord kommer att vara nya.
Och det finns en hel del funktioner i här vi har aldrig sett och kanske inte någonsin se
under loppet av terminen.
>> I slutet av dagen, följer samma regler och logik som vi har spelat med hittills.
Så detta är alldeles för gammal för att knäcka din iPhone 3s eller 4s eller snart 5s dessa dagar,
men vet att det är alla mycket härrör från denna värld som vi har dök in.
Låt oss ta en titt på lite mer enkelt exempel:
här, bara för att få värmas upp med lite syntax och även några andra datatyp
att vi har pratat om, men har inte riktigt sett i C.
Detta är en fil som heter positive1.c, och per kommentarerna överst,
detta kräver bara att användaren ger ett positivt tal.
Så det är ett exempel på en gör-while-slinga, vilket är trevligt för användaren interaktiva program
där du måste tala om för användaren att göra något,
och om de inte samarbetar du skriker åt dem eller förkasta deras input.
Ett typexempel: Jag kommer att göra linjerna 19 till 24
så länge användaren inte har gett mig ett positivt tal.
Denna detalj här på linje 18, varför jag förklarar N över hela denna looping konstruera
i motsats till höger bredvid rad 22 där jag faktiskt bryr få n? Ja.
[Elev] Scope. >> Ja, så det här numret av omfattning.
Och i lekmannaspråk, vad räckvidd hänvisar till?
Ja. >> [Ohörbart elev svar] >> Kan du prata lite högre?
[Elev] Om du kan komma åt den variabeln. >> Perfekt.
Där du kan komma en viss variabel.
Och generellt tumregeln hittills varit att omfattningen av vissa rörliga
definieras av de senaste klammerparenteser som du har sett.
>> Och så i det här fallet, om jag gjorde misstaget att förklara n på linjen 22, skulle den linjen fungerar.
Jag skulle få en int, och jag skulle sätta den i den variabeln n i linje 22,
men som kodrad skulle nu ha någon aning om vad jag pratar om? >> [Elev] 25.
[Malan] 25, och det visar sig 24 och eftersom det i detta fall faller utanför de klammerparenteser.
Så bara en liten bit av en olägenhet men mycket enkelt lösas genom att helt enkelt förklara variabeln
utanför själva funktionen.
Vi får se senare idag kan du gå ett steg längre
och du kan även få lite lat.
Och det är inte att rekommendera i allmänhet, men du kan även få lata
och sätta en variabel globalt, så att säga, inte inne i en funktion, inte inne i en slinga,
men i själva filen, utanför alla funktioner du har skrivit, som jag gjorde här på rad 15.
Detta är vanligtvis ogillande, men inser att detta är en lösning ibland till andra problem,
som vi så småningom se.
Så nu ska vi lämna det så här, men låt oss se om vi kan skriva om detta
bara att börja uttrycka oss lite annorlunda.
Detta program, bara för att vara tydlig, är positive1.
Låt mig gå vidare här och i min terminalfönster göra positive1, Enter.
Sammanställer okej. Jag ska köra positive1, tryck Enter.
Jag kräver att du ger mig ett positivt heltal. Jag ska säga -1. Det fungerade inte.
0, 99. Det verkar fungera.
Kanske inte den mest rigorösa testet, men åtminstone det är en trevlig sanity check
att vi är på rätt väg.
>> Så nu låt mig gå vidare och öppna version 2 av detta,
och vad är annorlunda redan?
Det genomför samma sak, men vad hoppa ut så klart annorlunda den här gången?
Detta bool i grönt. Den lyser grönt, detta sökord som kallas bool, som är en datatyp.
Det kommer inte inbyggd i alla versioner av C.
Du måste inkludera en viss bibliotek.
I vårt fall ingår jag CS50 biblioteket så att vi har tillgång till bool.
Men i linje 18, verkar vi ha ett booleskt värde här kallas tacksam.
Jag kunde ha kallat denna något, men jag kallade det tacksam
bara för att typ av förmedla några semantisk innebörd.
Så först på linjen 18, jag tydligen inte tacksam
eftersom det booleska värdet tacksam initieras till false i linje 18.
Och då verkar det som jag har gjort här i ledningarna 21 till 23
är jag bara lite omskriven min logik.
Så ingen funktionellt olika, men i linje 22 nu jag kontrollera om det int användaren har gett
är större än 0, så ändrar jag bara värdet av tacksamma till true.
Och varför gör jag det? Eftersom i linje 25, tydligen ska jag kolla ett villkor.
Gör denna slinga medan tacksam är falskt.
Så jag föreslog detta som ett alternativ till version 1
eftersom det är åtminstone lite mer intuitiv kanske är det lite mer grundad på engelska.
Så gör du följande när du inte är tacksam eller när tacksamma är falskt.
Och den här gången för jag tydligen bryr inte komma ihåg vad användaren skrivit in
eftersom varsel finns det ingen variabel n, så egentligen, en liten vit lögn där.
>> Funktionellt är programmet lite annorlunda när vi kommer till botten med det
eftersom jag inte ihåg vad n är.
Men jag ville visa även här att även om vi har sett getInt
och GetString som används på den högra sidan av ett likhetstecken hittills
så att vi kommer ihåg värdet, tekniskt, det är inte absolut nödvändigt.
Om du av någon anledning bara inte lust att spara värdet,
du bara vill kontrollera värdet, märker att vi helt enkelt kan skriva detta som getInt,
öppna paren, nära parentes.
Denna funktion kommer att returnera ett värde, som vi har sagt.
Det kommer att ge dig tillbaka en int.
Och så om du tror mentalt att detta ska hända,
När jag skriver in 99, återvänder getInt numret 99,
och så begreppsmässigt, är det som om min kod var faktiskt här.
Så om 99 verkligen är större än 0, så tacksam blir sann,
sedan linje 25 inser ooh, vi gjort eftersom jag nu tacksam,
och i linje 26, säger vi helt enkelt "Tack för den positiva heltal!"
vad det råkade vara.
Nu ska vi göra något syntaktisk socker här, så att säga.
Låt oss se om vi kan städa upp denna linje 25 med denna tredje och sista varianten i positive3.
>> Lägg märke till den enda skillnaden nu är vad kodrad? >> [Elev] 25. >> [Malan] Ja, 25.
Och vi har inte har verkligen sett detta trick ännu, men vi såg utropstecken på måndag,
som betecknar vad? >> [Elev] inte. >> Ej eller förnekande.
Så ta ett booleskt värde och vända dess värde.
True blir falskt, blir falskt sant.
Så det här, jag skulle föreslå, är ännu lite mer intuitivt sätt att skriva koden
eftersom jag fortfarande initiera tacksam till false, gör jag fortfarande följande,
Jag satt tacksam till true när det är dags,
men nu kan du egentligen bara översätta denna kod muntligen vänster till höger,
medan (tacksam!), därför Bang eller utropstecken anger begreppet inte,
så även om de inte tacksam.
Så återigen, har vi infört några nya begrepp i sig.
Vi pratade om Booleans tillbaka när vi spelade med Scratch,
men nu inser vi bara kan börja skriva vår kod på många olika sätt.
Så speciellt i pset1 om du typ av kämpar för att räkna ut sätt att skriva något program,
oddsen är du tur eftersom det kan finnas ett obegränsat antal lösningar
som du kan hända på.
Till exempel, är detta bara 3 för även de enklaste av programmen. Okej.
Och nu minns på måndag vi kvar på denna not med returvärden.
Så för första gången skrev vi ett program som inte bara har stora;
Det har också sin egen anpassad funktion som jag skrev här.
Så i linje 31 till 34 har jag genomfört en kub funktion.
Det är inte komplicerat. Det är bara en * a * a i detta fall.
Men vad som är viktigt om det är att jag tar in i form av en
och jag tillbaka ut i form av en * a * a.
Så nu har jag möjlighet, ungefär som jag brukade med prinf ensam,
att kalla denna funktion genom att ringa kuben funktionen.
>> Och kuben funktionen tar lite input och kuben returnerar någon utgång.
Däremot gjorde printf bara något.
Det tog inte tillbaka någonting som vi brydde sig om, även om som en undan det gör returnera ett värde;
du bara allmänt ignorera det.
Printf bara gjorde något. Den hade en bieffekt av att skriva ut på skärmen.
Däremot här har vi kuben funktionen, som faktiskt återvänder något.
Så för dem som känner till detta, det är en ganska enkel idé.
Men för de mindre bekant med denna idé om att passera i ingångar och komma tillbaka utgångar,
låt oss försöka bara något super enkelt.
Är det någon bekväm kommer upp på scenen en kort stund?
Du måste vara bekväm med en kamera på dig också. Ja? Okej.
Vad heter du? >> [Studenten] Ken. >> Ken. Okej. Ken, kom upp.
Ken kommer att vara en funktion av slag här.
Låt oss gå vidare och göra det. Låt oss få lite fantasi.
TREVLIGT ATT TRÄFFAS. Välkommen till centrum. Okej.
Låt oss slå den här knappen här. Okej.
Så här har du en modern svarta tavlan,
och vad jag är den viktigaste funktionen, till exempel,
och jag har inte en iPad i min hand.
>> Jag förstår inte riktigt ihåg hur man - Tja, jag kan inte säga det.
Jag har inte riktigt bra handstil,
och så därför vill jag att du skriver ut något på skärmen för mig.
Jag är huvudprogrammet, och jag kommer att få dig att säga det här
genom att skriva det i min kyckling repa och sedan passerar du en ingång.
Så dumt men denna övning är, begreppet funktioner och kräver en funktion
och returnera en funktion verkligen kokar ner till detta.
Jag är viktigaste, har jag skrivit bara printf, citat-unquote något på skärmen,
Jag kör det här programmet, och så fort printf anropas,
det tar ett argument eller en parameter ibland mellan citationstecken.
Här är det argumentet. Jag passerar den till Ken.
Han är en svart låda skrivit ett visst antal år sedan
som uppenbarligen bara vet hur man skriver ut saker på skärmen.
Så exekvera.
Det är inte illa. Mycket bra.
Så nu Ken görs köra. Behöver han att lämna mig någonting tillbaka?
Inte för att vi har sett hittills.
Återigen, inte printf faktiskt returnera ett tal, men vi kommer att ignorera det för nu
eftersom vi aldrig har använt den. Så det är det för Ken.
Och så nu viktigaste tar över kontrollen av programmet igen
eftersom det kodrad, printf, görs köra.
Och vi går om vår väg, köra oavsett andra linjer finns.
Så nu ska vi prova en lite annorlunda exempel.
Den här gången låter här första rensa skärmen, och den här gången ska vi göra cubing funktion,
men den här gången, jag förväntar mig ett produktionsvärde.
>> Så låt oss gå vidare och göra det.
Nu har jag en kodrad som säger X får kub av X.
Kodraden, minns, ser ut så här: x = cube (x);
Så hur kommer detta att fungera? Låt oss gå vidare och ge dig en vit skärm igen.
Jag kommer att skriva ner nu värdet av x,
som vid denna tidpunkt råkar vara, låt oss säga, 2 för att hålla det enkelt.
Jag har skrivit ner på ett papper värdet 2, vilket är mitt värde x.
Jag lämna det till Ken. >> Och jag skriver bara svaret? >> Ja, låt oss bara skriva svaret.
Okej. Och nu måste han återvända mig något. Perfekt. Trevlig Segue.
Så nu har han överlämnar mig tillbaka värdet 8 i detta fall, och vad gör jag med den?
Faktiskt - låt oss se, få denna rätt. Vad ska jag göra med den?
Nu ska jag ta detta värde och faktiskt lagra den i samma bitar i minnet.
Men märker jag är typ att kämpa här.
Jag är lite förvirrad eftersom där kan jag faktiskt skriva värdet för x,
för det jag har just gjort är fysiskt handen Ken ett papper som hade värdet 2,
som var X, och faktiskt, det är precis vad som hände.
Så det visar sig att när du ringer funktionen och du passerar på ett argument
Liksom hej, värld eller om du passerar i ett argument som 2,
allmänhet, du passerar i en kopia av detta argument.
Och så precis som jag skrev ner numret 2 här och gav den till Ken,
det måste betyda att jag fortfarande har en kopia av värdet 2 någonstans
eftersom faktiskt, nu när jag har fått tillbaka värdet 8, måste jag gå tillbaka i RAM
och faktiskt skriva ner 8 där jag en gång hade numret 2.
Så visuellt, kom ihåg detta begrepp att passera i, bokstavligen, en kopia av värdet.
>> Ken gör sin grej, händer mig något - i det här fallet ett värde som 8 -
och då måste jag göra något med det värdet om jag vill hålla det runt.
Så allt detta kommer att komma tillbaka för att vara alltför bekant kort.
Tack så mycket för denna demo här, Ken. [Applåder]
Mycket bra gjort.
Låt oss se hur det i slutändan rör en del av den funktion kräver att vi har gjort här.
Låt mig gå vidare och föra oss tillbaka till cubing exempel.
Observera att om vi vill faktiskt börjar ta detta ytterligare,
vi kommer att vara uppmärksam på det faktum att antalet X som är passeras här
skiljer sig från vad som faktiskt skickas in till funktionen.
Så återigen, är detta pass med kopia kommer att bli ganska relevant på bara ett ögonblick.
Låt oss ta en titt på något som inte riktigt fungerar rätt ännu.
Jag ska gå vidare och öppna tredjedel buggy exempel som felaktig av naturen,
och det kallas buggy3 och genomför en swapping funktion.
Här har vi en huvudfunktion som x och y godtyckligt initieras till 1 respektive 2.
Vi skulle kunna använda getInt, men vi behöver bara en enkel övning,
så det är hårdkodad som 1 och 2.
I linjerna 21 och 22, ut vi tydligen ut x och y, 1 per rad.
Sedan på rad 23, hävdar jag jag byta dessa värden, punkt, punkt, punkt.
Jag kallar tydligen en funktion i linje 24 kallas swap som tar 2 argument.
Det är helt legit för funktioner för att ta 2 argument. Vi har sett printf gör det redan.
>> Så swap tar tydligen x och y, och som namnet antyder,
Jag hoppas att det kommer att byta dessa 2 värden.
Så då jag hävdar på rad 25 "Swappat!" och jag nytryck x och y
under antagandet att de verkligen har bytts.
Men om jag faktiskt köra programmet - låt mig öppna upp ett terminalfönster,
Låt mig göra buggy3 - som namnet antyder, detta kommer inte att sluta bra
för när jag trycker på Retur, märker att x är 1, y 2,
och ändå vid slutet av programmet, är de fortfarande i själva verket densamma.
Så baserad på visad just nu med Ken, vad egentligen som händer?
Låt oss dyka in i denna swap funktion. Det är super kort. Det är bara några få rader kod lång.
Men vad är det grundläggande problemet baseras på den enkla berättelse här uppe med Ken?
Varför swap bruten?
[Elev] Du lagrar en kopia, inte variabeln.
Exakt. Vi lagrar en kopia, inte variabeln själv.
Med andra ord tar swap tydligen 2 argument en int,
och det godtyckligt kallas a och b,
och här uppe har jag gått i x-och y som är respektive 1 och 2,
men jag inte bokstavligen är passerar i X, jag är inte bokstavligen passerar i år,
Jag passerar en kopia av x och en kopia av y..
Det är nästan som om du kopieras och klistras in swap
de värden som du vill att det ska faktiskt manipulera.
Så om så är fallet, när jag programstart utför linje 35 sedan 36,
när jag kommer till linjen 37, vid denna punkt i berättelsen, är det värdet av en?
Vid denna punkt i berättelsen, linje 37, vad är värdet av en vid det här laget? >> [Elev] 1.
[Malan] Det bör bara vara 1, höger, eftersom x passerades i det första argumentet,
och denna funktion bara godtyckligt ringer sitt första argument en.
Likaså är y det andra argumentet och det är bara godtyckligt ringer det andra argumentet miljarder.
>> Denna dikotomi är faktiskt ganska enkelt förklaras. Tänk på det.
Ingen av oss har träffat den person som skrev printf,
så väl, har han eller hon ingen aning om vad våra variabler 30 år senare kommer att kallas.
Så det måste finnas en skillnad mellan vad du kallar variabler i funktioner du skriver
och vad du kallar variabler i funktioner du ringer eller använder.
Så med andra ord, har jag skrivit mina variabler som x och y,
men om någon annan hade skrivit swap-funktionen, han eller hon absolut inte skulle veta
vad mina variabler kommer att kallas,
så inser att det är därför du har denna dualism av namn.
Tekniskt skulle jag göra det av en tillfällighet,
men de skulle ändå föras in som kopior.
Det skulle bara vara en ren tillfällighet estetiskt om personen som skrev swap
hade använt samma namn.
Så på denna punkt i berättelsen, linje 37, är en 1, b är 2, och nu har jag fortsätter att byta dem.
Först av allt, låt mig faktiskt göra det mycket enklare.
Jag vet inte vad de 3 rader kod gjorde.
Låt mig bara göra detta: b = a, a = b; gjort.
Varför är denna trasig, logiskt?
Det är typ av intuitiva sak, eller hur?
Så en blir b och b blir,
men problemet är att så snart som linjen 37 utför, vad är värdet av a och b?
Detsamma, 1, eftersom du har clobbered, så att säga, du har ändrat b för lika en.
Så när linjen 37 har utförts, det är bra, har du nu 2 kopior av nummer 1
insidan av denna funktion, så då när du säger i linje 38 a = b,
du typ av skruvade eftersom du bara tilldela 1 till 1.
Du har typ av förlorat det värde som du brydde dig om.
Så i den ursprungliga versionen av detta, märker vad jag gjorde.
Jag hade i stället tredjedel kodrad som såg ut så här.
Jag förklarar en temporär variabel.
>> Tmp är en mycket vanlig namn för en temporär variabel, och det är en int
eftersom det har att matcha vad jag vill göra en kopia av.
Jag lagrar kopia av en insida av TMP, så när linjen 37 har utförts,
Värdet på a är - snabb sanity kontroll - 1, är värdet av b 2,
och värdet av TMP är också 1.
Så nu har jag köra linje 38.
När linjen 38 utför, tar på värdet av b. Och b var 2, så en är nu 2.
Så vid denna punkt i berättelsen, är en 2, b är 2, och tmp är 1,
så nu logiskt kan vi bara plopp tmp värde i b och vi är klara.
Så vi har löst problemet.
Tyvärr, när jag kör det här programmet i denna form, inte egentligen byta några värden.
Men för att vara tydlig, varför?
Jag fixade den logiska problemet från bara en liten stund sedan,
men återigen, om jag kör det här programmet, x och y är oförändrade
i slutet av programmets genomförande.
[Ohörbart elev kommentar] >> Vi har inte återvänt någonting, så det är sant.
Men det visar sig att det är lite av ett problem här eftersom hittills,
det enda vi har kunnat återvända är en sak, och det är en begränsning av C.
Du kan bara returnera verkligen ett värde, i vilket fall är jag typ av fastnat här
eftersom jag kunde återvända det nya värdet på x eller jag kunde återvända det nya värdet på y,
men jag vill båda tillbaka.
Så återvänder inte den enkla lösningen här.
Men problemet är i grunden varför? Vad har vi bytte egentligen?
[Eleven] a och b. >> A och b.
Men a och b är kopior av x och y, vilket innebär att vi bara gjorde allt detta arbete,
Vi tillbringade bara 3 minuter talar om swap funktion och alla 3 av dessa variabler,
och det är bra, helt rätt för sig,
men a och b omfattning är bara i dessa rader här.
>> Så precis som en for-slinga, om du deklarerar ett heltal i innanför for-slingan,
Likaså om du förklara a och b inuti en funktion som du har skrivit,
de är endast giltiga insidan av den funktionen, vilket innebär så snart swap görs utför
och vi går från rad 24 till rad 25, har x och y inte ändrats alls.
Du slösat bara en massa tid att byta kopior av variabler.
Så det visar sig att lösningen på detta är faktiskt inte självklart.
Det är inte riktigt tillräckligt för att returnera värden eftersom vi bara kan returnera 1 värde,
och jag vill verkligen byta både x och y samtidigt,
så vi kommer att behöva komma tillbaka till detta.
Men nu inser att frågan i grunden härstammar från det faktum att a och b är kopior
och de är i sin egen räckvidd.
Låt oss försöka lösa detta på något sätt.
Låt mig faktiskt rulla tillbaka hit och öppna upp, låt oss säga, en fjärde variant av detta, buggy4.
Vad sägs om det här?
Detta är en liknande men enklare problem att titta på innan vi tar ett hugg på att lösa det.
Detta program kallas steg, och det tydligen initierar en x heltal till 1 i linje 18.
Jag sedan hävdar x är 1, hävdar jag då "uppräkning ..."
Jag kallar då steg, men då i ledningarna 22 och 23, jag hävdar att det är ökats,
Jag hävdar x är nu vad det är - 2, förmodligen - men det här programmet är buggigt.
Vad är problemet?
Ja. >> [Ohörbart elev svar] >> Exakt.
SO x har försatts naturligtvis på linje 18.
Det är inne i centrala s klammerparenteser.
Så det enkla svaret här är att medan X finns här,
Det finns inte i linje 32, så detta program faktiskt inte ens kommer att sammanställa.
Kompilatorn när jag försöker kompilera koden kommer att skrika på mig
om några odeklarerat identifierare eller något om detta. I själva verket, låt oss försöka.
Det är att buggy4. Där är det.
Användning av odeklarerat identifierare "x" i linje 32.
Och faktiskt, låt oss vara tydligare här i dag, så att det är användbart
i kontorstid och hemma.
>> Observera att det är lite kryptiskt skrivet.
Men det faktum att clang har yelled på oss, säger buggy4.c: 32:5, är faktiskt bra.
Det betyder att felet är på linje 32 vid teckenposition 5.
Så 1, 2, 3, 4, 5. Det är i själva verket där problemet är.
Och även också tänka på kontorstid och hemma, jag är lycklig här.
Jag har en misstag. Det kommer att vara relativt lätt att åtgärda.
Men om du får en hel skärm full med överväldigande felmeddelanden,
återigen inse att den nedersta en bara kan vara ett tecken på den översta en.
Så alltid jaga ner dina fel uppifrån och ned
eftersom det kan bara vara en kedjekoppling effekt
som föreslår att du har sätt fler problem än vad du faktiskt gör.
Så hur kan vi fixa detta om mitt mål är att öka x? >> [Elev] Gör X globalt.
Okej, så vi kan göra X globala.
Låt oss ta en genväg som jag varnade tidigare, men heck, vi behöver bara en snabb lösning,
så låt oss bara säga int x upp här. Det gör X global.
Så nu viktigaste har tillgång till den och steg har tillgång till det,
och så låt mig gå vidare och sammanställa detta nu.
Gör buggy4, Enter. Verkar kompilera nu.
Låt oss köra buggy4. Och det verkar faktiskt fungera.
Detta är en av dessa saker som är gör som jag säger, inte som jag gör,
som jag bara har gjort här, för i allmänhet,
våra program kommer att få mycket mer intressant och mycket längre än så här,
och om din lösning på livets problem är bara sätta alla variabler på toppen av din fil,
mycket snabbt får program får fasansfullt svårt att hantera.
Det blir svårare att komma på nya variabelnamn,
det blir svårare att förstå vad variabeln gör vad,
och så i allmänhet är detta inte en bra lösning.
Så låt oss göra det här bättre.
Vi vill inte använda en global variabel här.
>> Jag vill öka X, så jag kunde naturligtvis -
i slutet av dagen, är denna typ av en dum historia eftersom vi bara gör det -
men om jag inte visste om det operatören eller jag fick inte ändra det i huvud själv,
Hur skulle jag genomföra Ken hit den här gången inte kub utan att öka?
Hur ändrar jag det här här? Ja.
[Elev] Pass i x och sedan återvända [ohörbart] >> Okej, bra.
Så varför inte jag gå i x och sedan i stället tillbaka den,
varför inte jag bara inte tillbaka x + 1.
Ett par fler saker måste förändras här. Jag är på rätt spår.
Vad behöver jag för att justera? Någon annan. Ja.
[Ohörbart elev svar]
Jag behöver ändra tillbaka typ av steg eftersom det inte är ogiltig.
Void betyder ingenting skickas tillbaka, men uppenbarligen nu är det,
så detta måste ändras till - >> [elev] int.
int vara förenlig med vad jag faktiskt tillbaka.
Nu något annat är fortfarande buggigt här. Ja.
[Ohörbart elev svar] >> [Malan] Så jag måste öka x?
[Ohörbart elev svar] >> [Malan] Ah, så jag måste gå x.
Så jag behöver göra det här. >> [Ohörbart elev kommentar]
[Malan] Så prototypen, jag måste ändra detta här.
Så detta måste bli en int, måste detta bli -
hmm, jag har faktiskt en bugg här nere. Låt oss fixa detta först.
Vad ska det vara egentligen? Det måste vara en int något.
Det kan vara X, men ärligt talat, om du börjar ringa alla dina variabler x,
det kommer att bli mindre och mindre tydlig vilken som är vilken.
>> Så låt oss bara godtyckligt välja en annan namnkonvention för mina hjälpfunktioner,
funktioner jag skriver. Vi kallar det en, eller vi kan kalla det -
Låt oss kalla det nummer för att bli ännu tydligare.
Så då måste jag återvända oavsett antalet är plus 1,
och nu har jag ändra 1 sak upp här och en annan sak här.
Vad ska jag byta på linje 21 först? >> [Ohörbart elev svar]
[Malan] Jag måste tilldela den till x. Jag kan inte bara ringa ökning (x).
Jag behöver komma ihåg svaret genom att ändra värdet på x på vänster sida.
Och även om x är nu på vänster och höger, det är helt bra
eftersom den högra sidan blir utförs först sedan får plopped in vänster sak -
X i detta fall.
Och då slutligen, är detta en enkel fix nu.
Detta bör bara matcha vad nere, int antal.
Så en hel massa förändringar för en riktigt dum funktion
men representativ för saker som vi alltmer kommer att vilja göra.
Så gör buggy4. Jag har skruvat upp någonstans.
Herregud. Fem misstag i en 6-line-programmet.
Så vad är det för fel på rad 18, 5 tecken?
Så jag måste förklara detta, int.
Låt oss se. Det finns en hel massa andra fel.
Herregud - 19, 18, 21 - men återigen, låt oss bara rensa skärmen, Control L här,
och kör klang.
Så 5 problem är faktiskt bara att 1.
Så nu ska vi köra buggy4, Enter. Puh, har X ökats korrekt.
Okej. Har du frågor om hur man öka siffror? Ja.
[Ohörbart elev fråga] >> Bra fråga.
Hur kommer det sig att jag bara kan byta x till antalet och programmet kommer att veta direkt?
>> Återigen, tänk på det som denna abstraktion.
Så om jag är huvud och Ken är inkrement, ärligt talat, jag bryr mig inte vad Ken kallar sin iPad.
Jag bryr mig inte vad han kallar allt som har att göra med hans genomföra denna funktionalitet.
Detta är en implementering detalj som jag, huvud, inte behöver bry sig om.
Och så helt enkelt byta det konsekvent inuti funktionen - nummer här och nummer här -
är allt som behövs så länge jag kompilera.
Det är ungefär som om du tycker om många av oss, de av er med körkort
som har drivit eller om du ens kört i en bil,
de flesta av oss har ingen aning om hur en bil fungerar under huven.
Och bokstavligen, om du öppnar upp huven, de flesta av oss - däribland jag själv -
kommer inte att verkligen veta vad vi tittar på,
ungefär som du kan känna med sånt här just nu.
Men vi har egentligen inte bry hur bilen fungerar,
Vi behöver inte bry sig om vad alla stavar och kolvar och kablar inne i bilen
faktiskt gör.
Så något liknande vad du kallar kolven spelar ingen roll här i detta fall. Samma idé.
Ja. >> [Ohörbart elev fråga]
Om det finns fler användningsområden för den variabla xa stund sedan,
du, programmerare, skulle behöva ändra dem överallt.
Eller så kan du bokstavligen göra Fil, Meny och sedan Sök, Ersätt - något liknande -
men du kommer att behöva göra dessa ändringar själv.
Du måste vara konsekvent. >> [Elev] Om det finns flera variabler [ohörbart]
En särskild ordning som här, om detta var int annat nummer? >> [Elev] Korrekt.
[Malan] Ja. Beställ frågor när du ringer funktionen.
>> Så om jag ringer inkrement här med något kommatecken något,
Det finns en direkt mappning.
Den första variabeln, vad det heter, görs en kopia av det första argumentet hit.
Ursäkta. Detta bör inte vara en parentes.
Det andra argumentet ställer upp med den andra. Så att, ja, frågor. Okej.
Ursäkta. Jag tog den långa vägen dit. Övriga frågor? Okej.
Så låt oss se om vi inte kan måla en bild av vad som faktiskt händer här
under huven, så att säga.
Detta är en rektangel som kan representera datorns minne.
Även om du har ingen aning om hur minnet fungerar eller hur RAM fungerar,
åtminstone förutsätter att du har klasar av det dessa dagar.
Du har megabyte av det, har du gigabyte den,
och vi vet från vecka 0 att en byte är precis vad? >> [Studerande] 8 bitar.
8 bitar, eller hur? Så 8 nollor och 1.
Så om din dator har en spelning RAM, 2 gig RAM dessa dagar,
du har en miljard eller 2 miljarder byte minne eller ungefär 8 miljarder eller 16 miljarder bitar
insidan av din dator.
Till skillnad från den lilla Wooly Willy exempel, det är inte magnetiska partiklar vanligtvis längre.
Alltmer - i bärbara datorer minst - det är Solid State Drives, SSD,
som bara har några rörliga delar. Det är alla elektroniska. Det är all el-baserade.
Så tänk på detta rektangel som bara representerar 1 eller 2 gigabyte minne som du har.
>> Så det är en bit av minne.
I världen av datavetenskap har slags avskiljas
bitar av minne för att göra olika saker.
Till exempel, om detta är datorns RAM-minne, som föreslagits av rektangeln där,
det visar sig att enligt praxis, på toppen av ditt RAM, så att säga,
är i allmänhet vad som kallas en text segment.
De är 0 och 1 som du har sammanställt.
Så när vi har tittat under huven på vad a.out är,
alla dessa 0 och 1, när du kör ett program,
de 0s och 1s laddas från hårddisken till något som kallas RAM,
och i RAM de är lagt på toppen.
Samtidigt har du andra saker: initiera data avinitiera data.
De 2 stråk av minne hänvisar till globala variabler, som du inte använder ofta
men ibland om du gör, hamnar de upp där också.
Sedan finns några andra saker: miljövariabler, som vi inte kommer att spendera mycket tid på,
men sedan 2 viktiga saker som kommer tillbaka hela terminen,
stacken och heap.
Så de flesta av datorns minne är reserverat när man kör ett program
för något som kallas stapeln och något som kallas högen.
Vi kommer inte att tala om högen idag, men vi kommer att tala om stacken.
Stacken är avsedd att trolla fram den visuella av måltiden dining hall brickor i Mather House
eller var du råkar vara där matsalen personalen rengöra dem varje dag,
de stack upp dem från golvet på upp,
och på samma sätt, i minnet, det är denna idé om att sätta något på en bunt,
sätta något på en bunt, sätta något på en stack.
Och vad menar vi med det?
>> Låt oss zooma in på just den nedre halvan av bilden, datorns RAM-minne,
att föreslå följande.
Det visar sig att när du kör ett program som a.out eller hej -
vad programmet är att du har skrivit -
igen, 0 och 1 som laddas från hårddisken, vilket är långtidslagring,
stannar där även när du dra ur kontakten, laddas till RAM.
RAM är snabbare än hårddiskar - det är mindre än hårddiskar -
men det är där program bor när du kör dem.
Så du dubbelklickar på ett program på en Mac eller PC, det laddas från hårddisken till RAM-minnet.
Så snart det är laddat i RAM, den 0 och 1 gå på vägen upp,
den så kallade textsegment, men sedan så fort ditt program faktiskt startar,
huvudsakliga funktionen kallas, och viktigaste, som vi har sett, ofta lokala variabler,
och det har Ints och strängar samt tecken och liknande.
Så om ditt program som du har skrivit eller det program som du dubbelklickar har klickat
använt några variabler inuti huvud,
de hamnar på botten av din stack minne, så att säga.
Mer konkret vad innebär egentligen?
Det betyder bara att om vi skulle numrera byte RAM i datorn,
märker att detta kan vara byte nummer 0, kan detta vara byte nummer 1, 2, 3, 4, 5, 6,
hela vägen upp till 2 miljarder skulle vara hela vägen upp där i toppen.
Så med andra ord, när vi talar om RAM eller minne i form av byte,
Det betyder bara att någon har bestämt vad som numrera varje av dessa bitar av minnet.
Så när du behöver 32 bitar för en int eller om du behöver 8 bitar för en röding,
där slutar de upp i minnet?
>> Begreppsmässigt hamnar de bara upp på botten av denna sak som kallas stapeln.
Men vad som är intressant nu är när stora anropar en funktion -
Anta att en funktion som kallas foo, bara ett godtyckligt namn -
vad som händer är viktigaste är längst ned i denna stack minne,
foo nu läggs ovanpå viktigaste i minnet.
Så några lokala variabler som foo har hamnar slags konceptuellt högre än i main.
Om foo kallar en annan funktion som heter bar, dessa variabler hamna här.
Om spärra samtal något annat, här, här, här.
Så vad är intressant om hur du kör ett program är att när du ringer funktioner
och eftersom dessa funktioner kräver funktioner och eftersom dessa funktioner kräver funktioner,
du bygga upp denna trave funktioner i minnet.
Och bara en gång en funktion returnerar börjar man få att minnet tillbaka.
Så en av de enklaste sätten att få slut på minne i ett datorprogram
är att skriva funktioner som aldrig återvända.
Så till exempel, låt oss visa så mycket med ett avsiktligt buggy program.
Låt mig gå vidare och göra # include ,
int main (void),
och jag ska göra medan (2> 1), som troligen inte kommer någonsin ändra på oss,
och låt mig gå vidare nu och göra printf.
Egentligen är det kommer att bli mindre visuellt intressant. Låt oss göra detta.
För int i = 0; i> 0 - låt oss göra detta misstag - i + +.
Och låt oss inte printf här. Låt oss leva som jag predikade.
Låt oss ha en metod här, ogiltig kör, och vi kommer att säga int i,
och då ska jag säga printf - nej, låt oss göra det mer intressant.
Låt oss faktiskt inte ut något alls. Låt oss bara göra detta: kör (i).
Okej. Så detta är buggig eftersom varför?
Jag gör detta som jag går eftersom programmet inte egentligen göra någonting av intresse.
>> Men det är inte målet.
Målet är att skriva ett program vars huvudfunktion gör vad, tydligen?
Kalla sig. Och faktiskt, vi behöver inte slingan.
Låt oss förenkla även detta bara för att inte glömma verkligen grundläggande felet.
Huvudsakliga samtal refräng att sjunga lite kör,
då jag gjorde något dumt och jag hade kör kör samtal
eftersom jag antar att någon annan skulle genomföra det kanske,
och nu detta inte kommer att sammanställa ännu. Jag behöver göra det?
Jag behöver prototypen, minns.
Så jag måste ha här uppe void kör (int i);
Så nu om jag går ner här - faktiskt, låt oss använda den större fönstret.
Låt oss gå vidare och göra kör.
Användning av odeklarerat identifierare i..
Åh, det var dumt. Vi behöver inte argumentet. Låt oss bara göra detta.
Jag önskar att vi hade börjat på detta sätt. Det skulle ha varit en mycket enklare program för att skriva.
Där. Nu ska vi gå över till min terminalfönster, kör klang, och här kör vi.
Det var verkligen snabbt.
Vad som egentligen hände, men?
Nåväl, nu ska jag lägga den tryckta linjen så vi kan se.
Låt mig säga printf ("Jag är här") - inga variabler. Vi lämnar det så.
Låt mig köra göra. Låt mig köra kör.
Och ... kom igen. Fortsätt.
Som en sidoreplik, varför har det kraschade inte ännu?
Den segmenteringsfel hände supersnabb tidigare.
[Ohörbart elev svar] >> Exakt. Så det tar tid att skriva ut, eller hur?
Det tar bara mer arbete på datorns sida.
Och det är det: segmenteringsfel.
>> Så märker hur snabbt program körs.
Om du inte skriver något, supersnabb.
Men vi fick ändå denna segmentering fel eftersom vad som hände?
Om du tänker på hur datorns minne är anlagd,
Detta råkar vara huvud, men här vi bara kalla denna kör, och låt oss kalla denna kör.
Och nu om jag gör mitt estetik rätt, kommer detta bara säga kör, kör, kör,
kör, kör, kör, kör, ad nauseum, och så småningom, vad som kommer att hända?
Om helheten, bokstavligen, är det, vad händer just begreppsmässigt?
Bunten överskridanden högen.
Eller ännu värre, överskridande du bara allt, inklusive texten segmentet,
som är den 0 och 1 som representerar ditt program.
Kort sagt, detta är bara super, super dåligt.
Ditt program har spiraled utom kontroll.
Du använder mycket mer minne än du tänkt
allt på grund av ett dumt misstag i detta fall,
eller i detta fall en mycket medvetet gjort funktion kallar sig.
Nu är detta inte dåligt.
Funktioner som kallar sig har faktiskt stor makt när du använder den på rätt sätt.
Jag har inte använt det på rätt här.
Så detta är inte allt dåligt, men det faktum att jag aldrig sluta kalla mig själv
är en grundläggande svaghet här i detta program.
Så vart är vi på väg med allt detta? Vad som verkligen händer?
När jag ringer ökningen funktion som vi gjorde i dessa exempel,
Jag har ett värde som 1 som jag passerar i.
Jag passerar i en kopia av siffran 1, så följande händer.
Låt oss gå in i steg exempel den här killen här borta.
Här är vad som faktiskt händer.
När jag ringer ökning och jag passerar i x, bildmässigt, vad som händer här är det.
>> Om jag har värdet 1 sparas här och jag faktiskt kallar steg,
som nu kallas refrängen - iPad kastar mig här.
Låt oss kalla detta steg, och vi vet inte vad det nästa funktion kommer att bli.
Så vad som faktiskt händer här någonstans i huvud har jag en bit av minne
som lagrar numret 1.
När jag ringer steg, jag använder en annan bit av minnet,
men nu har jag en kopia av 1.
När jag öka detta värde blir detta 2,
men vad händer när inkrement återvänder?
Detta minne blir bara lämnas tillbaka till operativsystemet,
vilket innebär att alla du har gjort är inget användbart.
Den 1 som ursprungligen ingick i huvud är fortfarande faktiskt det.
Så vart är vi på väg med detta?
Det visar sig att i minnet du har denna back-to-back sekvens av byte
som du kan sätta saker i, och det visar sig att vi redan har sett något
som innebär att sätta saker rygg mot rygg mot rygg mot rygg.
Vad är en sträng baserad på vecka 1 och vecka nu 2?
Det är bara en samling av tecken.
Så det visar sig precis som du kan sätta siffror i minnet,
liknande kan du sätta tecken i minnet.
Och när vi börjar sätta tecken i minnet tillbaka till tillbaka till rygg mot rygg,
det visar sig att använda den enklaste av saker som en for-slinga eller en while-slinga,
Vi kan iterera från vänster till höger över tecknen i en sträng
och börja massera dem i olika karaktärer helt -
en kan bli b, kunde B bli c -
så att i slutändan, kan vi ta en engelsk mening som faktiskt är vettigt
och omvandla var och en av dessa bokstäver en åt gången
genom att gå igenom vår dators minne från vänster till höger för att verkligen kryptera.
Så låt oss ta vår fem-minuters paus här,
och när vi kommer tillbaka, börjar vi processen att förvränga information.
>> Okej.
Innan vi dyka in några krypto och dessa saker som kallas matriser,
Låt mig stanna upp några frågor eftersom jag känner att jag verkligen slags rörig
vissa av dessa ämnen. Så låt oss fixa nu om vi kan.
Vi bara pratade om returvärden, talade vi om argument,
och vi pratade om detta begrepp, som vi ska återkomma till i de kommande veckorna,
att betrakta minnet som en massa av dessa staplade brickor, så att säga,
från botten på upp, så att varje fack som får sätta på stacken
representerar en funktion som för närvarande är som anropas.
Några frågor?
Låt mig ställa en fråga här.
Låt mig förenkla tillbaka till vad det var innan några av våra tidigare Q & A.
Det faktum att ökningen har öppen parentes, int antal, stängd parentes -
Vad utgör int nummer?
[Eleven] Ett argument. >> Ett argument. Okej. Men vad är ett argument?
[Ohörbart elev svar] >> Vad är det? >> [Elev] Något som du skickar in
Okej, så något som du passerar i. Och mer allmänt, det är bara ingången.
Om du skriver en funktion och att funktionens syfte i livet
är att göra något lite annorlunda varje gång du använder det,
då det enda sättet för att det ska hända verkligen tycks vara att förse den med ingång
så att den kan göra något annorlunda med den ingången varje gång.
>> Så du måste ange två saker när en funktion tar in.
Du måste ange det namn som du vill ge till denna ingång
enbart för din egen bekvämlighet så att du kan hänvisa till den
i den funktion som du själv skriver, som jag gjorde här i linje 32.
Men du måste också ange dess typ eftersom C är ett programmeringsspråk
som kräver bara att om du vill ha en variabel, måste du tala om för datorn vad datatyp det är,
till stor del så att den vet hur många bitar att fördela för den variabeln
eftersom det kan vara 6 - förlåt, kommer det inte 6.
Det kan vara 16, kan det vara 8, kan det vara 32, även 64,
men datorn behöver veta.
Nu representerar int på den vänstra sidan vad däremot?
[Ohörbart elev svar] >> Vad är det? >> [Elev] Typ av funktion.
Typen av en funktion och, mer specifikt, den typ av produktionen. Rätt.
Så medan sak i parentes representerar dess ingång, om någon,
sak till vänster representerar dess utgång.
Och i det här fallet returnerar steg tydligen en int,
och så int är returtyp av denna funktion.
Vad innebär det att återvända?
Bokstavligen, använder du nyckelordet tillbaka och sedan om vad du återvänder
till höger om sökordet är ett heltal,
då verkligen överensstämmer med vad vi har lovat.
Du kunde inte göra något liknande - hej, värld - för det är en sträng.
>> Uppenbarligen är det inte ett heltal.
Så kort sagt, är bördan verkligen på oss, programmeraren, att vara specifik
vad vi tillbaka och sedan faktiskt gå tillbaka det.
Sammanhanget här är nu att datorns minne är en gigabyte, 2 gigabyte -
vad - kanske är det mer, kanske är det mindre,
men datorn ser det som att ha olika sektioner.
Något går ner dit, går något annat där uppe,
olika saker går i mitten, och idag har vi bara börja berätta historien,
men vi ska återkomma till detta med tiden.
För nu, är det enda minne vi verkligen bryr oss om texten segmentet
eftersom det bara är den 0 och 1 som klang har matas ut.
Så när du kör ett kommando på tangentbordet som a.out
eller du dubbelklicka på en ikon i Mac OS eller Windows,
ditt program laddas från hårddisken till RAM
och det är plopped på toppen av datorns RAM-minne, så att säga.
Samtidigt som programmet startar och viktigaste anropas
i det program som du skrev eller programmet Microsoft eller Apple skrev,
någon av dess lokala variabler hamnar nere på botten av din dators minne.
Men om stora samtal en annan funktion som själv har variabler eller argument hamnar de ovanför.
Och om den funktionen kallar någonting, hamnar de ovanför, ovanför, ovanför den.
>> Och endast en gång en funktion görs verkställande inte stapeln av brickor, så att säga,
börjar bli lägre och lägre.
Och detta är vad då, i ett nötskal, förklarar varför när du ringer kub
eller du kallar steg, du passerar i en kopia av värdet.
Och vad det betyder bildmässigt är att du bokstavligen skriver siffran 1
i en annan del av minnet, förändras att 1 till 2 i fallet med inkrementet
eller till en 8 vid kuben och sedan kasta att minnet bort
så snart inkrement eller kuben återgår funktionen. Fråga.
[Elev] Var är globala variabler lagras?
Globala variabler lagras i vad som för närvarande kallas initierade data eller oinitierade data,
Skillnaden är om du har en global variabel och tilldelar den omedelbart ett värde
med likhetstecknet, slutar upp i toppen där,
och om du bara säga int x, utan värde, slutar det upp något lägre i RAM
helt enkelt genom konventionen.
Övriga frågor? Okej.
Så den här bilden kommer tillbaka när vi blir mer kraftfull
med vad vi kan göra med datorn,
men nu ska vi ha en kort introduktion till kryptografi,
en viss typ av kryptering som inte lösa alla världens problem
men löser några av dem.
I detta fallet här har vi något som kallas hemliga key kryptografi.
Hemlig-nyckel kryptografi, som namnet antyder, får sin säkerhet från en hemlighet.
>> Till exempel, om du var tillbaka i skolan och du passerar en liten bokstav hemliga kärlek
till pojke eller flicka du krossa, om du ville passera denna anmärkning genom publiken,
du förmodligen inte skulle skriva en sådan anteckning i engelska eller vad ditt modersmål är.
Snarare kan du kryptera den eller du kanske bara skicka dem ett SMS i dessa dagar.
Men du kan faktiskt passera dem en anteckning hela klassrummet.
Och att göra detta säkert på ett sådant sätt att dina vänner och lärare
vet inte vad du skriver, kan du komma med en ganska enkel algoritm,
ung men du kan vara, bara förvränga orden.
Så istället för att skriva en du kan skriva b,
istället för B du kan skriva c,
istället för c du kan skriva d, och så vidare.
Eller så kan du komma med en mer sofistikerad översättning
av brev till olika bokstäver.
Men fångsten är pojke eller flicka som du ska skicka detta meddelande
behöver veta något, vilket är vad, uppenbarligen? >> [Eleven] Vad du skickar.
Vad din hemlighet är, liksom vad är det mappning mellan s och B: s och C: s och D: s.
Är det att lägga bara 1 till var och en av bokstäverna för att gå från A till B, B till C?
Är det mer komplext än så?
>> Så du och din kärlek måste ha denna hemlig information,
men det är lite av en fångst-22 här.
Om detta är första gången du skickar detta kärleksbrev genom klassen,
hur är det pojke eller flicka kommer att veta vad hemligheten med är?
Så hemlig-nyckel krypto löser inte alla världens problem,
och det finns faktiskt en relation här som vi ska återkomma till mot termin slut.
Likaså gör de flesta av oss vet inte någon som fungerar, till exempel på Amazon.com,
och ändå många av oss har säkert köpt grejer på Amazon.com,
och vi har fått lära oss att anta att dessa e-handelstransaktioner är säkra.
Webbadressen säger förmodligen https, det finns kanske en dum liten hänglås-ikonen någonstans,
Det finns någon form av kryptering säkra din kreditkortsinformation
mellan dig och Amazon.com.
Och ändå om kryptografi innebär att veta någon hemlighet
och ändå vet jag inte vem som helst på Amazon och jag har verkligen inte arrangerat någon form av hemlig
med någon på Amazon, hur är min dator eller min webbläsare gör detta?
Det visar sig att det finns andra typer av kryptografi helt att lösa det problemet.
Men för idag, vi fokuserar på det enkla en
där du kan ordna i förväg veta någon hemlig
som en eller några mappning mellan A: s och B: s.
Och processen för kryptografi involverar generellt detta.
Du har några oformaterad text, visas här till vänster,
du kör det genom någon form av algoritm eller förfarande för kryptering det -
kanske det är bara en blir B, blir B C -
och sedan sluta med chiffertext.
Samtidigt när din kärlek får denna hemliga anmärkning,
han eller hon har att sedan dekryptera det med allmänt motverka dessa algoritm
så att få tillbaka oformaterad text.
Det finns fysiska inkarnationer av detta.
>> Till exempel är det en liten hemlighet dekoder ring,
och detta är en ring i den meningen att det finns två rattar här.
På utsidan periferi denna sak, det finns bokstäverna A till Z,
även om de är i slumpmässig ordning,
och på insidan, det finns faktiskt några siffror
så att med denna ring kan du typ av tur utsidan men inte insidan
För att rada upp numren med bokstäver.
Från en film som heter A Christmas Story, ser du den lilla Ralphie
var så ivriga att räkna ut vad Little Orphan Annie hemliga budskap var att han
som hade meddelats, tror jag, i form av numeriska meddelanden på ett flingpaket
och du var tvungen att samla alla de små korten som kom i flingpaket,
du var tvungen att posta dem i, var du tvungen att få tillbaka den hemliga dekoder ringen
så att du kan äntligen räkna ut vad mappningen mellan bokstäver och siffror
eller bokstäver och bokstäver.
Hur i en dator kan vi gå att genomföra eller representerar saker som detta?
Vi behöver ett sätt att uttrycka oss själva lite mer flexibelt
än våra variabler hittills ha tillåtit.
Vi har haft Ints, vi har haft tecken, vi har haft flöten och dubblar och några andra,
men de är enskilda delar av minnet som egentligen inte tillåter oss att uttrycka saker
som ord och meningar och fraser.
I själva verket har vi kallade dessa saker strängar,
men vi lovar att det är egentligen bara en förenkling av CS50 biblioteket
att vi har för avsikt att dra tillbaka.
Och så låt oss börja att göra det här.
Låt mig gå vidare och öppna upp en fil -
alla dessa filer finns som vanligt på nätet - kallad array.c
att lösa ett problem utan samband med strängar men det ger en bild här
om hur vi kan använda något som kallas en matris.
>> En array är en datatyp.
Det är en typ av variabel slags som har flera mindre datatyper inuti den
rygg mot rygg mot rygg mot rygg.
Så till exempel, om vi ville skriva ett litet program som ger dig din frågesport genomsnitt
för en kurs som 50 som har 2 frågesporter,
kan du mycket enkelt skriva det här programmet bygger även på några av förra veckans material
genom getInt och ett par variabler: int quiz1, int quiz2.
Och det är ganska enkelt.
Det är kanske 10, 20 rader kod Max att genomföra ett program
som frågar användaren om 2 frågesport poäng och sedan beräknar deras genomsnittliga
genom att lägga till dem tillsammans, dela med 2 och sedan skriva ut resultatet.
Vi kan nog göra det ganska lätt nu efter ett antal minuter.
Men problemet är att anta att 50 hade 3 frågesporter eller 4.
Anta att du vill använda samma program för en klass som hade veckovis frågesporter.
Tänk på en klass som varje vecka har frågesporter.
Om det finns 16 eller så veckor i termin, nu har du 16 variabler:
int quiz1, int quiz2, int quiz3, int quiz4.
Så snart du börjar se denna redundans, detta kopiera och klistra in i kod,
den ska börja att göra dig önskar att det fanns ett bättre sätt.
Och tack och lov, på grund av matriser finns. Så låt oss göra det här.
Först, låt mig presentera en mycket enkel sak att vi inte har använt hittills,
men du kommer att se det ibland i koden.
>> Detta är vad som allmänt kallas en konstant.
Så det är en konstant i den meningen att detta värde inte ändras.
Den mänskliga konvention när du skapar en konstant
är att använda versaler bara så att det verkligen sticker ut i din kod,
och den speciella nyckelord som du använder i C definierar #.
Så vi säger # define då ett utrymme, så det ord du vill använda för konstanten namn
och sedan värdet på konstanten.
Notera att detta är annorlunda tilldela något till en variabel.
Det finns ingen likhetstecken, det finns ingen semikolon.
Detta är vad som allmänt är känt som en preprocessor direktiv,
men mer om det en annan gång.
För nu, skapar detta en oföränderlig värde kallas frågesporter
vars faktiska numeriska värdet är 2.
Så var du ser frågesport, frågesport, frågesporter hela filen,
det är bara nummer 2.
Om jag tittar på huvud nu, låt oss se hur det fungerar.
Först ser det lite kryptiskt, men det är alla grejer från vecka 1.
Be användaren för betyg. Hur gör vi det?
I linje 22 - detta är verkligen den saftiga delen - Jag förklarar en flottör
men inte en enda flottör. Jag förklarar snarare en rad flyttalsvärden.
Den variabeln kommer att kallas kvaliteter, vilket antyds här,
men den enda del av nya syntaxen är då dessa hakparenteser.
Det faktum att jag har sagt float betyg och öppna sedan fäste och sedan ett antal -
märker om det är en konstant är precis som vi gjorde detta -
Detta innebär, "Hej dator, ge mig 2 flyter och låt oss tillsammans kalla dem betyg."
>> Detta står i kontrast till en mycket mer mödosam process så här: float Grade1;
float grade2, och så vidare.
Så en array kan vi genomföra denna idé, men mycket mindre messily,
på ett sådant sätt att vi kan skriva 1 kodrad i stället för, säg, 16 för en 16-veckors termin.
Jag ville inte hård-kod 2 för om man tänker på det nu logiskt,
antar nästa år CS50 ändringar 3 frågesporter istället
och jag hade nummer 2 här, hade jag numret 2 här,
Jag hade nummer 2 här numret 2 här.
Det blir mycket tröttande och mycket lätt att skruva upp
och att oavsiktligt ändra 1 värde till 3 och missa något annat värde av 2.
Så jag ska istället abstrakta detta bort och använda denna konstant som,
Som namnet antyder, förändras aldrig.
Och nu spelar ingen roll om vi har olika frågesporter i år eller nästa,
Jag måste bara ändra det på ett ställe här uppe på toppen.
Så det är allt en konstant är.
Samtidigt är den nya konceptuella funktion som av en matris.
Så hakparenteser ge mig så många flottar och låter mig kollektivt kallar dem kvaliteter här.
Så nu ska vi se vad jag ska göra.
Här i linje 24 är början av en for-slinga.
>> Detta är verkligen ingenting fancy. Det är bara att använda frågesporter stället för en hårdkodad nummer.
Men det finns inget intellektuellt annorlunda där från förra veckan.
Detta är bara printf så printf ("Quiz #% d av% ​​d:")
eftersom jag vill bara skriva ut mig frågesport nummer 1 av 2 och sedan 2 av 2.
Så detta är en rent estetisk sak.
Men det intressanta är nu i linje 27.
För att fylla i en av de två platshållare med en floating-point värde,
du använda igen hakparenteser.
I det här fallet, jag använder jag eftersom det för slinga har börjat med i motsvarande vad värde, tydligen?
[Elev] 0. >> [Malan] 0.
Så på den första iteration av denna slinga är det som om jag skrev detta i kod,
men på andra iteration av denna slinga är det som om jag skrev detta i min kod.
Men det faktum att jag använder en variabel är perfekt eftersom, som namnet antyder,
det variera dess värde på varje iteration,
så jag fyller denna array en plats åt gången.
Hur ser denna array ut?
Anledningen till att jag drog super enkel rektangel på skärmen här var innan av detta skäl.
En array är bara en bit av minnet, följt av en annan bit av minnet
följt av en annan bit av minne och så vidare.
Så om min array är av storlek 2 i detta fallet här, allt jag skulle göra
genom att skriva i min frågesport poäng som här - jag fick 100 på detta och sedan fick jag en 99 på den här -
då detta minne kanske inte ens användas eftersom jag har bara frågat datorn
för en rad storlek 2.
Dessa rutor är fortfarande där, eller hur?
Du har fortfarande 2 gigabyte RAM-minne, även om du bara ber om 2 flyter.
Så tanken bakom arrayer är att datorn bara tar en bit av minne
och sedan fördelas proportionellt mindre bitar rygg mot rygg mot rygg mot rygg.
Och så är allt en array är.
>> Det är en sammanhängande bit av minne inuti som du kan lägga saker.
Det händer så gör några tråkiga aritmetik.
Om jag bläddra ner hit, det är här jag sedan iterera över arrayen.
Jag kommer upp med summan av alla värden i matrisen,
och då använder jag den runda funktion här att faktiskt göra det belopp dividerat med frågesporter.
Men låt mig våg min hand på det som en slags tillräckligt aritmetik för nu.
Men allt som gör för mig ytterst beräknar ett genomsnitt.
Så först frågesport plus 2. Frågesport delat med 2 och sedan skriva ut det som en int.
Men låt övergång nu till en annan exempel heter sträng1,
vilket ger en liknande bild, men med strängar.
Låt mig gå vidare och förenkla detta för ett ögonblick.
Förlåt indraget för nu.
Meddelande i linje 19 i detta exempel, får jag en sträng från användaren.
Men märka vad jag nästa ska göra i rader 22 och framåt.
Jag är faktiskt iteration från i upp till - och detta är ett nytt trick - strlen, stränglängd.
Detta är en funktion som kommer med C att om du ge det en sträng,
Det talar om för dig hur många tecken finns i den strängen. Det är allt.
Och det faktum att det är strlen istället för sträng längd är bara för att det är mer kortfattad.
För trettio år sedan, tyckte folk att skriva saker så kortfattat som möjligt,
så vi har hållit denna konvention här.
i + + betyder bara öka i i varje iteration.
Och nu märker detta, vilket är riktigt intressant.
I linje 24, säger jag, "Dator, ge mig ett tecken, 8 bitar, och kallar det c".
Men vad är detta på höger sida säger?
På engelska, vad står?
[Eleven] Det första tecknet i arrayen.
Exakt. Ge mig det första tecknet i arrayen.
Eller mer allmänt, ge mig den i: te tecknet i arrayen.
Och inse att det är nu viktigt att som datavetare,
vi faktiskt räknat från 0.
>> Du har inte utrymme för skönsmässig bedömning nu att börja göra det.
Nu måste du agera i enlighet med datorns förväntningar och räknar från 0
eftersom [0] kommer att bli det första tecknet i en sträng,
[1] kommer att vara den andra, [2] kommer att vara den tredje, och så vidare.
Så det här programmet, om jag kompilera det, är detta återigen sträng1, så sträng1,
och nu har jag springa sträng1 i min terminalfönster.
Det väntar för inmatning, så jag kommer att skriva i David, Enter,
och nu skriver David allt på olika linjer eftersom varsel vad jag gör.
Jag skriver ett tecken i taget.
Vi kommer inte att gå in i detalj i dag om detta, men jag raderade nyss denna kontroll här.
Det visar sig att om användaren missköter, kontradiktoriskt, eller bara förvirrad,
kan du faktiskt misslyckas med att ge en sträng av viss längd.
Om du trycker på fel tangent på tangentbordet, kan du ge några sträng alls,
eller om du är skadlig, kan du prova att klistra in en gigabyte värde av en uppsats
att fylla detta sträng, och om datorn får slut på minne,
det visar sig att vi kommer att få tillbaka denna speciella värde som kallas NULL.
Så för nu, bara veta att det är det här särskilt värde kallas NULL
som ger oss möjlighet att kontrollera när vi är ute på minne, bland annat.
Men om jag öppnar nu sträng2, märker en skillnad här.
Lägg märke till en skillnad här med sträng2.
Med sträng2 är detta för slinga lite annorlunda.
>> Låt mig ta bort nollorna så att vi kan tala om dem en annan gång.
Vad är annorlunda for-slingan den här gången?
Jag kan gå tillbaka till det tidigare exemplet.
Så det är version 2, är denna version 1. 1, 2.
1, 2.
Det strlen samtalet var?
Det är i första delen av for-slingan.
Några tankar om varför jag gör det här? Ja.
[Elev] Så du kallar inte funktionen varje gång.
[Malan] Så vi inte anropa funktionen varje gång. Exakt.
Minns från loopar att de är super enkla
när du typ av förstå att detta är initieringen, tillstånd och uppdateringen.
Problemet är att villkoret händer på varje iteration av slingan.
Och så i detta exempel här är vad dåligt om det faktum att detta är mitt tillstånd?
[Eleven] Du kallar strlen.
[Malan] Du kallar strlen igen och igen och igen.
Men när jag har skrivit i David, är längden på den strängen 5,
och det kommer inte att ändra på varje iteration av slingan
eftersom strängen fortfarande D-A-V-I-d.
Så detta är ett tips på vad som kommer att bli en allt viktigare idé
känd som en design beslut där bara inte göra datorn gör onödigt arbete.
>> Precis som en förhandstitt på pset2, pset2 i standardversionen
kommer att utmana dig att faktiskt genomföra ett visst antal chiffer,
ett visst antal krypteringsalgoritmer, så att du både kan kryptera
och dekryptera hemliga meddelanden mycket som den Ralphie där avkodas.
I hacker upplagan av pset2, kommer vi att gå lite längre.
Vi kommer att lämna dig en fil från en faktisk dator
som innehåller en hel massa användarnamn och faktiska krypterade lösenord,
och utmaningen för hacker upplagan kommer att vara att knäcka dessa lösenord
och räkna ut vad kryptografi eller vad hemligheten användes för att faktiskt generera dessa lösenord.
Och vi kommer att göra detta genom att använda en ny funktion här av C
att jag ska ge dig bara en demo av sk kommandoradsargument.
Det visar sig, som några av er kanske har sett i avsnitt eller i läroböcker,
viktigaste inte alltid vara ogiltig inom parentes.
Det visar sig att stora även kan skrivas så här, med två argument,
argc och argv, där argc är antalet ord
att du skriver efter programmets namn på kommandoraden
och argv är själva orden.
Och som hakparenteserna där antyder, är argv tydligen en matris.
Det kommer att vara en sträng efter en sträng efter en sträng i minnet.
>> Så vad vi ska kunna göra börjar med pset 2 är ungefär så här.
Om jag gör argv1, vilket är ett exempel som vi ska återkomma till på måndag, och kör den,
märker att det inte verkar göra något ännu.
Den skriver bara ut sitt eget namn.
Men om jag säger adjö klass, meddelande att detta program uppenbarligen itererar
över vart och ett av orden som skrivs vid prompten.
Och de medel genom vilka vi får tillgång till ord som användaren har skrivit vid prompten
är genom att ändra viktigaste utgångspunkt i helgen från int main (void) och int main (argc, argv)
och därmed kommer att födas kommandoradsargument.
Och när du får riktigt sofistikerad på detta, kommer du att kunna skriva riktigt trippy program
som denna här, som går utöver
vissa funktioner vi har gjort hittills, men alla ganska kraftfull.
>> Så vi lämnar detta med detta på skärmen, och vi kommer att se dig på måndag.
>> [CS50.TV]