[Omtale: Quiz 1] [Ali fant sitt, Oreoluwa Barbarinsa, Lucas Freitas, Rob Bowden] [Harvard University] [Dette er CS50.] [CS50.TV] [Lucas Freitas] Velkommen alle sammen. Dette er vurdering for quiz en. Akkurat som en ansvarsfraskrivelse, dette er - jeg mener, vi kommer til å prøve å dekke så mye materiale som mulig, men det betyr ikke at vi kommer til å dekke alle de tingene som kan være i quiz en. Så vær sikker på at du også ta en titt på forelesning, seksjoner, alt du kan. Quiz 1 kommer til å være på onsdag, neste onsdag. Så sørg for å studere. Det kommer til å være, ganske mye, som den første quiz hensyn til format, men det er trolig kommer til å være mye vanskeligere. Minst, i fjor da jeg tok 50, jeg trodde det var mye vanskeligere. Så studere mye. Jeg kommer til å dekke datastrukturer og Huffman koding. Dette er noe som mange mennesker tror er kompleks, men jeg skal prøve å gjøre det så enkelt som mulig. Først av alt, hva ønsker vi dere å vite for quiz 1 er å forstå de konseptuelle beskrivelser av hver av de datastrukturer som jeg kommer til å presentere. Det betyr at du ikke trenger å faktisk gjennomføre en hash tabell i quiz en. Vi ønsker ikke å gjennomføre en hel hash table, kanskje vi skal prøve for at du skal gjennomføre noen funksjoner, de vanligste operasjonene, men vi kommer ikke til å gjøre deg gjennomføre alt. Så det er viktig at du forstår konseptet bak hver datastruktur og også at du er i stand til å kode i C, kun de mest vanlige operasjoner de har for hver datastruktur. Og også kunne gjennomgå pekere og structs, fordi de synes mye i disse datastrukturer. Først knyttet lister. Koplede listene er faktisk veldig lik matriser, men forskjellen mellom en lenket liste og en matrise, først og fremst er at en lenket liste har en meget fleksibel størrelse, mens i matriser må du enten velge en veldig stor størrelse for matrisen, slik at du vet at du kommer til å være i stand til å lagre alle dine data i denne matrisen, eller du må bruke malloc å ha en fleksibel lengde på array. I lenkede lister er det veldig lett å bare få flere elementer, sette flere elementer i lenket liste eller fjerne elementer. Og faktisk, hvis du ikke vil at lenket liste skal sorteres, du kan søke og fjerne elementer i konstant tid, så O (1) tid, så det er veldig praktisk. Du må bare være forsiktig med å alltid huske å malloc og gratis nodene, bare fordi hvis du ikke gjør det, vil du ha minnelekkasjer. Så lenkede lister - definisjonen av en node er akkurat som det vi har rett der. Jeg satte int n, men du kan lagre alle data du vil. Så hvis du ønsker å lagre en streng, er det fint. Hvis du ønsker å lagre en struct, det er greit, en dobbel, hva du vil. Jeg bare sette int n for eksemplene her. Og du har en peker til neste node. Så, i utgangspunktet, har en lenket liste noen data, og deretter den peker til neste node. Hvis det er det siste elementet i lenket liste, det kommer til å peke til NULL. Dette er altså et eksempel på en lenket liste. Ok, så nå får vi se hva vi skal gjøre hvis jeg vil sette inn et element i en lenket liste. For det første vil en funksjonsinnsats være av typen void fordi jeg ikke ønsker å returnere noe. Og jeg kommer til å ta en int som et argument, fordi jeg ønsker å vite hva jeg vil sette inn. Så hva er det første jeg bør gjøre? Vel, jeg skal malloc på newnode, slik at det er den første linje. Jeg er bare å skape en ny node til å sette i en lenket liste. Så hva kan jeg gjøre? Vel, vi vet at i våre implementeringer av lenkede lister i klassen, vi alltid setter hodet som en global variabel. Så det vi kan gjøre er å endre hodet. Jeg kan gjøre dette nye noden bli ny leder, og det kommer til å peke til den forrige hodet. Hvordan kan vi gjøre det? Det første jeg må gjøre er å endre 'n' i den nye noden til verdi, som ble sendes til funksjonen. Deretter newnode det neste kommer til å være leder. Hodet kommer til å bli newnode. Så det er ganske enkelt. For å slette en node, kan vi gjøre det som - En måte vi kan gjøre det på er å si, ok, hvis jeg ønsket å slette, for eksempel tre, hva jeg kan gjøre er å bare peke forrige node til den neste noden 3. Så jeg ville bare gjøre noe sånt. Men hva er problemet med å gjøre det? Jeg har en minnelekkasje, så jeg har ikke tilgang til nummer tre lenger. Problemet med det er at jeg ikke kommer til å være i stand til å frigjøre den noden. Jeg kommer til å ha minnelekkasje og (uforståelig) kommer til å hate meg. Så i stedet for å gjøre det, bør jeg nok ha en midlertidig peker. Så jeg satte temp. Det kommer til å peke på noden som jeg ønsker å slette. Og så kan jeg flytte de tidligere noder til punkt til neste node av noden som jeg ønsker å slette. Og til slutt, kan jeg frigjøre pekeren. Må jeg å frigjøre peker som jeg laget akkurat der? Jeg trenger ikke å, nettopp fordi - forskjellen er at denne noden ble opprettet ved hjelp av malloc, så det er i haugen, mens dette ble nettopp erklært som en NULL-bryteren i bunken. Så jeg trenger ikke å få det løs. Ok. Så nå la oss snakke om stabler. Stacks er ganske grei. Vi gjorde stabler og køer i klassen bare ved hjelp av matriser, men du bør være kjent - bare vær oppmerksom på at du også kan gjøre stabler i køer med lenkede lister også. Så hvis du har en rekke, ville det være en stabel? En stabel, først, blir nødt til å ha en størrelse. Du må lagre hva er størrelsen av stabelen at du har akkurat nå. Og også ville ha en rekke, i dette tilfelle av tall, men hvis du vil, kan det være en rekke strenger, en rekke struct, noe som du ønsker å lagre. Om bunken: Forskjellen mellom en stabel og en lenket liste er at det i stabelen du kun har tilgang til det siste element som er satt inn i stabelen. Det kalles sist inn, først ut. Akkurat som du har en bunke med magasiner, hvis du setter en skuff på toppen av bunken, du må fjerne den skuffen først å ha tilgang til de andre skuffene. Det er det samme med stabler. Så hvis jeg vil, for eksempel legge til et element i en stabel, hva bør jeg gjøre? Det kalles push, og det er ganske grei. Det første du må gjøre er å sjekke om størrelsen på stakken ikke er større eller lik kapasiteten i stabelen. Fordi hvis du allerede er på full kapasitet, kan du ikke legge til noe annet. Og så hvis ikke, du må bare legge til elementet i bunken. Og til slutt, øke størrelsen. Så det er ganske grei. Så jeg bare legge til nummeret to. Og hvis jeg ønsker å pop, noe som betyr at jeg ønsker å fjerne det siste element som er overført, og returnerer verdien av elementet, det første jeg må sjekke er at bunken ikke er tom. Fordi hvis det er tomt, kan jeg ikke gå tilbake noe. I så fall er jeg tilbake -1. Ellers kommer jeg til å minske størrelsen på spec, og returnere tall (s.size). Hvorfor gjorde jeg minske størrelsen og deretter returnere s.size? Det er fordi, i dette tilfelle, har de spec størrelse 4, og jeg ønsker å returnere det fjerde elementet, ikke sant? Men hva er indeksen for det fjerde elementet? Tre. Siden jeg størrelse - kommer til å være tre, kan jeg bare gå tilbake s.numbers (s.size) fordi det er tre. Så det er bare indeksen. Nå køer. Køer er ganske mye det samme. Den eneste forskjellen er at i stedet for å ha siste inn, først ut, du har først inn, først ut. Sannsynligvis hvis du venter på å gå på en konsert, du vil ikke være fornøyd hvis du hadde en stabel i stedet for en kø. Å være den siste personen til å komme ville være den første personen til å gå inn i konserten. Du har sannsynligvis ikke ville være fornøyd. I køen, er den første personen til å komme inn også den første personen til å komme seg ut. Så i definisjonen av en kø, foruten å ha en størrelse i matrisen, må man også ha et innlegg, som er indeksen til hodet på stabelen. Så det første elementet akkurat nå. Enqueue er det samme som push for stabler. Hvis du var veldig naiv, vil du bare si, vel, jeg kan bare gjøre akkurat det samme som jeg gjorde for push. Jeg kan bare sjekke om det ikke utover kapasiteten. Hvis det er, jeg return false, ellers kan jeg bare eksportere den nye verdien og deretter øke størrelsen. Men hvorfor er dette galt? La oss se dette eksemplet. Jeg prøver å Enqueue en haug med ting, og da kommer jeg til å dequeue og Enqueue. Det er mye av kommandoer, men det er veldig enkelt. Jeg kommer til å Enqueue 5, så legg fem, og deretter 7, 1, 4, 6, og da vil jeg dequeue noe, noe som betyr at jeg kommer til å fjerne det første elementet. Så jeg kommer til å fjerne nummeret 3, ikke sant? Det første elementet. Ok. Nå hvis jeg prøver å Enqueue noe annet, hva kommer til å skje? Ifølge min gjennomføring, Jeg hadde tenkt å sette det neste nummeret i indeksen q.size. I dette tilfelle er størrelsen 8, så indeksen 8 vil være her i den siste posisjonen. Hvis jeg prøver å Enqueue en rett her, ville jeg være å overskrive den siste plassen til tallet 1, som er fullstendig feil. Hva jeg vil gjøre er å vikle seg rundt og gå til den første posisjonen. Kanskje du ville bare si, vel, jeg må bare sjekke hvis jeg kan faktisk sette noe der. Hvis ikke, jeg bare sier, oh, den nye full kapasitet er faktisk kapasitet - en, og du kan ikke sette et element der. Men hva er problemet? Problemet er at hvis jeg bare dequeue alt rett her og da jeg prøver å legge til noe annet, det ville bare si, vel, du var på full kapasitet, noe som er 0. Så din køen er borte. Du må brytes rundt, og en måte å pakke rundt at dere lært i visjonære og andre psets brukte mod. Du kan prøve det hjemme å forstå hvorfor du ville gjøre q.size + q.head mod kapasitet, men hvis du sjekker akkurat her, Vi kan se at det fungerer. Så i det siste eksemplet, q.size var åtte og hodet var 1, fordi det var denne posisjonen her i matrisen. Så det vil være 8 + 1, 9. Mod kapasitet ni ville være 0. Det ville gå til indeksen 0. Vi vil være i riktig posisjon. Og så prøve køen hjemme. Noen viktige ting: prøv å forstå forskjellen mellom en stabel og en kø. Hjemme, prøve å få veldig kjent med å implementere enqueue, dequeue, push og pop. Og også forstå når du skal bruke hver av dem. Så la oss slappe av i 10 sekunder med en haug av Pokemons. Og nå la oss gå tilbake til datastrukturer. Hash tabeller. Mange var redd for hash tabeller. i oppgavesettet 6, stavekontroll. Hash tabeller og prøver, mange mennesker blir skremt av dem. De tror de er så vanskelig å forstå. Yeah? [Rob Bowden] Problem satt fem. Problem satt fem, ja. Takket Rob. Yeah. Seks var Huff n 'Puff, ja. Problem satt fem ble stavekontroll, og du måtte bruke enten en hash tabell eller en prøve. Mange trodde at de var super vanskelig å forstå, men de er faktisk ganske enkelt. Hva er en hash table, i utgangspunktet? En hash table er en rekke lenkede lister. Den eneste forskjellen mellom en matrise og en hash table er at i hash table du har noe som kalles en hash-funksjon. Hva er en hash-funksjon? Jeg vet ikke om dere kan lese her. Dette er et eksempel på en nøkkeltabell. Så du kan se at du har en rekke med 31 elementer. Og hva vi gjør i en hash tabellen har en hash-funksjon som kommer til å oversette en nøkkel, hver int til en indeks. Hvis, for eksempel, hvis jeg ønsker å velge for B. Harrison, Jeg ville sette B. Harrison i mine hash funksjoner, og hash-funksjon vil returnere 24. Så jeg vet at jeg ønsker å lagre B. Harrison i 24. Så det er forskjellen mellom bare å ha en matrise og ha en hash table. I hash tabellen vil du ha en funksjon som kommer til å fortelle deg hvor du vil lagre dataene som du ønsker å lagre. For den hash-funksjon, vil du se etter en hash-funksjon som er deterministisk og godt fordelt. Som du kan se her, ser du at mye av dataene som jeg ønsket å butikken var faktisk 19 i stedet for ved hjelp av 31 og 30 og 29, som alle var fri. Så hash-funksjon som jeg brukte var ikke veldig godt fordelt. Når vi sier godt fordelt, betyr det at vi ønsker å ha, lag, i det minste en eller to for hver av de - som, en forskjell på en eller to for hver av indeksene i matriser. Du ønsker å ha, omtrent det samme antallet elementer i hver lenket liste i rekken. Og det er lett å sjekke om det er gyldig i hash table, se som hash tabeller. Så trær. Dette er et tre. Trær i informatikk er opp ned eller annen grunn. Så akkurat her har du roten av treet og deretter bladene. Du bør bare vite nomenklatur for foreldre og barn. Hver node har sine barn, som er de nodene som er under den overordnede. Så, for eksempel 2 til å være den overordnede til 3 og for det annet barn der, mens tre kommer til å være forelder for en og de andre barna som er der. Og en kommer til å være tre er barn, og så videre. Vi har noe mye mer interessant, kalles et binært søketre, hvor alle verdiene på høyre for en node kommer til å være på høyre side, rett her - til høyre, kommer til å være større enn det element i roten. Så hvis jeg har nummer fem akkurat her, alle elementer på høyre kommer til å være større enn 5, og på venstre alle elementene kommer til å være mindre enn fem. Hvorfor er dette nyttig? Vel, hvis jeg ønsker å sjekke om tallet 7 er her, for eksempel, Jeg bare gå til fem første, og jeg kommer til å se, er syv større eller mindre enn 5? Det er større, så jeg vet at det kommer til å være på høyre side av treet. Så jeg har mye mindre ting å se på. I gjennomføringen av et binært søketre, noden, jeg er bare nødt til å ha data, så int n, du kan også ha en streng eller noe du ville. Du må bare være forsiktig med å definere hva som er større, hva er mindre. Så hvis du hadde strenger, for eksempel, kan du definere at alle disse tingene på den rette kommer til å ha større lengde, venstre kommer til å ha lavere lengder, så det er egentlig opp til deg. Hvordan kan jeg implementere finne for BST? Det første vi må gjøre er å sjekke om roten er NULL. Hvis det er NULL, betyr det at ting ikke er der fordi du ikke engang har et tre, ikke sant? Så jeg return false. Ellers kommer jeg til å sjekke om tallet er større enn verdien i roten. Jeg kommer til å prøve å finne elementet på høyre av treet. Du ser at jeg bruker rekursjon her. Og så hvis det er mindre, kommer jeg til å se på venstre side. Og til slutt, ellers, hvis det ikke er mindre eller ikke større, det betyr at det er selve verdien. Så jeg bare returnere true. Du kan se her at jeg brukte hvis, hvis, hvis. Og husk, i quiz 0, hadde vi et problem som hadde hvis, hvis, hvis, og du skulle finne på ineffektivitet, og ineffektiviteten var at du brukte om. Du bør ha brukt hvis, annet hvis, annet hvis, og annet. Så, bør jeg bruke annet hvis og annet hvis og annet her? Er det noen som - ja? [Student taler, uhørlig] Det er perfekt. Så hun sier at det ikke spiller noen rolle, bare fordi den ineffektivitet som vi hadde før var det fordi, kanskje hvis noen kravet var oppfylt, slik at du har utført en handling, men da du skulle sjekke alle de andre forholdene. Men i dette tilfellet, det kom tilbake med en gang, så det spiller ingen rolle. Så du trenger ikke å bruke annet hvis. Og til slutt, la oss snakke om prøver, som er alles favoritt. En prøve er et tre av arrays. Det er veldig fort å lete opp verdier, men den bruker mye minne. Og det er som regel å filtrere ord, så når du ønsker å gjennomføre, for eksempel, vet jeg ikke, som en telefonboken på telefonen og du vil være i stand til å skrive B og bare ha navn på personer som har B. Det er svært enkelt å implementere at bruk av en prøve, for eksempel. Hvordan definerer du en node i et forsøk? Du må bare ha en bool som kommer til å bli is_word. Det representerer at bruk av alle tegnene før den noden, du var i stand til å danne et ord, og da vil du ha en rekke pekere til noder. Kan du se at vi har en rekke overordnede noder, slik node * array? Yeah? Så la oss se hvordan det vil fungere. For stavekontroll, vi har en matrise med 27 elementer, fordi vi har alle bokstavene pluss apostrof. Før her jeg bare kommer til å bruke to fordi jeg ønsker å være i stand til å skrive på tavlen. Ok. Så dette er et eksempel på en prøve. Hvis jeg bare definere den første noden, vil jeg ha en rekke to elementer som er to pekere til NULL, så jeg bare sette 'a' og 'b'. Og jeg kommer til å ha en bool som sier is_word. Det kommer til å være falsk for den første, bare fordi, før at du ikke har noen tegn. Så et tomt ord er ikke et ord. Så det er falsk. Hvis jeg ønsker å legge til 'a' til denne ordboken, hva ville jeg gjøre? Jeg ville bare ha til malloc en ny node for 'a', og deretter legge sitt ord til sann. Så det bare representerer det å ha 'a' kommer til å være sant. Fornuftig? Så hvis jeg ønsker å legge til 'ba', vil jeg måtte malloc 1 for 'b', og da kommer jeg til å sette opp boolean til false, fordi 'b' i seg selv er ikke et ord. Så jeg kommer til malloc en annen for 'a', så 'ba', og da kommer jeg til å sette opp det er et ord til sann. Fordi 'ba' er et ord. Og så hvis jeg ønsker å se om 'b' er i denne ordboken, Jeg kan bare gå til den første, 'b'. Jeg går ned, og jeg ser på er ordet, og det sier falsk. Så det er ikke et ord. Hvis jeg ønsker å sjekke 'ba', Jeg går til den første, 'b', og deretter gå til 'a', og jeg ser sant, så det er et ord. Fornuftig? Mange mennesker blir forvirret av prøver. Nei? Endelig Huffman koding. Huffman koding er svært nyttig å spare minne og komprimere tekstfiler, bare fordi mange ganger du bruker 'a' og 'e', ​​for eksempel, i dokumentene, men jeg vet ikke om dere bruker 'q' eller 'z' så mye. Å ha bare en byte for hver enkelt karakter, hver enkelt - de 256 tegnene som vi har i ASCII-tabellen er ikke veldig optimal, bare fordi det er noen tegn på at du bruker mye mer, så du bør nok bruke mindre minne for dem. Hvordan bruker jeg Huffman koding? Vi må gjøre en Huffman treet.  En Huffman treet har noder som har et symbol som kommer til å være som, 'a', 'b', 'c', brevet, uansett brev du har, en frekvens som er frekvensen at ordet vises i teksten, at du skulle lage den Huffman treet for, og deretter en node som kommer til å peke til venstre for Huffman treet og en annen node som kommer til å peke til høyre. Så akkurat som et tre. Hvordan kan du bygge en Huffman treet? Du kommer til å plukke de to noder som har de laveste frekvensene. Hvis du har et slips du kommer til å plukke de to noder som har de laveste ASCII-verdier i tillegg. Da kommer du til å opprette et nytt tre ut av disse to noder som kommer til å ha den kombinerte frekvens i foreldrenoden. Og så kommer dere til å fjerne de to barna fra skogen og erstatte dem med den overordnede. Og du kommer til å gjenta det til det bare er ett tre i skogen. Så la oss se hvordan du ville gjøre en Huffman treet for ZAMYLA. Du kan se her at alle bokstavene har frekvens 1 unntatt for 'A'; som har frekvens to. Så jeg laget noder for alle bokstavene jeg satt i rekkefølge av ASCII-verdi og frekvens. Så hvis jeg ønsker å opprette det første treet, vil det være med 'L' og 'M'. Så det er her. Frekvensen av de to vil være 2 fordi det er en + 1, deretter neste to med de laveste frekvensene er "Y" og "Z". Og så har jeg alle av dem er - har en frekvens på to. Så hvilke som er de som har den laveste ASCII verdi for den neste? 'A' og 'L'. Så jeg opprette den nye noden, og til slutt, er det fire og to, så to kommer til å være på venstre side. Og dette er den Huffman treet. Så hvis jeg ønsker å skrive litt tekst, som i binær å konvertere til tekst ved hjelp av Huffman treet er veldig enkelt. For eksempel, hvis jeg sier at å flytte til venstre er en 0 og beveger seg til høyre er en 1, Hva kommer det til å representere? Så ut som en, en, så høyre, høyre, og deretter 0, så igjen vil være L, og deretter 1, 0, 0. Så en, 0, så bare ett, 0, 'A'. Og deretter 0, 1, slik at 'Z'. Og så en, 0, 0 - nei. 0, 0 vil være 'Y', så lat. Så det er alt for meg, Rob kommer til å ta over. [Rob Bowden] Så, uke 7 ting. Vi har mye å gå over veldig fort. Bitvis operatører, buffer overflow, CS50 bibliotek, deretter HTML, HTTP, CSS. Alt i som 15 til 20 minutter. Bitvis operatører. Det er seks av dem at du trenger å vite. Bitvis og, bitvis eller, XOR, venstre shift, høyre shift, og ikke. Høyre skift og ikke du knapt så på forelesning i det hele tatt. Vi vil gå over det raskt her, men det er godt å vite at disse er de seks som eksisterer. Husk at bitvis operatører er som når du gjør 3 + 4. Du forholder seg ikke med det binære av tre og fire. Med bitvis operatører er du faktisk arbeider med individuelle biter av tallene 3 og 4. Så det første at vi vil si er bitvis ikke, og alt den gjør er å snu alle biter. Så her, hvis du skriver dette i C, du ville ikke skrive det som ~ 11 011 eller noe, ville du skrive det liker ~ 4, og da ville det snu den binære representasjonen av fire. Så her, ~ av noen binære tallet 1101101 kommer til akkurat snu alle 1 til 0 og alle 0 til 1-tallet. Som jeg sier det, den hyppige bruken av dette, og vi vil se det i et litt, er som vi ønsker å komme opp med noen tall hvor alle biter er en, bortsett fra en av dem. Så det er vanligvis lettere å uttrykke antall hvor nettopp det enkelt bit er satt, og deretter ta ~ av det, slik at annenhver bit er innstilt med unntak av at en. Så det er det vi kommer til å bruke mer i en bit. Bitwise eller. Her er to binære tall, og disse to tallene er ganske representative, siden de representerer alle mulige kombinasjon av biter du kan trenger for å operere på. Her, når jeg ELLER-behandlet hver bit, vi kommer bare til å sammenligne rett ned. Så på venstre side har vi en 1 og en 1. Når jeg bitvis | de, hva jeg kommer til å få? One. Deretter bitvis | 0 og 1 kommer til å gi meg? One. Bitvis 1 og 0 kommer til å være det samme, en. Bitvis 0 | 0 kommer til å gi meg 0. Så det eneste tilfellet hvor jeg får 0 er i 0 | 0 tilfelle. Og du kan tenke på at akkurat som dine logiske ORS. Så hvis du tenker på en så ekte og 0 som falsk, gjelder det samme her. Så sant eller sant er sant, sant eller usant er sant. Falsk eller sant er sant, usant eller usant er det eneste som faktisk er falske. Her er et eksempel som du bør vite som et ganske godt eksempel på når bitvis operatører brukes. Her hvis vi eller kapital 'A' med OX20, og vi skal se på disse i et sekund, får vi noe. Og hvis vi eller små bokstaver 'a' med OX20, får vi noe. Så la oss trekke opp ASCII-tabellen. Ok. Her ser vi at "A" er - her har vi 'A' er desimal 65. Men jeg skal gå med heksadesimale, som er Ox41. Ganske sikker på at vi så det i klassen. Jeg tror vi så det i klassen at det er ganske enkelt å konvertere fra heksadesimale til binære. Så her, hvis jeg ønsker å sette 4 i binær, som bare kommer til å være 0100. Dette er en plass, 2 plass, 4 plass, så dette er fire. Da kan jeg dele en i binær, som kommer til å være 0001. Og så dette kommer til å være representasjon av 'A' i binær. Tar små bokstaver 'a', det er nå kommer til å bli Ox61, der, dele disse opp i den binære, så en 6 - La oss faktisk gjør det - er det ingen viskelær? Viskelær. Ox61. Så splitte 6 i binær kommer til å være 0 + 4 + 2 + 0. Og splitting en kommer til å være 0001. Ser vi på forskjellen mellom disse to, vi ser at den eneste forskjellen mellom en små bokstaver og en kapital "A" er dette eneste bit. Så kommer tilbake til her - greit. Kommer tilbake til her, hvis vi ser på hva den litt OX20 er, så splitting OX20 inn sin binære, er 0010, 0000. OX20, den eneste bit som er satt er dette litt som vi er opptatt av, med veksling mellom kapital og små bokstaver 'a'. Hvis jeg eller 'A', som er denne, 'A', hvis jeg eller 'A' med OX20, hva skal jeg bli? [Student, uhørlig] Små bokstaver 'a', fordi det kommer til å snu dette litt til en 1. Og hvis jeg eller 'a' med OX20, hva jeg kommer til å få? Små bokstaver a, fordi bare ORING 'a' med OX20, Jeg skal bare være ORING dette enkelt bit til en 1, det er allerede en en, så det spiller ingen rolle. Så vi får 'a' og 'a'. Bitwise og. Igjen, kan vi tenke på dette som vår logiske og motpart. På venstre side har vi sann og ekte. Det kommer til å være sant, og for alle de tilfellene falsk og ekte eller sant og usant, eller falsk og usann, ingen av disse tingene er sanne. Så hva vi ender opp med å få er 1000. Så nå, her, her hvor jeg har brukt den trofaste bitvis ikke, hvor vi hadde OX20. Så dette er OX20. Nå hva jeg ønsker å gjøre, bitvis ~ av OX20. Det kommer til å snu alle biter. Så jeg har 1101, 1111. Og så 'A' anded med ~ OX20 kommer til å gi meg det? Den eneste bit vi virkelig trenger å tenke på er denne, siden, dersom alle disse biter er satt til 1, så vi kommer til å få akkurat det 'A' var, med unntak av eventuelt hva denne bit er. Fordi hvis det var en en, nå kommer det til å bli satt til en 0, fordi uansett hva dette er, anded med dette kommer til å være 0. Så hva er 'A' & ~ OX20 kommer til å gi meg? [Studentene svarer, ikke hørbar] Og hva er 'a' og - det er 'A'. Og hva er 'a' & ~ OX20 kommer til å gi meg? 'A.' Fordi dette er i dag en ett. Anding med dette 0 kommer til å gjøre det en 0, og nå skal vi få en 'A'. Begge er "A", og sist men ikke minst av denne typen, vi har XOR. Det er veldig mye som eller, bortsett fra at det betyr utelukkende eller. Dette er som det du vanligvis tenker på som eller i den virkelige verden. Så du gjør enten 'x' eller 'y', men ikke begge deler. Her en ^ 1 kommer til å være 0. Fordi sann, er dette - det fungerer ikke så bra med den logiske sant og usant som bitvis & og eller gjøre, men sant ^ sant er usant. Fordi vi bare ønsker å returnere true hvis bare én av dem er ekte. Så en ^ 1 er 0. Hva med 0 ^ 1? Er en. 1 ^ 0 er 1, 0 ^ 0 er 0. Så under alle omstendigheter, er 0 bitvis noe 0 kommer til å være 0. En bitvis noe 0 eller 0 bitvis 1, hvis det er | eller ^, vil det være en 1, og hvis det er og det vil være 0. Og det eneste tilfellet der en bitvis en er ikke en er med eksklusive eller. Det er 0110. Så her nå, ved hjelp av XOR - så vi er tilbake på 20. 'A' ^ OX20 er disse to biter vi sammenlikne. Så en 1 ^ 0 kommer til å gi meg en hva? En ett. 'A' ^ OX20 kommer til å gi meg? Små bokstaver en. 'A' ^ OX20 kommer til å gi meg? Capital A. Fordi hva dette gjør, dette XORing med OX20 er effektivt bla hva denne biten er. Hvis dette er en 0, er det nå kommer til å bli en en. Siden dette er en 1, 1 ^ 1 er 0. Så vår 'a' har blitt 'A', og vår 'A' har blitt 'a'. Så XOR er en veldig praktisk måte å bare bla saken. Du bare ønsker å iterere over en kombinasjon av bokstaver og veksle tilfelle av hver enkelt karakter, du bare XOR alt med OX20. Nå har vi igjen skiftet. Venstre shift er bare kommer til å, i utgangspunktet, skyve alle tallene inn, eller til venstre, og sette inn 0 er bak dem. Så her har vi 00001101. Vi kommer til å presse tre 0-tallet fra høyre, og vi får 01.101.000. I ikke-binær form, vi ser at det er virkelig arbeider 13 venstre-forskjøvet med tre, noe som gir oss 104. Så venstre skiftende, ser vi her, er x << y utgangspunktet x * 2 ^ y. 13 * 2 ^ 3, 2 ^ 3 er 8, slik at 13 * 8 er 104. Hvis du bare tenke på binære generelt, hvordan hvert siffer, Hvis vi starter fra høyre, er det en plass, deretter 2 plass, deretter 4 plass. Så ved å trykke på 0-er fra høyre, vi bare skyve ting som var i 4 plass til 8 plass, og ting som var i 8 plass til 16 plass. Hvert skift bare multipliserer med to. Yeah? [Student] Hva skjer hvis du forskjøvet med 5? [Bowden] Hvis du forskjøvet med 5 ville du bare miste sifre. Uunngåelig, er det det samme. Som, heltall er bare 32 bits, så hvis du legger to virkelig store heltall, det bare ikke passer i et heltall. Så det er det samme her. Hvis du forskjøvet med 5, vi ville bare miste den. Og det er litt av hva jeg mener med "grovt," der hvis du flytter for langt, mister du biter. Høyre shift kommer til å være det motsatte, hvor vi kommer til å skubbe 0 er off slutten, og for vårt formål, fyll inn 0-er fra venstre. Så gjør dette, er vi i utgangspunktet reversere det vi allerede hadde gjort. Og vi ser at de tre 0-er på rett har nettopp falt av, og vi har presset 1,101 hele veien mot høyre. Dette gjør 104 3, som er effektivt, x / 2 ^ y. Så nå, her er det en lignende idé. Hvorfor er det bare omtrent x / 2 ^ y, og ikke faktisk x / 2 ^ y? Fordi hvis jeg hadde flyttet med fire, ville jeg ha mistet en. Innerst inne, hva du tenker på, bare tenk på heltallsdivisjon generelt. Så, som 5/2 er to. Det er ikke 2,5. Det er den samme ideen her. Når vi deler med to, vi kan miste merkelig biter underveis. Så nå - det er det for bitvis. Det er alt du trenger å vite. Husk bruken sakene vi så i klassen, som litt maske er nyttig for bitvis operatører, eller du bruker dem for bit masker. Store bokstaver og små bokstaver, konverteringer er en ganske prototypisk eksempel. Ok, så buffer overflow angrep. Noen som husker hva som var galt med denne funksjonen? Legg merke vi erklært en rekke 12 bytes, 12 tegn, og da vi kopierer inn vår buffer på 12 chars hele strengen bar. Så hva er problemet her? Det magiske tallet 12 skal ganske mye umiddelbart sprette ut som - hvorfor 12? Hva hvis bar skjer for å være mer enn 12 tegn? Hva hvis baren er millioner av tegn? Her er problemet memcpy. Hvis linjen er lang nok, det vil bare helt - 'c', 'c' bryr seg ikke om at det var bare 12 tegn; 'C' bryr seg ikke at det ikke kan passe på at mange bytes. Det vil bare helt overskrive røye, de 12 bytes vi har avsatt til det, og alt forbi det i minnet som ikke egentlig hører til at buffer med hva strengen linjen er. Så dette var det bildet vi så i klassen der vi har vår stabel vokser opp. Du bør være vant til disse bildene, eller bli kjent med dem igjen. Vi har vår stabel vokser opp, minneadresser starter på 0 på toppen og vokse ned å like 4 milliarder nederst. Vi har vår matrise 'c' et sted i minnet, da har vi vår pekeren til bar rett under den, og så har vi dette lagret ramme pekeren i vår returadresse og vårt moder rutine stack. Husk hva returadresse er? Det er når hoved kaller en funksjon foo, kaller en funksjon bar, uunngåelig, bar avkastning. Så da bar avkastning, de trenger å vite at det kommer tilbake til foo som kalte det. Så returadresse er adressen til den funksjonen at den har å gå tilbake til når funksjonen returnerer. Grunnen som er viktig for buffer overflow angrep er fordi, praktisk, hackere liker å endre det returadresse. I stedet for å gå tilbake til foo, kommer jeg til å gå tilbake dit hacker vil ha meg til å gå tilbake til. Og, beleilig, hvor hacker ofte ønsker å gå tilbake til er starten på bufferen som vi opprinnelig hadde. Så legger merke til, igjen, Little Indian. Apparatet er et eksempel på en Little Indian system, så et heltall eller en peker lagres med byte reversert. Så her ser vi - er dette? Yeah. Vi ser Ox80, OxC0, Ox35, OxO8. Husk de heksadesimale siffer? Vi trenger ikke reversere de heksadesimale siffer i Little Indian, fordi to heksadesimale siffer utgjør en enkelt byte, og vi reversere bytes. Det er derfor vi ikke lagre, som, 80530CO8. Vi lagrer, i stedet, hvert par av to siffer, med start fra høyre. At adresse refererer til adressen til start av vår buffer som vi faktisk ønsket å kopiere inn i første omgang. Grunnen til det er nyttig er fordi, hva hvis den angriper skjedde med, i stedet for å ha en streng som var bare en ufarlig rekke lignende, deres navn eller noe, hva om, i stedet, at strengen var bare noen vilkårlig kode som gjorde hva de ville at den skulle gjøre? Så de kunne - Jeg kan ikke komme på noen kule kode. Det kan være hva som helst, skjønt. Enhver katastrofal kode. Hvis de ville, kunne de bare gjøre noe på segmenter feil, men det ville være meningsløst. De pleier å gjøre det for å hacke systemet ditt. Ok. CS50 bibliotek. Dette er, i utgangspunktet, getInt, getString, alle de funksjonene vi gitt for deg. Så vi har char * streng, og det er den abstraksjon som vi blåste bort på et tidspunkt i løpet av semesteret. Husk at en streng er bare en rekke tegn. Så her ser vi en forkortet versjon av getString. Du bør se tilbake på det å huske hvordan det faktisk blir gjennomført. Viktige detaljer er, merker vi får i et enkelt tegn om gangen fra standard i, som er akkurat som oss å skrive på tastaturet. Så et enkelt tegn om gangen, og hvis vi får for mange tegn, slik at hvis n + 1 er større enn kapasiteten, Da må vi øke kapasiteten vår buffer. Så her er vi dobler størrelsen på vår buffer. Og det fortsetter å gå, vi sette inn tegnet inn vår buffer inntil vi får en ny linje eller slutten av filen eller hva, i så fall er vi ferdige med strengen og deretter den virke getString krymper minnet, som hvis vi tildelt for mye minne det vil gå tilbake og krympe litt. Så vi ikke viser det, men hovedideen er det har å lese i en enkelt tegn om gangen. Det kan ikke bare lese i en hele greia på en gang, fordi deres bufferen er bare av en viss størrelse. Så hvis strengen at den prøver å sette inn i buffer er for stor, så det ville renne over. Så her er vi forhindre at ved bare å lese i en enkelt karakter om gangen og voksende når vi må. Så getInt og de andre CS50 biblioteket funksjoner pleier å bruke getString i sine implementeringer. Så jeg uthevet de viktige tingene her. Det kaller getString å få en streng. Hvis getString unnlatt å returnere minne, husk at getString mallocs noe, så når du ringer getString du bør ikke (uforståelig) frigjøre strengen som du fikk. Så her, hvis det ikke klarte å malloc noe, returnerer vi INT_MAX som bare et flagg som, hei, vi var faktisk ikke i stand til å få et heltall. Du bør ignorere hva jeg kommer tilbake til deg, eller du bør ikke behandle dette som en gyldig inngang. Til slutt, forutsatt at det lyktes, bruker vi sscanf med den spesielle flagg, som betyr først matche et heltall, deretter med noen tegn etter at heltall. Så oppdager vi ønsker den skal være lik en. Så sscanf avkastning hvor mange kamper hvis hell laget? Den vil returnere en hvis det lykkes matchet et heltall, det vil returnere 0 hvis det ikke samsvarte med et heltall, og det vil returnere 2 Hvis det passet et helt tall etterfulgt av noen tegn. Så merker vi prøve på nytt hvis vi matche alt annet enn en. Så hvis vi angitt 1, 2, 3, C, eller 1, 2, 3, X, deretter 1, 2, 3 vil bli lagret i det hele tall, X ville bli lagret på karakteren, sscanf ville returnere to, og vi ville prøve på nytt, fordi vi bare ønsker et heltall. Raskt blåser gjennom HTML, HTTP, CSS. Hypertext Markup Language er strukturen og semantikk av nettet. Her er et eksempel fra foredrag der vi har HTML-koder. Vi har hodet kodene, kropps koder, Vi har eksempler på tomme koder der vi faktisk ikke har en start og sluttkode, vi bare har link og bilde. Det er ingen avsluttende bildekode, det er bare en enkelt kode som oppnår alt tag trenger å gjøre. Koblingen er et eksempel, vi får se hvordan du kobler til CSS, skriptet er et eksempel på hvordan du kobler til en ekstern Javascript. Det er ganske grei, og husk, HTML er ikke et programmeringsspråk. Her må du huske hvordan du vil definere en form eller i det minste hva dette ville gjøre? En slik form har en handling og en fremgangsmåte. Metodene du vil bare noensinne se er GET og POST. Så GET er den versjonen der ting blir satt i nettadressen. POST er der det ikke er satt i nettadressen. I stedet, noen data fra skjemaet er satt inn mer skjult i HTTP-forespørsel. Så her, definerer handling der HTTP-forespørsel går. Hvor det kommer er google.com / search. Metode. Husk forskjellene mellom GET og POST, og, bare si som et eksempel, hvis du ønsker å bokmerke noe. Du vil aldri være i stand til å bokmerke en POST URL fordi dataene ikke er inkludert i nettadressen. HTTP, nå, er Hypertext Transfer Protocol. Hypertext Transfer Protocol, ville du forventer det å overføre Hypertext Markup Language, og det gjør det. Men det også overfører noen bilder du finner på nettet, noen nedlastinger du gjør starte som en HTTP-forespørsel. Så HTTP er bare språket i World Wide Web. Og her må du kjenne igjen denne typen en HTTP-forespørsel. Her HTTP/1.1 på siden bare sier det er den versjonen av protokollen jeg bruker. Det er stort sett alltid kommer til å være HTTP/1.1, som du får se det. Da ser vi at dette var GET, alternativet er POST, som du kan se. Og nettadressen som jeg prøvde å besøke var www.google.com/search?q = blah, blah, blah. Så husk at dette spørsmålstegnet q = blah blah blah, er den slags ting som er sendt inn av en form. Responsen det kanskje tilbake til meg vil se omtrent slik ut. Igjen, starter med protokollen, noe som kommer til å være det, etterfulgt av statuskoden. Her er det 200 OK. Og til slutt, vil nettsiden at jeg faktisk ba om bli fulgt. Den mulige statuskode du kan se, og du bør vite flere av dem. 200 OK du har sikkert sett før. 403 Forbidden, 404 Not Found, 500 Internal Server Error er vanligvis hvis du går til et nettsted og noe er ødelagt eller deres PHP-kode krasjer, mens i apparatet har vi den store oransje boks som kommer opp og sier, som er noe galt, betyr denne koden fungerer ikke eller denne funksjonen er ille. Vanligvis nettsteder ikke ønsker du å vite hvilke funksjoner er faktisk dårlig, så i stedet de vil bare gi deg 500 Intern serverfeil. TCP / IP er en lag under HTTP. Husk at det er Internett utenfor av World Wide Web. Som hvis du spiller et online spill som ikke går gjennom HTTP, det er å gå gjennom en annen - det er fortsatt bruk av Internett, men den ikke bruker HTTP. HTTP er bare ett eksempel på protokoll bygget på TCP / IP. IP bokstavelig betyr Internet Protocol. Hver datamaskin har en IP-adresse, de er de fire-sifrede ting som 192.168.2.1, eller hva, som har en tendens til å være en lokal en. Men det er et billede av en IP-adresse. Så DNS, Domain Name Service, det er det som betyr ting som google.com til en faktisk IP-adresse. Så hvis du skriver at IP-adressen inn i en URL, som ville bringe deg til Google, men du har en tendens til ikke å huske disse tingene. Du har en tendens til å huske google.com i stedet. Det siste vi har er porter, der dette er TCP del av IP. TCP gjør mer. Tenk om, som, du har din nettleser kjører. Kanskje du har noen e-postprogrammet kjører; kanskje du har noen andre program som bruker Internett i gang. De trenger tilgang til Internett, men datamaskinen har bare en WiFi-kort eller hva. Så porter er den måten at vi er i stand til å splitte opp hvordan disse programmene er i stand til å bruke Internett. Hver søknad får en bestemt port at det kan lytte på, og som standard, bruker HTTP port 80. Noen e-posttjenester bruker 25. Den lave-nummerert de pleier å være reservert. Du er vanligvis i stand til å få høyere nummererte dem for deg selv. CSS, Cascading Style Sheets. Vi style nettsider med CSS, ikke med HTML. Det er tre steder du kan sette ditt CSS. Det kan være inline, mellom stil koder, eller i en helt egen fil og deretter koblet i. Og her er bare et eksempel på CSS. Du bør anerkjenne dette mønsteret, hvor det første eksempelet er vi matchende body-koden, og her er vi sentre body-koden. Det andre eksemplet, er vi matche ting med ID bunntekst, og vi søker noen stiler til det. Legg merke til at ID-bunntekst justerer til venstre, mens kroppen tekstjusterer sentrum. Bunntekst er inne i kroppen. Det vil, i stedet, text-align igjen, selv om kroppen sier text-align center. Dette er hele gripende del av det. Du kan ha - du kan angi stiler for kroppen, og deretter ting i kroppen kan du angi mer spesifikke stiler, og ting fungerer som du forventer. Mer spesifikke CSS bransjen forrang. Jeg tror det er det. [Ali Nahm] Hei alle sammen. Hvis jeg bare kunne få din oppmerksomhet. Jeg er Ali og jeg kommer til å gå gjennom PHP og SQL veldig fort. Så vi kan begynne. PHP er en forkortelse for PHP: Hypertext Preprocessor. Og som dere alle burde vite, det er en server-side skriptspråk, og vi bruker det for bakenden av nettsteder, og hvordan den gjør mye av beregningene, bak-kulissene del. Syntaks. Det er ikke som C, surprise, surprise. Det har alltid å starte med det, hvis du kan se, - jeg kan ikke gå videre. Du kan se du trenger nye typer tannregulering og da trenger du også det? Php. Det er alltid som man har til å ramme inn PHP tekst, din PHP-kode. Så det kan ikke bare være som C, hvor du på en måte sette den på første. Du må alltid omgir den. Og nå, er den viktigste syntaks at alle variabler må starte med $ tegn. Du må gjøre det når du definerer dem, du trenger å gjøre det når du refererer til dem senere. Du må alltid at $. Det er din nye bestevenn, ganske mye. Du trenger ikke - i motsetning til C, du trenger ikke å sette hva slags variabel type det er. Så mens du gjør trenger $, trenger du ikke å sette, som, int x eller streng y, etcetera, etcetera. Så en liten forskjell. Som et resultat av dette, så betyr det at PHP er et svakt type. PHP er et svakt typen språk, og det har svakt skrevet variabler. Med andre ord, det betyr at du kan bytte mellom ulike typer variable typer. Du kan lagre nummeret ditt en som en int, du kan lagre det som en streng, og du kan lagre det som en dupp, og det vil være at nummer 1. Selv om du lagrer den i ulike former, det er fortsatt - de variable typer er fremdeles holder til slutt. Så hvis du ser her, hvis du husker fra PSett 7, mange av dere sikkert har hatt problemer med dette. To like tegn, tre like tegn, 4 like tegn. Ok, det er ingen 4 like tegn, men det er to og tre. Du bruker to like tegn for å sjekke verdiene. Det kan du sjekke på tvers av typer. Så hvis du kan se på det første eksemplet, Jeg har num_int == num_string. Så din int og strengen er både teknisk, 1, men de er forskjellige typer. Men for de doble likemenn, vil det fortsatt passere. Men for trippel likemenn, sjekker den verdi samt de forskjellige typene. Det betyr at det ikke kommer til å passere i det andre tilfellet her, hvor du bruker tre like tegn i stedet. Så det er en stor forskjell at du bør alle har vist nå. String sammensetning er en annen mektig ting du kan bruke i PHP. Det er i utgangspunktet bare denne hendige dot notasjon, og det er hvordan du kan binde strenger sammen. Så hvis du har katt, og du har hund, og du ønsker å sette de to strenger sammen, du kan bruke den perioden, og det er litt av hvordan det fungerer. Du kan også bare plassere dem ved siden av hverandre, som du kan se her i bunnen eksempel hvor jeg har ekko streng 1, plass streng to. PHP vil vite å erstatte dem som sådan. Arrays. Nå, i PHP, det er to forskjellige typer av matriser. Du kan ha vanlige arrays, og du kan også ha assosiative arrays, og vi kommer til å gå gjennom dem akkurat nå. Regelmessige arrays er nettopp dette i C, og så du har indekser som er nummerert. Akkurat nå er vi bare nødt til å lage en og sagt - så dette er hvordan vi skaper en tom array, så vi kommer til å sette inn indeksnummeret 0. Vi kommer til å sette nummer seks, verdien seks. Du kan se det på bunnen her. Where's - på indeksnummer 1 skal vi sette verdien nummer fire, og slik at du kan se det er en seks, det er en fire, og deretter som vi skriver ut ting, når vi prøver og skrive ut verdien som er lagret på indeksnummer 0, så får vi se verdien seks som skrives ut. Cool? Så det er vanlige arrays for deg. En annen måte du kan også legge ting til vanlige arrays nå er kan du bare legge dem på slutten. Det betyr at du ikke trenger å spesifisere nærmere angitt indeks. Du kan se nummer, og deretter i klammeparenteser er det ingen indeks spesifisert. Og det vil vite - PHP vil vite å bare legge det til slutten av listen, den neste gratis spot. Så du kan se en rett der på at 0 spot, de to gikk der på første plass. Den tre går - er lagt der også. Så den slags er fornuftig. Du er bare tiden legger det, og deretter når vi ekko indeksen av nummer 1, det vil skrive ut verdien to. Da har vi arrays som er assosiative arrays. Assosiative arrays, i stedet for å ha numeriske indekser, hva de gjør er, de har indekser som er av strengen. Du kan se, i stedet for - jeg ble kvitt alle disse tallindekser, og nå er det nøkkel1, TAST2, TAST3, og de er i anførselstegn for å markere at de er alle strenger. Så vi kan ha et eksempel på dette. Det eksempel på dette er at vi har tf, og det er indeksnavnet. Vi kommer til å sette "Ali" som navn, på indeksen, kalorier spist, vi kan sette en int denne gangen i stedet for en streng, og deretter på indeks liker, kan vi sette en hel rekke innsiden av det. Så dette er slags - det er et lignende konsept til hvordan vi hadde indekser med tall, men nå kan vi endre indeksene rundt å ha dem som strenger i stedet. Du kan også gjøre dette, i tillegg til bare å gjøre det individuelt, du kan gjøre alt i én klump. Så du kan se at tf av denne matrisen, og da vi satt dem alle i én gigantisk hakeparentes sett. Så det kan øke hastigheten ting opp. Det er mer av et stilistisk valg enn ikke. Vi har også løkker. I C har vi looper som fungerer som dette. Vi hadde vår rekke, og vi gikk fra indeks 0 til slutten av listen, og vi skriver ut det hele, ikke sant? Bortsett problemet er, for assosiative arrays, vi ikke nødvendigvis vet de numeriske indekser fordi nå har vi de streng indeksene. Nå bruker vi foreach løkker, som, igjen, du forhåpentligvis brukes i PSett 7. Foreach løkker vil bare vite hver eneste del av listen. Og det trenger ikke å vite nøyaktig numerisk indeks som du har. Så du har foreach syntaks, så det er foreach, du putter matrisen. Så min matrise kalles PSett, og deretter som, ordet som, og deretter sette denne lokale midlertidig variabel som du kommer til å bruke bare for den spesifikke ting som kommer til å holde den spesifikke - en forekomst eller en del av matrisen. PSett num vil holde en, og så kanskje det vil holde nummer seks, og da vil det holde nummer 2. Men det er garantert å gå gjennom hver enkelt verdi som er i matrisen. Nyttige funksjoner som du bør vite i PHP er den krever, slik som sørger for at du er inkludert visse filer, ekko, exit, tom. Jeg anbefaler at du ser på PSett 7 og se på disse funksjonene. Du har kanskje kjent med dem, så jeg ville definitivt vet hva, akkurat, de alle gjør. Og nå skal vi gå gjennom omfanget veldig raskt. I omfang, er PHP slags funky ting, i motsetning til C, og så vi bare kommer til å gå gjennom det raskt. Så la oss si at vi starter på den pilen som vi har der. Og vi kommer til å starte med $ i. Så variabelen 'i' kommer til å være 0, og vi bare kommer til å fortsette å skrive det i det store hvite boksen der borte. Vi kommer til å starte med i0, og så skal vi til ekko det. Så det er 0. Og så kommer vi til å øke den ved for loop, og da kommer det til å være verdien av en. Den ene er mindre enn tre, så det kommer til å passere gjennom den for loop, og da skal vi se det skrevet ut igjen. Vi kommer til å øke den igjen til 2, og to er mindre enn tre, så det vil passere for loop, og det vil skrive ut to. Da vil du merke at 3 er ikke mindre enn tre, så vi vil bryte ut av for-løkken. Så nå har vi gått ut, og da vi kommer til å gå inn aFunction. Ok. Så du må være oppmerksom på at denne variabelen at vi har opprettet, 'i' variabel, ikke er lokalt scoped. Det betyr at det ikke er lokale til løkken, og den variabelen vi kan fortsatt få tilgang til og endre etterpå, og det vil fortsatt være effektiv. Så hvis du går inn i funksjonen nå, vil du se at vi også bruke "jeg"-variabelen, og vi kommer til å øke 'i' + +. Du skulle tro ved første, basert på C, at det er en kopi av "jeg"-variabelen. Det er en helt annen ting, som er korrekt. Så når vi skriver det, kommer vi til å skrive ut 'i' + +, noe som kommer til å skrive ut som fire, og deretter skal vi - beklager. Så får vi kommer til å ende ut av denne funksjonen, og vi kommer til å være der som pilen er akkurat nå. Det vil si at da har imidlertid selv om funksjonen endres verdien av 'i', det endret ikke utenfor funksjonen, fordi funksjonen har en separat omfang. Det betyr at når vi echo 'i', det har ikke forandret seg i det omfanget av funksjonen, og så så vi kommer til å skrive ut tre igjen. Forskjellige ting om omfanget i PHP enn i C. Nå i PHP og HTML. PHP brukes til å lage websider dynamisk. Det gjør slags ting annerledes. Vi har det forskjellig fra HTML. Med HTML, vi alltid bare har det samme statiske ting, som hvordan Rob viste, mens PHP, kan du endre ting basert på hvem brukeren er. Så hvis jeg har dette, jeg har, "Du er logget inn som -" og deretter navnet, og jeg kan endre navnet. Så akkurat nå navnet er Joseph, og det har den "om meg", men så kan jeg også endre navnet å ha Tommy. Og det ville være en annen ting. Så da kan vi også endre forskjellige ting om ham, og det vil vise forskjellig innhold basert på navnet. Så PHP kan slags endre hva som skjer på nettstedet ditt. Samme her. Men merk at de har forskjellig innhold, selv om du er teknisk sett fortsatt tilgang til den samme nettsiden på overflaten. Genererer HTML. Det er to forskjellige måter du kan gjøre dette. Så får vi gå gjennom det akkurat nå. Den første måten er, du har - ja, beklager. Så må du bare din vanlige for loop i PHP, og deretter du ekko i PHP, og du ekko ut HTML. Bruke hva Rob viste deg av HTML script og deretter bruke PHP print å bare skrive det ut til websiden. Alternativet måten er å gjøre det som om du skille ut PHP og HTML. Så du kan ha en linje av PHP som starter for loop, så kan du ha linjen av HTML i en egen ting, og så ender du sløyfen, igjen, med en PHP. Så det er slags skille det ut. På venstre side, kan du at du har all den - det er bare en del av PHP. På høyre side kan du se at du har en linje av PHP, du har en linje med HTML, og du har en linje med PHP igjen. Så skille det ut i hva de gjør. Og du vil merke at uansett, for en av dem, de fremdeles skrive ut bildet, bildet, bildet, slik at HTML fortsatt skrives på samme måte. Og da vil du fortsatt se de tre bildene vises på nettstedet ditt. Så det er to forskjellige måter å gjøre det samme. Nå har vi former og forespørsler. Som Rob viste deg, det finnes former for HTML, og vi vil bare sus gjennom dette. Du har en handling og du har en metode, og din handling slags viser deg hvor du skal sende den, og metoden er om det kommer til å være en GET eller et POST. Og en GET-forespørsel, som Rob sa, betyr at du kommer til å sette den i en form og du vil se det som en URL, mens en POST-forespørsel vil du ikke se i en URL. Så en liten forskjell. Men en ting som er en lignende ting er at POST og GET er like usikker. Så du kan tro at bare fordi du ikke ser det i nettadressen, det betyr at POST er sikrere, men du kan fortsatt se det i informasjonskapslene i den informasjonen som du sender. Så tror ikke at om det ene eller det andre. En annen ting å merke seg er at du har også seksjons variabler. Dere brukte dette i PSett 7 for å få din bruker-ID informasjon. Det som skjedde var at du kan bruke denne assosiativ array, den $ _SESSION, og da er du i stand til å få tilgang til forskjellige ting og lagre forskjellige ting på tvers av sider. Siste ting er at vi har SQL, Structured Query Language, og dette er et programmeringsspråk for å administrere databaser. Hva, nøyaktig, er databaser? De er samlinger av tabeller, og hvert bord kan ha lignende typer objekter. Så vi hadde en tabell med brukere i finans PSett. Og hvorfor er de nyttige? Fordi det er en måte å permanent lagring av informasjon. Det er en måte å spore ting og administrere ting og faktisk se det på forskjellige sider og holde styr. Mens hvis du bare lagre det på at en umiddelbar øyeblikk og deretter bruke den senere, vil du ikke kunne få tilgang til noe som du har lagret. Vi har fire store ting som vi bruker for SQL-kommandoer. Vi har å velge, sette inn, slette og oppdatere. De er veldig viktig for dere å vite for quiz. Vi vil raskt gå over velger akkurat nå. I utgangspunktet, du velge rader fra en database. Så hvis du har, akkurat her - vi har disse to forskjellige ting, og vi ønsker å velge fra klassene tabellen hvor awesome - hvor i fantastisk kolonnen verdien er en. Så du kan se her, har vi disse to tingene i klassenavnet, CS50 og STAT110, og vi har klasse IDer og slagordet. Så vi ønsker å velge all denne informasjonen. Da kan du se her at det er slags plukke ut av det kjempebra kolonnen, hvor alle ting er ett, og deretter den har klassen ID, klasse navn og slagord som den kan plukke ut. Hvor nøyaktig kan du gjøre dette i koden? Du må bruke PHP. Så det er slags hvordan PHP og SQL er relatert til hverandre. Nå har vi vår kode, og vi kommer til å bruke vår spørring funksjon som vi gjorde i PSett 7, og vi kommer til å kjøre SQL-spørringen. Så skal vi ha - vi alltid må sjekke om rad trippel lik hvis usann. Så igjen, du vil sjekke hvilken type og verdi, og hvis det ikke fungerer, så du ønsker å be om unnskyldning, som vanlig, slik vi gjorde i PSett 7. Ellers vil du sløyfe gjennom alt med dem hendig foreach løkker at vi bare gikk over. Nå som vi er looping gjennom, og vi har gjort det siste, la oss anta at vår spørring passert, nå har vi vår foreach loop. Og den første raden den har, så her er rad, akkurat her, det er eske. Det kommer til å skrive ut all informasjon som det er blitt. Så det kommer til å skrive ut på bunnen "Wanna Lær HTML?" Så det kommer til å gå til neste rad, fordi det er fullført den første for-løkken, og så så det kommer til å skrive ut den andre linjen av det, som kommer til å være STAT110, Finn alle Moments. En siste ting er på SQL Vulnerabilities. Jeg vet David berørt dette litt i forelesningen. Du kan lese dette senere. Det er virkelig morsomt. SQL Injection er en slags vanskelige ting. La oss si at du bare holde disse variablene rett inn i søket, som du kan se i den første linjen. Så det virker fint, ikke sant? Du er bare å sette inn brukernavnet og passord til din SQL-spørring, og du ønsker å sende den av og få alt som er i datatabellen. Det virker ganske enkelt. Så kan si noen setter inn, for passordet, dette ELLER teksten her - bør faktisk være i den røde boksen. Så la oss si at de satt som passord i - det er det de kommer inn. Så de legger OR "1" = 1. Slag av en dum passord for å ha. Nå la oss bare erstatte den i, og du vil merke at i at SQL-spørring nå, det vurderer å alltid sant, fordi du vil merke at du kan SQL-spørring velge all denne informasjonen eller du kan bare ha 1 = 1. Slik at det alltid kommer til å vurdere å true. Det kommer ikke til å virkelig jobbe, fordi det betyr at hackeren kan bryte seg inn i systemet ditt. Løsningen på dette er at du må bruke PUD-systemet, noe som betyr at du må bruke spørsmålstegn, som er det du brukte i PSett 7, hvor du kommer til å bruke et spørsmålstegn i stedet for hvor du ønsker å sette noe, og så kommer du til å ha et komma, og da vil du ha etterpå, etter streng, til de ulike variablene som du vil bytte inn din spørsmålstegn. Så du vil merke seg her at nå har jeg disse røde spørsmålstegn. Da jeg satte variablene etter mine strenger så jeg vet å erstatte dem i den rekkefølgen etterpå. Det vil sørge for at hvis noen gjør det slik, og de har den eller en = en situasjon, som vil sørge for, i bakenden, sørg for at det ikke vil faktisk bryte SQL-spørringen. Ok, så det er ganske mye det, en virvelvind av PHP og SQL. Lykke til alle dere, og nå til Ore [Oreoluwatomiwa Babarinsa] Ok alle. På tide å gå over noen Java og noen andre ting veldig fort, så vi trenger ikke holde deg i kveld. Javascript. Ja. Javascript er slag av en kul ting, angivelig. De tingene du virkelig trenger å vite om Javascript, er det liksom som klientsiden slutten av hva din web app kommer til å gjøre. Det er noen ting du bare ikke ønsker å ta vare på hele tiden på serversiden. Alle de små interaksjoner, fremhever en ting, og gjør noe forsvinner. Du virkelig ikke ønsker å ha til å snakke med serveren din hele tiden for det. Og noe av det er ikke engang mulig å gjøre på serversiden. Dette er grunnen til at vi trenger noe som Javascript. Kule ting om Java: Det er dynamisk skrevet. Hva dette betyr er at programmet ikke trenger å vite hva, akkurat, variablene er når du skriver det ut. Det vil bare liksom finne det ut som den kjører. Andre ting som er kult om det: Det er en klammeparentes språk, noe som betyr at syntaksen er lik C og PHP. Du trenger ikke å gjøre mye ekstraarbeid når du lærer Javascript. Her har vi en liten bit av Javascript. Interessant ting her er at hvis du ser på det, vi har en bit av Java rett der i hodet tag. Hva er ikke er i utgangspunktet bare omfatter en Javascript-fil. Dette er en måte du kan inkludere Java inn i programmet. Da den andre litt er faktisk noen inline Javascript, svært lik en innebygd stil med CSS, og du bare å skrive noen kode svært raskt der. Javascript har arrays. Bare en annen måte å holde data rundt, veldig nyttig. Veldig fin og enkel syntaks. Du bruker hakeparenteser for å få tilgang til alt og holde alt sammen. Ingenting er for komplisert. Den kule ting om Javascript og skriptspråk generelt er at du ikke trenger å bekymre deg for array-størrelser. Du kan bare bruke tabell.length og holde styr på det, og også matrisen kan vokse eller krympe når du trenger det til. Så trenger du ikke engang trenger å bekymre deg for noen form for, oh no, jeg trenger å bevilge flere ting, eller noe sånt. Det kule her er at Javascript har noe som kalles gjenstander. Det er et objektorientert språk, så hva det har er, i hovedsak, en måte for deg å gruppere data sammen, noe som ligner på en struct, men du kan få tilgang til det som en struct eller i en assosiativ array syntaks. Det er ganske enkelt, og hva du kan gjøre med dette er gruppen data sammen hvis du har en haug med data som er relatert. Fordi det er alle de tingene du trenger for å beskrive en bil, du trenger ikke å ha det i en haug med forskjellige steder. Du kan bare stikke den inn i en objekt i Javascript. Som du sikkert vet, er itera en av de kjedelige oppgavene. Du bare gjør det over en igjen. Du trenger å snakke med hver gjenstand i bilen, eller du trenger å gå gjennom hvert eneste element i en liste eller noe sånt. Så Java har, i likhet med PHP, en foreach syntaks. I dette tilfellet er det et for i loop. Du ønsker å bruke dette bare på objekter. Det er noen problemer som oppstår hvis du bruker dette på arrays. Det er vanligvis en av de tingene, skjønt, er at svært nyttig, fordi du eliminere mye av overhead fordi du ikke trenger å trekke opp alt i objektet selv. Du trenger ikke å huske alle de viktigste navnene. Du bare liksom få dem tilbake i denne syntaksen. I dette, med for, du bare ønsker å huske at du får tilbake alle nøklene, i en svært lik måte til hasj tabellen. Hvis du husker fra det, når du vil sette inn en streng du kan få noe ut som vil ha en tilknyttet verdi med den. Hva du kan gjøre med dette er at du kan si, all right, Jeg satt i en bil, og jeg kalte det en Ferrari. Så du kan sette i strengen Ferrari igjen senere, og du kan få det ut. Og du kan gjøre det i en sløyfe, med for i loop. Så bare mer om stedene. Nøkkelen ting fra dette må du huske er at du kan bruke objektet struct som syntaks når du vil med disse, unntatt hvis hva du kommer til å bruke som en streng er ikke et gyldig variabelnavn. Så hvis du ser på det der, har vi nøkkelen med mellomrom. Vel, hvis du skulle sette object.key, plass, med, mellomrom, mellomrom, som bare ikke ville være fornuftig syntaktisk. Slik at du bare kan gjøre det med denne typen brakett syntaks. Dessuten er Java svært omfang-messig til PHP. Du har to måter å møte omfang. Du kan ikke ha VaR foran en variabel, og det betyr bare dette er global. Du kan se den fra hvor som helst. Selv om du skulle sette dette i en if setning, noe annet sted i koden etter det punktet du kunne se at variabelen. En annen ting, skjønt, er med var, det er begrenset til hva funksjonen du er i. Hvis du ikke er i en funksjon, vel, det er global. Men hvis du er i en funksjon det er bare synlig innenfor den funksjonen. Jeg har ikke et eksempel, men, ja. Det er en av de tingene der du kan styre hva variablene du ønsker å være global, hva variablene du ønsker å være lokale, men du trenger å være forsiktig med dette, fordi du ikke har den type finkornet kontroll du gjør i C, der hvis noe er deklarert i en for loop, det kommer til å bo i det for loop. Saken vi faktisk bryr seg om å bruke Javascript for er manipulere websider, ikke sant? Jeg mener, det er derfor vi gjør dette. For å gjøre det, vi bruker noe som kalles DOM. The Document Object Model. Innerst inne, hva den gjør er det tar all din HTML og modeller det ut i en haug med gjenstander som er nestet i hverandre. Du starter med noe sånt som dette. Du har, på høyre for meg, en haug med kode der ute som er liksom - Du skulle tro at ville være svært vanskelig å manipulere, fordi du ville bli parsing gjennom en haug med tekst og måtte sette fra hverandre ting. Og hva om det ikke var riktig formatert? Dårlige ting ville skje. Så Java tar seg av dette for deg, og du får en fin datastruktur, som en på min venstre side, der du bare har et dokument, og inne at du har noe som kalles HTML, og inne at du har et hode og en kropp, og inne i det hodet du har en tittel, etcetera, etcetera, etcetera. Dette forenkler manipulere en nettside, slik at det er bare, oh, jeg vil bare snakke til dette objektet. Sortering av en svært lik måte som du ville snakke med et annet objekt du har laget selv. Som jeg sa, er alt DOM i dokumentobjekt. Enten det er bare ett sted, og så kan du gå i det å finne ting, og du kan gjøre det - dette er den gamle stil å gjøre det, der oppe, hvor du gjør document.getElementById, og deretter navnet, og som du kan sikkert fortelle, blir dette veldig uhåndterlig etter en stund. Så har du sannsynligvis ikke vil gjøre det. Det er derfor vi har neste ting vi kommer til å snakke om etter dette. Det viktigste her er at, ok, du har alle disse elementene, ikke sant? Så kanskje jeg kan endre fargen på noe når siden lastes. Så hva? Hva om min bruker klikker noe? Jeg vil at det skal gjøre noe interessant når de klikker noe. Det er derfor vi har arrangementer. Du kan, i utgangspunktet, finner noe element i DOM, og deretter si hei. Når dette laster eller noen klikker det, eller når de musen over det, gjør noe med det. Og hva du har er, du har funksjoner som håndterer dette for deg. Disse funksjonene er hendelsesbehandlinger. Hva they're - det er bare en fancy måte å si, Denne funksjonen er kun utført når denne hendelsen skjer. Så det håndterer hendelsen som inntreffer. Dette er hvordan du ville legge ut en hendelseshåndterer. Jeg har litt knapp, og når du klikker på den, eksploderer det. Så ikke klikk på knappen. Dette er en måte å tilnærme seg det, ikke sant? Du har en knapp tag, og på klikk du har en streng som sier: oh, forresten, jeg gjør dette eksploderende tingen for meg. Ellers er det akkurat som en vanlig knapp du nettopp laget. Du kan også gjøre dette på en annen måte, ved å gripe tak i DOM-element, men sparer vi at etter at vi snakker om jQuery. JQuery: Det er et bibliotek som er kryss-nettleser. Du kan bruke det i stort sett alt. Og det bare gir deg en rekke verktøy for å arbeide med. Fordi Javascript, mens kraftig, har ikke alle de verktøyene du trenger ut av boksen for å virkelig takle en web app du kanskje ønsker å gjøre. Så det forenkler en del ting, gir deg en rekke funksjoner ut av boksen som du normalt ville ha til å skrive selv, om og om og om igjen. Og bare gjør ting veldig enkelt. Du har også velgere, som lar deg ta ut alle de elementene fra din DOM mye mer rett og slett, i stedet for å måtte bruke disse svært lange funksjonskall. Mer om disse velgere. Du har, opp der du har, la oss si Jeg ønsker å få et element med ID "rock". Vel, i jQuery, det er bare $ og deretter en streng som har en halvkilo, og deretter "rock". Det er veldig enkelt og mye raskere enn den tradisjonelle Java måte å takle dette problemet. Og du har lignende ting for klasser og elementtyper. jQuery er - en av de kule funksjonene er at du kan liksom komprimere ned dine spørsmål om din DOM veldig, veldig fort. Nå er vi tilbake til hendelseshåndtering, og dette er hvordan du ville håndtere en hendelse i jQuery. Så hva skal vi her er vi sier, all right. Jeg har et script tag, ikke sant? Så jeg har denne inline Javascript. Hva vi skal gjøre er at vi kommer til å si, all right. Når dokumentet er ferdig, noe som betyr at dokumentet er blitt lastet, vi kommer til å gå inn til den funksjonen, og vi kommer til å si, all right, denne funksjonen er faktisk å gjøre noe annet. Det har i utgangspunktet si, ok, får meg elementet med ID "myid." Og så gir dette en funksjon handler som utføres når du klikker på det. I utgangspunktet hva dette betyr er, det sier alt rett. Den siden er lastet, så jeg kommer til i, finner dette elementet, gi det denne hendelsen handler, og det i utgangspunktet setter opp siden din for deg. Og dette er hvordan du ønsker å tenke på hendelsen håndtering. Du bare ønsker å tenke på, all right, når noe skjer, hva ønsker jeg å skje? Du ønsker ikke å tenke på, ok, jeg trenger å sørge for at denne tingen snakker til denne tingen, denne tingen blah blah blah, fordi du bare ønsker å snakke ting i form av arrangementer. Når dette skjer, så skjer dette. Når dette skjer, så skjer det. Og hvis ting utløse andre ting, det er flott. Men du ikke ønsker å prøve og gjøre komplisert kode hvor du utløser flere ting samtidig, fordi du bare kommer til å gi deg hodepine. Greit. Nå kan vi få vår side til å håndtere hendelser, men la oss si at min bruker klikker på en knapp. Hva om jeg ønsker å sende denne anmodningen tilbake til serveren, men jeg ønsker ikke å laste siden på nytt, fordi å måtte laste en ny side hver eneste gang blir slags kjedelig, og hvorfor trenger jeg å trekke ned header igjen, og bunnteksten på nytt, og alle elementer på siden igjen bare for å oppdatere hilsenen eller tiden? Så det er derfor vi har noe som Ajax. Hva vi kan gjøre her med Ajax er at vi kan si, all right, Jeg ønsker å sende noen data til serveren, og jeg ønsker å få et svar tilbake så jeg kan oppdatere siden min, eller kanskje bare gjøre noen algoritmisk beregning som ikke nødvendigvis viser noe for brukeren. Hva trenger du å gjøre dette? Vel, trenger du en URL du trenger å snakke med. Din server kan ikke bare magisk lytte inn fra ingensteds. Du må ha et bestemt sted du sender disse dataene til. Og du trenger også noen data å sende, eller kanskje det er en dataless spørring. Du ønsker bare å pinge tilbake til serveren og si hei, jeg er i live, eller noe sånt. Og så du vil ha en funksjon som i utgangspunktet håndterer med suksess. La oss si at du får tilbake litt informasjon fra serveren, og du ønsker å endre brukerens tittelen på deres side. Så du ville få informasjonen tilbake, og du ville presse som til skjermen. Hva som skjer er, når siden er klar, du opprette en på klikk-funksjon for denne knappen som heter Greeter. Hva dette så gjør er, når den knappen er trykket, du snakke med greetings.php, du gjør en POST-forespørsel, og du sier, hei, få meg noe fra din side. Vi trenger egentlig ikke å beskrive det, men greetings.php, la oss bare si, gir tilbake "hello world." Så vi får tilbake denne "hello world", og på suksess av dette, forutsatt at ingenting går galt, så vi bare gå til dette målet sted at vi spesifisert og vi bare holde responsen der. Og dette er en svært enkel måte å sette opp en Ajax spørring. Svært raskt, Rob slags nevnt dette allerede, ting kan gå galt, kan dårlige ting skje, slik at du ønsker å bli kjent med disse HTTP svarkoder. Hva disse er er bare, som, 200, alt gikk greit. Noe annet, som skjedde dårlige ting. Det er som regel det ting du ønsker å huske. Men det er hyggelig å vite alle disse. Og til slutt, når vi har gått gjennom alt dette, vi trenger å snakke veldig raskt om utforming, og så kan vi fortelle dere alle forlate. Design. Ting du ønsker å huske. Spør deg selv disse spørsmålene: Hvem skal bruke dette? Hva vil de bruke den til? Hva gjør brukerne mine bryr seg om? Hva er det de ikke bryr seg om? Du ønsker ikke å lage en app, og la det bare vokse og bli denne gigantiske, altoppslukende ting som du selv ikke kan fullføre. Du ønsker å ha diskrete mål og planer og ting du ønsker å ta opp. Gjør det enkelt. Alt dette står i utgangspunktet gjør det enkelt for brukeren å bruke det, ikke gjør det til en gigantisk blob av tekst som dette lysbildet er, faktisk. Du vil bare at det skal være noe der det er veldig lett for noen å gå inn og gjøre hva de vil gjøre. Du ønsker ikke at de skal ha for å navigere 5 sider å komme til din viktigste funksjon av nettstedet ditt. Hvis Google hadde fem sider før kan du også søke noe, ingen ville bruke den. Og til slutt, papir prototype, fokusgruppe. Ha god design og testing praksis. Bare fordi du synes det fungerer for deg, betyr ikke noen andre mener det fungerer. Men ja, det er det. [CS50.TV]