[Redarea muzicii] David J. MALAN: Bine este CS50 iar acest lucru este începutul săptămânii cinci. Așa că astăzi, sub perne de siguranta, nu veți găsi nimic. Dar de mai sus, ar trebui să găsiți acestea, un mic semn al aprecierii noastre pentru toate lucrările pe care le pune în joc de cincisprezece. Pur și simplu scoateți cerc mic de pe partea de jos pentru a începe joaca pentru restul de clasă. Astfel amintesc că, sau știți că problema stabilit patru, care a mers în acest week-end, implică scris un alt joc. Dar de data aceasta implică utilizarea unui interfață grafică real, nu un interfață textuale cum ar fi Jocul a fost Cincisprezece. Și jocul care se află în fața ta, Dacă nu ați văzut încă acest viitor, arata ceva ca acesta. Am de gând să meargă în terminalul meu Fereastra aici, în GDB. Și am de gând să merg mai departe și să rulați Soluția de personal, pe care le puteți accesa , după care rulează actualizare 50 ca de obicei. Dar am de gând să-l pună într-o mică Modul secret, un pic de Paște ou, așa-numita modul Dumnezeu, prin pune Dumnezeu în argv1. Și trebuie să urmeze propriile mele direcții, care rulează în propria mea Problema stabilit director. Deci, acum veți vedea o versiune completă de joc de Breakout. De fapt, acesta este modul NO-mâinile. Deci, e de fapt - uimit, deși s-ar putea fi - destul de banal pentru a pune în aplicare modul lui Dumnezeu în Breakout, spre deosebire de jocuri de cincisprezece ani, pe care unii dintre voi ar putea fi abordate pentru ediția hacker. În Breakout este suficient în Dumnezeu modul de a face pur și simplu ceea ce, intuitiv cu zbaturi? Doar face egal, indiferent de Poziția orizontală este de minge. Și, atâta timp cât faci acest lucru în lockstep cu mingea se deplasează acest joc va niciodată, niciodată, niciodată dor de minge și veți câștiga de fiecare dată. Dar, în ediția hacker această săptămână nu e mai mult decât doar modul lui Dumnezeu. Există o serie de alte caracteristici. Dintre acestea, lasere. Așa că, dacă aveți cu adevărat nerăbdător te poate începe trage in jos cărămizi și alte câteva. Iar pentru cei dintre voi care ar dori să calibra standard, comparativ cu hacker ediție, eu pot vedea că această săptămână Ediția hacker în mod deliberat este o puțin mai greu de realizat, spune, decât Dumnezeu Modul fost cu joc de Cincisprezece. Deci, dacă sunteți în căutarea pentru o întindere și sunteți în căutarea pentru unele distractiv suplimentare Caracteristici sa se arunca cu capul în cazul în care de interes. Acum, mai practic, lasă-mă să subliniez de un singur lucru, de asemenea. GDB, pe care unii dintre voi nu poate avea încă atins personal, ceea ce este bine. Dar acum este într-adevăr timp să te obișnuiești la acest lucru și confortabil cu acest instrument deoarece aceasta va face viața ta mult mai ușor, într-adevăr. Per prelegere lui Rob pe GDB un cuplu de săptămâni în urmă, reamintim că GDB este un program de depanare. Este un instrument care vă permite să rulați dvs. Programul dar rulați-l pas cu pas, linie de linie, astfel încât să puteți bagi nasul, astfel încât să vezi lucrurile se întâmplă, așa pe care le puteți imprima Valorile variabilelor. Pe scurt, vă oferă atât de mult mai mult putere decât printDef face. Acum, desigur, interfața este destul de arcane. Interfață alb-negru textual în cea mai mare parte. Comenzile sunt oarecum greu să-și amintească de la început. Dar, chiar dacă ar putea să vă luați jumătate o oră, o oră, pentru a pune ca avans investiții de timp în ea, ai încredere în mine. Desigur, până la sfârșitul semestrului se va salva un ordin de mărime mai timp decât atât. Deci, la începutul săptămânii se arunca cu capul inch Și în termeni de Breakout, știu că tu pot face acest lucru, atât timp cât aveți codul de distribuție sau propriul cod în curs de desfășurare în directorul Pst4. Să știți că puteți rula gdb. / Breakout. Acest lucru se va deschide o fereastră ca aceasta. Permiteți-mi să mă dau mai mult de o fereastră de terminal. Și atunci ce am de gând să merg mai departe și nu, nu este o rulați. Am de gând să se stabilească mai întâi un punct de pauză rechemare, care vă permite să întrerupeți executarea la un anumit loc. Doar pentru a menține lucrurile simple, am de gând pentru a sparge la linia una doar prin tastarea numărul unu. Permiteți-mi, de fapt re-deschide această fereastră pentru că este obtinerea unui mic mic acolo. Deci, ceea ce am acum de gând să faci aici este dacă am deschide fereastra mea terminalului. Haide, acolo mergem. Deci, acum, dacă mă întorc la Dropbox, Pst4 și rulați gdb. / Breakout intra, observa Am de gând să rupă o pentru a seta un punct de pauză la linia unu. Și acum am de gând să merg înainte și tipul alerga. Și când o voi face, observa nimic pare să se întâmple. Nu e nici o fereastra pop-up. Nu e nici o grafică Interfața de utilizator încă. Dar e de înțeles că sunt literalmente la linia unu în programul meu. Și observați că am transmis rapid, în mod specific acum la 62, deoarece toate lucrurile la partea de sus a acestui fișier este lucruri cum ar fi comentariile și constante și neinteresante lucruri pentru acum. Deci acum sunt în interiorul principal, se pare, la linia 62. Și aceasta este doar de distribuție cod, amintesc. Dacă am deschis asta de a merge, în mod similar, în directorul meu caseta verticală în Pst4, în breakout.c. Și dacă derulați în jos și în jos și de jos, și lasă-mă să merg mai departe și porniți numerele mele de linie. Ceea ce voi vedea, dacă derulați în jos pentru a linia 62, este exact linia pe care ne-am oprit pe. Deci, această linie aici, 62, este unde suntem pe cale de a fi. Deci, acum, în GDB, dacă am merge mai departe și tastați Acum următor, introduceți-l va executa acea linie. Si voila, avem așa-numita fereastră g. Dacă familiarizati cu ceea ce un GWindow este, nu vă faceți griji. Spec. vă va prezenta la ea, ca precum și o serie de clipuri video walkthrough încorporate în spec.. Dar acum hai sa facem acest lucru o pic mai interesant. Permiteți-mi să mutați această fereastră de peste la partea un pic. Permiteți-mi să fac fereastra un pic mai mare, așa că am putea vedea mai mult. Și acum lasă-mă să merg mai departe și face în continuare din nou. Și acolo sunt cărămizi mele. Dacă scriu viitoare din nou acum vad mingea. Și dacă tastați viitoare din nou Acum văd cu zbaturi. Și din fericire, acest lucru nu este gedit într-adevăr cooperează arătându mine tot ce vreau. Dar acum, dacă eu fac în continuare din nou, viitor, din nou, eu sunt doar declararea unor variabile. Și eu pot imprima orice unul acestor tipi. Cărămizi imprimare, viața amprente. Și acum, dacă am continua să facă următoare, observa că voi fi interiorul a buclei. Dar codul se va executa exact așa cum mă aștept. Așa că atunci când am lovit această funcție, așteptați pentru Click, se va face este literalmente că. Așa că am părea să fi pierdut controlul peste program. GDB nu este să-mi dea un alt prompt. Dar nu vă faceți griji. Du-te la jocul meu, faceți clic pe undeva. Și voila, acum se trece la linia 86. Deci, din nou, e neprețuit, în cele din urmă, pentru probleme de depanare. Pentru ca poti sa pasesti prin Codul dvs., lucrurile tipări și mai mult, mult, mai mult. Dar pentru acum, aceste singure unelte ar trebui sa ai destul de mult. Deci noi suntem, desigur, a lua o privire la Grafica acum, toate dintr-o dată. Și acum lumea noastră devine un pic mult mai interesant. Și știți, probabil, de la o parte din clipuri video online pe care le au aceste pantaloni scurți care te-ai uitat ca parte a seturilor problemă. Și ei au fost împușcați, în mod deliberat, pe un fundal alb. Iar unele dintre ele au de predare Fellows desen un text pe ecran care este acoperit pe partea laterală a ei. Dar, desigur, acest lucru nu este tot ceea ce interesant în lumea reală. Aceasta este doar o sală de lectură cu o ecran alb mare și un fundal. Și uimitor nostru fel de echipa de productie a face ca totul să arate frumos după faptul de trunchiere din sau suprapunerea nimic facem sau nu vrem. Acum, doar pentru a motiva această săptămână și într-adevăr, unde puteți merge, în cele din urmă, cu informatică. Nu doar după ce problema stabilit patru. Dar, după un alt curs sau un întreg Curriculum-ul este uimitor ce poti face în aceste zile în ceea ce privește grafică, în special. Unii dintre voi s-ar putea fi văzut acest lucru care curge în jurul on-line. Dar m-am gândit eu aș arăta, pentru doar o câteva minute, o bucatica din ceea ce tehnologia informatică și de ce CGI, grafica pe calculator se poate face în aceste zile cu un cântec familiar și, probabil film. [MUSIC - LANA DEL RAY, "Tânără și frumoasă] SPEAKER 1: Este doar un pic uimitor, probabil, cât de omniprezent - [Aplauze] SPEAKER 1: Tocmai am descarcat. Dar este într-adevăr uimitor, cred, doar Cum Software-ul omniprezent și codul și instrumente de acest gen sunt cu adevărat. Deci, asta e un gust de direcție in care poti sa te duci. Oh, nu mai Appliance azi. Ei bine, asta e de fapt momentul tragic având în vedere punctul am încercat să fac. Bine, asa ca hai sa lanseze Fuziune din nou. Amintește-mi mai târziu. Bine, și ar trebui să au luat o e-mail ca o parte dacă nu ai luat o observa ca asta. În regulă, astfel amintesc că săptămâna trecută am început să coaja înapoi în acest cunoscut mai târziu ca șir. șir amintește un tip de date care este a declarat în CS50 biblioteca. Și este parte a roților de formare care va începe acum să decoleze. A fost un concept util devreme. Dar acum este mergi la a lua mai mult interesant și mai puternic pentru a a se vedea de fapt că sub capota, un șir este doar ceea ce, am spus? Da, așa că este un așa-numit char *. Și * nu denotă că nu există un fel de adresa implicate. Așa că atunci când spui char * sa spui doar o variabilă a cărui tip de date este o pointer acum. Faptul că nu e stea acolo înseamnă doar că se declară un așa-numita pointer. Și că indicatorul se va aparent stoca adresa, de Desigur, un char. Acum, de ce nu face acest sens? Ei bine, ceea ce este un șir sub capota? Ei bine, de ceva timp ne-am spus ca un șir sub capota este Tocmai h-e-l-l-o, de exemplu. Dar am vorbit despre acest lucru ca fiind, în esență, o matrice. Și o serie ar arata apoi un pic mai mult ca aceasta, cu fiecare dintre acestea a lua o muscatura. Și atunci am spus că nu e ceva special aici, backslash 0, sau null terminator. Deci, tot acest timp, aceasta aici a fost un șir. Dar, de fapt, un șir este de fapt, o adresă. Și adrese, așa cum vom vedea, sunt de multe ori prefixate cu 0x prin convenție. Ce 0x denotă? Stie cineva? Deci, aceasta înseamnă doar hexazecimal. Deci, s-ar putea aminti, de fapt, de la Pst 1, cred, unul din warm-up întrebări de fapt despre notație hexazecimală, în plus față de binar și zecimal. Și motivația aici este că cu hexazecimal aveți 16 cifre la dispoziția dumneavoastră. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, urmată prin a, b, c, d, e, f. Și dacă te numeri pe toți cei în sus, veți obține un total de 16. Deci, acest lucru este în contrast cu zecimal, unde avem 10 cifre, 0 prin noua. Este în contrast cu binar unde avem doar 0 și 1. Dar la sfârșitul zilei, puteți pur și simplu reprezenta aceleași numere, dar oarecum diferit. Și hexazecimal este comun pentru ca se pare - și vom vedea asta mai târziu, în cursul - chiar și atunci când ajungem pentru programare web, în ​​contextul HTML și codurile de culoare, hexazecimal este frumos. Pentru ca fiecare cifră, se dovedește, reprezinta patru biti perfect. Deci, doar un fel de linii de până frumos așa cum vom vedea în cele din urmă. Deci, acest lucru ar putea fi Ox123 sau ceva cum ar fi că, denotă adresa 123 undeva în interiorul meu memoria calculatorului. Dar, desigur, unele probleme apar datorită acestui suport punere în aplicare. Și amintesc că am luat o lovitură de cuțit la de punere în aplicare o funcție ca asta - compara bord 0 punct c săptămâna trecută, că chiar dacă se parea ca a fost dreapta, pur și simplu nu a compara două șiruri corect. Am aruncat principal, și m-am aruncat departe de comentarii doar pentru a se concentreze asupra cod care este de interes aici. Și este în roșu, pentru că este buggy. Pentru ce motiv? Ei bine, partea de sus acolo când am declarat un șir, ce se întâmplă cu adevărat pe sub capota? Ei bine, lasă-mă să merg pe la ecran aici și trage asta. Așa că am declarat, din nou, string s getstring. Așa că am de gând să merg mai departe acum și trage e pentru ceea ce este cu adevărat. O să fie un pătrat aici. Și am de gând să pretindă că e 32 de biți. Cel puțin, de obicei, este, cel puțin pe CS50 aparatul într-o mulțime de calculatoare. Am de gând să-l e numesc. Dar acum ne reamintim că numit getstring. Revine astfel getstring, Desigur, un șir. Dacă utilizatorul tastează în H-e-L-L-O intra șirul de salut devine întors. Și că șir, așa cum am spus, se termină undeva în memoria computerului cu un 0 backslash la sfârșitul anului. Voi desena acest lucru ca matrice - sau bloc contiguu de personaje - care este de fapt. Și acum, ce se getstring de fapt revenirea? Ceea ce a getstring fost revenirea tot acest timp? Ei bine, am spune, în săptămâni înainte, se returnează un șir. Dar mai mult de vedere tehnic, ceea ce face Getstring retur aparent? Audiența: O adresă. SPEAKER 1: O adresă. În mod specific se returnează adresa de prima mușcătură, orice ar fi. Mă tot folosind una, două, trei pentru că este convenabil. Returnează adresa primului caracter în șir. Și am spus săptămâna trecută că că este suficientă. Pentru ca ne putem da seama întotdeauna unde capătul șirului doar prin iterarea peste ea, poate, cu o pentru buclă sau o buclă în timp sau ceva de genul că, în căutarea doar pentru "backslash 0", caracterul special Sentinel. Și atunci știm că șirul se întâmplă să fie de lungime - în acest caz - Cinci. Deci, punct de vedere tehnic ce face getstring se returnează Ox123 în acest caz. Și punct de vedere tehnic ceea ce se întâmplă atunci este pe care le stoca, în interiorul s, Ox123. La sfârșitul zilei, chiar dacă acest lucru este nou concept, indicii, sunt doar variabile. Dar se întâmplă pentru a stoca biți care reprezintă împreună o adresă. Deci, punct de vedere tehnic toate acestea se stocate în s este Ox123. Dar noi, ca oameni - inclusiv azi înainte - sunt într-adevăr nu o să aibă grijă, de obicei, ce adresa reală este de unele bucată de memorie. Este doar la nivelul scăzut de detaliere a fi intelectual interesant. Așa că am de gând pentru a anula aceasta. Și în loc, la nivel mai înalt, spun doar că atunci când vorbim despre indicii Am de gând să atragă doar mai mult săgeată user-friendly, care transmite idee și același rezumate distanță de datele de ceea ce efectiv adresa de bază este. Acum, dacă ne întoarcem la codului, ceea ce sa întâmplat săptămâna trecută, dacă avem șirul t este egal cu getstring? Ei bine, dacă eu din nou, de tip în Hello de data aceasta am de gând pentru a obține un alt segment de memorie. h-e-l-l-o bară oblică inversă 0. Dar, pentru că am sunat getstring a doua oară - și știu acest lucru de la uita la codul sursă pentru getstring - chiar deși este o coincidență faptul că salut a fost tastat în de două ori, getstring nu este O să încerc să optimizeze și de a fi inteligent. Este doar mergi la a lua o altă bucată de memorie de la calculator, care este va fi la o altă adresă. Să arbitrar spunem doar 456. Și atunci ce este de gând să se întoarcă? O să se întoarcă 456 și se păstrează într-t. Deci, ce se întâmplă cu adevărat, pe partea stângă este mai am o bucată de memorie, 32 biți de obicei. Și de acolo se va merge Ox456. Dar, din nou, eu nu sunt interesat de aceste anymore anumite numere. Mă duc la abstract trage-l ca o săgeată. Deci, aceasta este acum o nouă explicație. Dar e aceeasi idee exact care este se întâmplă tot acest timp. Și așa motiv, atunci, că această primă Versiunea de comparare a fost buggy săptămâna trecută este de ce? Când faceți dacă e egal cu egal t Ce ești tu cu adevărat sub capota compararea? Te compararea adreselor. Și doar intuitiv, în mod clar, Ox123 nu este de gând să egal Ox456. Aceste numere, aceste biți sunt doar diferite. Și astfel în mod constant, saptamana trecuta a spus tastați lucruri diferite, chiar dacă Cuvintele au fost Verbatim același. Așa că am rezolva această problemă. În termeni simpli, ceea ce a fost fix? Audiența: Folosiți o funcție. SPEAKER 1: Utilizați o funcție. Sau stelele sunt implicate cu siguranta, dar utilizează o funcție pentru a face ce? Audiența: Pentru a compara siruri de caractere. SPEAKER 1: Pentru a compara siruri de caractere. Deci, problema fundamentală aici a fost că am fost doar luând în considerare Calitatea șiruri să fie definite prin compararea adresele lor. Și, evident că e doar prost acum o dată ați înțeles ce se întâmplă sub capota. Pentru a compara cu adevărat siruri de caractere pentru a vedea dacă ele sunt egale în modul în care un om ar lua în considerare două șiruri să fie egal avem nevoie pentru a le compara caractere pentru caracter pentru caracter. Acum, am fi putut face acest lucru foarte plictisitor. Dar familiar, suntem folosind o buclă. Și tocmai compara e suport i împotriva t suport i. s suport I plus 1 împotriva t suport i plus 1, și așa mai departe, în interiorul un fel de buclă. Și dacă la fața locului oricare două personaje care diferă, sau dacă îmi dau seama că ooh, e este scurt decât t sau mai lungă decât t Pot spune imediat false, ei nu sunt la fel. Dar dacă mă prin e și t și spune același, același, același, același, la fel, sfârșitul ambele siruri de caractere, pot să spun adevărate, ele sunt egale. Ei bine, din fericire, de ani în urmă pe cineva a scris că cod pentru noi. Și au numit-o StrComp pentru șir comparație. Și, chiar dacă este un pic contra intuitiv, StrComp returnează 0 dacă cele două șiruri, s și t sunt aceleași. Dar se întoarce o valoare negativă dacă s ar trebui să vină înainte de t în ordine alfabetică sau valoare pozitivă dacă aceasta ar trebui să vină după t în ordine alfabetică. Deci, dacă vrei vreodată să rezolve ceva, se dovedește că StrComp este util. Pentru că nu spune doar da sau nu, egal sau nu. Acesta vă oferă un sentiment de comanda ca o putere dicționar. Deci StrComp, s virgulă t este egal adică 0 înseamnă că siruri de caractere sunt cu adevărat egale. Pentru că cine a scris această funcție ani în urmă, probabil folosit o buclă sau o buclă în timp sau ceva de genul asta a integra peste caracterele din nou și din nou și din nou. Dar două problemă a apărut aici. Acest lucru a fost copy0.c. Și două în roșu este pentru că este greșită. Și ce facem aici? Ei bine, în primul rând am sunat getstring. Și am păstrat valoarea returnată în s.. Așa că e destul de mult la fel ca și această parte de sus a imaginii. Dar ceea ce vine după asta? Ei bine, lasă-mă să merg mai departe și de a scăpa de o grămadă de aceasta. Vom înapoi în timp pentru care ne-am Trebuie s, care este acum în concordanță cu linia unu acolo. Am verificat. Dacă e egal egal cu 0. Acum, o notă rapidă, atunci când s-ar putea getstring returna 0? Nu este suficientă memorie. Dreapta? Este rar ca acest lucru se va întâmpla, cu siguranță pe un calculator care este primit sute de megabytes sau chiar gig-uri de memorie RAM. Dar ar putea, în teorie, întoarce 0, mai ales dacă Utilizatorul nu cooperează. Există modalități de a preface că nu au nimic introduse și truc Getstring în revenirea 0 în mod eficient. Deci, se va verifica pentru asta. Pentru că dacă oricare dintre voi au început să se, deja, defecte de segmentare - care a fost, probabil, o sursă de unele frustrare - acestea sunt aproape întotdeauna rezultatul de memorie legate de eroare. Cumva ai incurcat cu privire la o pointer, chiar dacă nu am dat seama a existat un pointer. Deci, s-ar putea fi indus de segmentare defecte ca mai devreme de o saptamana cu ajutorul ceva ca un pentru buclă sau un timp buclă și o serie de merge prea departe dincolo de limitele unor matrice care te a declarat, în două săptămâni, în special. S-ar putea fi făcut chiar în problema set patru cu Breakout. Chiar dacă, probabil, nu s-au văzut orice stele din codul de distributie pentru Breakout, se pare că cei GRect și astfel de lucruri Goval și alte, cei care sunt de fapt indicii sub capota. Dar, Stanford, ca și noi, un fel de piei care detaliu cel puțin pentru bibliotecile scopuri, mai mult ca noi pentru string și char *. Dar GRect și Goval și tuturor celor lucruri voi sunt sau vor fi utilizați această săptămână sunt în cele din urmă adrese de memorie. Pur si simplu nu-l știu. Deci, nu e de mirare, atunci, probabil, care s-ar putea excursie pe un defecte de segmentare. Dar ceea ce este interesant aici acum, dacă după ce vom verifica pentru 0 facem șir t devine e. Ei bine, lasă-mă să declare t. Am de gând să-l trage ca un pătrat, 32 de biți, acesta t numesc. Și apoi am de gând să fac primeste s. Ei bine, ce înseamnă asta? Ei bine, e un pic cam greu să se gândească despre aceasta imagine înțelept. Dar să ne gândim ceea ce este în interiorul de x? Ce este literalmente în interiorul această variabilă? Valoarea Ox123. Deci, atunci când spun șir t devine e, că doar literalmente înseamnă ia numărul în s, care este Ox123 și a pus-o Ox123. Sau pictural, dacă am un fel de abstract departe de acest detaliu are Efectul de literalmente face aceasta, de asemenea. Deci, acum, cred că înapoi la săptămâna trecută, când am procedat la capitalist T. I a făcut T suport 0. Ei bine, T suport 0, chiar dacă este un pointer, aveți posibilitatea să-l ca și cum tratează este o matrice, cu un pătrat notație suport. Deci, unde este T suport 0? Ei bine, e h. Așa că atunci când vom folosi ca linie de cod, două superioară, care este în care c type.h fișier antet, acolo este declarat. Te valorificarea acest H. Dar de Desigur, asta e la fel h exact care este interiorul e, ca să spunem așa. Iar acum s-au schimbat sau valorificate atât în ​​original și așa-numita copie. Pentru că nu a făcut o copie în modul în care un om ar vrea să fie. Deci, ceea ce era fix aici, în copy1.c săptămâna trecută? Funcții, așa că am putea de fapt copia șir. Și fundamental, ce trebuie să ne face în scopul de a copia șirul? Ei bine, în această versiune verde, aici am O să-l nivel destul de redus face. Nu sunt de fapt funcții acestea ar putea ajuta cu asta. Dar cel mai de bază, și mai unul familiar, cel puțin, va fi în curând familiar pentru noi, este următoarea - astfel încât o pe prima linie de cod în verde acum. Am rescris e ca char *. Nu e nici o funcțională Diferența acolo. Am aruncat biblioteca CS50 și Eu l sun ceea ce este, un char *. Acum punct, punct, punct, pentru că s-au unele verificarea erorilor care nu este interesant să vorbesc despre nou. Deci, acum t este declarat. Acesta este de asemenea un char *. Așa că am tras un pic pătrat pe ecran ca înainte. Dar pe partea dreaptă, malloc, am spus este memoria aloca. Deci aloca unele bucată de memorie. Și cât de multe bytes avem de fapt Vreau să aloce, nu ți se pare? Ei bine, lungimea șirului de e. Deci, dacă e salut că este Va fi cinci. Vom spune h-e-L-L-o. Deci, cinci bytes. Dar apoi plus 1, de ce 1? 0 caractere. Dacă nu ne lasă loc pentru acest tip am s-ar putea crea accidental o situație în cazul în care șirul este h-e-l-l-o. Și apoi următorul getstring timp este numit și tip I în, de exemplu, David, D-a-v-i-d, calculatorul se întâmplă să cred că este de fapt h-e-l-l-o-d-o-v-i-d, deoarece există nici o pauză între aceste cuvinte. Deci, avem nevoie de pauza. Deci, noi nu vrem cinci. Vrem șase bytes. Și bytes spun. Dar e marimea chiar timp de char. Punct de vedere tehnic char este aproape întotdeauna un singur octet. Dar doar pentru a face codul nostru portabil, ca să spunem așa, astfel că funcționează pe computere diferite, chiar dacă s-ar putea fi oarecum diferite sub capota, am de gând să generic spune dimensiunea de char, astfel încât codul meu funcționează întotdeauna. Și nu trebuie să-l recompilați doar pentru ca fac upgrade computerul meu sau de a folosi unele diferite platforme. Așa că am luat de 6 ori mai mare un caracter, care se întâmplă să fie 1. Asta înseamnă că malloc ar putea da-mi șase bytes. Ce este ca de fapt faci? Ei bine, lasă-mă să rostogolească înapoi în timp aici unde suntem în poveste. Deci, dacă mă întorc aici, am declarat un char * numit t. Am sunat acum malloc pentru șase bytes. Și acum am de gând să atragă cei șase bytes la fel ca matrice mai devreme. Dar eu de fapt, nu știu ce-i în interiorul acestui tablou. Dacă ați aloca memorie se dovedește că nu puteți avea încredere că există unele valoare cunoscută acolo. Aceasta ar putea fi fost folosite de ceva altceva, o altă funcție, un alt linie de cod pe care ai scris. Deci, vom numi, în general, aceste gunoi valorile și egal ei, poate, așa cum semne de întrebare, doar indicând faptul că noi Nu știu ce e de fapt acolo. Și asta nu e mare lucru, atât timp cât noi sunt destul de inteligent pentru a suprascrie cele Valorile de gunoi cu numere sau caractere pe care le pasă. Deci, în acest caz, ce am de gând să fac? Ei bine, codul linia mea de viitoare, am patru. int i lua 0, n devine Lungimea șir de s. Deci, un familiar pentru buclă. I este mai mică sau egală cu n, care de obicei este mai sus. Dar de data aceasta este deliberat. I + +, și apoi eu pur și simplu nu Nu suport i se e. Pentru ca poza mea arata ca acest lucru la acest moment, stocate în t este Adresa de care bucată aleator de memorie Valorile căror sunt necunoscute. Dar, de îndată ce eu fac t suportul 0 că mă pune aici. Și ceea ce se încheie până atrași acolo? Ne ajung punerea h.. Pentru că asta e ceea ce-i la s suport 0. Și apoi același lucru pentru e, și l, și l, și o. n, de ce m-am dus în sus prin un egal cu n? Datorită caracterului 0. Deci, doar pentru a fi clar, apoi, dacă am de fapt, șterge orice aceste gunoi Valorile sunt și apoi trage de fapt, în ceea ce ma astept, acest lucru este s suport 1, 2, 3, 4, plus că e urmă caracter nou. Iar acum, dacă am continuat trecut punct, punct, punct în această versiune corectă și capitalizată t suport 0 I ar fi, de Desigur, trebuie valorificarea doar acest tip de aici, care conceptual, a fost în cele din urmă scopul. Deci, asta e tot indicatorul este. Și ați fost le folosesc pentru săptămâni acum, în contextul siruri de caractere. Dar sub capota sunt un pic mai complex. Dar dacă te gândești la ele în acest forma picturala propun ca acestea sunt probabil, nu toate că înfricoșător ca acestea s-ar putea părea mai întâi la prima vedere, în special cu sintaxa astfel de noi. Orice întrebări cu privire la indicii, siruri de caractere, sau caractere? Da? Audiența: Poți să te întorci la [inaudibil]? SPEAKER 1: Sigur. Audiența: Deci, cum vin în ultimul dumneavoastră linie, nu aveți o linie * t și o * s în linia? Nu aveți trimitere la - SPEAKER 1: Ah, o întrebare foarte bună. De ce nu am o * t și o * e? Deoarece scurt, săptămâna trecută, cum ar fi în nostru schimba funcția, eu am spus că, atunci când le-ați luat un pointer mijloacele de care te duci acolo ca am facut fizic pe scenă, a fost de fapt utilizați operatorul stele. Se pare că acest pătrat-suport notația este ceea ce vom numi sintactic zahăr, care este doar un mod sexy de spunând notație e prescurtarea pentru exact ceea ce descrie. Dar e un pic mai intuitiv. Și la riscul de a face acest lucru pare mai mult complicata decat aceasta trebuie să fie, ceea ce se întâmplă cu adevărat aici este următoarea - Dacă spun * Nu înseamnă că merge la adresa stocată în t. Deci, literalmente, în cazul în care t este stocarea adresa care h inițial, * t înseamnă du-te aici. Acum, ceea ce nu t categorie de 0 înseamnă? Exact același lucru. E doar un pic mai ușor de utilizat prietenos pentru a scrie. Dar eu nu am terminat încă. Eu nu pot să spun doar * t * e primește. Pentru că ceea ce ar trebui sa fac atunci? Aș fi punerea h, h, h, h, h de-a lungul totul. Dreapta? Pentru ca * t este să mergeți la adresa din t. Dar suntem în interiorul unei bucle. Și ce valoare am incrementarea, desigur, pe fiecare iterație? Am. Dar există o oportunitate aici, nu? Chiar dacă acest lucru se simte ca și cum se face un pic mai sofisticat decât notația pătrat-suport ne-am folosit de ceva timp - permiteți-mi anula schimbarea mea h acolo - chiar dacă acest lucru este acum devine un pic crescator, ideea de bază, în cazul în care * t înseamnă aici si * t este doar du-te la adresa de t. Dar ceea ce a fost pe adresa de t? Numărul păstrăm cu ajutorul? Ca Ox456, să aduci înapoi doar de dragul discuției. Ei bine, dacă doriți să obțineți de la e din t șir, doar vreau să merg la, în esență, 456. Sau, mai degrabă, 457. Trebuie doar să adăugați una. Dar eu pot face asta, nu? Pentru că nu, chiar dacă am ține de desen acum ca o săgeată, e doar o număr, Ox456. Și dacă am adăuga unul la care, sau mai mult în general, dacă am adăuga eu la care pot de fapt, ajunge exact unde vreau. Deci, dacă am face de fapt acest lucru - și aceasta este ceea ce se numește acum aritmetică indicatorul - Am posibilitatea de a elimina această linie. Care este, sincer, cred că mai clar și un utilizator mai putin prietenos pentru a citi. Dar acest lucru nu este mai puțin corectă. Această linie de cod acum se utilizează indicatorul aritmetică. Se spune du-te la următoarea adresă - indiferent de început al t este, care este t plus eu, care inițial este 0, care este mare. Pentru că înseamnă începutul de t plus 1, plus 2, plus 3, și așa mai departe. Și la fel face cu e. Zahăr, astfel sintactic pentru aceasta. Dar înțelegerea a ceea ce se întâmplă cu adevărat pe sub capota, aș spune, este, de fapt util în sine. Pentru că acum înseamnă că nu este mult mai mult magie întâmplă sub capota. Nu vor fi mai multe straturi care ne putem coaja înapoi. Aceasta este c. Și acest lucru este de programare. Întrebare foarte bună. Bine, deci acest lucru a fost că buggy Programul m-am referit mai devreme. schimb a fost greșită. În cazul în care părea să funcționeze. Amintiți-vă că la fel ca cu lapte și suc de portocale - pe care am început băut demonstrația de azi. Deci, la fel ca și cu suc de portocale și lapte, am avut de a folosi un variabilă temporară, tmp, să dețină un temporar, astfel încât putem să schimba valoarea și apoi actualizați b. Dar această funcție, am spus, sau acest program în care această funcție a fost scris greșit și defecte, de ce? Da? Audiența: [inaudibil]. SPEAKER 1: Exact, atunci când Te sun de swap - sau, mai general, atunci când apela cele mai multe orice funcție - dacă argumentele acestei funcții sunt primitive, ca să spunem așa, int și caractere si la dublu și plutește, lucruri fără stele, ce se trece într-o copie de argumentul. Deci, dacă x fost de 1 și y a fost de 2, o va să fie 1 și b va fi 2. Dar ei vor fi diferite bucăți de biți, diferite bucăți de memorie care se întâmplă să fie stocarea valori identice. Deci acest cod este super perfectă la schimbarea a și b. Nu e bun la schimbarea - în exemplul de săptămâna trecută - x și y. Deoarece din nou, sunt în domeniul de aplicare greșită. Acum, cum ne-am dus de fixare asta? Am avut de a face funcția de uite un pic mai urât. Dar, din nou, ia în considerare ceea ce Acest lucru înseamnă doar. Și, de fapt, lasă-mă, pentru consecvență, schimba un singur lucru, astfel că este identic cu ceea ce am făcut. Așa cum am menționat săptămâna trecută, ea nu contează unde se duce. De fapt, de obicei, v-ar pune stele, de lângă numele variabilei. Dar cred că ar fi un pic mai ușor să ia în considerare * de lângă tip de date în sensul că este un pointer este un număr întreg, în acest caz. Deci, ce fac eu aici? Spun că nu-mi da un int urmat de un alt int, numindu-le o și b. Dă-mi adresa de int. Dă-mi adresa de alt Int. Apela acele adrese A și B. Și apoi folosind notația * jos de mai jos, du-te la fiecare dintre aceste adrese după cum este necesar pentru a obține fie sau pentru a seta valoarea sa. Dar există o excepție aici. De ce nu am un * lângă tmp? De ce nu am face acest lucru, de exemplu? Se simte ca și cum ar trebui să mergem toți afară și de a corecta totul. Da? Audiența: [inaudibil]. SPEAKER 1: Nu am declarat tmp ca un șir. Deci aceasta ar declara, în acest caz, un tmp să fie adresa de un int. Dar asta nu e chiar ceea ce vreau, pentru un cuplu de motive. Audiența: Nu vrei să le schimba. SPEAKER 1: Exact, nu vreau să schimbe nimic cu tmp. tmp este doar saptamana-un chestii. Tot ce vreau este o variabilă pentru a stoca un număr. Nu-mi pasă nici despre adresele în acest moment. Am nevoie de doar 32 de biți sau astfel încât pentru a stoca un int. Și vreau să pun în acele 32 de biți ceea ce nu este într-o, ca să spunem așa, dar ceea ce este la un, doar pentru a fi mai precis. Pentru că, dacă un este o adresă, * un mijloc du-te acolo și să obțină valoarea 1. De exemplu, în exemplul de săptămâna trecută sau în cazul b, a obține valoarea de 2. Deci, ce se întâmplă cu adevărat? Permiteți-mi trage o imagine aici, care va doar tachineze pe langa o parte din ziua de azi. Dar acest lucru va continua să apară de ceva timp. Acest lucru, eu susțin, este ceea ce a computerului memorie arata ca atunci când rulați un Programul, orice program. Când executați un program de la foarte de sus de RAM a computerului - deci cred că de acest dreptunghi, într-adevăr, așa cum dvs. RAM sau memoria computerului, toate 101 miliard de bytes de ea, toate două miliarde de bytes, toate doi gigabytes de ea, indiferent de cantitatea ce trebuie este, haideți să-l ca un dreptunghi trage. Și eu susțin că atunci când executați un program de cum ar fi Microsoft Word sau Chrome sau ceva de genul asta, de biti care Microsoft sau Google, care a scris - în cazul acestor programe - sunt încărcate în memoria computerului în cazul în care acestea pot fi executate mai rapid și hrănite în CPU, care este creierul calculatorului. Și în TAM acestea sunt depozitate la foarte partea de sus a programului dumneavoastră, ca să spunem așa. Cu alte cuvinte, în cazul în care acest lucru este o bucată de memorie, atunci când faceți dublu clic pe Microsoft Word, biții de vin de pe hard disk. Ei vor fi încărcate în memoria RAM. Și le vom împinge în sus la foarte de sus din acest dreptunghi conceptual. Ei bine, restul de memorie este folosit pentru lucruri diferite. La foarte de sus veți vedea inițializa date și să anuleze date. Acest lucru are de a face, în cea mai mare parte, cu constante sau variabile globale care au valori. Dar mai mult pe cei alt timp. Apoi, aveți morman, care vom reveni la. Dar în partea de jos este partea care este în special Germane chiar acum. Este așa-numitul stivă. Deci, la fel ca în cele mai multe orice sală D aici pe campus, aveți aceste tăvi care doar stivă unul peste altul pe care puteți pune mâncare și fleacuri. Stivă într-un sistem informatic este foarte asemănătoare. Cu excepția întrucât tavă, așa cum vom folosi în sala de mese, desigur, este menit pentru a transporta lucrurile tăvi sau cadrele - cum le vom numi - într-un computer memorie este folosit pentru a ține variabile și valori. Deci, ce se întâmplă cu adevărat sub capota? Ei bine, lasă-mă să flip peste la ecranul aici. Și haideți să se concentreze doar pe partea de jos pentru un moment. Dacă aceasta este partea de jos a mea memoria calculatorului se dovedește atunci când am apela funcția principală - care se întâmplă, sincer, în mod automat pentru mine - I a lua o bucată de memorie la partea de jos a RAM meu ca să spunem așa. Și acest lucru este în cazul în care este principala variabile locale merge. Este cazul în care argc și argv poate du-te, și orice variabile I declara interiorul principal. Ei ajung în partea de jos de RAM computerului meu. Acum, să presupunem că apelurile principale o funcție cum ar fi swap, așa cum a făcut-o săptămâna trecută? Ei bine, am pus în esență, un nou tavă, o Noul cadru, pe bucata mea de memorie. Și am de gând să descrie acest lucru ca aparținând funcția de swap. Acum, ceea ce este în interiorul de schimb? Ei bine, bazat pe programul de săptămâna trecută și cea pe care am văzut doar un fragment din, interiorul cadrului de swap lui, sau pe schimb de tavă, sunt ceea ce variabile? Ei bine, A și B. Deoarece acestea au fost argumentele sale locale, plus un al treilea, tmp. Deci, într-adevăr, am putea trage acest un pic mai curat. Lasă-mă să merg mai departe și să refacem eticheta. Și permiteți-mi să pretind că știi ce? o este, probabil, va ajunge aici. B se va termina aici. Și tmp se va termina aici. Acum, comanda ar putea fi un pic diferit. Dar conceptual aceasta este ideea. Și colectiv, aceasta este ceea ce vom numi cadrul swap, sau tavă de luat masa, hol. Și la fel face cu principal. Dar nu voi aspira asta. Dar asta e în cazul în care argc și argv și orice dintre variabilele sale locale ca x și y ar putea fi la fel de bine. Deci, acum în considerare ceea ce se întâmplă cu adevărat atunci când te sun de swap. Când apelați schimb, cod executarea cum ar fi acest lucru, sunteți în trecere, în Versiunea buggy, a și b sub formă de copii ale lui x și y. Deci, dacă eu atrag acum acest pe ecran - Trebuie să mă mai bine la asta - deci povestea i-am spus să mă a fost, în această versiune buggy, atunci când apel schimba trece în literalmente a și b ca numere întregi, ceea ce se întâmplă cu adevărat? Ei bine, ce se întâmplă cu adevărat este acest lucru. Lasă-mă să merg mai departe și să refacem doar pentru a clarifica unele spațiu aici. Deci, aceasta este memoria computerului meu. Deci, dacă am avea, de exemplu - lăsa să o facem în acest fel - dacă eu susțin că acest lucru este x, stocarea valoarea 1 la fel ca săptămâna trecută. Și acest lucru este y, stocarea valoarea 2 la fel ca săptămâna trecută. Și aceasta este principala, când am apel de swap, oferind astfel am acces la o și b și tmp, am de gând să pretind că aceasta este o și acest lucru este 1. Acest lucru este b. Aceasta este 2. Aceasta se numește tmp. Și inițial, acesta are o valoare de gunoi până când am stoca de fapt, într-o, care este 1. Apoi am merge mai departe și de a schimba o să fie ce? Valoarea B. Iar acum am doi aici. Și apoi am spus b. se tmp. Din nou, la fel ca și verifica un bun-simț, de-a treia linie de cod aici este pur și simplu acest lucru unul, b devine tmp. Și astfel în cele din urmă, ce să fac? Am merge mai departe și de a schimba b să fie orice valoarea tmp este, care este 1. Nu atingeți din nou tmp. Dar acum, problema este cât de curând schimb se întoarce, pentru că nu este predarea înapoi unele valoare, nu e nici o întoarcere afirmație în mod explicit în ea. Ce se intampla de fapt? Ei bine, în esență, toate această memorie - OK, se pare că radiera place doar un deget la un moment dat - doar dispare. Acum, în realitate, nu este merge oriunde. Dar vă puteți gândi la ea acum ca semne de întrebare. Pentru că nu mai este de fapt în uz. Și nu se face nimic cu aceste valori. Deci, în cazul versiunii de verde acest cod, ceea ce în schimb este în curs de a trecut în schimb? Așa se adresează. Deci adresa lui x și adresa de y. Deci, dacă am re-spunem aceasta poveste ultima timp, și am trage de fapt schimb din nou, dar cu indicii, aceasta fiind o, această fiind b, iar acest lucru fiind tmp, ceea ce este efectiv depozitată într-o în acest verde versiunea de codul meu în care am trece in adrese? O să fie un pointer la x. Deci, am putea trage o săgeată. Dar hai să folosim același arbitrară exemplu ca mai înainte. Să spunem că aceasta este ceva de genul Ox123. Și acest lucru se întâmplă să fie Ox127 deoarece este de patru bytes departe, pentru că este un Int, așa Ox127. Și din nou, eu iau niște libertăți cu numere. Sunt mult mai mici decât ar fi fie de fapt și într-o ordine diferită. Dar asta e modul în care imaginea este acum diferit. Dar când am folosi acest cod verde și eu tmp int obține * o. * Un mijloc de a face următoarele, ia adresa, care este într-o și du-te la ea, care este 1. Și asta e ceea ce apoi am pus în tmp. Între timp, în următoarea linie de cod aici, * a se b, ce înseamnă asta? Ei bine, * un, deci du-te aici devine * b, ceea ce înseamnă du-te acolo. Și asta înseamnă că a pus valoarea de acolo. În cele din urmă, ultima linie de cod pur și simplu a declarat * B se tmp. Deci, B spune du-te acolo și suprascrie cu tmp care, în acest caz, se va să fie, din nou, 1. Și acesta este motivul pentru versiunea verde a faptele noastre de cod, în timp ce roșu Versiunea niciodată nu a făcut. Totul doar se reduce la modul în care Memoria este gestionată și care este pus efectiv în dvs. RAM computerului. Și de acum, asta e unul din lucrurile că stiva este utilizat pentru. Întrebări cu privire la aspect? Pe indicii? Sau la schimb? În regulă, deci malloc, rechemare, a facut ceva de genul asta. Acesta a fost un exemplu foarte simplu. Și aceasta a fost cel care Binky ne-a prezentat, deși destul de repede, la sfârșitul clasei. La naiba, nu vom merge din nou. Astfel amintesc că acesta a fost un exemplu care Binky ne-a prezentat, deși oarecum repede la sfârșitul clasei. Și aici am folosit malloc adevărat pentru a doua oară. Pentru că prima dată l-am folosit pentru a crea suficient RAM, aloca suficient de memorie RAM pentru a stoca un șir. De data aceasta Binky pastrat simplu. Deci, este de a stoca doar un întreg, aparent. Și că e în regulă. E un pic ciudat, sincer, să folosi malloc pentru a aloca o Int. Dar punctul de claymation Nick era într-adevăr spune doar povestea a ceea ce se întâmplă sau nu se întâmplă atunci când ai maltrata memorie. Deci, în acest caz, acest program a făcut o serie de lucruri. În primul caz aici, se declară un indicator numit x la un int. Apoi, declară un pointer numita y este un număr întreg. Se stochează apoi în x, ce? Altcineva acum. Ceea ce este stocat în conformitate cu x a treia linie a acestui program? Audiența: [inaudibil]. SPEAKER 1: Ei bine, nu chiar bytes, pe spun. Fii mai precis acum. Ceea ce este stocat în x? O adresa, cred că l-am auzit. Deci, ce se întoarce malloc? malloc comportamental alocă o bucată de memorie. Dar cum se da acces la ea? Se întoarce ce? Adresa primului octet în bucată de memorie. Acum, acest lucru este foarte simplu. Este doar un octet, ceea ce înseamnă adresa primim înapoi este adresa totul. Astfel depozitate în x, atunci, este adresa de care bucată de memorie. Între timp, ceea ce se întâmplă în continuare? Așa că, de fapt, să mergem mai departe și trage acest rapid de reală. Deci, dacă mergem pe la ecranul de aici și vom juca asta int * x și int * y este de gând să facă ceea ce pentru mine? Eu susțin că este doar de gând să faci ceva de genul asta și îl numesc x, și acest lucru și-l numesc y. Între timp, a treia linie de cod este va aloca dimensiunea de un int, care se întâmplă să fie - Îmi pare rău dacă am spus o înainte de am vrut o Int - patru octeți de pe un calculator tipic. Cel puțin cu CS50 aparat. Deci, acest lucru se va aloca ea, cine știe? Undeva pe aici. Și acest lucru este stocat la unele Adresa Ox, cine știe? Dar ce se întâmplă să se returnate este acea adresă. Dar vom trage acest pictural ca doar o săgeată de genul asta. Acum, în următoarea linie * x devine 42. Ce * x înseamnă în termeni de nespecialist? Doar du-te acolo. Du-te la acea adresă. Sau cu alte cuvinte, urmați săgeată și a pus 42 acolo. Dar apoi sa întâmplat ceva rău la Binky, nu? Amintiti-va ca linia de cinci aici, * y devine 13, într-adevăr, un număr de ghinion, a făcut ceea ce pentru noi? Ei bine, * mijloace y du-te acolo. Ei bine, acest lucru nu a fost dat o valoare încă, nu? Codul nu are y fiind initializat cu nimic. Am avut x faza de inițializare la o adresă. Dar Y a fost declarat sus. Dar apoi o virgulă, nici o valoare a fost de fapt pus în ea. Deci, este corect să numim această o valoare gunoi. Cine știe ce-i acolo? Sunt resturi de biți care au fost folosite de o linie anterioară de cod în programul meu. Deci, dacă am spus acolo, acest lucru este ca, Nu am nici o idee unde acest lucru săgeata este va termina. Și asta e atunci când de obicei a obține o eroare de segmentare. Daca din greseala dereference, astfel încât să vorbesc, sau du-te la o adresă care nu este de fapt, o adresă legitim, se întâmplă lucruri rele. Și asta este exact ceea ce sa întâmplat să se gândească Binky. Astfel amintesc că povestea pe care Nick a fost spune aici a fost aceeași idee ca ceea ce Am desenat cu iluzia creta pe tablă acolo. X și Y sunt declarate. Apoi am alocat mărimea un int și depozitat-o ​​în x. Apoi următoarea linie am făcut * x. Aceasta a fost bagheta magică a lui Nick de dereferencing. Care pune 42 în memoria a subliniat de x. Dar acest lucru este în cazul în care lucrurile mers foarte prost. Dreapta? Am încercat să y dereference. Dar y avut o valoare fals, corect? Că săgeata în jos din partea stângă colț, nu este de fapt, arătând spre nimic. Este un fel de a face ceea ce am a făcut aici, de pe bord. Deci, se intampla lucruri rele, segmentarea vina, sau Binky vina, în acest caz. Dar, dacă atunci se stabilească faptul că prin a face x devine y Cum se schimbă povestea? Ei bine, dacă fac x devine y, care este efectiv aceeași cu a spune Orice ar fi, Ox-ceva va fi la fel aici, Ox-ceva. Sau pictural vom trage o săgeată. Deci, aici pe bord cu Binky, cu următoarea linie de cod, * y înseamnă că mergem acolo. Unde este acolo? Aceasta înseamnă peste aici. Și când am actualizare care să fie 13 aceasta implică doar merge și scris 13 aici acum. Deci, poate nu complet simplu la prima vedere. Dar trecerea în revistă și să utilizeze același jargon care Binky a folosit aici, așa primele două aloce indicii, x și y, dar nu a pointees. Și pointees nu face termen folosit în general. Dar indicatorul absolut este. Dar este ceea ce se a subliniat la în nomenclatura Binky. Această linie viitoare, desigur, alocă o pointee Int. Deci, o bucată de memorie - așa cum am atras peste pe partea dreapta acolo - și set x egal cu punctul de ea. Acest dereferences x pentru a stoca 42 în de memorie care este pointing la. Și apoi aceasta, desigur, a fost un lucru rău. Deoarece y nu a fost îndreptat la nimic încă. Aceasta se fixează. Deci, aceasta este în continuare program de buggy. Doar pentru că suntem suflare prin linie de cod de linie și spune, oh bine, lăsați-l să accident acolo. Asta e un lucru rău. Cote sunt programului doar de gând să abandona cu totul la acea linie. Dar dacă ar fi să scoateți prăbușit linie și să o înlocuiască cu ultimele două Liniile acolo atribui - folosind misiune pointer - y la punctul de x ca punct t. Și apoi dereference y într-un mod foarte sigur. Deci, unde ne duce asta? Ei bine, se dovedește că sub capota în CS50 biblioteca, indicii sunt utilizate în întreaga. Și vom începe efectiv de coaja înapoi ca strat înainte de lung. Dar se pare prea, o expresie care unii dintre voi s-ar putea să fie familiarizat cu, în special cele mai confortabile, este de fapt cea a unui foarte popular site-ul, sau Stack Overflow, în aceste zile. Dar acest fapt are foarte sensul tehnic. Acum știm ce o stivă este. E ca un teanc de tăvi în interiorul de o sală de mese. Sau în interiorul computerului Memoria sa aceste cadre care sunt utilizate de către funcțiile. Ei bine, se pare că din cauza asta implementarea foarte simplu de memorie și cadrele de pe așa-numitul stivă, puteți lua de fapt, controlul a unui sistem informatic destul de ușor. Puteți hack într-un sistem în cazul în care oamenii ca noi nu am scris codul nostru deosebit de bine. Dacă oameni ca noi folosesc bucăți de memorie sau de utilizare matrice - chiar mai frecvent - dar uneori uitați să verificați limitele gama noastră ca s-ar putea au tine uneori, și a reiterat mult prea departe dincolo de sfârșitul unei matrice. În cel mai bun caz, programul s-ar putea prăbuși doar. Eroare de segmentare, un fel de jenant. Nu este mare, dar nu este neapărat un lucru extrem de rău. Dar, în cazul în care programul este, de fapt pe reală computerele utilizatorilor, în cazul în care se execută pe un site web care persoane reale aleatoare pe Internet sunt lovind, permițându- oamenii induce lucruri rele pe care codul este în general, nu un lucru bun, deoarece înseamnă o oportunitate de a lua controlul calculatorului. Și acest lucru se întâmplă să uite un pic criptic. Dar am crezut că te sperii cu acest ultim exemplu aici. Iată un exemplu de cod. Și există o bună Wikipedia Articolul, care se plimba prin aceasta mai detaliat. Am principal la chemarea de jos foo, trecând în argv de 1. Și asta e doar astfel încât să puteți rula programul și să treacă o intrare arbitrar. Și apoi foo este declarat în sus de top ca acceptarea unui șir, sau mai mult precis, un char *. Ea declară apoi o serie de caractere. Numiți-un tampon, mai general, de mărimea 12. Deci, 12 caractere pot potrivi in ​​interiorul din care array numit C. Și apoi folosește această nouă funcție, ceea ce este nou, dar nu greu de înțelege, copie de memorie. Se copiază în memoria din bar, care a fost n trecut variabilă, indiferent utilizatorul tastat în argv 1 în C. Câți biți? Lungimea șir de bar. Deci, cu alte cuvinte, în cazul tipurilor de utilizare în h-e-l-l-o Introduceți, lungimea șirului de salut este de cinci ani. Deci, cinci dintre aceste bytes este mergi la a lua copiat în matrice numit C, care este de dimensiune 12. Dar tipurile de ceea ce utilizatorul într-o mult mai mult Cuvântul care este de 13 caractere sau 14 caractere sau 100 de caractere sau mai mult? În cazul în care au de gând să meargă? Ei bine, acel cadru, că tava în stivă de mese sala, ei vor să meargă acolo. Și este doar de gând să înceapă suprascrierea alte lucruri pe care e deja pe care stiva, debordant stiva, ca să spunem așa. Deci pictural, cred că de felul acesta. Aceasta este doar o versiune de colorat imaginea am fost de desen. În partea de jos, să spunem, este principala. Și pe partea de sus, ceea ce vedem acum este cadru, coduri de culoare acum, pentru o Funcția numit foo. Dar ceea ce este interesant aici despre foo este că aici este cadrul său. Deci, este redactat la fel cum am făcut, dar în albastru deschis. Iar acum acest lucru este în cazul în care C suport 0 merge. Și acest lucru este în cazul în c suport 11 se va termina. Cu alte cuvinte, se întâmplă să fi reprezentată ca un pătrat. Dar dacă doar vă păstrați plopping bytes jos - sau caractere - au de gând să se încheie până la locația 0 tot drumul în sus la 11 deoarece este 0 indexate. Dar unde este caracterul 13 va termina? Unde e al 14-lea? Unde e caracterul 50 va termina? Se va continua merge în jos. Pentru că, chiar dacă ne-am desenat imagine cu stiva de creștere, adrese, se pare, du-te la adrese mici, mici, indicii, la adrese mari. Așa că păstrează doar merge în sus și în sus. Deci, dacă utilizatorul tastează în Bună ziua, asta e minunat. Nu bug-ul, nici o problemă, în condiții de siguranță toată lumea. Dar dacă utilizatorul tastează în ceea ce vom apel cod contradictorie, reprezentată generic ca un, atac, atac, atac, atac, ce se poate întâmpla? Ei bine, dacă toate de intrare care utilizatorul tastat nu este doar un amical sau șir de caractere ofensiv. Este de fapt o secvență de caractere că, dacă l-ați compilat, este de fapt codul. Poate că e cod care șterge toate fișierele de pe hard disk sau trimite spam- sau ceva de genul asta. Observați că ceea ce este esențial aici este că În cazul în care personajul negativ ajuns suficient de norocos pentru a suprascrie bucată roșie de memorie - pe care nu am trage pe poza mea, dar această imagine Wikipedia are aici - așa-numitul adresa retur. Când se întoarce alimentare, atunci când se întoarce de swap, cum calculatorului știu să meargă la aici sus în jos aici? Sau în segmentul tehnologie până sus, cum nu știu să meargă din swap cod - 0 și de 1 care compun schimb - Înapoi la Principal? Există un așa-numitul adresa expeditorului stocate în același cadru stivă, pe aceeași tavă cantină. Deci, dacă cel rău este destul de inteligent pentru a pune codul de atac, cod de atac, de atac cod, și de a lua suficient de norocos - de multe ori prin încercare și eroare - a suprascrie care adresa expeditorului roșu, cu adresa și anunțul foarte de sus. Observați 0835C080. Este scris invers sus de top pentru Motivele vom poate revizita. Acest lucru este faptul că numărul. Deci, dacă cel rău devine suficient de norocos sau este suficient de inteligent pentru a suprascrie roșu fâșie de memorie cu adresa de cod care el sau ea are într-un fel injectat în computer, ghici cărui Codul va fi returnat îndată ce foo se face executare? Codul tipului cel rau. Deci, acest cod de atac, AAA, din nou, s-ar putea trimite spam-ul, s-ar putea șterge toate fișierele pe hard disk. Dar asta este ceea ce cu adevărat un stack overflow este, sau o depășire tampon, sau un buffer overflow atac. Și e incredibil, incredibil de comune la această zi, cu programe scrise în C, C + +, și chiar unele alte limbi. Pe această notă infricosator, vom se încheie cu o glumă. [Râsete] Ne vedem miercuri. La următoarea CS50 - Deci, eu sunt tot de lămpi disc de azi, dar așteptați, fara grasimi din lapte, jumătate din telefon carte, suc de portocale că am băut azi. Cablu USB, o cheie. [Redarea muzicii]