1 00:00:00,000 --> 00:00:02,350 >> [REPRODUCCIÓ DE MÚSICA] 2 00:00:02,350 --> 00:00:05,444 3 00:00:05,444 --> 00:00:06,360 DOUG LLOYD: D'acord. 4 00:00:06,360 --> 00:00:07,770 Tipus d'un tema estrany, no? 5 00:00:07,770 --> 00:00:09,050 Números de màgia. 6 00:00:09,050 --> 00:00:12,012 Què cérvola vol dir quan és parlant de nombres màgics? 7 00:00:12,012 --> 00:00:14,220 Bé, alguns dels programes que hem escrit en CS50 8 00:00:14,220 --> 00:00:16,660 fins al moment han tingut alguna estranya números de tipus d'llançats en ells. 9 00:00:16,660 --> 00:00:19,680 Potser per raons no ho fem totalment entendre ara. 10 00:00:19,680 --> 00:00:23,950 Per exemple, en el problema Mario, ens cobertes l'altura de la piràmide de 23. 11 00:00:23,950 --> 00:00:26,880 Li vam dir explícitament no pot anar més alt que 23. 12 00:00:26,880 --> 00:00:28,702 >> Però, ¿què vol dir 23? 13 00:00:28,702 --> 00:00:30,410 Bé, si vostè llegeix el spec acuradament, 14 00:00:30,410 --> 00:00:32,493 podria haver vist que el raó per la qual va coronar al 23 15 00:00:32,493 --> 00:00:36,160 és a causa de que l'altura estàndard d'una finestra de terminal és 24. 16 00:00:36,160 --> 00:00:38,860 I pel que si tenim la piràmide ser més alt que això, 17 00:00:38,860 --> 00:00:41,290 que podria fer aquesta cosa rara on s'executa fora de la pantalla. 18 00:00:41,290 --> 00:00:45,140 I ja saps, el que fa Això vol dir que en el context, no? 19 00:00:45,140 --> 00:00:48,880 >> És el significat de 23 immediatament obvi algú que mira al seu programa 20 00:00:48,880 --> 00:00:51,550 i potser té una diferent finestra de terminal mida? 21 00:00:51,550 --> 00:00:52,330 Probablement no. 22 00:00:52,330 --> 00:00:53,080 Sembla que, a D'acord. 23 00:00:53,080 --> 00:00:55,005 Bé, per què és una mica menys de 23? 24 00:00:55,005 --> 00:00:56,880 En general, és una espècie d'un mal hàbit en realitat 25 00:00:56,880 --> 00:00:58,940 per escriure constants en el codi. 26 00:00:58,940 --> 00:01:02,190 D'aquesta manera, quan en realitat ho fa escriure una constant en el seu codi, 27 00:01:02,190 --> 00:01:05,630 es refereix a vegades com l'ús de números màgics, que és una cosa 28 00:01:05,630 --> 00:01:08,030 en general, volem tractar d'evitar. 29 00:01:08,030 --> 00:01:12,830 >> Per exemple, anem a fer una ullada Aquesta senzilla funció aquí. 30 00:01:12,830 --> 00:01:15,726 Òbviament no hi ha dades tipus en C anomenat targeta o coberta. 31 00:01:15,726 --> 00:01:16,600 Així que tinguin paciència amb mi. 32 00:01:16,600 --> 00:01:18,910 És una mica de pseudocodi barrejat aquí. 33 00:01:18,910 --> 00:01:21,050 Aquesta és una funció anomenada tractar targeta que aparentment 34 00:01:21,050 --> 00:01:26,570 pren una baralla com a paràmetre, i sortida de voluntat per a mi una sola targeta. 35 00:01:26,570 --> 00:01:30,990 >> I jo estic fent alguna cosa aquí on jo tenir un bucle que va des de 0 a 52, 36 00:01:30,990 --> 00:01:33,394 i m'ocupo d'una targeta. 37 00:01:33,394 --> 00:01:35,310 Bé, tenim una màgia nombre aquí, a la dreta. 38 00:01:35,310 --> 00:01:38,790 Veus el que el nombre màgic és? 39 00:01:38,790 --> 00:01:42,280 O més important encara, oi veure quin és el problema aquí? 40 00:01:42,280 --> 00:01:44,310 En particular, si aquesta és només una funció 41 00:01:44,310 --> 00:01:48,030 en el seu propi arxiu en un carpeta que conté 42 00:01:48,030 --> 00:01:49,970 un munt de diferents arxius, cadascun dels quals 43 00:01:49,970 --> 00:01:51,670 fa altra cosa que una baralla de cartes. 44 00:01:51,670 --> 00:01:57,310 Potser ells baralla, o s'ocupa un cop de mà de cinc cartes en lloc d'una sola targeta. 45 00:01:57,310 --> 00:01:59,420 >> Veus el que el problema podria ser aquí? 46 00:01:59,420 --> 00:02:03,220 Veus el nombre màgic He s'injecta en el codi? 47 00:02:03,220 --> 00:02:04,390 És el 52, a la dreta. 48 00:02:04,390 --> 00:02:06,440 >> Igual que, intuïtivament vostè probablement sap, a D'acord. 49 00:02:06,440 --> 00:02:09,740 Igual que una baralla de targetes conté 52 cartes. 50 00:02:09,740 --> 00:02:12,570 Però en el nostre programa, és només tipus de flotant per aquí. 51 00:02:12,570 --> 00:02:15,280 És com, de sobte, hi ha un 52. 52 00:02:15,280 --> 00:02:18,290 >> Una manera de resoldre aquest problema és que fer això. 53 00:02:18,290 --> 00:02:22,724 Estem molt explícitament ara dient en veu alta la mida de la coberta com 52. 54 00:02:22,724 --> 00:02:25,390 Se li dóna una mica més intuïtiu és a dir, quan en el bucle for 55 00:02:25,390 --> 00:02:28,650 més endavant, doncs, direm, i és menor que la mida de la coberta. 56 00:02:28,650 --> 00:02:32,666 Simplement sembla millor que dir 52. 57 00:02:32,666 --> 00:02:34,290 Ara bé, això realment solucionar el problema. 58 00:02:34,290 --> 00:02:38,460 Es dóna alguna simbòlica sentit a la constant. 59 00:02:38,460 --> 00:02:40,820 Però sí espècie de realitat introduir un altre problema 60 00:02:40,820 --> 00:02:43,770 que podria no ser evident immediatament. 61 00:02:43,770 --> 00:02:45,859 Fins i tot si aquesta variable es declara globally-- 62 00:02:45,859 --> 00:02:47,650 Què recordes el que vol dir que quan vam declarar 63 00:02:47,650 --> 00:02:50,500 una variable a nivell mundial davant nivell local? 64 00:02:50,500 --> 00:02:53,340 Fins i tot si declarem una variable a nivell mundial, el que si hi ha 65 00:02:53,340 --> 00:02:55,500 una altra funció en nostre conjunt de funcions 66 00:02:55,500 --> 00:02:59,750 que tenen a veure amb la manipulació de targetes que inadvertidament canvis de mida de la coberta, 67 00:02:59,750 --> 00:03:02,727 o l'augmenta per 1 o disminueix per 1. 68 00:03:02,727 --> 00:03:04,060 Això podria significar un problema, oi? 69 00:03:04,060 --> 00:03:08,261 Sobretot si estem tractant amb un conjunt de cartes on remenar la baralla completa 70 00:03:08,261 --> 00:03:08,760 es requereix. 71 00:03:08,760 --> 00:03:12,804 Si es disminueix la mida de la coberta per 1, per exemple, a 51, 72 00:03:12,804 --> 00:03:14,970 no estem realment estudiant totes les cartes, possiblement. 73 00:03:14,970 --> 00:03:16,500 Ens anem a un d'ells. 74 00:03:16,500 --> 00:03:21,680 I aquest valor podria potser ser predit o explotada per un mal actor. 75 00:03:21,680 --> 00:03:24,920 >> C ofereix el que s'anomena un directiva de preprocessador, que 76 00:03:24,920 --> 00:03:27,764 també es diu una macro per creant constants simbòliques. 77 00:03:27,764 --> 00:03:30,180 I, de fet, ja ha vist una directiva de preprocessador, 78 00:03:30,180 --> 00:03:32,916 encara que no ha sentit anomenat així amb #include. 79 00:03:32,916 --> 00:03:37,150 És un altre exemple d'una macro o directiva de preprocessador. 80 00:03:37,150 --> 00:03:41,290 >> La forma de crear constants simbòliques, o donar un nom a una constant 81 00:03:41,290 --> 00:03:43,740 de manera que tingui més el que significa, és com segueix. 82 00:03:43,740 --> 00:03:47,030 #define, nom, reemplaçament. 83 00:03:47,030 --> 00:03:49,140 Realment important a un costat aquí realment ràpid. 84 00:03:49,140 --> 00:03:54,180 No poseu un punt i coma al Al final dels seus #defines. 85 00:03:54,180 --> 00:03:57,310 Així que és #define, nom, reemplaçament. 86 00:03:57,310 --> 00:03:59,540 >> Quan es compila el programa, el que realment passa 87 00:03:59,540 --> 00:04:01,740 és el compilador si va de passar pel seu codi 88 00:04:01,740 --> 00:04:06,770 i reemplaçar totes les instàncies de la paraula "nom" amb tot el que 89 00:04:06,770 --> 00:04:08,860 posar com a reemplaçament. 90 00:04:08,860 --> 00:04:13,060 Anàlogament, si #include és una espècie de similar a copiar i enganxar, 91 00:04:13,060 --> 00:04:15,700 llavors #define és una espècie de similar a cercar i reemplaçar, 92 00:04:15,700 --> 00:04:19,180 si alguna vegada has fet servir aquesta característica en un processador de textos, per exemple. 93 00:04:19,180 --> 00:04:26,345 >> Així, per exemple, si #define PI com 3.14159265, 94 00:04:26,345 --> 00:04:28,720 si ets millor matemàticament inclinada i de sobte 95 00:04:28,720 --> 00:04:31,640 veure 3.14159265 vol tot en el seu codi, 96 00:04:31,640 --> 00:04:33,517 vostè probablement sap que està parlant de pi. 97 00:04:33,517 --> 00:04:35,850 Però tal vegada puguem donar-li una poc significat més simbòlic. 98 00:04:35,850 --> 00:04:39,850 I en comptes podem dir #define pi com la boca plena de nombres 99 00:04:39,850 --> 00:04:42,110 que jo no vaig a seguir llegir una i altra. 100 00:04:42,110 --> 00:04:45,560 >> ¿I què passarà després a temps de compilació és quan el programa és 101 00:04:45,560 --> 00:04:48,530 compilat, el primer que passarà és que va a anar a través de 102 00:04:48,530 --> 00:04:51,520 i es reemplaçarà cada vegada que considera el capital P, capital I, 103 00:04:51,520 --> 00:04:55,610 va literalment substituir-la per 3.14 i així successivament, de manera que vostè 104 00:04:55,610 --> 00:04:58,090 no haver de escriure cada temps, mentre que el seu programa encara 105 00:04:58,090 --> 00:05:00,631 té la funcionalitat que esperar, perquè estàs treballant 106 00:05:00,631 --> 00:05:05,090 amb manipulació, multiplicar, dividint, el que sigui per pi. 107 00:05:05,090 --> 00:05:08,230 >> No està limitat a aquest substitució de només números. 108 00:05:08,230 --> 00:05:12,279 Per exemple, jo podria #define Per descomptat com el CS50 cadena. 109 00:05:12,279 --> 00:05:14,070 En aquest cas, quan el programa es compila, 110 00:05:14,070 --> 00:05:16,236 #define passaran per la codi, substitueixi cada vegada 111 00:05:16,236 --> 00:05:19,900 veu "clar" amb el CS50 cadena. 112 00:05:19,900 --> 00:05:21,720 >> S'ha de donar compte aquí també que amb freqüència 113 00:05:21,720 --> 00:05:26,090 #define tota la meva definit simbòlica constants, per així dir-ho, 114 00:05:26,090 --> 00:05:28,130 estan sempre en majúscules. 115 00:05:28,130 --> 00:05:28,960 És una convenció. 116 00:05:28,960 --> 00:05:30,170 No és necessari. 117 00:05:30,170 --> 00:05:33,900 La raó en general la gent utilitzarà totes les capitals quan estan #defining 118 00:05:33,900 --> 00:05:37,590 és només perquè sigui realment clar que aquest element particular de la meva codi 119 00:05:37,590 --> 00:05:38,820 és una constant definida. 120 00:05:38,820 --> 00:05:43,730 Si era minúscula, és possible que que podria confondre amb una variable. 121 00:05:43,730 --> 00:05:46,120 I això és, probablement, no és una bona cosa que fer. 122 00:05:46,120 --> 00:05:48,910 >> Així que aquest particular, solució és molt millor 123 00:05:48,910 --> 00:05:50,550 que qualsevol dels anteriors. 124 00:05:50,550 --> 00:05:59,950 Si jo primer #define mida de la coberta 52, a continuació, ara el meu ús de 52, o la mida de la coberta aquí, 125 00:05:59,950 --> 00:06:01,850 és molt més intuïtiu i molt més segur. 126 00:06:01,850 --> 00:06:03,280 No es pot manipular una constant. 127 00:06:03,280 --> 00:06:05,259 No es pot dir 52 plus plus. 128 00:06:05,259 --> 00:06:06,800 Això no va a convertir-lo a 53. 129 00:06:06,800 --> 00:06:09,390 No es pot canviar 52 a alguna cosa. 130 00:06:09,390 --> 00:06:12,470 >> Podeu canviar una variable el valor és 52, 131 00:06:12,470 --> 00:06:14,870 que va ser la primera solució que teníem abans. 132 00:06:14,870 --> 00:06:17,000 I vostè pot augmentar aquesta variable a 53. 133 00:06:17,000 --> 00:06:21,100 Però no es pot dir 52 plus plus i tenir que de sobte al seu torn 52-53. 134 00:06:21,100 --> 00:06:23,350 52 és sempre 52. 135 00:06:23,350 --> 00:06:28,860 I el que no pot canviar inadvertidament mida de la coberta aquí mitjançant la manipulació d'ella, 136 00:06:28,860 --> 00:06:29,940 137 00:06:29,940 --> 00:06:32,390 >> Un altre costat bo efecte d'això, però és 138 00:06:32,390 --> 00:06:38,310 que són conscients que no tots els països de tot el món 139 00:06:38,310 --> 00:06:40,690 utilitzar un mall de cartes de mida de 52? 140 00:06:40,690 --> 00:06:45,630 Per exemple, és molt comú en Alemanya utilitzar una mida de coberta de 32, 141 00:06:45,630 --> 00:06:48,020 on tira alguns de les cartes de menys valor. 142 00:06:48,020 --> 00:06:50,960 I en aquest cas, volgut port de la meva suite 143 00:06:50,960 --> 00:06:55,390 de les funcions que tenen a veure amb cartomàgia a Alemanya. 144 00:06:55,390 --> 00:06:59,440 Que vaig poder en la primera instància que va mostrar, han d'anar i reemplaçar 145 00:06:59,440 --> 00:07:03,570 totes les instàncies de 52 en el meu codi amb 32. 146 00:07:03,570 --> 00:07:07,940 >> Però aquí, si em #define mida de la coberta 32 a la part superior del meu codi, 147 00:07:07,940 --> 00:07:11,730 si he de canviar, no puc només ha d'anar i canviar aquesta cosa. 148 00:07:11,730 --> 00:07:15,010 Torneu a compilar el meu codi, i tots sobte es propaga a través. 149 00:07:15,010 --> 00:07:18,850 De fet, podem canviar la coberta grandària a qualsevol valor que volem. 150 00:07:18,850 --> 00:07:22,500 >> Et puc interessar en un joc de mida de la coberta de recollida? 151 00:07:22,500 --> 00:07:23,430 >> Sóc Doug Lloyd. 152 00:07:23,430 --> 00:07:25,840 I això és CS50. 153 00:07:25,840 --> 00:07:27,772