[RIPRODUZIONE DI BRANI MUSICALI] DOUG LLOYD: Va bene. Tipo di un argomento strano, giusto? Numeri magici. Cosa doe intendeva dire quando è parlando di numeri magici? Ebbene, alcuni dei programmi che abbiamo scritto in CS50 finora hanno avuto qualche strano numeri tipo di gettato in loro. Forse per ragioni non lo facciamo interamente capire adesso. Ad esempio, nel problema Mario, abbiamo ricoperto l'altezza della piramide a 23. Abbiamo detto in modo esplicito si non si può andare più in alto di 23. Ma cosa vuol dire 23? Beh, se avete letto il spec attenzione, si potrebbe aver visto che la motivo per cui abbiamo innevate che a 23 è perché l'altezza standard di una finestra di terminale è 24. E così, se abbiamo il piramide essere più alto di quello, si potrebbe fare questa cosa strana dove si corre fuori dallo schermo. E si sa, che cosa fa che significa in un contesto, giusto? È il significato del 23 immediatamente evidente a qualcuno che guarda il tuo programma e ha forse un diverso finestra di terminale dimensioni? Probabilmente no. Sembra, OK. Beh, perché è poco meno di 23? In generale, è una specie di una cattiva abitudine in realtà scrivere le costanti nel codice. In tal modo, quando si effettivamente fare scrivere un costante nel codice, è a volte indicato come l'utilizzo numeri magici, che è qualcosa generalmente vogliamo cercare di evitare. Ad esempio, diamo un'occhiata in questa semplice funzione qui. Ovviamente c'è nessun dato tipo in C chiamato carta o del ponte. Quindi, solo portare con me. E 'un po' di pseudocodice mescolato qui. Questa è una funzione denominata trattare carta che a quanto pare prende un mazzo come parametro, e volontà di uscita per me una singola scheda. E sto facendo qualcosa qui dove mi hanno un ciclo che va da 0 a 52, e mi occupo di una carta. Bene, abbiamo una magia numero in qua, a destra. Vedete quello che il numero magico è? O ancora più importante, si fa vedere qual è il problema qui? In particolare se questo è solo una funzione nel proprio file in un cartella che contiene un mucchio di diverso file, ciascuna delle quali fa un'altra cosa da un mazzo di carte. Forse li rimescola, o infligge una mano di cinque carte invece di una singola scheda. Vedete quello che il problema potrebbe essere qui? Vedete il numero magico Ho iniettato nel codice? E '52, a destra. Come, intuitivamente probabilmente sapete, OK. Come un mazzo standard di carte contiene 52 carte. Ma nel nostro programma, è solo tipo di galleggianti intorno in là. E 'come tutto ad un tratto c'è un 52. Un modo per risolvere questo problema è di fare questo. Siamo molto esplicito ora chiamando la dimensione ponte come 52. Dà un po 'più intuitivo cioè quando nel ciclo for in seguito abbiamo poi diciamo, i è di dimensioni inferiori ponte. Sembra proprio meglio che dire 52. Ora questo realmente risolvere il problema. Si dà un po 'simbolica cioè alla costante. Ma lo fa sorta di realtà introdurre un altro problema che potrebbe non essere immediatamente evidente. Anche se questa variabile è dichiarata globally-- ti ricordi che cosa significa che quando si dichiara una variabile globale contro a livello locale? Anche se si dichiara una variabile a livello globale, che cosa se non c'è un'altra funzione la nostra suite di funzioni che si occupano di CARTOMAGIA che cambia inavvertitamente le dimensioni della piattaforma, o aumenta dal 1 o diminuisce entro 1. Questo potrebbe significare guai, giusto? Soprattutto se abbiamo a che fare con un set di carte dove mescola il mazzo completo è obbligatorio. Se la dimensione della piattaforma è diminuita da 1, per esempio, a 51, non stiamo in realtà mischiare tutte le carte eventualmente. Stiamo lasciando uno di loro fuori. E che valore potrebbe forse previsti o sfruttato da un cattivo attore. C fornisce ciò che è chiamato un direttiva del preprocessore, che è chiamato anche una macro per creando costanti simboliche. E infatti, hai già visto una direttiva del preprocessore, anche se non avete sentito chiamata che con #include. E 'un altro esempio di una macro o direttiva del preprocessore. Il modo per creare costanti simboliche, o dare un nome a una costante in modo che abbia più il che significa, è il seguente. #define, nome, la sostituzione. Davvero importante da parte qui davvero veloce. Non mettere un punto e virgola alla fine dei vostri # definisce. Quindi è #define, nome, la sostituzione. Quando il programma viene compilato, ciò che effettivamente accade è il compilatore se andare per passare attraverso il codice e sostituire ogni istanza di la parola "nome" con tutto quello che mettere in sostituzione. Analogamente, se #include è una sorta di simile a copiare e incollare, poi #define è una sorta di simile per trovare e sostituire, se avete mai usato questa funzione in un programma di elaborazione testi, per esempio. Così, per esempio, se #define pi greco come 3.14159265, se siete meglio matematicamente improvvisamente inclinato e si vedi 3.14159265 volare intorno nel codice, probabilmente sapete che sta parlando pi greco. Ma forse possiamo dare un poco significato più simbolico. E possiamo invece dire #define pi come quello boccone di numeri che io non ho intenzione di continuare a leggere più e più volte. E cosa succederà poi a tempo di compilazione è quando il programma è compilato, la prima cosa che che accadrà è che passerà attraverso e sostituirà ogni volta vede la P maiuscola, maiuscola, che sarà letteralmente sostituirlo con 3.14 e così via, in modo che non c'è bisogno di digitare ogni tempo mentre il programma ancora ha la funzionalità che si aspettare, perché si sta lavorando con manipolazione, moltiplicando, dividendo, qualunque essa sia per pi. Non si sono limitati a questo sostituzione di solo numeri. Per esempio, potrei #define Naturalmente come il CS50 stringa. In questo caso, quando il programma è compilato, #define passerà attraverso il codice, sostituire ogni volta vede "corso" con il CS50 corda. Noterete qui anche che ho spesso #define tutto il mio definito simbolico costanti, per così dire, sono sempre in tutte le protezioni. Si tratta di una convenzione. Non è necessario. La ragione per cui generalmente la gente userà tutte le capitali quando sono #defining è solo per rendere veramente chiaro che questo particolare elemento del mio codice è una costante definita. Se era minuscolo, è possibile che potrebbe essere confusa con una variabile. E questo è probabilmente non è una buona cosa da fare. Così questo particolare soluzione è molto meglio a nessuno di quelli precedenti. Se ho #define formato mazzo di 52, quindi ora il mio uso di 52 o dimensione ponte qui, è molto più intuitivo e molto più sicuro. Non è possibile modificare una costante. Non si può dire 52 plus plus. Che non sta andando per convertirlo a 53. Non è possibile modificare 52 a qualcosa. È possibile modificare una variabile il cui valore è 52, che era il primo fix che avevamo prima. E si potrebbe aumentare la variabile a 53. Ma non si può dire 52 plus plus e avere che improvvisamente trasformare 52 in 53. 52 è sempre 52. E così non si può inavvertitamente cambiare Dimensioni ponte qui manipolando esso, Un altro lato positivo effetto di questo è però che sono consapevole che non tutti i paesi del mondo utilizzare un mazzo di carte di dimensioni 52? Ad esempio, è molto comune in La Germania di usare una dimensione mazzo di 32, dove si spogliano alcune delle carte di valore inferiore. E in questo caso, voluto porto mia suite di funzioni che si occupano di CARTOMAGIA in Germania. Ho potuto in primo luogo abbiamo ha dimostrato, devono andare e sostituire tutte le istanze di 52 nel mio codice con 32. Ma qui, se mi #define dimensioni ponte come 32 in cima del mio codice, se ho bisogno di cambiare, non posso basta andare a cambiare che una cosa. Ricompilare mio codice, e tutti All'improvviso si propaga attraverso. In realtà, siamo in grado di cambiare piattaforma size ad alcun valore che vogliamo. Posso interesse in un gioco di dimensioni ponte ritiro? Sono Doug Lloyd. E questo è CS50.