[REPRODUCCIÓ DE MÚSICA] DOUG LLOYD: D'acord. Tipus d'un tema estrany, no? Números de màgia. Què cérvola vol dir quan és parlant de nombres màgics? Bé, alguns dels programes que hem escrit en CS50 fins al moment han tingut alguna estranya números de tipus d'llançats en ells. Potser per raons no ho fem totalment entendre ara. Per exemple, en el problema Mario, ens cobertes l'altura de la piràmide de 23. Li vam dir explícitament no pot anar més alt que 23. Però, ¿què vol dir 23? Bé, si vostè llegeix el spec acuradament, podria haver vist que el raó per la qual va coronar al 23 és a causa de que l'altura estàndard d'una finestra de terminal és 24. I pel que si tenim la piràmide ser més alt que això, que podria fer aquesta cosa rara on s'executa fora de la pantalla. I ja saps, el que fa Això vol dir que en el context, no? És el significat de 23 immediatament obvi algú que mira al seu programa i potser té una diferent finestra de terminal mida? Probablement no. Sembla que, a D'acord. Bé, per què és una mica menys de 23? En general, és una espècie d'un mal hàbit en realitat per escriure constants en el codi. D'aquesta manera, quan en realitat ho fa escriure una constant en el seu codi, es refereix a vegades com l'ús de números màgics, que és una cosa en general, volem tractar d'evitar. Per exemple, anem a fer una ullada Aquesta senzilla funció aquí. Òbviament no hi ha dades tipus en C anomenat targeta o coberta. Així que tinguin paciència amb mi. És una mica de pseudocodi barrejat aquí. Aquesta és una funció anomenada tractar targeta que aparentment pren una baralla com a paràmetre, i sortida de voluntat per a mi una sola targeta. I jo estic fent alguna cosa aquí on jo tenir un bucle que va des de 0 a 52, i m'ocupo d'una targeta. Bé, tenim una màgia nombre aquí, a la dreta. Veus el que el nombre màgic és? O més important encara, oi veure quin és el problema aquí? En particular, si aquesta és només una funció en el seu propi arxiu en un carpeta que conté un munt de diferents arxius, cadascun dels quals fa altra cosa que una baralla de cartes. Potser ells baralla, o s'ocupa un cop de mà de cinc cartes en lloc d'una sola targeta. Veus el que el problema podria ser aquí? Veus el nombre màgic He s'injecta en el codi? És el 52, a la dreta. Igual que, intuïtivament vostè probablement sap, a D'acord. Igual que una baralla de targetes conté 52 cartes. Però en el nostre programa, és només tipus de flotant per aquí. És com, de sobte, hi ha un 52. Una manera de resoldre aquest problema és que fer això. Estem molt explícitament ara dient en veu alta la mida de la coberta com 52. Se li dóna una mica més intuïtiu és a dir, quan en el bucle for més endavant, doncs, direm, i és menor que la mida de la coberta. Simplement sembla millor que dir 52. Ara bé, això realment solucionar el problema. Es dóna alguna simbòlica sentit a la constant. Però sí espècie de realitat introduir un altre problema que podria no ser evident immediatament. Fins i tot si aquesta variable es declara globally-- Què recordes el que vol dir que quan vam declarar una variable a nivell mundial davant nivell local? Fins i tot si declarem una variable a nivell mundial, el que si hi ha una altra funció en nostre conjunt de funcions que tenen a veure amb la manipulació de targetes que inadvertidament canvis de mida de la coberta, o l'augmenta per 1 o disminueix per 1. Això podria significar un problema, oi? Sobretot si estem tractant amb un conjunt de cartes on remenar la baralla completa es requereix. Si es disminueix la mida de la coberta per 1, per exemple, a 51, no estem realment estudiant totes les cartes, possiblement. Ens anem a un d'ells. I aquest valor podria potser ser predit o explotada per un mal actor. C ofereix el que s'anomena un directiva de preprocessador, que també es diu una macro per creant constants simbòliques. I, de fet, ja ha vist una directiva de preprocessador, encara que no ha sentit anomenat així amb #include. És un altre exemple d'una macro o directiva de preprocessador. La forma de crear constants simbòliques, o donar un nom a una constant de manera que tingui més el que significa, és com segueix. #define, nom, reemplaçament. Realment important a un costat aquí realment ràpid. No poseu un punt i coma al Al final dels seus #defines. Així que és #define, nom, reemplaçament. Quan es compila el programa, el que realment passa és el compilador si va de passar pel seu codi i reemplaçar totes les instàncies de la paraula "nom" amb tot el que posar com a reemplaçament. Anàlogament, si #include és una espècie de similar a copiar i enganxar, llavors #define és una espècie de similar a cercar i reemplaçar, si alguna vegada has fet servir aquesta característica en un processador de textos, per exemple. Així, per exemple, si #define PI com 3.14159265, si ets millor matemàticament inclinada i de sobte veure 3.14159265 vol tot en el seu codi, vostè probablement sap que està parlant de pi. Però tal vegada puguem donar-li una poc significat més simbòlic. I en comptes podem dir #define pi com la boca plena de nombres que jo no vaig a seguir llegir una i altra. ¿I què passarà després a temps de compilació és quan el programa és compilat, el primer que passarà és que va a anar a través de i es reemplaçarà cada vegada que considera el capital P, capital I, va literalment substituir-la per 3.14 i així successivament, de manera que vostè no haver de escriure cada temps, mentre que el seu programa encara té la funcionalitat que esperar, perquè estàs treballant amb manipulació, multiplicar, dividint, el que sigui per pi. No està limitat a aquest substitució de només números. Per exemple, jo podria #define Per descomptat com el CS50 cadena. En aquest cas, quan el programa es compila, #define passaran per la codi, substitueixi cada vegada veu "clar" amb el CS50 cadena. S'ha de donar compte aquí també que amb freqüència #define tota la meva definit simbòlica constants, per així dir-ho, estan sempre en majúscules. És una convenció. No és necessari. La raó en general la gent utilitzarà totes les capitals quan estan #defining és només perquè sigui realment clar que aquest element particular de la meva codi és una constant definida. Si era minúscula, és possible que que podria confondre amb una variable. I això és, probablement, no és una bona cosa que fer. Així que aquest particular, solució és molt millor que qualsevol dels anteriors. Si jo primer #define mida de la coberta 52, a continuació, ara el meu ús de 52, o la mida de la coberta aquí, és molt més intuïtiu i molt més segur. No es pot manipular una constant. No es pot dir 52 plus plus. Això no va a convertir-lo a 53. No es pot canviar 52 a alguna cosa. Podeu canviar una variable el valor és 52, que va ser la primera solució que teníem abans. I vostè pot augmentar aquesta variable a 53. Però no es pot dir 52 plus plus i tenir que de sobte al seu torn 52-53. 52 és sempre 52. I el que no pot canviar inadvertidament mida de la coberta aquí mitjançant la manipulació d'ella, Un altre costat bo efecte d'això, però és que són conscients que no tots els països de tot el món utilitzar un mall de cartes de mida de 52? Per exemple, és molt comú en Alemanya utilitzar una mida de coberta de 32, on tira alguns de les cartes de menys valor. I en aquest cas, volgut port de la meva suite de les funcions que tenen a veure amb cartomàgia a Alemanya. Que vaig poder en la primera instància que va mostrar, han d'anar i reemplaçar totes les instàncies de 52 en el meu codi amb 32. Però aquí, si em #define mida de la coberta 32 a la part superior del meu codi, si he de canviar, no puc només ha d'anar i canviar aquesta cosa. Torneu a compilar el meu codi, i tots sobte es propaga a través. De fet, podem canviar la coberta grandària a qualsevol valor que volem. Et puc interessar en un joc de mida de la coberta de recollida? Sóc Doug Lloyd. I això és CS50.