>> [Muziek]
DOUG LLOYD: Oké.
Kind van een vreemde onderwerp, toch?
Magische getallen.
Wat doe hij bedoelt als hij over magische getallen?
Nou, een deel van de programma's dat we in CS50 heb geschreven
tot nu toe hebben sommige rare gehad aantallen soort gegooid in hen.
Misschien om redenen die we niet doen volledig begrijpen nu.
Bijvoorbeeld, in het Mario probleem, we bedekte de hoogte van de piramide op 23.
We expliciet gezegd dat je kan niet hoger zijn dan 23.
>> Maar wat betekent 23 betekenen?
Nou, als je de spec zorgvuldig, u
misschien gezien dat de reden waarom we bedekte het op 23
omdat de standaardhoogte van een terminal venster is 24.
En dus als we de pyramide groter dan die,
is het misschien een raar ding te doen waar het loopt van het scherm af.
En weet je, wat doet dat betekent in de context, toch?
>> Is de betekenis van 23 onmiddellijk duidelijk aan iemand die kijkt naar je programma
en heeft misschien een andere grootte terminal venster?
Waarschijnlijk niet.
Het lijkt alsof, OK.
Nou, waarom is het iets minder dan 23?
In het algemeen, het is een soort van een slechte gewoonte eigenlijk
constanten schrijven in uw code.
Daarbij, als je eigenlijk doen schrijf een constante in uw code,
het wordt soms aangeduid als het gebruik magische getallen, dat is iets
we willen over het algemeen proberen te vermijden.
>> Bijvoorbeeld, laten we eens een kijkje nemen Dit eenvoudige functie here.
Uiteraard is er geen gegevens Typ C genaamd kaart of dek.
Dus gewoon geduld met mij.
Het is een beetje pseudocode gemengd in hier.
Dit is een functie genaamd behandelen kaart die blijkbaar
neemt een dek als parameter, en wil uitgang voor mij een enkele kaart.
>> En ik ben hier om iets te doen waar ik een lus die loopt van 0 tot en met 52
en ik om een ​​kaart.
Nou, we hebben een magische gekregen nummer hier, rechts.
Ziet u wat het magische getal is?
Of nog belangrijker, wil je zien wat het probleem is hier?
Vooral indien is slechts één functie
in zijn eigen bestand in een map bevat
een bos van verschillende files, die elk
doet een ander ding om een ​​spel kaarten.
Misschien schudt hen, of gaat een hand vijf kaarten in plaats van een enkele kaart.
>> Ziet u wat de probleem zou hier zijn?
Zie je het magische getal Ik heb geïnjecteerd in de code?
Het is 52, rechts.
>> Zoals, intuïtief weet je waarschijnlijk, OK.
Als een standaard dek van kaarten bevat 52 kaarten.
Maar in ons programma, het is gewoon soort rondzweven in.
Het is als ineens is er een 52.
>> Een manier om dit op te lossen probleem is om dit te doen.
We zijn nu heel expliciet roepen het dek grootte als 52.
Het geeft het een beetje meer intuïtief wat betekent dat wanneer in de lus
Later wij dan zeggen, i minder dan dekgrootte.
Het lijkt beter dan zeggen 52.
Nu dit betekent eigenlijk het probleem op te lossen.
Het geeft een aantal symbolische betekent de constante.
Maar het soort eigenlijk ander probleem introduceren
dat misschien niet direct duidelijk.
Zelfs als deze variabele wordt verklaard globally--
herinnert u zich wat het betekent dat wanneer we verklaren
een variabele globaal versus lokaal?
Zelfs als we een variabele declareert wereldwijd, wat als er
andere functie in onze suite van functies
die deal met kaart manipulatie die per ongeluk verandert dek grootte,
of verhoogt door 1 of verlaagt door 1.
Dat kan spellen problemen, toch?
Vooral als we te maken hebben met een set kaarten, waar het schudden van de volledige dek
is vereist.
Als het dek wordt verkleind 1 door, bijvoorbeeld, 51,
we eigenlijk niet schuifelen alle kaarten mogelijk.
We vertrekken een van hen uit.
En die waarde kan misschien zijn voorspeld of uitgebuit door een slechte acteur.
>> C biedt wat heet een preprocessor richtlijn, die
wordt ook wel een macro voor creëren symbolische constanten.
En in feite, al heb je gezien een richtlijn preprocessor,
zelfs als je het nog niet gehoord riep dat met #include.
Het is een ander voorbeeld van een macro of richtlijn preprocessor.
>> De manier om symbolische constanten te maken, of het geven van een naam aan een constante
zodat het meer betekenis is als volgt.
#define, naam, vervanging.
Echt belangrijk opzij hier erg snel.
Zet geen puntkomma aan het einde van uw #defines.
Dus het is #define, naam, vervanging.
>> Wanneer het programma wordt samengesteld, wat er werkelijk gebeurt
is de compiler wanneer gaan om te gaan door uw code
en vervang elke instantie van het woord "naam" met alles wat je
zet als vervanging.
Analoog, als #include is een soort van vergelijkbaar met het kopiëren en plakken,
dan is #define soort Soortgelijke zoeken en vervangen,
als je ooit hebt gebruikt die functie in een tekstverwerkingsprogramma, bijvoorbeeld.
>> Dus bijvoorbeeld als ik #define pi als 3.14159265,
Als je beter bent wiskundig hellende en je plotseling
zie 3.14159265 vliegen rond in uw code,
u waarschijnlijk weet dat het over pi.
Maar misschien kunnen we het eens beetje meer symbolische betekenis.
En we kunnen in plaats daarvan zeggen #define pi als die hap van getallen
dat ik ben niet van plan om te blijven lezen over en voorbij.
>> En wat gaat er dan gebeuren bij compileren tijd is wanneer het programma is
gecompileerd, het eerste ding dat zal gebeuren is het zal gaan door
en het zal elke keer vervangen het ziet hoofdstad P, kapitaal I,
het zal letterlijk vervangen door 3,14 enzovoorts, zodat je
niet hoeft te elk type tijd, terwijl het programma nog steeds
heeft de functionaliteit die u verwachten, want je werkt
met manipuleren, te vermenigvuldigen, verdelen, wat het ook is door pi.
>> Je niet beperkt tot deze vervanging van alleen cijfers.
Zo kon ik #define Natuurlijk als de string CS50.
In dit geval, wanneer de programma gecompileerd,
#define zal gaan door de code, vervang elke keer
het ziet "cursus" met de string CS50.
>> U zult hier opmerken ook dat ik vaak
#define al mijn gedefinieerd symbolische constanten zogezegd,
zijn altijd in hoofdletters.
Het is een conventie.
Het is niet vereist.
De reden dat het algemeen mensen zullen gebruiken alle hoofdsteden als ze #defining
is alleen maar om het echt duidelijk dat maken dit bijzondere element van mijn code
is een gedefinieerde constante.
Als het kleine, is het mogelijk dat het zou kunnen worden verward met een variabele.
En dat is waarschijnlijk niet een goede zaak te doen.
>> Dus dit oplossing is veel beter
dan elk van de voorgaande.
Als ik voor het eerst #define dek maat 52, dan nu mijn gebruik van 52, of dek grootte hier,
is veel meer intuïtief en een stuk veiliger.
U kunt een constante niet manipuleren.
Je kunt niet zeggen 52 plus plus.
Dat gaat niet om te zetten naar 53.
Je kunt niet veranderen 52 iets.
>> U kunt een variabele veranderen waarvan de waarde is 52,
dat was de eerste fix we eerder hadden.
En je zou kunnen verhogen dat variabele 53.
Maar je kunt niet zeggen dat 52 plus en plus hebben die opeens 52 tot 53.
52 altijd 52.
En dus kun je niet per ongeluk veranderen dek grootte hier door het manipuleren van het,
>> Een andere goede kant effect hiervan is echter
dat bent u ervan bewust dat niet alle landen over de hele wereld
gebruik maken van een spel kaarten van maat 52?
Bijvoorbeeld, het is echt gebruikelijk in Duitsland naar een dek van 32 te gebruiken,
waar ze ontdoen van een aantal de lagere waarde kaarten.
En in dit geval, I wilde de haven mijn suite
functies die betrekking hebben card manipulatie naar Duitsland.
Ik kon in eerste instantie we toonde, moet gaan en te vervangen
alle exemplaren van 52 in mijn code met 32.
>> Maar hier, als ik #define dek formaat als 32 op de top van mijn code,
als ik het nodig om het te veranderen, kan ik gewoon gaan en te veranderen dat een ding.
Recompile mijn code, en al Ineens voortplant door.
In feite, kunnen we deck veranderen grootte op een waarde die we willen.
>> Kan ik u interesseren in een spel van het dek grootte pick-up?
>> Ik ben Doug Lloyd.
En dit is CS50.