[Granskning: Quiz 1] [Ali Nahm, Oreoluwa Barbarinsa, Lucas Freitas, Rob Bowden] [Harvard University] [Det här är CS50.] [CS50.TV] [Lucas Freitas] Välkommen alla. Detta är översyn för frågesport 1. Precis som en ansvarsfriskrivning, detta är - jag menar, vi kommer att försöka täcka så mycket material som möjligt, men det betyder inte att vi kommer att täcka alla de saker som kan vara i frågesport 1. Så se till att du även ta en titt på föreläsning, sektioner, allt du kan. Quiz 1 kommer att vara på onsdag, nästa onsdag. Så se till att studera. Det kommer att bli, ganska mycket, som den första quiz om dess format, men det är förmodligen kommer att bli mycket svårare. Åtminstone, förra året när jag tog 50, jag tyckte det var mycket svårare. Så studera en hel del. Jag kommer att täcka datastrukturer och Huffman kodning. Detta är något som många människor tycker är komplext, men jag ska försöka göra det så enkelt som möjligt. Först och främst, vad vi vill att ni ska veta att quiz 1 är att förstå de begreppsliga beskrivningar av var och en av de datastrukturer som jag kommer att presentera. Det innebär att du inte behöver faktiskt implementera en hashtabell i din quiz 1. Vi vill inte att du ska genomföra en hel hashtabell, kanske vi ska försöka att få dig att implementera vissa funktioner, de vanligaste operationer, men vi kommer inte att göra dig implementera allt. Så det är viktigt att du förstår konceptet bakom varje datastruktur och även att du har möjlighet att koda i C, bara de vanligaste operationer som de har för varje datastruktur. Och även kunna granska pekare och structs, eftersom de verkar mycket i dessa datastrukturer. Först länkade listor. Länkade listor är faktiskt mycket lik matriser, men skillnaden mellan en länkad lista och en matris, Först av allt, är att en länkad lista har en mycket flexibel storlek, medan i matriser måste du antingen välja en mycket stor storlek för matrisen, så vet du att du kommer att kunna lagra alla dina data i matrisen, eller du måste använda malloc att ha en flexibel längd på array. I länkade listor är det väldigt lätt att bara få fler element, sätta fler element i den länkade listan eller ta bort element. Och faktiskt, om du inte vill att den länkade listan som ska sorteras, Du kan söka efter och ta bort element i konstant tid, så O (1) tid, så det är mycket praktiskt. Du måste bara vara noga med att alltid komma ihåg att malloc och free noderna, bara för att om du inte gör det, har du minnesläckor. Så länkade listor - definitionen av en nod är precis vad vi har där. Jag lägger int n, men du kan lagra alla data som du vill. Så om du vill lagra en sträng, det är bra. Om du vill spara en struct, det är bra, en dubbel, vad du vill. Jag bara sätta int n för exemplen här. Och du har en pekare till nästa nod. Så i princip, har en länkad lista en del data, och sedan pekar till nästa nod. Om det är det sista elementet i den länkade listan, det kommer att peka på NULL. Så detta är ett exempel på en länkad lista. Okej, så nu ska vi se vad vi ska göra om jag vill sätta in ett element i en länkad lista. Först kommer en funktion insatsen vara av typen void eftersom jag inte vill återvända någonting. Och jag ska ta en int som argument, för jag vill veta vad jag vill infoga. Så vad är det första jag ska göra? Tja, ska jag malloc på newnode, så det är den första raden. Jag bara skapa en ny nod för att sätta i en länkad lista. Så vad kan jag göra? Tja, vi vet att i våra implementeringar av länkade listor i klassen, alltid lägger vi huvudet som en global variabel. Så vad vi kan göra är att ändra huvudet. Jag kan göra detta nya noden bli ny chef, och det kommer att peka på den tidigare chefen. Hur kan vi göra det? Det första jag måste göra är att ändra "n" i den nya noden till värde, som skickas till funktionen. Sedan newnode händer nu kommer att vara chef. Huvudet kommer att newnode. Så det är ganska enkelt. För att ta bort en nod, kan vi göra det som - Ett sätt vi kan göra det är att säga, okej, om jag ville ta bort, till exempel, 3, vad jag skulle kunna göra är att bara peka den föregående noden till nästa nod av 3. Så jag skulle bara göra något sådant. Men vad är problemet med att göra det? Jag har en minnesläcka, så jag har inte tillgång till antalet 3 längre. Problemet med det är att jag inte kommer att kunna frigöra den noden. Jag kommer att ha minnesläcka och (ohörbart) kommer att hata mig. Så istället för att göra det, skulle jag nog ha en temporär pekare. Så jag satte temp. Det går att peka på den nod som jag vill ta bort. Och då kan jag flytta de tidigare noderna att peka på nästa nod av den nod som jag vill ta bort. Och slutligen, kan jag befria pekaren. Måste jag befria pekare som jag skapade där? Jag behöver inte, bara för att - Skillnaden är att den här noden skapades med malloc, så det är i högen, medan detta bara förklaras som en NULL brytare i stacken. Så jag behöver inte befria den. Okej. Så nu ska vi prata om stackar. Stacks är ganska enkelt. Vi gjorde stackar och köer i klassen bara med hjälp av matriser, men du bör känna - bara vara medvetna om att du också kan göra högar i köer med hjälp av länkade listor också. Så om du har en array, skulle det vara en bunt? En stack första måste ha en storlek. Du måste lagra vad är storleken på stapeln som du har just nu. Och även du skulle ha en matris, i detta fall av siffror, men om du vill, kan det vara en array strängar, en matris med struct, vad som helst som du vill lagra. Om stacken: Skillnaden mellan en stack och en länkad lista är att i bunten har du bara tillgång till det sista elementet som sattes i stacken. Det kallas sist in, först ut. Precis som du har en hög med brickor, om du lägger en bricka på toppen av stacken, du måste ta bort det facket först för att få tillgång till de andra facken. Det är samma sak med staplar. Så om jag vill, till exempel lägga till ett element till en skorsten, vad ska jag göra? Det kallas push, och det är ganska enkelt. Det första du behöver göra är att kontrollera om storleken på stacken inte är större än eller lika med kapaciteten för stapeln. För om du redan är på full kapacitet, kan du inte lägga till något annat. Och sedan, om inte, är det bara att lägga till element till stacken. Och slutligen, öka storleken. Så det är ganska enkelt. Så jag bara lägga till numret 2. Och om jag vill dyka, vilket betyder att jag vill ta bort det sista elementet som tillsattes, och returnera värdet av elementet, det första jag måste kontrollera är att stacken inte är tom. För om den är tom, kan jag inte tillbaka något. I så fall, jag åter -1. Annars kommer jag att dekrementera storleken på spec, och returnummer (s.size). Varför fick jag dekrementera storlek och sedan återvända s.size? Det är för att, i detta fall, spec har storlek 4, och jag vill returnera det fjärde elementet, eller hur? Men vad är index för det fjärde elementet? Tre. Eftersom jag vet storlek - kommer att vara 3, kan jag bara gå tillbaka s.numbers (s.size) eftersom det är 3. Så det är bara indexet. Nu köer. Köer är ungefär samma sak. Den enda skillnaden är att istället för att ha sist in, först ut, du först in, först ut. Förmodligen om du väntar på att gå på en konsert, du inte skulle bli glad om du hade en bunt istället för en kö. Att vara den sista personen att komma skulle vara den första personen att komma in i konserten. Du har förmodligen inte skulle bli lycklig. I kön, är den första personen att komma in också den första personen att komma ut. Så i definitionen av en kö, förutom att ha storleken i matrisen, du måste också ha i huvudet, vilket är det index till chefen för stapeln. Så det första elementet just nu. Placera i kö är det samma sak som push för stackar. Om du var väldigt naiv, skulle du bara säga, Tja, jag kan bara göra exakt samma sak som jag gjorde för push. Jag kan bara kolla om det inte är bortom kapaciteten. Om det är, återvänder jag falskt, annars kan jag bara exportera det nya värdet och sedan öka storleken. Men varför är det fel? Låt oss se det här exemplet. Jag försöker att köa en massa saker, och sedan ska jag avköa och köa. Det finns en hel del kommandon, men det är mycket enkelt. Jag kommer att köa 5, så tillsätt 5, och sedan 7, 1, 4, 6, och då vill jag avköa något, vilket betyder att jag kommer att ta bort det första elementet. Så jag kommer att ta bort nummer 3, eller hur? Det första elementet. Okej. Nu om jag försöker köa något annat, är det som kommer att hända? Enligt mina genomförande, Jag hade tänkt att sätta nästa nummer i index q.size. I detta fall är storleken 8, så indexet 8 kommer att vara här i den sista positionen. Om jag försöker köa 1 här, skulle jag kunna skriva över den senaste positionen till antalet 1, vilket är helt fel. Vad jag vill göra är att linda runt och gå till den första positionen. Kanske vill du bara säga, ja, jag måste bara kolla om jag faktiskt kan sätta något där. Om inte, jag bara säger, åh, den nya fulla kapacitet är faktiskt kapacitet - 1, och du kan inte sätta ett element där. Men vad är problemet? Problemet är att om jag avköa precis allt här och då jag försöker lägga till något annat, det skulle bara säga, bra, du var full kapacitet, vilket är 0. Så ditt kön är borta. Du måste linda runt, och ett sätt att linda runt att ni lärt på visionära och andra psets använde mod. Du kan prova hemma för att förstå varför du skulle göra q.size + q.head mod kapacitet, men om du kolla här, Vi kan se att det fungerar. Så i det sista exemplet, q.size var 8 och huvudet var 1, eftersom det var denna position här i matrisen. Så det blir 8 + 1, 9. Mod kapacitet 9 skulle vara 0. Det skulle gå till index 0. Vi kommer att vara i rätt position. Och sedan försöka kön hemma. Några viktiga saker: att försöka förstå skillnaden mellan en stack och en kö. Hemma, försöka få väl förtrogen med att genomföra enqueue, dequeue, tryck och pop. Och också förstå när du skulle använda var och en av dem. Så låt oss slappna av i 10 sekunder med ett gäng Pokemons. Och nu ska vi gå tillbaka till datastrukturer. Hash tabeller. Många var rädda för hashtabeller. i problem set 6, stavningskontroll. Hashtabeller och försöker, en hel del människor blir rädda för dem. De tror att de är så svåra att förstå. Yeah? [Rob Bowden] Problem set 5. Problem set 5, ja. Tack Rob. Yeah. Sex var Huff n 'Puff, ja. Problem set 5 var stavningskontroll, och du var tvungen att använda antingen en hashtabell eller ett försök. Många trodde att de var super svårt att förstå, men de är faktiskt ganska enkelt. Vad är en hashtabell, i grund och botten? En hash-tabell är en array av länkade listor. Den enda skillnaden mellan en matris och en hashtabell är att i hash bord du har något som kallas en hashfunktion. Vad är en hash-funktion? Jag vet inte om ni kan läsa här. Detta är ett exempel på en hash-tabell. Så du kan se att du har en array med 31 element. Och vad gör vi i en hashtabell är en hashfunktion som kommer att översätta en nyckel, varje int till ett index. Om, till exempel, om jag vill välja för B. Harrison, Jag skulle sätta B. Harrison i mina hashfunktioner, och hashfunktion skulle återvända 24. Så jag vet att jag vill lagra B. Harrison i 24. Så det är skillnaden mellan att bara ha en matris och en hash-tabell. I hash tabellen har du en funktion som kommer att berätta för dig var du vill lagra de data som du vill lagra. För hashfunktion, vill du leta efter en hashfunktion som är deterministisk och väl fördelad. Som ni kan se här, ser du att en hel del av de uppgifter som jag ville butik var faktiskt 19 istället för att använda 31 och 30 och 29, som var alla fria. Så hash-funktion som jag använde var inte mycket väl fördelad. När vi säger väl fördelad, innebär det att vi vill ha, ungefär, åtminstone 1 eller 2 för var och en av de - liknande, en skillnad på 1 eller 2 för varje index i arrayer. Du vill ha, ungefär, samma antal element i varje länkad lista i arrayen. Och det är lätt att kontrollera om det är giltigt i hash-tabellen, se som hashtabeller. Då träd. Detta är ett träd. Träd i datavetenskap är upp och ner av någon anledning. Så här har du roten av trädet och sedan bladen. Du ska bara veta nomenklaturen för föräldrar och barn. Varje nod har sina barn, som är de noder som är lägre än den överordnade. Så, till exempel, 2 kommer att vara den överordnade för 3 och för det andra barnet just där, medan 3 kommer att vara den överordnade för 1 och de andra barnen som är där. Och 1 kommer att bli 3: s barn, och så vidare. Vi har något mycket mer intressant, som kallas ett binärt sökträd, där alla värden till höger om en nod kommer att vara till höger, just här - på höger, kommer att vara större än den del av roten. Så om jag har nummer 5 här, alla delar på rätt kommer att vara större än 5, och på vänster alla element kommer att vara mindre än fem. Varför är detta bra? Om jag vill kontrollera om antalet 7 är här, till exempel, Jag går bara till 5 först och jag kommer att se, är 7 större eller mindre än 5? Den är större, så jag vet att det kommer att vara på höger sida om trädet. Så jag har mycket mindre saker att titta på. Vid genomförandet av ett binärt sökträd, noden, jag bara kommer att behöva ha uppgifter, så int n, du kan också ha en sträng eller vad du ville ha. Du måste bara vara noga med att definiera vad som är större, det som är mindre. Så om du hade strängar, till exempel, kan du definiera att alla dessa saker till höger kommer att ha större längd, vänster kommer att ha lägre längder, så det är verkligen upp till dig. Hur kan jag genomföra hitta för BST? Det första vi måste göra är att kontrollera om roten är NULL. Om det är NULL, betyder det att saken är inte där eftersom du inte ens har ett träd, eller hur? Så jag returnera false. Annars kommer jag att kontrollera om antalet är större än värdet i roten. Jag ska försöka hitta elementet till höger av trädet. Du ser att jag använder rekursion här. Och sedan om det är mindre, jag kommer att titta till vänster. Och slutligen, annars, om det inte är mindre eller inte högre, Det innebär att det är själva värdet. Så jag återvänder bara sant. Du kan se här att jag använt, om, om, om. Och kom ihåg, i frågesport 0, uppstod ett problem som hade, om, om, om, och du skulle hitta den ineffektivitet, och ineffektivitet var som du använde vid. Du skulle ha använt om det, annars om, annars om, och annat. Så ska jag använda annars om och annars om och annan här? Finns det någon - ja? [Student tala, ohörbart] Det var perfekt. Så hon säger att det inte spelar någon roll, bara för att den ineffektivitet som vi hade innan var det därför, kanske om något villkor var uppfyllt, så du har utfört en åtgärd, men då du skulle kontrollera alla de andra villkoren. Men i detta fall, återvände det direkt, så det spelar ingen roll. Så du behöver inte använda annan om. Och slutligen, låt oss tala om försök, som är allas favorit. Ett försök är ett träd av matriser. Det är väldigt snabbt att slå upp värden, men den använder mycket minne. Och det är oftast att filtrera ord, så när du vill genomföra, till exempel, jag vet inte, som en telefonbok i telefonen och du vill kunna skriva B och bara ha namn på personer som har B. Det är väldigt lätt att genomföra det med hjälp av ett försök, till exempel. Hur definierar du en nod i ett försök? Du måste bara ha en bool som kommer att is_word. Det innebär att använda alla tecken innan den noden, man kunde bilda ett ord, och då har du en mängd pekare till noder. Kan du se att vi har en rad överordnade noder, så nod * array? Yeah? Så låt oss se hur det kommer att fungera. För stavningskontroll, vi har en array med 27 element, eftersom vi har alla bokstäver plus apostrof. Innan här jag ska bara använda 2 eftersom jag vill kunna skriva på tavlan. Okej. Så detta är ett exempel på ett försök. Om jag bara definierar den första noden, jag har en matris med två element det finns 2 pekare till NULL, så jag bara sätta "a" och "b". Och jag kommer att ha en bool som säger is_word. Det kommer att vara falskt för det första, bara för att, innan att du inte har några tecken. Så ett tomt ord är inte ett ord. Så det är falskt. Om jag vill lägga till "a" till denna ordbok, vad skulle jag göra? Jag skulle bara behöva malloc en ny nod för "a", och sedan lägga sitt ord till true. Så det bara innebär att ha "a" kommer att bli sann. Vettigt? Sen om jag vill lägga till "ba", jag måste malloc 1 för "b", och sedan ska jag ställa in boolean false eftersom "b" i sig är inte ett ord. Sen kommer jag att malloc ett annat för "a", så 'ba', och sedan ska jag ställa in det är ett ord till true. Eftersom 'ba' är ett ord. Och sedan om jag vill se om "b" är i denna ordbok, Jag kan bara gå till den första, "b". Jag går ner, och jag tittar på är ordet, och det står falskt. Så det är inte ett ord. Om jag vill kontrollera 'ba', Jag går till den första, "b", och gå sedan till "a", och jag ser sant, så det är ett ord. Vettigt? Många människor blir förvirrade av försök. Nej? Slutligen Huffmankodning. Huffman-kodning är mycket användbar för att spara minne och komprimera textfiler, bara för att många gånger du använder "a" och "e", till exempel, i dina dokument, men jag vet inte om ni använder "q" och "z" så mycket. Med bara 1 byte för varje enskilt tecken, varje - de 256 tecken som vi har i ASCII-tabellen är inte särskilt optimalt, bara för att det finns vissa tecken som du använder mycket mer, så du bör nog använda mindre minne för dem. Hur använder jag Huffman kodning? Vi måste göra en Huffman träd.  En Huffman träd har noder som har en symbol som kommer att vara som, "a", "b", "c", brevet, vilken bokstav du har, en frekvens som är den frekvens som ordet förekommer i texten, att du skapar den Huffman träd för, och sedan en nod som kommer att peka åt vänster av Huffmanträdet och en annan nod som kommer att peka åt höger. Så precis som ett träd. Hur du bygger en Huffman träd? Du kommer att plocka de två noder som har de lägsta frekvenserna. Om du har en slips du kommer att plocka de två noder som har de lägsta ASCII-värden också. Då du kommer att skapa ett nytt träd ur dessa två noder som kommer att ha den kombinerade frekvensen i den överordnade noden. Och då du kommer att ta bort de 2 barnen från skogen och ersätta dem med föräldern. Och du kommer att upprepa det tills du bara har 1 träd i skogen. Så låt oss se hur du skulle göra en Huffman träd för ZAMYLA. Du kan se här att alla bokstäver har frekvensen 1 med undantag för "A", som har frekvensen 2. Så jag skapade noder för alla brev jag in i ordning av ASCII-värde och frekvens. Så om jag vill skapa det första trädet, kommer det att vara med "L" och "M". Så det är här. Frekvensen hos paret kommer att vara två eftersom det är 1 + 1, sedan nästa 2 med de lägsta frekvenserna är "Y" och "Z". Och då har jag alla av dem är - ha en frekvens på 2. Så vilka som är de som har de lägsta ASCII-värdet för nästa? "A" och "L". Så jag skapar den nya noden, och slutligen, det är 4 och 2, så 2 kommer att vara på vänster sida. Och detta är Huffman träd. Sen om jag vill skriva en text, som i binär att konvertera till text, med hjälp av Huffman-träd är mycket enkelt. Till exempel, om jag säger att flytta till vänster är en 0 och flyttar till höger är en 1, Vad är det som går att representera? Så som 1, 1, så rätt, rätt, och sedan 0, så kvar skulle vara L, och sedan 1, 0, 0. Så 1, 0, så det är bara 1, 0, "A". Och sedan 0, 1, så 'Z'. Och sedan 1, 0, 0 - nej. 0, 0 kommer att vara 'Y', så lat. Så det är allt för mig, Rob kommer att ta över. [Rob Bowden] Så, vecka 7 grejer. Vi har mycket att gå över väldigt snabbt. Bitvis operatörer, buffertspill, CS50 bibliotek, då HTML, HTTP, CSS. Sammantaget som 15 till 20 minuter. Bitvis operatörer. Det finns 6 av dem som du behöver veta. Bitvis och, bitvis eller, XOR, vänster shift, högerskift, och inte. Höger skift och inte du knappt såg i föreläsning alls. Vi ska gå igenom det snabbt här, men det är bra att veta att dessa är de 6 som finns. Kom ihåg att bitvisa operatörer är som när du gör 3 + 4. Du inte har att göra med den binära av 3 och 4. Med bitvisa operatörer du faktiskt hantera de enskilda bitarna i siffrorna 3 och 4. Så det första som vi säger är bitvis inte, och allt det gör är att vända alla bitarna. Så här, om du skriver detta i C, skulle du inte skriva det som ~ 11011 eller vad skulle du skriva det gillar ~ 4, och då det skulle vända den binära representationen av 4. Så här, ~ av vissa binära talet 1101101 ska precis vända alla 1 s till 0 s och alla 0 s till 1 s. När jag säger det, den frekventa användningen av detta, och vi får se det i lite, är som vi vill komma med några nummer där alla bitar är 1, med undantag för en av dem. Så det är oftast lättare att uttrycka antalet var just det enda bit är satt, och sedan ta ~ av den, så att varje annan bit är satt med undantag för att en. Så det är vad vi kommer att använda mer i lite. Bitvis eller. Här finns 2 binära tal, och dessa två siffror är ganska representativa, eftersom de representerar alla möjliga kombination av bitar kan du behöva för att driva på. Här, när jag or'd varje bit, vi kommer bara att jämföra rakt ner. Så på vänster sida har vi en 1 och en 1. När jag bitvis | dem, vad ska jag få? One. Sedan bitvis | 0 och 1 kommer att ge mig? One. Bitvis 1 och 0 kommer att vara samma sak, en. Bitvis 0 | 0 kommer att ge mig 0. Så det enda fall där jag får 0 är i 0 | 0 fall. Och du kan tänka på att precis som dina logiska ors. Så om du tänker på en så sann och 0 som falskt, samma sak gäller här. Så sant eller sant är sant, sant eller falskt är sant. Falskt eller sant är sant, falskt eller falskt är det enda som faktiskt är falska. Här är det exempel som du bör veta som ett ganska bra exempel på när bitvisa operatörer används. Här om vi eller kapital "A" med OX20, och vi kommer att titta på dessa i en andra, vi får något. Och om vi eller gement "a" med OX20, vi får något. Så låt oss dra upp ASCII-tabellen. Okej. Här ser vi att "A" är - Här har vi "A" är decimal 65. Men jag ska gå med hexadecimal, vilket är Ox41. Ganska säker på att vi såg det i klassen. Jag tror att vi såg det i klassen att det är ganska lätt att konvertera från hexadecimalt till binärt. Så här, om jag vill sätta 4 till binär, som bara kommer att bli 0100. Det här är en plats, 2 plats, 4 plats, så det är 4. Då kan jag dela upp 1 till binär, vilket kommer att bli 0001. Och så det här kommer att bli representationen av "A" i binärt. Med gement "a", det nu kommer att bli Ox61, där, att dela upp dessa i sin binära, så en 6 - Låt oss faktiskt gör det - finns det ingen suddgummi? Suddgummi. Ox61. Så dela 6 i binär kommer att bli 0 + 4 + 2 + 0. Och uppdelningen 1 kommer att bli 0001. Om man tittar på skillnaden mellan dessa två, Vi ser att den enda skillnaden mellan ett gement och stort "A" är det enda bit. Så kommer tillbaka till här - okej. Kommer tillbaka till här, om vi tittar på vad det lite OX20 är, så klyvningen OX20 in i dess binära, är 0010, 0000. OX20, den enda bit som är satt är det lite som vi sysslar med, med att växla mellan stora och små bokstäver "a". Om jag eller "A", som är här en, "A", om jag eller "A" med OX20, vad ska jag få? [Student, ohörbart] Gemener "a", eftersom det kommer att vända denna bit till en 1. Och om jag eller "a" med OX20, vad ska jag få? Små bokstäver a, eftersom bara oring 'a' med OX20, Jag ska bara vara oring denna enda bit till en 1, det är redan en 1, så det spelar ingen roll. Så vi får "a" och "a". Bitvis och. Återigen kan vi se det som vår logiska och motsvarighet. På vänster sida har vi sanna och äkta. Det kommer att vara sant, och för alla de fall, false & sant eller sant och falskt, eller false & falskt, Ingen av dessa saker är sanna. Så vad vi i slutändan får är 1000. Så nu, här, här är där jag har använt den pålitliga bitvis inte, där vi hade OX20. Så det här är OX20. Nu vad jag vill göra, bitvis ~ för OX20. Det kommer att vända alla bitar. Så jag har 1101, 1111. Och så "A" anded med ~ OX20 kommer att ge mig det? Den enda bit som vi verkligen måste tänka på är den här, eftersom, om alla dessa bitar är satta till 1, då vi kommer att få exakt vad "A" var, utom, möjligen, vad denna bit är. För om det var en 1, nu det kommer att ställas in på 0, eftersom allt detta är, anded med detta kommer att bli 0. Så vad är "A" & ~ OX20 kommer att ge mig? [Eleverna svarar, ohörbart] Och vad är "a" och - det är "A". Och vad är "a" & ~ OX20 kommer att ge mig? "A." Eftersom detta är för närvarande en 1. Anding med detta 0 kommer att göra det till en 0, och nu ska vi få ett "A". Båda är "A", och sist men inte minst av denna typ, vi har XOR. Det är väldigt likt eller, förutom att det innebär uteslutande eller. Detta är precis vad du brukar tänka på när eller i den verkliga världen. Så du gör antingen "x" eller "y", men inte båda. Här 1 ^ 1 kommer att vara 0. Eftersom sant, är detta - det fungerar inte så bra med den logiska sant och falskt som bitvis & och eller göra, men sant ^ sant är falskt. Eftersom vi bara vill återvända sant om endast en av dem är sann. Så 1 ^ 1 är 0. Hur är 0 ^ 1? Är 1. 1 ^ 0 är 1, 0 ^ 0 är 0. Så under alla omständigheter, är 0 bitvis något 0 kommer att vara 0. 1 bitvis något 0 eller 0 bitvis 1, om det är | eller ^, det blir en 1, och om det är och det ska vara 0. Och det enda fall där 1 bitvis 1 är inte 1 är med exklusivt eller. Det är 0110. Så här nu, med hjälp av XOR - så vi är tillbaka vid 20. 'A' ^ OX20 är dessa 2 bitar vi jämför. Så en 1 ^ 0 kommer att ge mig en vad? En en. 'A' ^ OX20 kommer att ge mig? Små bokstäver en. 'A' ^ OX20 kommer att ge mig? Capital A. Eftersom allt detta gör, detta XOR med OX20 effektivt vända vad denna bit är. Om detta är en 0, det kommer nu att bli en 1. Eftersom detta är en 1, 1 ^ 1 är 0. Så vår "a" har blivit "A", och vår "A" har blivit "a". Så XOR är ett riktigt bekvämt sätt att bara vända ärendet. Du vill bara att iterera över en rad bokstäver och alternera det gäller varje enskilt tecken, du bara XOR allt med OX20. Nu har vi lämnat skift. Vänster skift är bara att, i princip, skjuta alla nummer i, eller till vänster, och sätt 0 s bakom dem. Så här har vi 00.001.101. Vi kommer att driva 3 0 s in från höger, och vi får 01.101.000. I icke-binär termer, Vi ser att det verkligen handlar 13 vänster-skiftat med 3, vilket ger oss 104. Så vänsterförskjutning, ser vi här, är x << y princip x * 2 ^ y. 13 * 2 ^ 3, 2 ^ 3 är 8, så 13 * 8 är 104. Om du bara tänker på binär i allmänhet, hur varje siffra, Om vi ​​börjar från höger, det är en plats, sedan den 2: s plats, då den 4 plats. Så genom att trycka på 0 s från höger, vi bara driver saker som var på 4 plats på 8 plats, och saker som var på 8 plats till 16 plats. Varje skift multiplicerar bara med 2. Yeah? [Student] Vad händer om du skiftat med 5? [Bowden] Om du skiftat med 5 skulle du bara förlora siffror. Oundvikligen är det samma sak. Liksom, heltal är endast 32 bitar, så om du lägger två riktigt stora heltal, det bara inte passar i ett heltal. Så det är samma sak här. Om du skiftat med 5, vi skulle bara förlora den. Och det är ungefär vad jag menar med "grovt" där om du skiftar för långt, förlorar du bitar. Höger skift kommer att bli det motsatta, där vi ska shove 0 s från slutet, och för våra syften, fyll i 0 s från vänster. Så gör det, är vi i princip vända det vi redan hade gjort. Och vi ser att de tre 0 s till höger precis har fallit bort, och vi har drivit den 1101 hela vägen till höger. Detta gör 104 3, som är effektivt, x / 2 ^ y. Så nu, här, det är en liknande idé. Varför är det bara ungefär x / 2 ^ y, och inte egentligen x / 2 ^ y? För om jag hade skiftat med 4, skulle jag ha förlorat en 1. I grund och botten, vad du tycker om, tänk bara på heltalsdivision i allmänhet. Så som 5/2 är 2. Det är inte 2.5. Det är samma idé här. När vi delar med 2, Vi kan förlora udda bitar på vägen. Så nu - det är det för bitvis. Det är allt du behöver veta. Minns de användningsfall som vi såg i klassen, som en bitmask är användbar för bitvisa operatörer, eller om du använder dem för bit masker. Versaler och gemener, konverteringar är en ganska prototypiska exempel. Okej, så buffer overflow attacker. Någon som kommer ihåg vad som var fel med den här funktionen? Märker vi förklarade en matris med 12 byte, 12 tecken, och sedan kopierar vi in ​​i vår buffert på 12 tecken hela strängen bar. Så vad är problemet här? Det magiska talet 12 bör ganska mycket omedelbart pop ut som - varför 12? Tänk om bar råkar vara mer än 12 tecken? Tänk om bar är miljontals tecken? Här är frågan memcpy. Om bar är tillräckligt lång, det kommer bara helt - "c", "c" inte bryr sig att det var bara 12 tecken; "C" inte bryr sig om att det inte får plats så många byte. Det kommer bara att skriva över röding, de 12 byte som vi har tilldelats för det, och allt förbi det i minnet som egentligen inte hör till denna buffert med allt vad det strängfältet är. Så detta var den bild vi såg i klassen där vi har vår stack växer upp. Du bör användas för dessa bilder eller bekanta med dem igen. Vi har vår stack växer upp, minnesadresser börjar på 0 i toppen och växa ner att gilla 4 miljarder i botten. Vi har vår array "c" någonstans i minnet, då har vi vår pekaren till bar precis under den, och sedan har vi det här sparade ram pekare i vår returadress och vår moder rutin stack. Kom ihåg vad avsändaradressen är? Det är när huvud anropar en funktion foo, anropar en funktion bar, oundvikligen, bar avkastning. Så när bar avkastning, måste de veta att det kommer tillbaka till foo som kallade det. Så avsändaradressen är adressen till den funktion som den har att återvända till när funktionen returnerar. Anledningen till att det är viktigt för attacker buffertspill är därför, enkelt, hackare vilja ändra den returadress. Istället för att gå tillbaka till foo, jag kommer att gå tillbaka dit hacker vill att jag ska gå tillbaka till. Och, enkelt, där hackaren vill ofta att gå tillbaka till är början av bufferten som vi ursprungligen hade. Så märker, återigen, Little Indian. Apparaten är ett exempel på en liten indiska systemet, så ett heltal eller en pekare lagras med de bytes omkastade. Så här ser vi - är det här? Yeah. Vi ser Ox80, OxC0, Ox35, OxO8. Kom ihåg hexadecimala siffror? Vi vill inte kasta om hexadecimala siffror i Little Indian, eftersom 2 hexadecimala siffror utgör ett enda byte, och vi vända byte. Det är därför vi inte lagrar, liksom, 80530CO8. Vi lagrar, istället, varje par av 2 siffror, med början från höger. Denna adress hänför sig till adressen för starten av vår buffert som vi ville verkligen att kopiera in i första hand. Anledningen till det är användbart är att, tänk om angriparen hänt, istället för att ha en sträng som var precis en ofarlig sträng av liknande, deras namn eller något, tänk om istället att strängen var bara några av godtycklig kod som gjorde vad de ville göra? Så de kunde - Jag kan inte komma på något coolt kod. Det kan vara vad som helst, dock. Varje katastrofala kod. Om de vill kan de bara göra något på seg fel, men det skulle vara meningslöst. De gör oftast det att hacka systemet. Okej. CS50-bibliotek. Detta är, i grunden, getInt, getString, alla de funktioner som vi gett er. Så vi har char * sträng, och det är den abstraktion som vi blåste bort någon gång under terminen. Kom ihåg att en sträng är bara en uppsättning av tecken. Så här ser vi en förkortad version av getString. Du bör titta tillbaka på den för att komma ihåg hur det faktiskt har genomförts. Viktiga detaljer är, märker vi i ett enda tecken i taget från standard in, vilket är precis som oss att skriva på tangentbordet. Så ett tecken åt gången, och om vi får för många tecken, så om n + 1 är större än kapaciteten då måste vi öka kapaciteten i vår buffert. Så här är vi fördubbla storleken på vår buffert. Och det fortsätter att gå, vi infoga tecknet i vår buffert tills vi får en ny linje eller slutet av filen eller vad som helst, i vilket fall, vi gjort med strängen och sedan den verkliga getString krymper minnet, som om vi tilldelats för mycket minne det ska gå tillbaka och krympa lite. Så vi inte visar det, men huvudtanken är det måste läsas i ett enda tecken i taget. Det kan inte bara läsa i en hela på en gång, eftersom deras buffert är bara av en viss storlek. Så om strängen som den försöker att infoga i bufferten är för stor, då skulle det svämma över. Så här förhindrar vi att genom att bara läsa i ett enda tecken i taget och växer när vi behöver. Så getInt och de andra CS50 bibliotek funktioner tenderar att använda getString i deras implementeringar. Så jag lyfte fram viktiga saker här. Den uppmanar getString att få en sträng. Om getString misslyckades att återvända minne, kom ihåg att getString mallocs något, så när du ringer getString du bör inte (ohörbart) befria den strängen som du fick. Så här, om den inte malloc något, återvänder vi INT_MAX som bara en flagga som, hey, vi var faktiskt inte kunna få ett heltal. Du bör ignorera vad jag tillbaka till dig, eller ska du inte behandla detta som en giltig inmatning. Slutligen, om man antar att lyckades använder vi sscanf med den speciella flaggan, vilket innebär, först matcha ett heltal, sedan matcha alla tecken efter det heltal. Så märker vi vill att det ska vara lika med 1. Så sscanf avkastning hur många matcher om framgångsrikt gjort? Det kommer tillbaka 1 om det framgångsrikt matchas ett heltal, den ger 0 om det inte matchar ett heltal, och den ger 2 om det matchade ett heltal följt av vissa tecken. Så märker vi försöka igen om vi matchar allt annat än 1. Så om vi gick in 1, 2, 3, C, eller 1, 2, 3, X, därefter 1, 2, 3 skulle få lagras i heltal, X skulle få lagras i karaktären, sscanf skulle återvända 2, och vi skulle försöka igen, eftersom vi bara vill ha ett heltal. Snabbt blåser genom HTML, HTTP, CSS. Hypertext Markup Language är strukturen och semantik av banan. Här är exempel från föreläsningen där vi har HTML-taggar. Vi har huvudet taggar, body-taggarna, Vi har exempel på tomma taggar där vi faktiskt inte har en start och nära tag, vi bara få länk och bild. Det finns ingen stängningsbildtaggen, det finns bara en enda tagg som åstadkommer allt taggen behöver göra. Länken är ett exempel, vi får se hur du länkar till CSS, skriptet är ett exempel på hur du länkar till en extern JavaScript. Det är ganska enkelt, och kom ihåg, HTML är inte ett programmeringsspråk. Här, kom ihåg hur man skulle definiera en form eller åtminstone vad det skulle göra? Ett sådant formulär har en handling och en metod. Metoderna du bara någonsin kommer att se är GET och POST. Så få är den version där saken får sätta i webbadressen. POST är där det inte sätts i webbadressen. Istället är alla data från formuläret infogas mer dold i HTTP-begäran. Så här definierar åtgärder där HTTP-begäran går. Om det händer är google.com / search. Method. Tänk på skillnaderna mellan GET och POST, och, bara säga som ett exempel, om du vill bokmärka något. Du kommer aldrig att kunna bokmärka en POST-URL eftersom data inte finns med i webbadressen. HTTP, nu, är Hypertext Transfer Protocol. Hypertext Transfer Protocol, skulle du förvänta dig det att överföra Hypertext Markup Language, och det gör det. Men den överför också några bilder som du hittar på webben, någon nedladdning du gör börjar som en HTTP-begäran. Så HTTP är bara språket i World Wide Web. Och här måste du känna igen denna typ av en HTTP-begäran. Här HTTP/1.1 på sidan bara säger att det är den versionen av protokollet jag använder. Det är ganska mycket alltid att vara HTTP/1.1, som du ser det. Då ser vi att detta var GET, alternativet är POST, som du kan se. Och den URL som jag försökte besöka var www.google.com/search?q = bla, bla, bla. Så kom ihåg att detta frågetecken q = bla bla bla, är den typ av saker som lämnas in av ett formulär. Svaret kan det tillbaka till mig skulle se ut så här. Återigen, med början i protokollet, som kommer att bli det, följt av statuskoden. Här är det 200 OK. Och slutligen, kommer webbsidan att jag faktiskt bad om att följas. Det möjliga statuskoden kan du se, och du bör känna flera av dem. 200 OK har du förmodligen sett förut. 403 Forbidden, 404 Not Found, 500 Internal Server Error vanligtvis om du går till en webbplats och något är trasigt eller deras PHP-kod kraschar, medan apparaten vi har den stora orange ruta som kommer upp och säger, liksom, är fel någonting, denna kod inte fungerar eller denna funktion är dåliga. Vanligtvis webbplatser inte vill att du veta vilka funktioner är faktiskt dåligt, så istället de ska bara ge dig 500 Interna Server fel. TCP / IP är ett lager under HTTP. Kom ihåg att det finns Internet utanför webben. Som om du spelar ett online spel som inte går via HTTP, det går igenom en annan - det är fortfarande med hjälp av Internet, men den inte använder HTTP. HTTP är bara ett exempel på protokoll som bygger på TCP / IP. IP betyder bokstavligen Internet Protocol. Varje dator har en IP-adress, de är de 4-siffriga saker som 192.168.2.1, eller vad, som tenderar att vara en lokal. Men det är ett mönster av en IP-adress. Så DNS, Domain Name Service, det är det som översätter saker som google.com till en verklig IP-adress. Så om du skriver att IP-adressen till en URL, som skulle ta dig till Google, men du brukar inte komma ihåg dessa saker. Du tenderar att minnas google.com istället. Det sista vi har är hamnar, där detta är TCP delen av undersökningsperioden. TCP gör mer. Fundera på, liksom, du har din webbläsare igång. Kanske du har någon e-postprogram kör; kanske du har något annat program som använder Internet igång. De behöver alla tillgång till Internet, men datorn har bara 1 WiFi-kort eller vad som helst. Så hamnar är det sätt som vi kan dela upp hur dessa program kan använda Internet. Varje ansökan får en specifik port att den kan lyssna på, och som standard, HTTP använder port 80. Vissa e-tjänster använder 25. De låg-numrerade dem tenderar att vara reserverade. Du brukar kunna få högre numrerade dem för dig själv. CSS, Cascading Style Sheets. Vi utformar webbsidor med CSS, inte med HTML. Det finns 3 platser du kan sätta din CSS. Det kan vara inline, mellan stil taggar, eller i ett helt separat fil och sedan kopplas in Och här är bara ett exempel på CSS. Du bör känna igen detta mönster, där det första exemplet har vi matchande body-taggen, och här vi centre body-taggen. Det andra exemplet, vi matchar den sak med ID sidfot, och vi tillämpar vissa stilar till det. Lägg märke till att ID-sidfot text-Ansluter till vänster, medan kroppen text-justeras centrum. Sidfot är inuti kroppen. Det kommer i stället, text-align kvar, även om kroppen säger text-align center. Detta är hela kaskad del av den. Du kan ha - du kan ange färger för kroppen, och sedan saker i kroppen kan du ange mer specifika stilar, och saker och ting fungerar som du förväntar dig. Mer specifika CSS specifice företräde. Jag tror det är det. [Ali Nahm] Hej alla. Om jag bara kunde få din uppmärksamhet. Jag är Ali och jag kommer att gå igenom PHP och SQL riktigt snabbt. Så vi kan börja. PHP står för PHP: Hypertext Preprocessor. Och som ni alla borde veta, det är en server-side skriptspråk, och vi använder den för den bakre änden av webbplatser, och hur det gör en hel del av beräkningarna, att bakom kulisserna del. Syntax. Det är inte som C, surprise, surprise. Det måste alltid börja med det, om du kan se den - jag kan inte gå vidare. Du kan se att du behöver nya typer av hängslen och då behöver du också? Php. Det är alltid hur du måste rama in PHP-text, din PHP-kod. Så det kan inte bara vara som C, där du slags lägga den på första. Du måste alltid omge den. Och nu är den stora syntax att alla variabler måste börja med tecknet $. Du måste göra det när du definierar dem, du behöver för att göra det När du hänvisar till dem senare. Du måste alltid att $. Det är din nya bästa vän, ganska mycket. Du behöver inte - till skillnad från C, du behöver inte sätta vilken typ av variabel typ det är. Så när du behöver den $, behöver du inte att sätta, liksom, int x eller sträng y, etcetera, etcetera. Så en liten skillnad. Som ett resultat av detta så innebär det att PHP är en svagt typen. PHP är ett svagt språk, och det har svagt skrivit variabler. Med andra ord innebär det att du kan växla mellan olika typer av variabeltyper. Du kan spara ditt nummer 1 som en int, du kan spara den som en sträng, och du kan spara den som en flottör, och det kommer allt att bli som nummer 1. Även om du lagrar den i olika former, det är fortfarande - de variabeltyper håller fortfarande i slutändan. Så om du ser här, om du kommer ihåg från pset 7, många av er förmodligen hade problem med detta. Två likhetstecken, 3 likhetstecken, 4 likhetstecken. Okej, det finns inga 4 likhetstecken, men det finns 2 och 3. Du använder två likhetstecken för att kontrollera värdena. Det kan kontrollera över typer. Så om du kan se i det första exemplet, Jag har num_int == num_string. Så din int och din sträng är både tekniskt, 1, men de är olika typer. Men för de dubbla jämlikar, kommer det fortfarande passera. Men för de tredubbla jämlikar, kontrollerar den värdet samt de olika typerna. Det betyder att det inte kommer att passera i det andra fallet här, där du använder 3 likhetstecken istället. Så det är en stor skillnad som du borde alla ha visat nu. String sammanslagning är ett annat kraftfullt sak som du kan använda i PHP. Det är i princip bara denna behändiga punktnotation, och det är hur du kan binda strängar tillsammans. Så om du har katt och du har hund, och du vill placera de 2 strängar tillsammans, du kan använda den tid, och det är typ av hur det fungerar. Du kan också bara ställa dem bredvid varandra, som ni kan se här i botten exempel där jag har eko sträng 1, rymd sträng 2. PHP vet att ersätta dem som sådana. Matriser. Nu, i PHP, det finns 2 olika typer av matriser. Du kan ha regelbundna arrayer, och du kan även ha associativa arrayer, och vi kommer att gå igenom dem just nu. Regelbundna arrayer är just detta i C, och så du har index som är numrerade. Just nu är vi bara kommer att skapa en och sätta - så detta är hur vi skapar en tom array, då vi kommer att tas i indexnumret 0. Vi ska sätta siffran 6, värdet 6. Du kan se det längst ner här. Where's - vid indexnummer 1 vi ska sätta värde nummer 4, och så att du kan se att det finns en 6, finns det en 4, och sedan när vi skriver ut saker och ting, när vi försöker och skriva ut värdet lagras vid indexnummer 0, sedan får vi se värdet 6 att skrivas ut. Cool? Så det är regelbundna arrayer för dig. Ett annat sätt du kan även lägga till saker till vanliga arrayer nu är att du kan bara lägga dem i slutet. Det innebär att du inte behöver ange specifikt index. Du kan se numret, och sedan i hakparenteserna finns det inget index anges. Och det kommer att veta - PHP vet att bara lägga till det i slutet av listan, nästa lediga plats. Så du kan se ett direkt vid det 0 fläck, den 2 gick rätt där på första plats. Den 3 går - läggs där. Så det slags vettigt. Du är bara hela tiden till det, och sedan när vi ekande index för nummer 1, det kommer att skriva ut värdet 2. Sedan har vi arrayer som är associativa arrayer. Associativa arrayer, i stället för att ha numeriska index, vad de gör är, har de index som är med snöre. Du kan se, i stället för - Jag blev av med alla dessa sifferindex, och nu är det nyckel1, KEY2, KEY3, och de är inom citationstecken för att markera att de är alla strängar. Så vi kan få ett exempel på detta. Exemplet på detta är att vi har tf, och det är indexnamnet. Vi kommer att sätta "Ali" som namn på index, kalorier ätit, Vi kan sätta en int den här gången istället för en sträng, och sedan på index gillar, kan vi sätta en hel rad i den. Så det här är sådan - det är ett liknande koncept för hur vi hade index med siffror, men nu kan vi ändra indexen runt att ha dem som strängar i stället. Du kan också göra detta, förutom att bara göra det för sig, du kan göra allt på en bit. Så du kan se att tf av denna samling, och sedan vi satt dem alla i en gigantisk fyrkantig fäste set. Så det kan snabba upp saker och ting. Det är mer av en stilistisk val än inte. Vi har även slingor. I C har vi loopar som fungerar så här. Vi hade vår samling, och vi gick från index 0 till slutet av listan, och vi skriver ut allt, eller hur? Förutom problemet är, för associativa arrayer, Vi behöver inte nödvändigtvis vet de numeriska index för nu har vi de strängindex. Nu använder vi foreach loopar, som, igen, förhoppningsvis använt dig pset 7. Foreach loopar kommer bara vet varenda del av listan. Och det behöver inte veta exakt det numeriska index som du har. Så du har foreach syntaxen, så det är foreach, du sätter matrisen. Så min samling heter pset, och sedan som ordet som, och då du sätter denna lokal temporär variabel som du ska använda bara för specifik sak som kommer att hålla den specifika - en instans eller en del av matrisen. Pset num kommer att hålla 1, och då kanske det kommer att hålla i nummer 6, och så kommer det att hålla numret 2. Men det är garanterat att gå igenom varje enskilt värde som finns i arrayen. Praktiska funktioner som du bör veta i PHP är de kräver, så som ser till att du även vissa filer, eko, avfart, tom. Jag rekommenderar att du tittar på pset 7 och titta på dessa funktioner. Du kanske måste känna dem, så jag skulle definitivt vet vad, exakt, som alla gör. Nu ska vi gå igenom omfattningen riktigt snabbt. I omfattning, är PHP typ av en funky sak, till skillnad från C, och så vi ska bara gå igenom det snabbt. Så låt oss säga att vi börjar på den pil som vi har där. Och vi kommer att börja med $ i. Så variabeln "i" kommer att vara 0, och vi kommer bara att fortsätta att skriva ut det i den stora vita rutan där borta. Vi ska börja med I0, och sedan ska vi upprepa det. Så det finns det 0. Och då kommer vi att öka den genom att slingan, och då det kommer att vara värdet 1. En är mindre än 3, så det kommer att passera genom det för loop, och då kommer vi att se den tryckt igen. Vi kommer att öka igen till 2, och 2 är mindre än 3, så det ska passera för loop, och det kommer att skriva ut 2. Då kommer du att notera att 3 är inte mindre än 3, så vi kommer att bryta sig ur den för slingan. Så nu har vi avslutat, och sedan ska vi gå in aFunction. Okej. Så du måste notera att denna variabel som vi har skapat, "i" variabel, inte lokalt scoped. Det betyder att det inte är lokala till slingan, och den variabeln vi kan fortfarande komma åt och ändra i efterhand, och det kommer fortfarande att vara effektiv. Så om du går in i funktionen nu, ser du att vi använder även "i" variabel, och vi kommer att öka "i" + +. Man skulle kunna tro, först, baserat på C, att det är en kopia av "i" variabel. Det är en helt annan sak, vilket är korrekt. Så när vi skriver ut det, kommer vi att skriva ut 'i' + +, som kommer att skriva ut den 4, och sedan ska vi - tyvärr. Sen ska vi avsluta ur denna funktion, och vi kommer att vara där som pilen är just nu. Det innebär att dess emellertid, trots att funktionen ändrat värdet för "i", Det ändrade inte utanför funktionen, eftersom funktionen har en separat räckvidd. Det betyder att när vi echo "i", det har inte förändrats inom ramen för funktionen, och så då ska vi ut 3 igen. Olika saker om utrymme i PHP än i C. Nu i PHP och HTML. PHP används för att göra webbsidor dynamiska. Det gör slags saker annorlunda. Vi har det sig från HTML. Med HTML, vi alltid bara har samma statiska sak, liksom hur Rob visade, medan PHP, kan du ändra saker baserat på vem användaren är. Så om jag har det, jag har, "Du är inloggad som -" och sedan namnet, och jag kan ändra namnet. Så just nu namnet är Josef, och det har den "om mig", men då kan jag också byta namn för att ha Tommy. Och det skulle vara en annan sak. Så då kan vi också ändra olika saker om honom, och det kommer att visa olika innehåll baserat på namnet. Så PHP kan slags ändra vad som händer på din webbplats. Samma här. Ändå, notera att de har olika innehåll, även om du är tekniskt sett fortfarande tillgång till samma webbsida på ytan. Generera HTML. Det finns två olika sätt som du kan göra här. Så vi ska gå igenom det just nu. Det första sättet är, du har - ja, förlåt. Så du bara har din vanliga för loop i PHP, och då ekar i PHP och du echo ut HTML. Använda vad Rob visade dig av HTML-skript och sedan med hjälp av PHP-print att bara skriva ut den på webbsidan. Det alternativa sättet är att göra det som om du skilja ut PHP och HTML. Så du kan ha en rad av PHP som startar för slingan, då kan du ha den raden i HTML i en separat sak, och sedan avsluta slingan, återigen, med en PHP. Så det är typ att skilja ut det. På vänster sida kan du att du har all den - det är bara 1 bit av PHP. Till höger kan du se att du har en linje av PHP, du har en linje av HTML, och du har en rad av PHP igen. Så separera ut i vad de gör. Och du kommer att notera att båda hållen, för någon av dem, de fortfarande skriva ut bilden, bilden, bilden, så att HTML fortfarande skrivs ut på samma sätt. Och då kommer du fortfarande se de 3 bilderna visas på din webbplats. Så det är två olika sätt att göra samma sak. Nu har vi blanketter och ansökningar. Som Rob visade dig, det finns former av HTML, och vi kommer bara vind genom detta. Du har en handling och du har en metod, och din handling typ av visar var du ska skicka det, och metoden är om det kommer att bli en GET eller POST. Och en begäran GET, som Rob sa, innebär att du kommer att lägga den i en form och du ser det som en URL, medan en begäran POST du inte kommer att se i en webbadress. Så en liten skillnad. Men en sak som är en liknande sak är att POST och GET är lika osäkra. Så du kanske tror att bara för att du inte ser det i URL, det betyder att POST är säkrare, men du kan fortfarande se det i dina cookies i den information som du skickar. Så tror inte att ungefär ena eller det andra. En annan sak att notera är att du även har sektionsvariabler. Ni använde detta i pset 7 för att få ditt användar-ID. Det som hände var att du kan använda denna associativ array, de $ _SESSION, och då du kan komma åt olika saker och förvara olika saker över sidorna. Senaste är att vi har SQL, Structured Query Language, och detta är ett programmeringsspråk för att hantera databaser. Vad, exakt, är databaser? De är samlingar av tabeller, och varje tabell kan ha liknande typer av objekt. Så vi hade en tabell för användare i din ekonomi pset. Och varför är de användbara? Eftersom det är ett sätt att permanent lagra information. Det är ett sätt att spåra saker och hantera saker och faktiskt se det på olika sidor och hålla koll. Medan om du bara lagra den på att en omedelbar ögonblicket och sedan använda den senare, kommer du inte att kunna komma åt något som du har sparat. Vi har 4 stora saker som vi använder för SQL-kommandon. Vi har att välja, infoga, ta bort och uppdatera. Det är verkligen viktigt för er att veta för din frågesport. Vi ska snabbt gå över väljer just nu. I grund och botten, du väljer rader från en databas. Så om du har, just här - vi har dessa två olika saker, och vi vill välja från tabellen klasser där awesome - var i fantastisk kolumnen värdet är 1. Så du kan se här, vi har dessa 2 saker av klassnamn, CS50 och Stat110, och vi har de klass ID och slogan. Så vi vill markera all denna information. Sedan kan du se här att det är typ att plocka ut ur det enorma kolumnen där alla saker är 1, och därefter har den klass-ID, klassnamn och slogan som den kan plocka ut. Exakt hur gör man det i kod? Du måste använda PHP. Så det är typ hur PHP och SQL är relaterade till varandra. Nu har vi vår kod, och vi kommer att använda vår sökfunktion som vi gjorde i pset 7, och vi kommer att köra SQL-frågan. Sen ska vi ha - vi alltid måste kontrollera om rad triple lika om falskt. Så återigen, vill du kontrollera typ och värde, och sedan om det inte fungerar, då du vill be om ursäkt, som vanligt, som vi gjorde i pset 7. Annars vill slinga genom allt med dem som praktiskt foreach loopar att vi bara gick över. Nu när vi loopa igenom och vi har gjort det tidigare, låt oss anta att vår fråga gått, nu har vi vår foreach loop. Och den första raden har det, så här är raden, just här, det är inramade. Det kommer att skriva ut all information som det har blivit. Så det kommer att skrivas ut i botten "Vill du lära HTML?" Då kommer det att gå till nästa rad, eftersom det är slutfört den första för slinga, och så då det kommer att skriva ut den andra raden i den, som kommer att bli STAT110, Hitta alla Moments. En sista sak är på SQL sårbarheter. Jag vet att David var inne på detta lite i föreläsning. Du kan läsa det här senare. Det är verkligen roligt. SQL Injection är en sorts knepig sak. Låt oss säga att du bara hålla dessa variabler direkt i din fråga, som ni kan se i den första raden. Så det verkar bra, eller hur? Du bara sätter in användarnamnet och lösenord till din SQL-fråga, och du vill skicka bort det och få allt som är i datatabellen. Det verkar ganska enkelt. Så låt säga någon sätter in, för lösenord, detta ELLER text här - borde egentligen vara i den röda rutan. Så låt oss säga att de sätter det lösenordet i - det är vad de kommer in. Så de lägger ELLER "1" = 1. Typ av en enfaldigt lösenord för att ha. Nu ska vi bara byta ut det, och du kommer att notera att i den SQL-fråga nu, det utvärderas till alltid sant, eftersom du kommer att notera att du kan SQL-fråga markera all denna information eller du kan bara ha 1 = 1. Så det alltid kommer att utvärderas till true. Det kommer inte att verkligen fungerar, eftersom det innebär att hackare kan bryta sig in i ditt system. Lösningen på detta är att du måste använda PDO-systemet, vilket innebär att du måste använda frågetecken, vilket är vad ni killar som används i pset 7, där du ska använda ett frågetecken i stället för var du vill lägga något, och då du kommer att ha ett kommatecken, och sedan har du efteråt, efter din sträng, till de olika variabler som du vill byta in din frågetecken. Så du kommer att notera att nu har jag dessa röda frågetecken. Sedan satte jag variablerna efter mina strängar så jag vet att ersätta dem i den ordningen efteråt. Det kommer att se till att om någon gör det så här, och de har eller 1 = 1 situation, som kommer att se, i bakändan, se till att det faktiskt inte kommer att bryta SQL-fråga. Okej, så det är ganska mycket det, en virvelvind av PHP och SQL. Lycka till er alla, och nu till Ore [Oreoluwatomiwa Babarinsa] Okej alla. Dags att gå igenom några JavaScript och en del andra saker väldigt snabbt så vi behöver inte hålla dig i kväll. JavaScript. Ja. JavaScript är lite av en cool grej, enligt uppgift. De saker som du verkligen behöver veta om JavaScript, det är ungefär som klientsidan slutet av vad din web app kommer att göra. Det finns några saker som du bara inte vill ta hand om hela tiden på serversidan. Alla små interaktioner, lyfta fram en sak, gör något försvinner. Du vill verkligen inte att behöva prata med din server hela tiden för det. Och en del av det är inte ens möjligt att göra på serversidan. Det är därför vi behöver något som JavaScript. Coola saker om JavaScript: Det är dynamiskt skrivit. Vad detta betyder är att ditt program inte behöver veta Vad, exakt, är variablerna när du skriver ut det. Det ska bara sorts lista ut det eftersom det är igång. Andra saker som är coolt om det: Det är en klammer språk, vilket innebär syntaxen liknar C och PHP. Du behöver inte göra mycket omarbete när du lär JavaScript. Här har vi en liten bit av JavaScript. Intressant sak här är att om man ser på det, vi har lite av JavaScript direkt i huvudet taggen. Vad är gör är i grunden bara innehålla en JavaScript-fil. Detta är ett sätt du kan inkludera JavaScript i ditt program. Sedan den andra lite är faktiskt en del inline JavaScript mycket lik en infogad stil med CSS, och du bara skriva lite kod väldigt snabbt där. JavaScript har arrayer. Bara ett annat sätt att hålla data runt, mycket användbart. Mycket trevlig och enkel syntax. Du använder hakparenteser för att få tillgång till allt och håller ihop allting. Inget alltför komplicerad. Det häftiga JavaScript och skriptspråk i allmänhet är att du inte behöver oroa dig för arraystorlekar. Du kan bara använda Array.length och hålla reda på det, och även matrisen kan växa eller krympa när du behöver det. Så du behöver inte ens oroa dig för någon form av, åh nej, jag måste avsätta mer saker, eller något liknande. Det häftiga här är att JavaScript har något som kallas objekt. Det är ett objektorienterat språk, så vad det har är, i huvudsak, ett sätt för dig att gruppera uppgifter tillsammans, något som liknar en struct, men du kan komma åt det som en struct eller i en associativ array syntax. Det är ganska enkelt, och vad du kan göra med detta är gruppuppgifter tillsammans om du har en massa data som är relaterade. Eftersom det är allt du behöver för att beskriva en bil, du behöver inte ha det i en massa olika ställen. Du kan bara hålla den i 1-objekt i JavaScript. Som du säkert vet, är iteration en av dessa tråkiga uppgifter. Du gör bara det över en igen. Du måste prata med varje föremål i bilen, eller du behöver gå igenom varje objekt i en lista eller något liknande. Så JavaScript har, likt PHP, en foreach syntax. I det här fallet är det en i slinga. Du vill använda detta endast på objekt. Det finns vissa problem som uppstår om du använder detta på matriser. Det är i allmänhet en av de saker, dock är det mycket användbart, eftersom du eliminera en hel del overhead eftersom du inte behöver dra upp allt i ditt objekt själv. Du behöver inte komma ihåg alla viktiga namn. Du bara sorts få tillbaka dem i denna syntax. I detta, med för, vill du bara komma ihåg att du får tillbaka alla nycklar, i ett mycket liknande sätt som hash tabell. Om du kommer ihåg från det, när man skulle sätta in en sträng som du kan få ut något som skulle ha ett associerat värde med det. Vad du kan göra med detta är att du kan säga, okej, Jag satt i en bil, och jag kallade det en Ferrari. Så du kan sätta i strängen Ferrari igen senare, och du kan få ut det. Och du kan göra det i en slinga, med i loopen. Så bara mer om objekten. Det viktigaste av detta måste du komma ihåg är att du kan använda objektet struct liknande syntax när du vill med dem, förutom om vad du ska använda som en sträng är inte ett giltigt variabelnamn. Så om du tittar på det där, har vi nyckeln med mellanslag. Tja, om du skulle sätta object.key, utrymme, med, utrymme, utrymmen, som bara inte skulle vara meningsfullt syntaktiskt. Så du bara kan göra det med denna typ av fäste syntax. Dessutom är JavaScript mycket utrymme-klokt att PHP. Du har två sätt att lösa omfattning. Du kan inte ha det var framför en variabel, och det betyder bara att detta är global. Du kan se det från någonstans. Även om du skulle sätta detta i en if-sats, någon annanstans i koden efter den punkten att du kunde se att variabeln. En annan sak är dock med det var, det är begränsat till vad funktion du befinner dig i. Om du inte är i en funktion, ja, det är globalt. Men om du är i en funktion är det bara syns i den funktionen. Jag har ett exempel, men, ja. Det är en av de saker där du kan hantera vilka variabler du vill vara globalt, vilka variabler du vill vara lokala, men du måste vara försiktig om det här, eftersom du inte har den typen av finkornig kontroll du gör i C, där om något deklareras i en for-loop, det kommer att stanna i det för slinga. Det vi faktiskt bryr sig om att använda JavaScript för manipulerar webbsidor, eller hur? Jag menar, det är därför vi gör det här. För att göra detta använder vi något som kallas DOM. Document Object Model. I grund och botten, vad den gör är det tar all din HTML och modeller ut den i en massa föremål som är kapslade i varandra. Du börjar med något som detta. Du har, om rätt för mig, en massa kod där ute som blir liksom - Man skulle kunna tro det skulle vara mycket svårt att manipulera, eftersom du skulle vara pars igenom en massa text och med att pussla isär saker. Och tänk om det inte var korrekt formaterad? Dåliga saker skulle hända. Så JavaScript tar hand om detta för dig, och du får en fin datastruktur, som den på min vänstra, där du bara har ett dokument, och inne att du har något som kallas HTML, och inne att du har ett huvud och en kropp, och inuti det huvudet du har en titel, etcetera, etcetera, etcetera. Detta förenklar manipulera en webbsida så att det är bara, åh, jag vill bara prata med det här objektet. Sortera på ett mycket liknande sätt som du skulle prata med ett annat objekt som du gjort själv. Som sagt, allt DOM i dokumentobjektet. Antingen är det bara ett ställe och sedan kan du gå i den för att hitta saker, och du kan göra det - det är den gamla stilen av att göra det, där uppe, där du gör document.getElementById, och sedan namnet, och som ni säkert vet, blir det väldigt otymplig efter ett tag. Så du kanske inte vill göra det. Det är därför vi har nästa sak vi ska prata om efter detta. Det viktiga här är att, okej, du har alla dessa element, eller hur? Så kanske jag kan ändra färg på något när sidan laddas. Så vad? Vad händer om min användare klickar på något? Jag vill att det ska göra något intressant när de klickar på något. Det är därför vi har händelser. Du kan, i princip, hitta alla element i din DOM, och sedan säga, hej. När detta läses eller någon klickar på den, eller när de musen över den, göra något med den. Och det du har är, du har funktioner som hanterar detta åt dig. Dessa funktioner är händelsehanterare. Vad Dom - det är bara ett finare sätt att säga, Denna funktion är endast körs när denna händelse inträffar. Så det hanterar händelsen som inträffar. Detta är hur du skulle lägga ut en händelsehanterare. Jag har lite knapp, och när du klickar på den, exploderar det. Så inte klicka på knappen. Detta är ett sätt att närma sig det, eller hur? Du har en knapp tag, och på klick har du en sträng som säger, Åh, förresten, gör jag det exploderande sak för mig. Annars är det precis som en vanlig knapp som du just gjorde. Du kan också göra det på ett annat sätt, genom att ta tag i DOM-elementet, men vi ska spara som när vi talar om jQuery. JQuery: Det är ett bibliotek som är cross-browser. Du kan använda den i stort sett allt. Och det bara ger dig en hel del verktyg att arbeta med. Eftersom JavaScript, medan kraftfulla, inte har alla verktyg du behöver ur lådan för att verkligen ta itu med ett webbprogram som du kanske vill göra. Så det förenklar en hel del saker, ger dig en hel del funktioner ur lådan som du normalt skulle behöva skriva själv, om och om och om igen. Och bara gör saker och ting mycket enklare. Du har också väljare, vilket gör att du tar ut alla de element från DOM mycket enklare, i stället för att använda dessa mycket långa funktionsanrop. Mer om dessa väljare. Du har, där uppe du har, låt oss säga Jag vill få ett element med id "rock." Tja, i jQuery, det är bara $ och sedan en sträng som har ett halvt kilo, och sedan "rock." Det är mycket enkelt och mycket snabbare än den traditionella JavaScript sättet att ta itu med detta problem. Och du har liknande saker för klasser och elementtyper. jQuery är - en av de häftiga funktioner är att du kan sorts komprimera ner dina frågor på ditt DOM väldigt, väldigt snabbt. Nu är vi tillbaka till händelsehantering, och det är hur du skulle hantera en händelse i jQuery. Så vad vi ska här är vi säger, okej. Jag har en script-tagg, eller hur? Så jag har denna inline JavaScript. Vad vi ska göra är att vi kommer att säga, okej. När dokumentet är färdigt, vilket innebär att dokumentet har laddats, vi kommer att gå in på den funktionen, och vi kommer att säga, okej, denna funktion är faktiskt att göra något annat. Det är i grund och botten säger, okej, ge mig elementet med id "myid." Och sedan ge detta en funktion hanterare som körs när du klickar på den. I grund och botten vad detta innebär är, den säger, okej. Den sidan är laddad, så jag ska in, finner detta element, ge den här händelsehanterare, och det i princip sätter upp din sida för dig. Och detta är hur du vill tänka på händelsehantering. Du vill bara att tänka på, okej, när något inträffar, vad jag vill ska hända? Du vill inte att tänka på, okej, jag måste se till att denna sak talar för denna sak, denna sak bla bla bla, eftersom du bara vill prata sak när det gäller evenemang. När det händer, händer det här. När det händer, händer det. Och om saker utlösa andra saker, det är bra. Men du vill inte försöka göra komplicerade kod där du utlöser flera saker samtidigt, eftersom du bara kommer att ge dig själv en huvudvärk. Okej. Nu kan vi få vår sida att hantera händelser, men låt oss säga att min användare klickar på en knapp. Vad händer om jag vill skicka begäran tillbaka till servern, men jag vill inte ladda om sidan, därför att behöva ladda en ny sida varje gång blir typ av tråkiga, och varför behöver jag för att dra ner huvudet igen, och sidfoten igen, och alla delar av sidan igen bara för att uppdatera hälsning eller tiden? Så det är därför vi har något som Ajax. Det vi kan göra här med Ajax är att vi kan säga, okej, Jag vill skicka några data till servern, och jag vill få ett svar tillbaka så jag kan uppdatera min sida, eller kanske bara göra några algoritmberäkning som inte nödvändigtvis visa något för användaren. Vad behöver du för att göra detta? Tja, du behöver en webbadress som du behöver prata med. Din server kan inte bara magiskt lyssna in från ingenstans. Du måste ha en viss plats du skickar dessa data till. Och du behöver också en del data att skicka, eller kanske är det en utan lokala data-fråga. Du vill bara att pinga tillbaka till servern och säga hej, jag lever, eller något liknande. Och då du vill ha en funktion som i princip hanterar med framgång. Låt oss säga att du får tillbaka en del information från din server, och du vill ändra användarens titel på sin sida. Så du skulle få tillbaka informationen, och du skulle driva det till skärmen. Vad som händer är, när sidan är klar, du skapar en på klickfunktion för den här knappen som heter Greeter. Vad detta sedan innebär är, när den knappen trycks, du pratar med greetings.php, du gör en förfrågan POST, och du säger, hej, ge mig något från din sida. Vi behöver egentligen inte att beskriva det, men greetings.php, låt oss bara säga, ger tillbaka "hej världen." Så vi får tillbaka denna "Hello World", och på framgången av detta, antar ingenting går fel, då vi bara gå till detta mål plats att vi specificerade och vi bara hålla svaret där. Och detta är ett mycket enkelt sätt att skapa en Ajax-fråga. Mycket snabbt, Rob slags nämnde detta redan, saker kan gå fel, kan dåliga saker hända, så du vill bekanta dig med dessa HTTP-svarskoder. Vilka dessa är är precis, som, 200, allt gick okej. Något annat, hände dåliga saker. Det är i allmänhet den sak som du vill komma ihåg. Men det är skönt att veta alla dessa. Och slutligen, när vi har gått igenom allt detta, vi behöver prata mycket snabbt om design, och då kan vi låta dig alla lämnar. Design. Saker som du vill komma ihåg. Ställ dig följande frågor: Vem kommer att använda det här? Vad kommer de att använda det till? Vad gör mina användare bryr sig om? Vad de inte bryr sig om? Du vill bara inte att göra en app och låt det bara växa och bli denna jätte, allt krävande sak som du inte ens kan avsluta. Du vill ha diskreta mål och planer och saker du vill ta upp. Gör det enkelt. Allt detta står i grund och botten gör det enkelt för användaren att använda det, inte göra det till en jätte klump text som den här bilden är, faktiskt. Du vill bara att det ska vara något där det är väldigt lätt för någon att gå in och göra vad de vill göra. Du vill inte att de ska behöva navigera 5 sidor att komma till din främsta funktion på din webbplats. Om Google hade 5 sidor innan du kan även söka något, ingen skulle använda den. Och slutligen, pappersprototyp, fokusgrupp. Ha god design och testmetoder. Bara för att du tror att det fungerar för dig, betyder inte att någon annan tycker det fungerar. Men ja, det är det. [CS50.TV]