[Musik Spela] DAVID J. MALAN: Okej detta är CS50 och detta är början på vecka fem. Så idag, under dina sittdynor, du kommer inte hitta något. Men ovan, bör du hitta dessa, en litet tecken på vår uppskattning för allt arbete som du lägger i Game of Fifteen. Ta bara bort den lilla cirkeln på botten för att börja spela för resten av klassen. Så minns att, eller vet att problem som fyra, som gick ut i helgen, innebär att skriva en annan lek. Men den här gången innebär att man använder en faktiska grafiskt användargränssnitt, inte en textuella gränssnitt som Game of Fifteen var. Och spelet som ligger framför dig, Om du inte har ännu sett detta nästa, ser lite ut så här. Jag kommer att gå in i min terminal fönster här i GDB. Och jag ska gå vidare och köra Personalen lösning, som du kan komma åt efter att ha kört uppdateringen 50 som vanligt. Men jag ska sätta den i en liten hemlig läge, lite påskägg, sk Gud läge, genom sätta Gud i argv1. Och jag måste följa mina egna riktningar, kör det i min egen Problemet inställd katalogen. Så nu ser du en komplett version av spelet Breakout. I själva verket är detta ingen händer läget. Så det är faktiskt - bländade fast du kan vara - ganska trivialt att implementera Gud läget i Breakout, till skillnad från Game of Fifteen, som vissa av er kanske har tacklat för hacker upplagan. I Breakout det räcker i Gud läge för att helt enkelt göra vad, intuitivt med paddeln? Bara göra det lika oavsett horisontellt läge är av bollen. Och så länge du gör det i takt med bollen rör sig här spelet kommer aldrig, någonsin, någonsin missa bollen och du kommer att vinna varje gång. Men i denna veckas hacker edition det finns mer än bara Gud läget. Det finns ett antal andra funktioner. Bland dem, lasrar. Så att om du får riktigt otålig du kan börja skjuta ner tegelstenarna och några andra. Och för er som vill kalibrera standard kontra hacker edition, kan jag se att denna veckas hacker edition är medvetet ett lite mer genomförbart, säger, än Gud läget var med Game of Fifteen. Så om du letar efter en sträcka och du är ute efter lite extra kul funktioner gör dyk in om intresse. Nu mer praktiskt, låt mig peka ut en sak också. GDB, vilket några av er kanske inte har ännu berörde personligen, vilket är bra. Men nu är verkligen tid att vänja till detta och bekväma med detta verktyg eftersom det kommer att göra ditt liv mycket lättare, verkligen. Per Rob föreläsning på GDB ett par veckor sedan, minns att GDB är en debugger. Det är ett verktyg som låter dig köra din program men kör det steg för steg, linje av linje, så att du kan rota runt, så att du ser saker som händer, så att du kan skriva ut värden på variabler. Kort sagt, det ger dig så mycket mer effekt än printDef gör. Nu visserligen gränssnittet är ganska svårbegriplig. Svart och vit text gränssnitt för det mesta. Kommandona är något tufft att komma ihåg i början. Men även om det kan ta en halv en timme, en timme, för att sätta det i förskott investering i tid till det, lita på mig. Visst genom termins slut kommer det att spara du en storleksordning mer tid än så. Så i början av veckan dyker i. Och i termer av Breakout, vet att du kan göra detta så länge du har distributionen koden eller din egen kod pågår i din Pst4 katalogen. Vet att du kan köra gdb. / Breakout. Detta kommer att öppna upp ett fönster som detta. Låt mig ge mig mer av ett terminalfönster. Och sedan vad jag ska gå vidare och göra, är det inte bara köra det. Jag ska först sätta en brytpunkt återkallelse, vilket gör att du kan pausa exekvering på en viss plats. Bara för att hålla det enkelt Jag kommer att bryta på linjen en bara genom att skriva nummer ett. Låt mig faktiskt åter öppna det här fönstret eftersom det blir en lite små där. Så vad jag nu ska göra här är Om jag öppnar mitt terminalfönster. Kom igen, det går vi. Så nu om jag går tillbaka till dropbox, Pst4 och köra gdb. / breakout in, märker Jag kommer att bryta en att ställa en brytpunkt på linje ett. Och nu ska jag gå framåt och typ springa. Och när jag gör det, märker ingenting verkar hända. Det finns inga pop up. Det finns ingen grafisk användargränssnitt ännu. Men det är förståeligt eftersom jag är bokstavligen på rad ett i mitt program. Och märker att jag snabbt har överlämnats, specifikt nu till 62, eftersom alla grejer på toppen av denna fil är saker som kommentarer och konstanter och ointressant grejer för nu. Så nu är jag inne i huvud, det verkar, på rad 62. Och detta är bara fördelningen kod, återkallelse. Om jag öppnar detta upp genom att gå, på liknande sätt, i min drop box katalog i Pst4, in breakout.c. Och om jag bläddra ner och ner och ner, och låt mig gå vidare och slå på mina radnummer. Vad jag får se om jag bläddra ner till linje 62, är exakt den linje som Vi har pausat den. Så här linjen här, 62, är där vi ska vara. Så nu i GDB, om jag går vidare och skriver nu nästa, skriv det kommer att exekvera den linjen. Och voila, vi har den så kallade g fönster. Om obekant med vad en GWindow är, att inte oroa dig. Den spec kommer att introducera dig till det, som samt ett antal av genomgång videor inbäddade i spec. Men nu ska vi göra detta till en lite mer intressant. Låt mig gå här fönstret över åt sidan lite. Låt mig göra fönstret lite större så jag kan se mer. Och låt mig nu gå vidare och göra nästa gång. Och det är mina tegelstenar. Om jag skriver nästa gång nu ser jag bollen. Och om jag skriver nästa gång nu ser jag paddeln. Och lyckligtvis detta gedit är inte verkligen samarbeta genom att visa mig allt jag vill ha. Men nu när jag gör nästa gång, nästa gång, jag är bara förklara några variabler. Och jag kan skriva ut någon av dessa killar. Skriv tegel, grafik liv. Och nu om jag fortsätter att göra nästa, märker att jag ska vara insidan av denna slinga. Men koden kommer att köra precis som jag förväntar. Så när jag träffade den här funktionen, Vänta för klick, det kommer att göra det som bokstavligen. Så jag verkade ha förlorat kontrollen över programmet. GDB inte ge mig en annan snabbt. Men inte att oroa sig. Gå till mitt spel, klicka någonstans. Och voila, nu fortsätter det till linje 86. Så återigen, det är ovärderligt, i slutändan, för felsökning problem. Eftersom du kan bokstavligen gå igenom din kod, skriva ut saker och mycket, mycket, mer. Men för nu, dessa verktyg enbart borde få dig ganska långt. Så vi är, naturligtvis, ta en titt vid Grafik nu, helt plötsligt. Och nu vår värld blir lite mer intressant. Och ni vet, kanske, från några av de videoklipp på nätet som vi har dessa shorts som du har tittat på som en del av problemsamlingar. Och de har blivit skjuten, medvetet, mot en vit bakgrund. Och några av dem har undervisningen Fellows dra lite text på skärm som är överlagras på sidan av dem. Men naturligtvis är det inte så intressant i den verkliga världen. Detta är bara en föreläsningssal med en stor vit skärm och en bakgrund. Och vår fantastiska produktionsteam sort av gör allting ser vacker i efterhand genom att beskära ut eller överliggande något vi gör eller inte vill. Nu bara för att motivera denna vecka och riktigt, där du kan gå i slutändan, med datavetenskap. Inte bara efter problem som fyra. Men efter en kurs eller en hel läroplanen är det fantastiskt vad man kan göra dessa dagar med avseende på grafik i synnerhet. Några av er kanske har sett detta flyter runt på nätet. Men jag tänkte att jag skulle visa er, för bara ett par minuter, en glimt av vad datateknik och vad CGI, datorgrafik kan göra dessa dagar med en välbekant sång och kanske filmen. [MUSIK - LANA DEL RAY, "Ung och vacker] Högtalare 1: Det är bara en liten bit fantastiskt, kanske, hur allestädes närvarande - [Applåder] Högtalare 1: Jag har precis hämtat den. Men det är verkligen fantastiskt, jag tror, ​​precis hur allestädes närvarande program och kod, och verktyg som detta är riktigt. Så det är en smak av riktningen där du kan gå. Åh, inget mer Appliance idag. Jo, det är faktiskt tragiskt timing givet den punkt jag bara försökt att göra. Okej, så låt oss starta Fusion igen. Påminn mig senare. Okej, och du bör ha fått en e-post som en åt sidan om du fick en märker sånt. Okej, så minns att förra veckan Vi började att dra tillbaka detta senare känd som sträng. string påminner en datatyp som är deklareras i CS50 biblioteket. Och det är en del av stödhjul som nu börjar ta fart. Det var ett användbart begrepp tidigt. Men nu kommer det att bli mer intressant och mer kraftfullt för att faktiskt se att under huven, en sträng är precis vad vi sa? Ja, så det är en så kallad char *. Och * det visar att det finns någon form av adress inblandade. Och så när du säger char * du menar bara en variabel vars datatyp är en pekare nu. Det faktum att det finns en stjärna där betyder bara att du deklarerar en så kallad pekare. Och att pekaren ska tydligen lagra adress, för Naturligtvis, en röding. Nu varför detta vettigt? Tja, vad är en sträng under huven? Tja, för lite tid vi har sagt att en sträng under huven är bara h-e-L-l-o, till exempel. Men vi har pratat om detta som är, i huvudsak, en array. Och en matris skulle då se lite mer om detta, med var och en av dessa tar upp en bit. Och då har vi sagt att det finns något speciellt tillbaka hit, det backslash 0, eller null terminator. Så hela den här tiden, det här har varit en sträng. Men egentligen, är en sträng faktiskt en adress. Och adresser, som vi ska se, är ofta prefixet 0x av konvention. Vad betecknar 0x? Någon som vet? Så det betyder bara hexadecimalt. Så du kanske minns, faktiskt, från Pst 1, jag tror, ​​en av uppvärmning frågor egentligen om hexadecimal form förutom binär och decimal. Och motivationen här är att med hexadecimala du har 16 siffrorna till ditt förfogande. 0, följt 1, 2, 3, 4, 5, 6, 7, 8, 9, av a, b, c, d, e, f. Och om man räknar alla de upp, du får totalt 16. Så detta är i kontrast med decimal, där vi har 10 siffror, 0 till nio. Det är i kontrast med binär där vi har bara 0 och 1. Men i slutet av dagen kan du bara representerar samma nummer, men något annorlunda. Och hexadecimal är vanligt eftersom så det visar sig - och vi kommer att se detta senare i kursen - även när vi får för webbprogrammering i samband med HTML och färgkoder, hexadecimal är trevligt. Eftersom varje siffra, visar sig, representerar fyra bitar perfekt. Så det typ bara för ledningar upp snyggt som vi så småningom se. Så detta kan vara Ox123 eller något sådär, betecknar adress 123 någonstans inne i min datorns minne. Men naturligtvis vissa problem uppstår på grund av denna underliggande genomförande. Och minns att jag tog en stab på genomföra en funktion som denna - jämför dash 0 dot c förra veckan, som trots att det såg ut som om det var rätt, det helt enkelt inte jämföra två strängar korrekt. Jag har kastat bort huvud, och jag har kastat bort kommentarer bara för att fokusera på den kod som är intressant här. Och det är i rött eftersom det är buggig. Av vilken anledning? Tja, på toppen där när jag förklarade en sträng, vad händer egentligen på under huven? Nåväl, låt mig gå över till sålla här och dra det. Så jag förklarade igen, sträng s GetString. Så jag ska gå vidare nu och dra er för vad den verkligen är. Det kommer att bli en kvadrat här. Och jag kommer att hävda att det är 32 bitar. Åtminstone är det oftast, åtminstone på CS50 apparaten i många datorer. Jag ska kalla det är. Men nu minns att vi kallas GetString. Så getString avkastning, naturligtvis en sträng. Om användaren skriver i h-e-l-l-o ange strängen hej blir returneras. Och den strängen, som vi just sagt, slutar upp någonstans i din dators minne ett omvänt snedstreck 0 i slutet. Jag ska göra det som array - eller sammanhängande block av tecken - att det faktiskt är. Och nu, är vad getString faktiskt återvända? Vad har getString varit återvänder all denna tid? Tja, säger vi, i veckor innan, den returnerar en sträng. Men mer tekniskt, vad GetString avkastning tydligen? Publik: En adress. Högtalare 1: En adress. Specifikt den returnerar adressen för den allra första tuggan, vad det än är. Jag håller bara med hjälp av en, två, tre eftersom det är bekvämt. Den returnerar adressen för den första tecken i strängen. Och vi sade förra veckan att som är tillräcklig. Eftersom vi kan alltid räkna ut var slutet av strängen bara genom iteration över det, kanske, med en för slinga eller en while-slinga eller något liknande att bara letar efter "backslash 0", den speciella sentinel karaktär. Och då vet vi att strängen råkar vara av längd - i detta fall - fem. Så tekniskt vad GetString gör är det returnerar Ox123 i detta fall. Och tekniskt vad som sedan händer är att vi lagrar, insidan av s, Ox123. Vid slutet av dagen, även om detta är nytt koncept, pekare, de är bara variabler. Men de råkar lagra bitar som tillsammans representerar en adress. Så tekniskt sett allt de får lagras i s är Ox123. Men vi som människor - inklusive idag onward - är verkligen inte kommer att bry sig, typiskt, vad den faktiska adressen är av viss del av minnet. Det är bara till låg detaljnivå till vara intellektuellt intressant. Så jag kommer att ångra detta. Och i stället, mer hög nivå, bara säga att när vi pratar om pekare Jag ska bara dra mer användarvänlig pilen som förmedlar Samma idé och abstracts bort uppgifter om vad det faktiska underliggande adress är. Om vi ​​nu går tillbaka till koden, vad hände förra veckan om vi har string t lika getString? Tja, om jag igen, typ i hello den här gången kommer jag att få en annan del av minnet. h-e-l-l-o backslash 0. Men eftersom jag ringde getString en andra gång - och jag vet detta från att titta på källkod för GetString - även även om det är en tillfällighet att hej var skrev i två gånger, är GetString inte kommer att försöka optimera och vara smart. Det kommer bara att få en annan bit av minne från datorn, som är kommer att vara på en annan adress. Låt godtyckligt bara säga 456. Och vad kommer det att återvända? Det kommer att gå tillbaka 456 och förvara den i t. Så vad som verkligen händer, om vänster sida är jag har en annan bit minne, 32 bitar typiskt. Och det kommer att gå Ox456. Men återigen, jag är inte intresserad av dessa särskilda siffror längre. Jag kommer bara att abstrakt rita den som en pil. Så detta är nu en ny förklaring. Men det är exakt samma idé som är pågått hela tiden. Och så anledning då, att denna första version av Compare var buggy förra veckan är varför? När du gör om s är lika med lika t Vad är du verkligen under huven jämföra? Du jämför adresserna. Och bara intuitivt, tydligt, Ox123 kommer inte till lika Ox456. Dessa siffror, dessa bitar är bara annorlunda. Och så konsekvent, förra veckan sa du skriver olika saker, även om ord var ordagrant samma. Så vi fixa detta. I lekmannaspråk, vad var fix? Publik: Använd en funktion. Högtalare 1: Använd en funktion. Eller stjärnor är definitivt inblandade, men använder en funktion för att göra vad? Publik: Att jämföra strängar. Högtalare 1: Att jämföra strängar. Så det grundläggande problemet här var att jag var just med tanke på kvaliteten på strängar som skall fastställas av jämförelse av deras adresser. Och självklart det är bara dum nu en gång du förstår vad som händer under huven. För att verkligen jämföra strängar för att se om de är lika på det sätt som en människa skulle överväga två strängar är lika vi behöver jämföra dem karaktär för tecken för tecken. Nu kunde jag ha gjort detta mycket tediously. Men familjärt, vi med hjälp av en for-loop. Och bara jämföra s konsol Jag mot t fäste i.. s fäste i plus 1 mot t fäste I plus ett, och så vidare, inuti något slags slinga. Och om jag upptäcker några två tecken som skiljer sig, eller om jag inser att ooh, är s kortare än t eller längre än t Jag kan direkt säga falsk, de är inte samma sak. Men om jag får igenom s och t och säga samma, samma, samma, samma, samma, i slutet av båda strängar, kan jag säga sant, de är lika. Tja, tack och lov, år sedan någon skrev att koden för oss. Och de kallade det StrComp för sträng jämföra. Och även om det är en liten räknare intuitivt, returnerar StrComp 0 om de två strängar, s och t är desamma. Men den returnerar negativt värde om s bör komma före t bokstavsordning positivt värde om det skulle komma efter t alfabetiskt. Så om du någonsin vill sortera något, det visar sig att StrComp är användbar. Eftersom den inte bara säga ja eller nej, lika eller inte. Det ger dig en känsla av att beställa gillar en ordbok makt. Så StrComp, lika s kommatecken t är lika med 0 innebär att strängar är verkligen lika. Eftersom den som skrev denna funktion år sedan antagligen använt en for-loop eller en while-slinga eller något liknande att integrera över karaktärerna igen och igen och igen. Men problemet två uppstod här. Detta var copy0.c. Och de två i rött är eftersom det är bristfällig. Och vad gjorde vi här? Tja, först jag ringde getString. Och jag lagrat returvärdet i ar. Så det är ganska mycket samma som denna övre delen av bilden. Men vad kommer efter det? Nåväl, låt mig gå vidare och bli av en hel massa av detta. Vi ska spola tillbaka i tiden till när vi bara har s, vilket är konsekvent med line en uppe. Jag kollar. Om s är lika med är lika med 0. Nu, en snabb liten not, när kanske GetString returnera 0? Det finns inte tillräckligt med minne. Rätt? Det är sällsynt att detta kommer att hända, förvisso på en dator som är fick hundratals meg eller även gig RAM. Men det kan, i teorin, tillbaka 0, i synnerhet om användaren inte samarbetar. Det finns olika sätt att låtsas som att du inte har inmatade någonting och trick GetString till att återvända 0 effektivt. Så det kommer att kontrollera detta. För om någon av er har börjat få, redan, segmentering fel - som förmodligen har varit en källa av viss frustration - de är nästan alltid resultatet minne-relaterat fel. På något sätt du trasslat med avseende på en pekare, även om du inte inser det fanns en pekare. Så du kanske har inducerat segmentering fel så tidigt som vecka en med något som en for-loop eller en stund slinga och en array genom att gå för långt förbi gränserna för någon array som du förklarade, i vecka två i synnerhet. Du kanske har gjort det även i problem ställa fyra med Breakout. Även om du förmodligen inte har sett några stjärnor i distributionen koden för Breakout, visar det sig att de GRect och GOval och andra sådana saker, de är faktiskt pekare under huven. Men Stanford, liksom vi, typ av hudar att specificera åtminstone för biblioteken ändamål, ungefär som vi gör för sträng och röding *. Men GRect och GOval och alla de saker ni är eller kommer att använda denna vecka är ytterst minnesadresser. Du vet bara inte det. Så det är inte förvånande då, kanske, att du kanske snubbla över några segmentering fel. Men vad som är intressant här nu, om när vi kontrollerar för 0 vi gör string t blir s. Nåväl, låt mig förklara t. Jag kommer att göra det som en kvadrat, 32 bitar, kalla det t. Och sen ska jag göra blir s. Tja, vad betyder det? Tja, det är lite svårt att tänka om det föreställa klokt. Men låt oss tänka på vad som finns inuti x? Vad är bokstavligen inuti denna variabel? Värdet Ox123. Så när jag säger string t blir s, som bara betyder ordagrant ta nummer i s, vilket är Ox123 och lägga den Ox123. Eller bildmässigt, om jag slags abstrakt bort från denna detalj den har effekt bokstavligen göra detta också. Så nu tänker tillbaka på förra veckan när Vi fortsatte till kapitalistiska T. I gjorde T bracket 0. Tja, T bracket 0, även om det är en pekare, kan du behandla det som om det är en array, med en kvadratisk hakparenteser. Så där är T bracket 0? Tja, det är det h.. Och så när vi använder denna kodrad, två övre, som är i att C type.h headerfil, det är där det är deklarerade. Du kapitalisera denna H. Men Naturligtvis, det är exakt samma h som är insidan av s, så att säga. Och så nu har ändrats eller aktiveras både den ursprungliga och den så kallade kopia. Eftersom du inte göra en kopia i sätt att en människa vill att det ska vara. Så vad var det fix här, i copy1.c förra veckan? Funktioner, så vi kunde faktiskt kopiera strängen. Och i grunden, vad vi behöver göra för att kopiera strängen? Nåväl, i denna gröna versionen här är jag kommer att göra det ganska låg nivå. Det finns faktiskt fungerar de kunde hjälpa till med detta. Men den mest grundläggande en, och den mest välbekant, åtminstone, kommer snart att vara bekant för oss, är följande - så en på den första raden av koden i grönt nu. Jag skrev precis s som char *. Det finns ingen fungerande skillnad där. Jag kastade bara bort CS50 biblioteket och Jag kallar det vad det är, en char *. Nu dot, dot, dot, eftersom det fanns någon felkontroll som inte intressant att prata om igen. Så nu t deklareras. Det är också en char *. Så jag ritade en liten fyrkant på skärmen som förut. Men på den högra sidan, malloc, vi sagt är minnet fördela. Så anslå cirka bit av minnet. Och hur många byte gör vi faktiskt vill fördela, det verkar? Tja, strängen längd s. Så om det är hej det är kommer att bli fem. Vi kommer att säga h-e-l-l-o. Så fem bytes. Men sedan plus 1, varför ett? Den 0 tecken. Om vi ​​inte lämnar utrymme för den här killen vi kan av misstag skapa en situation där strängen är h-e-l-l-o. Och sedan nästa gång GetString är ringde och jag skriver in, till exempel, David, D-a-v-i-d, den datorn kommer att tro att s är faktiskt h-e-l-l-o-d-a-v-i-d eftersom det finns Ingen paus mellan dessa ord. Så vi behöver denna paus. Så vill vi inte fem. Vi vill ha sex byte. Och byte jag säga. Men det är verkligen dags storlek röding. Tekniskt röding är nästan alltid en enda byte. Men bara för att göra vår kod bärbar, så att säga, så att det fungerar på olika datorer även om de kanske vara något annorlunda under huva, jag ska generiskt säga storleken på röding, så att min kod fungerar alltid. Och jag behöver inte kompilera det bara eftersom jag uppgradera min dator eller använda någon annan plattform. Så jag har 6 gånger större en röding, som råkar vara 1. Så det innebär malloc kunde ge mig sex byte. Vad är det egentligen gör? Nåväl, låt mig rulla tillbaka i tiden här dit vi är i berättelsen. Så om jag går tillbaka hit, har jag förklarat en char * heter t. Jag har nu heter malloc för sex byte. Och nu ska jag dra dessa sex bytes precis som arrayen tidigare. Men jag vet faktiskt inte vad som är inuti denna array. Om du tilldelar minne det visar sig att Du kan inte lita på att det finns någon kända värdet där. Det kunde ha använts av något annat, någon annan funktion, någon annan kodrad som du skrev. Så vi ska generellt kalla dessa sopor värden och rita dem, kanske, som frågetecken, bara visar att vi vet inte vad som faktiskt finns. Och det är ingen big deal så länge vi är smart nog att skriva över dem sopor värden med siffror eller tecken som vi bryr oss om. Så i det här fallet vad ska jag göra? Tja, min kodrad nästa, har jag fyra. int jag får 0, blir n sträng längd s. Så en bekant för slinga. I är mindre än eller lika med n, som vanligtvis är över. Men den här gången är det avsiktligt. Jag + +, och då gör jag helt enkelt t fäste jag blir s. Eftersom min bild ser ut så här på detta ögonblick, som lagras i t är adress för att slumpmässiga bit av minne vars värden är okända. Men så fort jag gör t fäste 0 som sätter mig här. Och vad slutar upp att få dras dit? Vi hamnar att lägga tim. För det är vad som står på s konsol 0. Och sedan samma sak för e, och L, och L och o. n, varför jag går upp genom en lika med n? På grund av den 0 karaktär. Så bara för att vara tydlig, då, om jag faktiskt radera oavsett dessa sopor värden och sedan faktiskt dra in vad jag förväntar, är detta s bracket 1, 2, 3, 4, plus det är släpande ny karaktär. Och så nu, om vi fortsatte förbi punkten, prick, prick i denna rätt version och aktiverade T konsol 0 Jag skulle, om naturligtvis utnyttja just detta kille här, som begreppsmässigt, var slutligen målet. Så det är allt pekaren är. Och du har använt dem i flera veckor nu i samband med strängar. Men under huven de är lite mer komplex. Men om man tänker på dem i denna illustrerad formen föreslår jag att de är förmodligen inte så skrämmande som de kan först tyckas vid första anblicken, särskilt med en sådan ny syntax. Eventuella frågor om pekare, strängar, eller tecken? Yeah? Publik: Kan du gå tillbaka till [OHÖRBAR]? SPEAKER 1: Visst. Publik: Så hur kommer i allra sista linje, har du inte en * t linje och en * s på linjen? Har du inte hänvisningen till - Högtalare 1: Ah, en riktigt bra fråga. Varför inte jag har en * t och en * s? Eftersom kortfattat, förra veckan, som i vårt swap-funktion, sa jag att när du har en pekare till medel som du går det som vi gjorde fysiskt på scenen, var faktiskt använda stjärnan operatören. Det visar sig att detta torg-fäste notation är vad vi kallar syntaktiska socker, vilket är bara en sexig sätt säger att det är förkortning notation för exakt vad du beskriver. Men det är lite mer intuitiv. Och med risk för att detta verkar mer komplicerat än det behöver vara, vad som verkligen händer här är följande - Om jag säger * t som innebär att gå till adressen lagrad i t. Så bokstavligt, om t lagrar adressen till att H initialt, * t medel gå hit. Nu, vad gör t bracket 0 betyder? Exakt samma sak. Det är bara lite mer användarvänlig vänligt att skriva. Men jag är inte klar ännu. Jag kan inte bara säga * t får * s. För vad skulle jag göra då? Jag skulle kunna sätta h, h, h, h, h hela saken. Rätt? Eftersom * t är att gå till den adressen it. Men vi är inne i en loop. Och vilket värde jag uppräkning, naturligtvis på varje iteration? i.. Men det finns en möjlighet här, eller hur? Även om detta känns som det blir lite mer sofistikerad än torget-fästet notation vi har använt under en längre tid - låt mig ångra min h förändring där - även om detta nu bli lite finare, den grundläggande idén, om * t betyder här och * t är bara gå till adressen it. Men vad var adressen i t? Numret vi fortsätta använda? Gilla Ox456, låt oss få det tillbaka bara för diskussionens skull. Tja, om jag vill komma åt e i t sträng, vill jag bara gå till, huvudsak 456. Eller snarare, 457. Jag behöver bara lägga till en. Men jag kan göra det, eller hur? Eftersom t, även om jag håller ritning det nu som en pil, det är bara en nummer, Ox456. Och om jag lägger till något till det, eller mer allmänhet, om jag lägger jag till att jag kan faktiskt få precis där jag vill. Så om jag faktiskt gör det här - och detta är vad som nu kallas pekararitmetik - Jag kan ta bort den här raden. Vilket är, uppriktigt sagt, tror jag klarare och lite mer användarvänlig att läsa. Men detta är inte mindre korrekt. Denna kodrad nu använder pekararitmetik. Det säger gå till efter adress - oavsett starten av t är, som är t plus att jag, som inledningsvis är 0, vilket är bra. Eftersom det innebär början på t plus 1, plus två, plus tre, och så vidare. Och samma deal med er. Så syntaktiska socker för detta. Men förstå vad som verkligen händer under huven, vill jag hävda, är faktiskt användbart i och av sig själv. Eftersom det innebär att nu finns det inte mycket mer magiskt på gång under huven. Det kommer inte att bli många fler lager som vi kan skära ner för dig. Det är c. Och detta är programmering. Riktigt bra fråga. Okej, så detta var att buggy Programmet jag syftade på tidigare. swap var bristfällig. Om verkade fungera. Minns att precis som med mjölk och apelsinjuice - som jag började dricka dagens demonstration. Så precis som med apelsinjuice och mjölken, vi måste använda ett temporär variabel, TMP, att hålla en tillfälligt så att vi kunde då ändra dess värde och sedan uppdatera b.. Men denna funktion, sade vi, eller detta program där denna funktion var skrivet var fel och brister, varför? Ja? Publik: [OHÖRBAR]. Högtalare 1: Exakt, när du pendling - eller mer allmänt, när man ringa flesta någon funktion - om argumenten för denna funktion är primitiva, så att säga, ints och chars och dubblar och flottar, saker utan stjärnor, du passerar i en kopia av argumentet. Så om x var 1 och y var 2, är en pågående att vara 1 och B kommer att vara 2. Men de kommer att vara olika bitar av bitar, olika bitar av minne som råkar vara lagra identiska värden. Så här koden är super perfekt på att byta a och b. Det är inte bra på att byta - i förra veckans exempel - x och y. Eftersom igen, de är i fel räckvidd. Nu, hur vi ska bestämma detta? Vi var tvungna att göra funktionen ser lite fulare. Men återigen, överväga vad Det betyder bara. Och faktiskt, låt mig, för konsekvensens skull, ändra en sak så det är identiskt med vad vi just gjorde. Som jag nämnde förra veckan, det gör det inte oavsett var den går. I själva verket, typiskt du skulle sätta stjärnan bredvid variabelnamnet. Men jag tror att det skulle vara lite lättare att överväga * bredvid datatyp som innebär att det är en pekare till en int i det här fallet. Så vad gör jag här? Jag säger inte ger mig en int följt av ytterligare int, kalla dem a och b. Ge mig adressen till en int. Ge mig adressen till en annan int. Ring dessa adresser a och b. Och sedan använda * notation ner nedan, gå till vart och ett av dessa adresser efter behov för att antingen få eller ställa in dess värde. Men det finns ett undantag här. Varför har jag inte en * bredvid tmp? Varför gör jag inte det här, till exempel? Det känns som jag ska bara gå all ut och korrigera det hela. Yeah? Publik: [OHÖRBAR]. Högtalare 1: Jag har inte deklarerats tmp som en sträng. Så detta skulle förklara, i detta fall, en tmp vara adressen till en int. Men det är inte riktigt vad jag vill, för ett par anledningar. Målgrupp: Du vill inte byta dem. Högtalare 1: Exakt, jag vill inte byta något med tmp. TMP är bara vecka-en grejer. Allt jag vill ha är en variabel att lagra vissa nummer. Jag bryr mig inte ens om adresser i detta ögonblick. Jag behöver bara 32 bitar så att lagra en int. Och jag vill sätta in dessa 32 bitar vad är inte i ett, så att säga, men vad som står på en, bara för att vara mer exakt. För om en är en adress, * a innebär gå dit och få värdet 1. Till exempel, i förra veckans exempel eller i B: s fall får värdet 2. Så vad som verkligen händer? Låt mig dra en bild här som kommer bara retas isär en del av idag. Men detta kommer att fortsätta att synas under ganska lång tid. Detta, hävdar jag, är vad din dators minne ser ut när du kör en program, alla program. När du kör ett program i den absoluta toppen av datorns RAM-minne - så tänk på denna rektangel, verkligen, som din datorns RAM eller minne, alla 101 miljard byte av det, alla två miljardfolk byte, alla två gigabyte det, oavsett den mängd du har är, låt oss göra det som en rektangel. Och jag hävdar att när du kör ett program som Microsoft Word eller Chrome eller nåt sånt, de bitar som Microsoft eller att Google skrev - i fallen med dessa program - laddas i datorns minne där de kan genomföras mer snabbt och matas in i CPU, som är hjärnan i datorn. Och i TAM de är lagrade på mycket toppen av ditt program, så att säga. Med andra ord, om detta är en bit av minne, när du dubbelklicka på Microsoft Word, bitarna kommer bort hårddisken. De få laddas in i RAM-minnet. Och vi kommer att stoppa upp dem i toppen av denna rektangel konceptuellt. Tja, är resten av ditt minne användas för olika saker. Längst upp ser du initiera uppgifter och avinitiera data. Detta har att göra, för det mesta, med konstanter eller globala variabler som har värden. Men mer om dem en annan gång. Då har du högen, vilket Vi ska återkomma till. Men i botten är den del som är särskilt relevant just nu. Det är den så kallade stack. Så precis som i de flesta någon D Hall här på campus, har du dessa brickor som bara stapla ovanpå varandra på vilka du kan få mat och allt. Stapeln i ett datorsystem är mycket lika. Utom medan facket, som vi använder i matsalen, naturligtvis, menas att bära saker facken eller ramarna - som vi kallar dem - i en dators minne används för att hålla variabler och värden. Så vad går egentligen på under huven? Nåväl, låt mig vända över till skärmen här. Och låt oss bara fokusera på nedre del för en stund. Om detta är den nedre delen av min datorns minne visar det sig när jag anropa funktionen main - vilket händer, ärligt talat, automatiskt för mig - Jag får en bit av minnet på djupet av mitt RAM så att säga. Och det är där huvud är lokala variabler går. Det är där argc och argv kanske gå, och alla variabler I deklarera inuti main. De hamnar i botten av datorns RAM. Antag nu att huvudsakliga Anropar en funktion som swap, som det gjorde förra veckan? Nåväl, satte vi i huvudsak ett nytt magasin, en ny ram, på min bit av minnet. Och jag kommer att beskriva detta som hör till swap-funktionen. Vad är nu inne i swap? Tja, baserat på förra veckans program och den vi såg bara ett utdrag från, insidan av swap s ram, eller på swapens fack, vad variabler? Tja, a och b. Eftersom de var dess lokala argument, plus en tredje, tmp. Så egentligen, kunde jag dra denna lite mer rent. Låt mig gå vidare och ångra etiketten. Och låt mig påstå att du vet vad? en är förmodligen kommer att hamna här. B kommer att hamna här. Och TMP kommer att hamna här. Nu, den beställning kanske vara lite annorlunda. Men begreppsmässigt detta är tanken. Och precis kollektivt, är detta vad vi kallar swapens ram, eller matsalen facket. Och samma deal med huvud. Men jag kommer inte att rita det. Men det är där argc och argv och eventuella dess lokala variabler som x och y kan vara så bra. Så nu överväga vad som verkligen händer när du ringer swap. När du ringer swap, köra kod som detta, du går in, i buggy version, a och b som kopior av x och y. Så om jag drar nu detta på skärmen - fick bli bättre på detta - så historien jag berättade för mig själv var i denna barnvagn versionen, när vi pendling passerar bokstavligen a och b som heltal, vad händer egentligen? Tja, vad som verkligen händer är här. Låt mig gå vidare och ångra bara att rensa upp lite utrymme här. Så det här är min dators minne. Så om jag har, till exempel - faktiskt Låt oss göra det här sättet - om jag hävdar att det är x, lagring värdet 1 precis som förra veckan. Och detta är y, lagra värdet 2 gillar bara förra veckan. Och detta är viktigaste, när jag pendling, därigenom ge mig tillgång till en och b och TMP, kommer jag att hävda att detta är en och detta är ett. Detta är b.. Detta är 2. Detta kallas TMP. Och inledningsvis, har det vissa skräp värde tills jag förvara faktiskt i det, vilket är ett. Då ska jag gå vidare och ändra en vara vad? B: s värde. Och så nu har jag två här. Och då sa vi b får tmp. Återigen, precis som en sundhetskontroll, den tredje kodrad här är helt enkelt detta en, blir b tmp. Och så slutligen, vad gör jag? Jag går vidare och ändra b för att vara vad värdet av tmp är, vilket är 1. Jag rör inte tmp igen. Men nu är problemet så snart som swap avkastning, eftersom det inte är handing backa något värde, det finns ingen återvändo uttalande explicit i det. Vad händer egentligen? Tja, i huvudsak allt detta minne - OK, uppenbarligen suddgummi gillar bara ett finger i taget - bara försvinner. Nu i verkligheten är det inte kommer någonstans. Men du kan tänka på det nu som frågetecken. Eftersom det inte längre faktiskt används. Och ingenting görs med dessa värden. Så i fallet med den gröna versionen av denna kod, är det istället vara övergått i swap? Så behandlar. Så adress av x och adressen till y. Så om vi åter berätta historien en sista tid, och jag drar faktiskt swap igen, men med pekare, vilket det, detta vara b, och detta är tmp, vilken är faktiskt lagras i en i denna gröna version av min kod där jag passerar i adresser? Det kommer att vara en pekare till x. Så jag kunde rita en pil. Men låt oss använda samma godtyckliga exempel som tidigare. Låt oss säga att det är något liknande Ox123. Och detta kommer att bli Ox127 eftersom det är fyra bytes bort eftersom det är en int, så Ox127. Och återigen, jag tar några friheter med siffrorna. De är mycket mindre än de skulle faktiskt vara och i en annan ordning. Men det är hur bilden är nu annorlunda. Men när jag använder denna gröna koden och jag får int tmp * a. * Ett medel för att göra följande, ta behandla som finns i en och gå till det, vilket är ett. Och det är vad jag sedan lägga i tmp. Under tiden i nästa kodrad här, * a blir b, vad betyder det? Tja, * a, så gå här blir * b, vilket innebär att åka dit. Och det innebär att sätta värdet till det. Slutligen, den sista raden i koden sade bara * b får tmp. Så B säger gå dit och skriva över den med tmp som, i det här fallet, kommer att vara, igen, en. Och det är därför den gröna versionen av vår kod fungerar, medan den röda version gjorde aldrig. Det hela handlar bara ner till hur minne hanteras och där det är faktiskt placerats i din datorns RAM-minne. Och för nu, det är en av de saker att stapeln används för. Frågor på layouten? På pekare? Eller om swap? Okej, så malloc, återkallelse, gjorde något liknande. Detta var en super enkelt exempel. Och det var det som Binky introducerade oss till, om än ganska snabbt, vid slutet av klassen. Helvete, där vi gå igen. Så minns att detta var det exempel som Binky introducerade oss till, om än något snabbt i slutet av klassen. Och här har vi använt malloc verkligen för andra gången. Eftersom den första gången vi använde det för att skapa tillräckligt med RAM, allokera tillräckligt med RAM att lagra en sträng. Denna gång hålls Binky det enkelt. Så det är att lagra bara en int, tydligen. Och det är helt bra. Det är lite konstigt, ärligt talat, att använda malloc att allokera en int. Men poängen med Nicks claymation var egentligen bara berätta historien om vad händer eller inte händer när du misshandla minne. Så i detta fall, det här programmet gjorde ett par saker. I det första fallet här, förklarar det en pekare som heter x till en int. Det förklarar sedan en pekare kallas y till en int. Den lagrar sedan i x, vad? Någon annan nu. Vad får lagras i x enligt den tredje raden i det här programmet? Publik: [OHÖRBAR]. Högtalare 1: Tja, inte riktigt bytes, per säga. Vara mer exakt nu. Vad får lagras i x? En adress, jag tror jag hörde det. Så vad betyder återvänder malloc? malloc beteendemässigt allokerar en bit av minnet. Men hur ger det dig tillgång till det? Den returnerar vad? Adressen för den första byten i bit av minnet. Nu är det super enkelt. Det är bara ett byte, vilket innebär att itu vi får tillbaka är adress på det hela. Så lagras i x då är adressen av denna bit av minnet. Under tiden, vad händer nu? Så egentligen, låt oss gå vidare och dra ut det riktigt snabbt. Så om vi går över till skärmen här och vi spelar här ut int * x och int * y kommer att göra det för mig? Jag hävdar att det bara kommer att göra något som detta och kalla det x, och detta och kallar det y. Under tiden är den tredje kodrad kommer att fördela storleken på en int, som råkar vara - ledsen om jag sa en innan jag menade en int - fyra byte på en vanlig dator. Åtminstone med CS50 apparaten. Så detta kommer att fördela det, vem vet? Någonstans här ute. Och detta lagras vid vissa adress Ox, vem vet? Men vad som kommer att få tillbaka är den adressen. Men vi ska dra denna bildmässigt som bara en pil som. Nu i nästa rad * x blir 42. Vad betyder * x innebär i lekmannaspråk? Bara åka dit. Gå till denna adress. Eller med andra ord, följ pil och satte 42 där. Men sedan hände något dåligt till Binky, rätt? Minns att linjen fem här, blir * y 13, ja ett otursnummer, gjorde vad för oss? Tja, * y medel gå dit. Tja, har detta inte fått ett värde ändå, eller hur? Koden har inte y är initieras till någonting. Vi hade x initieras till en adress. Men y förklarades uppe. Men sedan ett semikolon, inget värde var faktiskt sätta i det. Så det är rättvist att kalla detta ett skräp värde. Vem vet vad som finns där? Det är resterna av bitarna som använts av några tidigare kodrad i mitt program. Så om jag säger gå dit, detta är som, Jag har ingen aning om var den här pilen är kommer att hamna. Och det är då du vanligtvis få en segmentering fel. Om du av misstag dereferens, så att tala, eller gå till en adress som inte är faktiskt en behörig adress, dåliga saker hända. Och det är precis vad som hände att tänka Binky. Så minns att berättelsen att Nick var berättar här var samma idé som vad Jag har ritat med illusionen av krita på tavlan där. X och y är deklarerade. Då vi anslog storlek en int och lagras den i x. Sedan nästa rad vi gjorde * x. Detta var Nicks trollspö av dereferencing. Det satte 42 i minnet påpekats av x. Men det är där saker och ting gick fruktansvärt fel. Rätt? Vi försökte dereference y. Men y hade några falska värde, rätt? Att pilen i nedre vänstra hörn, är inte faktiskt pekar på någonting. Det är typ att göra vad jag gjorde här på tavlan. Så dåliga saker hända, segmentering fel, eller Binky fel, i det här fallet. Men om vi fixar så att genom att göra x får y hur ser historien förändras? Tja, om jag gör x blir y, det är effektivt detsamma som att säga vad det är, Ox-något kommer att vara det samma här, Ox-någonting. Eller bildmässigt vi ska rita en pil. Så här på brädan med Binky, med nästa rad av kod, betyder * y åka dit. Var finns det? Det betyder över här. Och när vi uppdaterar att vara 13 det handlar bara gå och skriver 13 här nu. Så kanske inte helt enkelt vid första anblicken. Men för att sammanfatta och att använda samma jargong som Binky använde här, så de två första fördela pekare, x och y, men inte de pointees. Och pointees är inte en allmänt använd term. Men pekare är absolut. Men det är vad som pekade på i Binky s nomenklatur. Denna nästa rad, naturligtvis, allokerar en int pointee. Så en bit av minnet - så jag drog över på den högra sidan där - och set x är lika med att peka på den. Detta dereferences x för att lagra 42 i minnet att den pekar på. Och sedan detta, naturligtvis, var en dålig sak. Eftersom y inte pekade på något ännu. Detta fixar det. Så detta är fortfarande buggig program. Bara för att vi blåser genom koden rad för rad och säga, jaha, låt det krascha det. Det är en dålig sak. Oddsen är att programmet bara kommer att avbryta helt och hållet på den linjen. Men om du skulle ta bort kraschade linje och ersätta den med de två sista linjer där du tilldelar - använda pekare uppdrag - y att peka på x som punkt t. Och då du avreferera y på ett mycket säkert sätt. Så var lämnar det oss? Tja, visar sig att under huven i CS50 biblioteket, pekare är används genomgående. Och vi ska faktiskt börja skal tillbaka det lagret innan länge. Men det visar också ett uttryck som några av er kanske känner till, särskilt de mer bekväm, är faktiskt som en mycket populär webbplats, eller stack overflow, dessa dagar. Men detta har faktiskt mycket teknisk mening. Vi vet nu vad en stapel är. Det är som en stapel av brickor inne i en matsal. Eller insidan av datorns minne Dess dessa ramar som används av funktioner. Jo, visar det sig att på grund av att mycket enkel implementering av minne och ramarna på den så kallade stack, kan du faktiskt ta kontroll av ett datorsystem ganska lätt. Du kan hacka in i ett system om människor som vi inte har skrivit vår kod särskilt väl. Om folk gillar oss använder bitar av minne eller använda matriser - ännu oftare - men ibland glömmer att kontrollera gränserna för vår array som du kanske har själv ibland, och itererad alldeles för långt förbi slutet en array. I bästa fall, ditt program kanske bara krascha. Segmentering fel, typ för pinsamt. Inte bra, men det är inte nödvändigtvis en enormt dålig sak. Men om ditt program är faktiskt på riktigt användarnas datorer, om det är igång På en webbplats som verkliga slumpmässiga människor på internet slår, uthyrning människor inducerar dåliga saker om din kod är allmänhet inte bra eftersom det innebär en möjlighet att ta kontroll över datorn. Och detta kommer att se ut lite kryptiskt. Men jag trodde att jag skulle skrämma er med detta sista exemplet här. Här är ett exempel på kod. Och det finns en bra Wikipedia artikel som går igenom detta mer i detalj. Jag har huvud på botten ringer foo, passerar i argv av 1. Och det är bara så att du kan köra programmet och skicka en godtycklig inmatning. Och sedan foo förklaras uppe som att acceptera en sträng, eller mer exakt, en char *. Den förklarar därefter en rad tecken. Kalla det en buffert, mer allmänt, av storlek 12. Så 12 tecken får plats inuti av denna grupp som kallas c. Och då använder denna nya funktion, som är nytt, men inte svårt att förstå, minneskopia. Den kopierar minnet från baren, vilket var variabeln förflutna n, oavsett användaren har skrivit in argv 1 i c. Hur många byte? Strängen längd bar. Så med andra ord, om användaren skriver in h-e-l-l-o enter, stränglängden av hej är fem. Så fem av dessa bytes kommer att få kopieras in i arrayen kallas C, vilket är av storlek 12. Men vad användaren skriver in en mycket längre ord som är 13 tecken eller 14 tecken eller 100 tecken eller mer? Där kommer de att gå? Nåväl, denna ram, som fack i matsalen stack, de kommer att åka dit. Och det är bara att börja skriva andra saker som redan på den stacken, överfyllda stapeln, så att säga. Så bildmässigt, tänk på det här sättet. Detta är bara en färgstark version av den bild vi har dragit. Längst ner, låt oss säga, är främsta. Och på toppen, vad du ser nu är ramen, färgkodade nu, för en Funktionen heter foo. Men vad som är intressant här om foo är att här är dess ram. Så det har dragit precis som jag gjorde men i ljusblått. Och nu det är här c konsol 0 går. Och det är där c fäste 11 kommer att hamna. Med andra ord, det händer att representeras som en kvadrat. Men om du håller bara plopping bytes ned - eller tecken - de kommer att sluta upp vid positionen 0 hela vägen upp till 11 eftersom det är 0 indexerade. Men där är det 13: e tecknet kommer att hamna? Var är den 14: e? Var är den 50: e tecknet kommer att hamna? Det kommer att fortsätta nedåt. För även om vi har dragit bild med stapeln växer upp, de adresser, visar det sig, att gå från små adresser, liten pekare, till stora adresser. Så det håller bara gå upp och upp. Så om användaren skriver in hej, det är bra. Ingen bugg, inga problem, allas säker. Men om användaren skriver in vad vi ska ringa kontradiktoriskt kod, representerade allmänt som en, attack, attack, attack, attack, vad kan hända? Tja, om all input som användaren skrev i är inte bara några vänliga eller kränkande teckensträng. Det är faktiskt en sekvens av tecken att om du sammanställt det, det är faktiskt kod. Kanske är det kod som raderar alla filer på din hårddisk eller skickar skräppost eller nåt sånt. Lägg märke till att det som är nyckeln här är att Om den dåliga killen fick turen att skriva över den röda bit av minnet - som jag inte rita på min bild, men denna Wikipedia bild här har - sin så kallade returadress. När mat återvänder, när swap returer, Hur vet datorn att gå från upp här nere? Eller i Tech segmentet upp ovan, hur vet den att gå från swap kod - 0 s och 1 s att komponera swap - tillbaka till main? Det finns en så kallad returadress lagras i samma stackram, på samma cafeterian facket. Så om skurken är tillräckligt smart för att sätta attack-kod, attack-kod, attack koden, och få turen - ofta genom försök och misstag - till skriva att röda returadress, med adress och meddelande den absoluta toppen. Lägg märke 0835C080. Den är skriven baklänges uppe för skäl kommer vi kanske återkomma. Detta är det numret. Så om den onde blir turen eller är smart nog att skriva över den röda remsor av minne med adressen till kod som han eller hon har något injiceras i datorn, gissa vars koden kommer att återlämnas till så snart som foo görs verkställande? Den onde kod. Så här attack-kod, AAA, igen, kanske skicka spam, kanske ta bort alla filer på din hårddisk. Men det är vad som verkligen en stackspill är, eller en buffert genom eller en buffertspill attack. Och det är otroligt, otroligt vanligt till denna dag med program skrivna i C, C + +, och även vissa andra språk. På det skrämmande anmärkning, vi slutar med ett skämt. [SKRATT] Vi ses på onsdag. Vid nästa CS50 - Så jag är alla ut av disk lampor idag men vänta, fettfri mjölk, hälften telefonen bok, apelsinjuice att jag drack idag. USB-kabel, en skiftnyckel. [Musik Spela]