1 00:00:00,000 --> 00:00:02,350 >> [Musik spiller] 2 00:00:02,350 --> 00:00:05,444 3 00:00:05,444 --> 00:00:06,360 DOUG LLOYD: Okay. 4 00:00:06,360 --> 00:00:07,770 Slags en mærkelig emne, ikke? 5 00:00:07,770 --> 00:00:09,050 Magiske tal. 6 00:00:09,050 --> 00:00:12,012 Hvad doe han mener, når han er taler om magiske tal? 7 00:00:12,012 --> 00:00:14,220 Tja, nogle af de programmer, at vi har skrevet i CS50 8 00:00:14,220 --> 00:00:16,660 hidtil har haft nogle underlige numre slags smidt i dem. 9 00:00:16,660 --> 00:00:19,680 Måske grunde vi ikke helt forstår lige nu. 10 00:00:19,680 --> 00:00:23,950 For eksempel i Mario problem, vi udjævnede højden af ​​pyramiden ved 23. 11 00:00:23,950 --> 00:00:26,880 Vi udtrykkeligt sagde, at du kan ikke gå højere end 23. 12 00:00:26,880 --> 00:00:28,702 >> Men hvad betyder 23 betyder? 13 00:00:28,702 --> 00:00:30,410 Tja, hvis du læser spec omhyggeligt, du 14 00:00:30,410 --> 00:00:32,493 måske har set, at Grunden til at vi udjævnede det ved 23 15 00:00:32,493 --> 00:00:36,160 skyldes, at den standard højde af en terminal vindue er 24. 16 00:00:36,160 --> 00:00:38,860 Og så hvis vi har den pyramide være højere end det, 17 00:00:38,860 --> 00:00:41,290 det kunne gøre dette underlige ting hvor den løber ud af skærmen. 18 00:00:41,290 --> 00:00:45,140 Og du ved, hvad betyder at betyde i sammenhæng, ikke? 19 00:00:45,140 --> 00:00:48,880 >> Er meningen med 23 umiddelbart indlysende til nogen, der ser på dit program 20 00:00:48,880 --> 00:00:51,550 og måske har en anden terminalvindue størrelse? 21 00:00:51,550 --> 00:00:52,330 Sikkert ikke. 22 00:00:52,330 --> 00:00:53,080 Det ser ud som, OK. 23 00:00:53,080 --> 00:00:55,005 Tja, hvorfor er det lige under 23? 24 00:00:55,005 --> 00:00:56,880 Generelt er det er sådan af en dårlig vane faktisk 25 00:00:56,880 --> 00:00:58,940 at skrive konstanter ind i din kode. 26 00:00:58,940 --> 00:01:02,190 Dermed når du rent faktisk gør skriver en konstant ind i din kode, 27 00:01:02,190 --> 00:01:05,630 det er undertiden benævnt hjælp magiske tal, hvilket er noget 28 00:01:05,630 --> 00:01:08,030 vi generelt ønsker at forsøge at undgå. 29 00:01:08,030 --> 00:01:12,830 >> For eksempel, lad os tage et kig på dette enkle funktion her. 30 00:01:12,830 --> 00:01:15,726 Selvfølgelig er der ingen data typen i C kaldes kort eller dæk. 31 00:01:15,726 --> 00:01:16,600 Så bare bære over med mig. 32 00:01:16,600 --> 00:01:18,910 Det er en lille smule pseudokode blandet i her. 33 00:01:18,910 --> 00:01:21,050 Dette er en funktion kaldet behandle kort, der tilsyneladende 34 00:01:21,050 --> 00:01:26,570 tager et dæk som parameter, og udsendes til mig et enkelt kort. 35 00:01:26,570 --> 00:01:30,990 >> Og jeg gør noget her, hvor jeg har en løkke, der løber fra 0 til 52, 36 00:01:30,990 --> 00:01:33,394 og jeg behandle et kort. 37 00:01:33,394 --> 00:01:35,310 Tja, vi har en magisk nummer her, lige. 38 00:01:35,310 --> 00:01:38,790 Kan du se, hvad det magiske nummer er? 39 00:01:38,790 --> 00:01:42,280 Eller endnu vigtigere, gør du se, hvad problemet er her? 40 00:01:42,280 --> 00:01:44,310 Især hvis det er blot én funktion 41 00:01:44,310 --> 00:01:48,030 i sin egen fil i en mappe, der indeholder 42 00:01:48,030 --> 00:01:49,970 en masse forskellige filer, som hver 43 00:01:49,970 --> 00:01:51,670 gør en anden ting til et spil kort. 44 00:01:51,670 --> 00:01:57,310 Måske blander dem, eller behandler en hånd fem kort i stedet for et enkelt kort. 45 00:01:57,310 --> 00:01:59,420 >> Kan du se, hvad problem kunne være her? 46 00:01:59,420 --> 00:02:03,220 Kan du se det magiske tal Jeg har sprøjtet ind i koden? 47 00:02:03,220 --> 00:02:04,390 Det er 52, til højre. 48 00:02:04,390 --> 00:02:06,440 >> Ligesom, intuitivt du sikkert ved, OK. 49 00:02:06,440 --> 00:02:09,740 Ligesom en standard kortspil med kort indeholder 52 kort. 50 00:02:09,740 --> 00:02:12,570 Men i vores program, det er bare slags flyder rundt derinde. 51 00:02:12,570 --> 00:02:15,280 Det er ligesom lige pludselig er der en 52. 52 00:02:15,280 --> 00:02:18,290 >> En måde at løse dette Problemet er at gøre dette. 53 00:02:18,290 --> 00:02:22,724 Vi er meget eksplicit nu råber dæk størrelse som 52. 54 00:02:22,724 --> 00:02:25,390 Det giver det lidt mere intuitiv hvilket betyder når i for-løkken 55 00:02:25,390 --> 00:02:28,650 senere vi så sige, jeg er mindre end dæk størrelse. 56 00:02:28,650 --> 00:02:32,666 Det virker bare bedre end at sige 52. 57 00:02:32,666 --> 00:02:34,290 Nu er dette rent faktisk løse problemet. 58 00:02:34,290 --> 00:02:38,460 Det giver nogle symbolske hvilket betyder, at den konstant. 59 00:02:38,460 --> 00:02:40,820 Men det gør slags faktisk indføre et andet problem 60 00:02:40,820 --> 00:02:43,770 der måske ikke være umiddelbart indlysende. 61 00:02:43,770 --> 00:02:45,859 Selv om denne variabel erklæres globally-- 62 00:02:45,859 --> 00:02:47,650 Kan du huske, hvad det betyder, når vi erklærer 63 00:02:47,650 --> 00:02:50,500 en variabel globalt versus lokalt? 64 00:02:50,500 --> 00:02:53,340 Selv hvis vi erklærer en variabel globalt, hvad hvis der er 65 00:02:53,340 --> 00:02:55,500 en anden funktion i vores suite af funktioner 66 00:02:55,500 --> 00:02:59,750 at beskæftige sig med kort manipulation der uforvarende ændrer dæk størrelse, 67 00:02:59,750 --> 00:03:02,727 eller det øger den ved 1 eller formindsker det med 1. 68 00:03:02,727 --> 00:03:04,060 Det kunne stave problemer, ikke? 69 00:03:04,060 --> 00:03:08,261 Især hvis vi har at gøre med et sæt af kort, hvor blander fuld dæk 70 00:03:08,261 --> 00:03:08,760 er nødvendigt. 71 00:03:08,760 --> 00:03:12,804 Hvis dækket størrelse mindskes med 1, for eksempel til 51, 72 00:03:12,804 --> 00:03:14,970 Vi er faktisk ikke blander alle kortene evt. 73 00:03:14,970 --> 00:03:16,500 Vi forlader en af ​​dem ud. 74 00:03:16,500 --> 00:03:21,680 Og denne værdi kunne måske være forudsete eller udnyttes af en dårlig aktør. 75 00:03:21,680 --> 00:03:24,920 >> C giver hvad der kaldes en præprocessor direktiv, som 76 00:03:24,920 --> 00:03:27,764 kaldes også en makro til skabe symbolske konstanter. 77 00:03:27,764 --> 00:03:30,180 Og i virkeligheden, har du allerede set en præprocessor direktiv, 78 00:03:30,180 --> 00:03:32,916 selvom du ikke har hørt det kaldte det med #include. 79 00:03:32,916 --> 00:03:37,150 Det er et andet eksempel på en makro eller præprocessor direktivet. 80 00:03:37,150 --> 00:03:41,290 >> Den måde at skabe symbolske konstanter, eller give et navn til en konstant 81 00:03:41,290 --> 00:03:43,740 således at det har mere betyder, er som følger. 82 00:03:43,740 --> 00:03:47,030 #define, navn, udskiftning. 83 00:03:47,030 --> 00:03:49,140 Virkelig vigtigt til side her virkelig hurtig. 84 00:03:49,140 --> 00:03:54,180 Du må ikke sætte et semikolon på slutningen af ​​dine #defines. 85 00:03:54,180 --> 00:03:57,310 Så det er #define, navn, udskiftning. 86 00:03:57,310 --> 00:03:59,540 >> Når dit program er kompileret, hvad der faktisk sker 87 00:03:59,540 --> 00:04:01,740 er compileren hvis vil at gå gennem din kode 88 00:04:01,740 --> 00:04:06,770 og erstatte alle forekomster af ordet "navn" med hvad du 89 00:04:06,770 --> 00:04:08,860 sætte som erstatning. 90 00:04:08,860 --> 00:04:13,060 Analogt, hvis #include er sortering af ligner kopiere og indsætte, 91 00:04:13,060 --> 00:04:15,700 derefter # define er sortering af lignende at finde og erstatte, 92 00:04:15,700 --> 00:04:19,180 hvis du nogensinde har brugt denne funktion i et tekstbehandlingsprogram, for eksempel. 93 00:04:19,180 --> 00:04:26,345 >> Altså for eksempel, hvis jeg # define pi som 3.14159265, 94 00:04:26,345 --> 00:04:28,720 hvis du er bedre matematisk krængning og du pludselig 95 00:04:28,720 --> 00:04:31,640 se 3.14159265 flyvende rundt i din kode, 96 00:04:31,640 --> 00:04:33,517 du sikkert ved, det er at tale om pi. 97 00:04:33,517 --> 00:04:35,850 Men måske kan vi give det en lidt mere symbolsk betydning. 98 00:04:35,850 --> 00:04:39,850 Og vi kan i stedet sige #define pi som mundfuld numre 99 00:04:39,850 --> 00:04:42,110 at jeg ikke har tænkt mig at holde læse igen og igen. 100 00:04:42,110 --> 00:04:45,560 >> Og hvad der vil ske derefter på kompilere tidspunkt er, når programmet er 101 00:04:45,560 --> 00:04:48,530 kompileret, den første ting, vil ske, er det vil gå igennem 102 00:04:48,530 --> 00:04:51,520 og det vil erstatte hver gang den ser kapital P, kapital I, 103 00:04:51,520 --> 00:04:55,610 det vil bogstaveligt erstatte det med 3.14 og så videre, så du 104 00:04:55,610 --> 00:04:58,090 behøver ikke at skrive det hver tid, mens dit program stadig 105 00:04:58,090 --> 00:05:00,631 har den funktionalitet, som du forventer, fordi du arbejder 106 00:05:00,631 --> 00:05:05,090 med manipulation, multiplikation, dividere, hvad det er ved pi. 107 00:05:05,090 --> 00:05:08,230 >> Du er ikke begrænset til denne substitution for kun tal. 108 00:05:08,230 --> 00:05:12,279 For eksempel kunne jeg # define kursus som strengen CS50. 109 00:05:12,279 --> 00:05:14,070 I dette tilfælde, når Programmet er kompileret, 110 00:05:14,070 --> 00:05:16,236 # define vil gå gennem kode, udskiftes hver gang 111 00:05:16,236 --> 00:05:19,900 det ser "kursus" med strengen CS50. 112 00:05:19,900 --> 00:05:21,720 >> Du vil opdage her også, at jeg ofte 113 00:05:21,720 --> 00:05:26,090 # define alle mine definerede symbolsk konstanter, så at sige, 114 00:05:26,090 --> 00:05:28,130 er altid i alle hætter. 115 00:05:28,130 --> 00:05:28,960 Det er en konvention. 116 00:05:28,960 --> 00:05:30,170 Det er ikke påkrævet. 117 00:05:30,170 --> 00:05:33,900 Grunden generelt folk vil bruge alle hovedstæder, når de er #defining 118 00:05:33,900 --> 00:05:37,590 er bare for at gøre det virkelig klart, at denne særlige element i min kode 119 00:05:37,590 --> 00:05:38,820 er en defineret konstant. 120 00:05:38,820 --> 00:05:43,730 Hvis det var små bogstaver, er det muligt, at Det vil kunne forveksles med en variabel. 121 00:05:43,730 --> 00:05:46,120 Og det er nok ikke en god ting at gøre. 122 00:05:46,120 --> 00:05:48,910 >> Så denne særlige opløsning er meget bedre 123 00:05:48,910 --> 00:05:50,550 end nogen af ​​de tidligere. 124 00:05:50,550 --> 00:05:59,950 Hvis jeg først #define dæk størrelse 52, så nu er min brug af 52, eller dæk størrelse her, 125 00:05:59,950 --> 00:06:01,850 er meget mere intuitiv og meget sikrere. 126 00:06:01,850 --> 00:06:03,280 Du kan ikke manipulere en konstant. 127 00:06:03,280 --> 00:06:05,259 Man kan ikke sige 52 plus plus. 128 00:06:05,259 --> 00:06:06,800 Det kommer ikke til at konvertere det til 53. 129 00:06:06,800 --> 00:06:09,390 Du kan ikke ændre 52 til noget. 130 00:06:09,390 --> 00:06:12,470 >> Du kan ændre en variabel hvis værdi er 52, 131 00:06:12,470 --> 00:06:14,870 som var det første fix, vi havde før. 132 00:06:14,870 --> 00:06:17,000 Og du kan øge denne variabel til 53. 133 00:06:17,000 --> 00:06:21,100 Men du kan ikke sige 52 plus plus og har der pludselig slå 52 ind 53. 134 00:06:21,100 --> 00:06:23,350 52 er altid 52. 135 00:06:23,350 --> 00:06:28,860 Og så kan du ikke uforvarende ændrer dæk størrelse her ved at manipulere det, 136 00:06:28,860 --> 00:06:29,940 137 00:06:29,940 --> 00:06:32,390 >> En anden god side Effekten af ​​denne er dog 138 00:06:32,390 --> 00:06:38,310 der er du klar over, at der ikke alle lande rundt om i verden 139 00:06:38,310 --> 00:06:40,690 bruge et spil kort i størrelse 52? 140 00:06:40,690 --> 00:06:45,630 For eksempel, det er virkelig almindeligt i Tyskland at anvende et dæk på 32, 141 00:06:45,630 --> 00:06:48,020 hvor de strimler nogle af de lavere kort værdi. 142 00:06:48,020 --> 00:06:50,960 Og i dette tilfælde, jeg ønskede at port min suite 143 00:06:50,960 --> 00:06:55,390 funktioner, der beskæftiger sig med card manipulation til Tyskland. 144 00:06:55,390 --> 00:06:59,440 Jeg kunne i første omgang vi viste, nødt til at gå og erstatte 145 00:06:59,440 --> 00:07:03,570 alle forekomster af 52 i min kode med 32. 146 00:07:03,570 --> 00:07:07,940 >> Men her, hvis jeg # define dæk størrelse som 32 på toppen af ​​min kode, 147 00:07:07,940 --> 00:07:11,730 hvis jeg har brug for at ændre det, kan jeg bare gå og ændre det én ting. 148 00:07:11,730 --> 00:07:15,010 Genkompilere min kode, og alle pludselig udbreder sig gennem. 149 00:07:15,010 --> 00:07:18,850 I virkeligheden, kan vi ændre dæk størrelse til enhver værdi, vi ønsker. 150 00:07:18,850 --> 00:07:22,500 >> Kan jeg interesserer dig i en spil dæk størrelse pickup? 151 00:07:22,500 --> 00:07:23,430 >> Jeg er Doug Lloyd. 152 00:07:23,430 --> 00:07:25,840 Og det er CS50. 153 00:07:25,840 --> 00:07:27,772