[Jouer de la musique] DOUG LLOYD: Très bien. Sorte d'un sujet étrange, non? Les nombres magiques. Que mangez-il dire quand il est parler de chiffres magiques? Eh bien, certains des programmes que nous avons écrit dans CS50 jusqu'à présent ont eu une certaine bizarre numéros sorte de jetés en eux. Peut-être que nous ne le faisons pas pour des raisons comprendre entièrement dès maintenant. Par exemple, dans le problème Mario, nous plafonné la hauteur de la pyramide à 23. Nous vous dit explicitement ne peut pas aller plus haut que 23. Mais qu'est-ce que 23 cela veut dire? Eh bien, si vous lisez le spec attentivement, vous aurait vu que le raison pour laquelle nous l'a couvert à 23 est parce que la hauteur standard d'une fenêtre de terminal est de 24. Et si nous avons la pyramide être plus grand que cela, il pourrait faire cette chose bizarre où il dirige hors de l'écran. Et vous savez, ce qui ne ce que cela signifie dans le contexte, non? Est la signification du 23 immédiatement évident à quelqu'un qui regarde votre programme et a peut-être un autre fenêtre de terminal de la taille? Probablement pas. Il semble que, OK. Eh bien, pourquoi est-il un peu moins de 23? En général, il est le genre d'une mauvaise habitude fait pour écrire des constantes dans votre code. Pour ce faire, lorsque vous faites réellement écrire une constante dans votre code, il est parfois appelé en utilisant numéros de magie, qui est quelque chose nous voulons généralement pour essayer d'éviter. Par exemple, nous allons jeter un coup d'oeil à ce simple fonction ici. Évidemment, il n'y a pas de données type dans C appelé carte ou le pont. Il suffit donc de garder avec moi. Il est un peu de pseudo mélangé ici. Ceci est une fonction appelée traiter carte qui apparemment prend une plate-forme en tant que paramètre, et volonté de sortie pour me une seule carte. Et je fais quelque chose ici où je une boucle qui va de 0 à 52, et je traite une carte. Eh bien, nous avons une magie nombre ici, à droite. Voyez-vous ce que le nombre magique est? Ou, plus important, avez-vous voir quel est le problème ici? En particulier, si ce est juste une fonction dans son propre fichier dans un dossier qui contient un tas de différents fichiers, dont chacun fait une autre chose à un jeu de cartes. Peut-être que les mélange, ou traite une main de cinq cartes au lieu d'une seule carte. Voyez-vous ce que le problème pourrait être ici? Voyez-vous le nombre magique Je l'ai injecté dans le code? Il est 52, à droite. Comme, intuitivement vous le savez probablement, OK. Comme un jeu standard de cartes contient 52 cartes. Mais, dans notre programme, il est juste type de flottant autour de là. Il est comme tout d'un coup il ya un 52. Une façon de résoudre ce problème est de le faire. Nous sommes très explicitement maintenant appelant la taille de pont que 52. Il donne un peu plus intuitive dire lorsque dans la boucle for plus tard on dit alors, i est inférieure à la taille de pont. Il semble juste mieux que de dire 52. Maintenant, cela ne résout effectivement le problème. Il ne donne une certaine symbolique un sens à la constante. Mais il ne sorte de réalité introduire un autre problème qui pourrait ne pas être immédiatement apparent. Même si cette variable est déclarée globally-- vous vous souvenez de ce qu'il signifie que lorsque nous déclarons une variable à l'échelle mondiale par rapport au niveau local? Même si nous déclarons une variable à l'échelle mondiale, ce qui si il ya dans une autre fonction notre gamme de fonctions qui traitent de la manipulation de la carte que les changements par inadvertance taille du pont, ou elle augmente par 1 ou diminue par 1. Cela pourrait causer des problèmes, non? Surtout si nous avons affaire à un ensemble de cartes où mélanger les cartes complète est requis. Si la taille de pont est diminuée par une, par exemple, à 51, nous ne sommes pas réellement brassage toutes les cartes éventuellement. Nous partons d'une d'entre elles. Et cette valeur pourrait peut-être prédit ou exploité par un mauvais acteur. C fournit ce qu'on appelle un directive de préprocesseur, qui est aussi appelé une macro pour créer constantes symboliques. Et en fait, vous avez déjà vu une directive de préprocesseur, même si vous ne l'avez pas entendu qui appelle avec #include. Il est un autre exemple d'une macro ou directive de préprocesseur. La façon de créer des constantes symboliques, ou de donner un nom à une constante de sorte qu 'il présente plus ce qui signifie, est comme suit. #define, le nom, le remplacement. Vraiment important côté ici vraiment rapide. Ne pas mettre un point-virgule la fin de vos #defines. Donc, il est #define, le nom, le remplacement. Lorsque votre programme est compilé, ce qui se passe réellement est le compilateur si vous allez de passer par votre code et remplacer chaque instance de le mot «nom» avec tout ce que vous mettre en remplacement. De manière analogue, si #include est en quelque sorte de similaire à copier et coller, puis #define est en quelque sorte similaire à rechercher et remplacer, si vous avez déjà utilisé cette fonctionnalité dans un programme de traitement de texte, par exemple. Ainsi, par exemple, si je #define PI comme 3.14159265, si vous êtes mieux mathématiquement inclinée et vous avez soudainement voir 3.14159265 vol autour de votre code, vous le savez probablement, il parle pi. Mais peut-être que nous pouvons lui donner un peu de signification plus symbolique. Et nous pouvons dire à la place #define pi que celle bouchée de numéros que je ne vais pas garder lisant et relisant. Et qu'est-ce qui va se passer ensuite au compilation est lorsque le programme est compilé, la première chose qui qui va se passer est il faudra passer par et il va remplacer à chaque fois il voit grand P, I majuscule, il va littéralement remplacer par 3.14 et ainsi de suite, de sorte que vous ne pas avoir à le taper à chaque temps pendant que votre programme encore a la fonctionnalité que vous attendre, parce que vous travaillez à la manipulation, multipliant, divise, quel qu'il soit par pi. Vous n'êtes pas limité à cette substitution pour que des chiffres. Par exemple, je pourrais #define Bien sûr que le CS50 de chaîne. Dans ce cas, lorsque le programme est compilé, #define passera par le code, remplacer chaque fois il voit "bien sûr" avec le CS50 de chaîne. Vous remarquerez ici aussi que je fréquemment #define tout mon défini symbolique constantes, pour ainsi dire, sont toujours en majuscules. Il est une convention. Il est pas nécessaire. La raison généralement les gens vont utiliser toutes les capitales quand ils #defining est juste pour le rendre vraiment clair que cet élément particulier de mon code est une constante définie. Si elle était minuscule, il est possible que il pourrait être confondu avec une variable. Et cela est probablement pas une bonne chose à faire. Donc, ce particulier solution est beaucoup mieux que chacun des précédents. Si je premier #define taille de paquet de 52, puis maintenant mon utilisation de 52, ou la taille de pont ici, est beaucoup plus intuitif et beaucoup plus sûr. Vous ne pouvez pas manipuler une constante. Vous ne pouvez pas dire 52 plus plus. Cela ne va pas pour le convertir en 53. Vous ne pouvez pas changer 52 à quelque chose. Vous pouvez modifier une variable dont la valeur est 52, qui a été la première solution que nous avions avant. Et vous pourriez augmenter cette variable à 53. Mais vous ne pouvez pas dire 52 plus plus et avoir ce soudain tourner 52 en 53. 52 est toujours 52. Et si vous ne pouvez pas changer par inadvertance Taille longue ici en le manipulant, Un autre bon côté effet de ce bien est qui êtes-vous conscient que tous les pays à travers le monde utiliser un jeu de cartes de la taille 52? Par exemple, il est très commun dans Allemagne à utiliser une taille de paquet de 32, où ils dépouillent certains des cartes de faible valeur. Et dans ce cas, je voulu au port ma suite des fonctions qui traitent de carte manipulation à l'Allemagne. Je pouvais dans le premier cas, nous a montré, à aller et remplacer toutes les instances de 52 dans mon code 32. Mais ici, si je #define taille de pont que 32 tout en haut de mon code, si je dois changer, je peux juste aller et changer une chose. Recompiler mon code, et tous un coup, il se propage à travers. En fait, nous pouvons changer le pont taille à une valeur que nous voulons. Puis-je vous intéresser dans un jeu de la taille de pont pick-up? Je suis Doug Lloyd. Et cela est CS50.