[MUSIC JOC] DOUG LLOYD: Bine. Un fel de subiect ciudat, nu? Numere magice. Ce doe să spună când e vorbim despre numere magice? Ei bine, unele dintre programele pe care le-am scris în CS50 până în prezent au avut unele ciudat Numerele tip de aruncat în ele. Poate din motive nu avem înțelege pe deplin acum. De exemplu, în problema Mario, am plafonate înălțimea piramidei la 23. Vă spus în mod explicit nu poate merge mai mare de 23. Dar ce înseamnă 23? Ei bine, dacă ai citit spec atenție, vă ar fi văzut că motiv am limitat la 23 se datorează faptului că înălțimea standard de de o fereastră de terminal este de 24. Și astfel, dacă avem piramidă să fie mai înalt decât că, s-ar putea face acest lucru ciudat în cazul în care se execută de pe ecran. Și știi, ce face Asta înseamnă, în context, nu? Este sensul de 23 imediat evidente pentru cineva care se uita la programul tău și poate are un alt fereastră terminal dimensiune? Probabil ca nu. Se pare ca, OK. Ei bine, de ce este doar mai puțin de 23? În general, e un fel de un obicei prost de fapt pentru a scrie constante în codul. În acest sens, atunci când de fapt, nu scrie o constantă în codul, este uneori menționată ca folosind numere magice, care este ceva Noi, în general doriți să încercați și de a evita. De exemplu, haideți să aruncăm o privire la această funcție simplă aici. Evident, nu există nici date tip în C numit card sau punte. Deci, doar să poarte cu mine. E un pic de pseudocod amestecat aici. Aceasta este o funcție numită face carte de care se pare că ia o punte ca parametru său și voința de ieșire pentru mine un singur card. Și eu fac ceva aici, unde am au o buclă care ruleaza 0-52, și am face un card. Ei bine, avem o magie Numărul aici, dreapta. Vezi ce numărul magic este? Sau mai important, nu-i așa vezi care e problema aici? În special în cazul în care acest lucru este doar o funcție în propriul fișier într-un dosar care conține o grămadă de diferite fișiere, fiecare dintre care nu un alt lucru la un pachet de cărți. Poate că le amesteca, oferte o mână de cinci cărți în loc de un singur card. Ai vedea ce problemă ar putea fi aici? Nu veți vedea numărul magic Am injectat în codul? E 52, dreapta. Ca, intuitiv probabil știți, OK. Ca un pachet standard de Carduri conține 52 de cărți. Dar, în programul nostru, e doar fel de plutesc în jurul acolo. E ca și cum dintr-o dată există o 52. O modalitate de a rezolva această problema este de a face acest lucru. Suntem foarte explicit acum strigând dimensiunea punte ca 52. Acesta oferă un pic mai mult intuitiv adică atunci când în bucla de mai târziu vom spune atunci, am este mai mică decât dimensiunea punte. Mi se pare mai bine decât a spune 52. Acum, acest lucru nu rezolva de fapt problema. Aceasta dă unele simbolică adică la constanta. Dar nu un fel de efectiv introduce o altă problemă care ar putea să nu fie vizibile imediat. Chiar dacă această variabilă este declarat globally-- Îți amintești ce înseamnă că atunci când ne declarăm o variabilă la nivel global față de la nivel local? Chiar dacă ne-am declara o variabilă la nivel global, ce dacă e o altă funcție în suita noastră de funcții care se ocupă cu manipularea carte care se schimbă accidental dimensiuni punte, sau crește de 1 sau scade cu 1. Asta ar putea vraja probleme, nu? Mai ales dacă avem de-a face cu un set de cărți în care amestecarea pachetul complet este necesară. Dacă dimensiunea punte este scăzut de 1, de exemplu, la 51, nu suntem de fapt amestecare toate cărțile eventual. Plecăm una dintre ele afară. Și că ar putea fi, probabil, o valoare prezis sau exploatat de către un actor prost. C oferă ceea ce se numește un Directiva preprocesor, care este de asemenea, numit un macro pentru crearea constante simbolice. Și, de fapt, ai deja văzut o directivă preprocesor, chiar dacă nu ați auzit numit care cu #include. Este un alt exemplu de macro sau directiva preprocesor. Modul de a crea constante simbolice, sau de a da un nume pentru o constantă astfel încât acesta are mai adică, este după cum urmează. #define, numele, de înlocuire. Într-adevăr importantă parte aici foarte repede. Nu pune punct și virgulă la la sfârșitul anului #defines tale. Deci e #define, numele, de înlocuire. Când programul este compilat, ce se întâmplă de fapt este compilatorul dacă merge pentru a merge prin codul și înlocuiți fiecare instanță a cuvântul "nume" cu tot ce pune ca înlocuitor. În mod analog, în cazul în care este un fel #include de similar cu copierea și lipirea, atunci #define este un fel de similar cu a găsi și înlocui, Dacă ați folosit vreodată că într-o funcție program de procesare de text, de exemplu. Deci, de exemplu, dacă am #define pi ca 3.14159265, daca esti mai bine matematic înclinat și dintr-o dată vezi 3.14159265 zbor în jurul valorii de în codul dvs., Probabil știi că vorbește despre pi. Dar poate putem da o puțin mai mult simbolic înțeles. Și putem spune în schimb #define pi ca și gura de numere că nu am de gând să păstreze lectură de peste si peste. Și ce se va întâmpla apoi la compila timp este atunci când programul este compilat, primul lucru pe care se va întâmpla este va trece prin și va înlocui de fiecare dată vede de capital P, capitalul I, acesta va înlocui literalmente cu o 3.14 și așa mai departe, astfel încât să Nu trebuie să tastați în fiecare timp în timp ce programul tău încă are funcționalitatea pe care le se așteaptă, pentru că lucrezi cu manipulare, înmulțirea, divizarea, orice ar fi de pi. Tu nu sunt limitate la acest înlocuire pentru doar numere. De exemplu, aș putea #define Desigur ca CS50 șir. În acest caz, în cazul în care Programul este compilat, #define va trece prin cod, înlocuiți de fiecare dată vede "curs", cu CS50 șir. Veți observa aici de asemenea, că am frecvent #define toate mea definit simbolic constante, ca să spunem așa, sunt întotdeauna în toate capacele. E o convenție. Nu este necesar. Motivul, în general, oamenii vor folosi toate capitalele atunci când acestea sunt #defining este doar pentru a face într-adevăr clar că acest element special de codul meu este o constantă definită. Dacă ar fi fost cu litere mici, este posibil ca ar putea fi confundat cu o variabilă. Și asta e, probabil, nu un lucru bun pentru a face. Deci, acest special soluție este mult mai bine decât oricare dintre cele anterioare. Dacă aș prima #define dimensiune pachet de 52, atunci acum utilizarea mea de 52, sau dimensiunea punte aici, este mult mai intuitivă și mult mai sigure. Nu puteți manipula o constantă. Nu se poate spune 52, plus, plus. Asta nu o să-l convertească la 53. Nu puteți schimba 52 la ceva. Puteți schimba o variabilă a căror valoare este de 52, care a fost primul fix am avut-o înainte. Și ar putea crește variabila la 53. Dar nu se poate spune 52, plus, plus și au ca transforma brusc 52 în 53. 52 este întotdeauna 52. Și astfel nu se poate schimba din greșeală Dimensiunea punte aici prin manipularea acesteia, Un alt parte buna efect de acest lucru, deși este că sunteți conștienți de faptul că nu toate țările din întreaga lume utilizați un pachet de cărți de dimensiuni 52? De exemplu, este foarte comun în Germania a utiliza o dimensiune pachet de 32, în cazul în care benzi unele de carduri de valoare inferioare. Și în acest caz, am a vrut să-mi port de suită de funcții care se ocupă cu manipulare carte în Germania. Am putea, în primul rând ne-am a arătat, trebuie să meargă și să înlocuiască toate cazurile de 52 în codul meu cu 32. Dar aici, dacă am #define dimensiune punte ca 32 la foarte de sus a codul meu, dacă am nevoie să-l schimbe, pot du-te și schimba asta un lucru. Recompilați codul meu, și toate Dintr-o dată se propagă prin intermediul. De fapt, putem schimba punte dimensiune la orice valoare dorim. Pot să vă interes într-o joc de dimensiuni punte pickup? Sunt Doug Lloyd. Și acest lucru este CS50.