1 00:00:00,000 --> 00:00:02,350 >> [Música tocando] 2 00:00:02,350 --> 00:00:05,444 3 00:00:05,444 --> 00:00:06,360 DOUG LLOYD: Tudo bem. 4 00:00:06,360 --> 00:00:07,770 Tipo de um tema estranho, certo? 5 00:00:07,770 --> 00:00:09,050 Números mágicos. 6 00:00:09,050 --> 00:00:12,012 O que doe ele quer dizer quando ele é falando de números mágicos? 7 00:00:12,012 --> 00:00:14,220 Bem, alguns dos programas que temos escrito em CS50 8 00:00:14,220 --> 00:00:16,660 até agora têm tido algum estranho números tipo de jogado neles. 9 00:00:16,660 --> 00:00:19,680 Talvez por razões que não fazer inteiramente compreender agora. 10 00:00:19,680 --> 00:00:23,950 Por exemplo, o problema em Mario, nós tampado a altura da pirâmide a 23. 11 00:00:23,950 --> 00:00:26,880 Nós explicitamente disse que não pode ir mais alto do que 23. 12 00:00:26,880 --> 00:00:28,702 >> Mas o que significa 23 significa? 13 00:00:28,702 --> 00:00:30,410 Bem, se você ler o especificação cuidado, você 14 00:00:30,410 --> 00:00:32,493 pode ter visto que o razão pela qual ele tampou a 23 15 00:00:32,493 --> 00:00:36,160 é porque a altura padrão de uma janela do terminal é de 24. 16 00:00:36,160 --> 00:00:38,860 E por isso, se temos a pirâmide ser mais alto do que isso, 17 00:00:38,860 --> 00:00:41,290 ele pode fazer essa coisa estranha onde ele é executado fora da tela. 18 00:00:41,290 --> 00:00:45,140 E você sabe, o que faz isso significa no contexto, certo? 19 00:00:45,140 --> 00:00:48,880 >> É o significado de 23 imediatamente óbvio para alguém que olha para o seu programa 20 00:00:48,880 --> 00:00:51,550 e talvez um diferente possui janela de terminal tamanho? 21 00:00:51,550 --> 00:00:52,330 Provavelmente não. 22 00:00:52,330 --> 00:00:53,080 Parece que, OK. 23 00:00:53,080 --> 00:00:55,005 Bem, por que é pouco menos de 23? 24 00:00:55,005 --> 00:00:56,880 Em geral, é uma espécie de um mau hábito, na verdade, 25 00:00:56,880 --> 00:00:58,940 para escrever constantes em seu código. 26 00:00:58,940 --> 00:01:02,190 Ao fazê-lo, quando você realmente fazê- escrever uma constante em seu código, 27 00:01:02,190 --> 00:01:05,630 às vezes é referido como usar números mágicos, o que é algo 28 00:01:05,630 --> 00:01:08,030 que geralmente quer tentar e evitar. 29 00:01:08,030 --> 00:01:12,830 >> Por exemplo, vamos dar uma olhada nesta função simples aqui. 30 00:01:12,830 --> 00:01:15,726 Obviamente, não há dados tipo em C chamado cartão ou deck. 31 00:01:15,726 --> 00:01:16,600 Então, só tenha paciência comigo. 32 00:01:16,600 --> 00:01:18,910 É um pouco de pseudocódigo misturados aqui. 33 00:01:18,910 --> 00:01:21,050 Esta é uma função chamada lidar cartão que aparentemente 34 00:01:21,050 --> 00:01:26,570 leva um deck como parâmetro, e saída vontade de me um único cartão. 35 00:01:26,570 --> 00:01:30,990 >> E eu estou fazendo algo aqui onde eu tenho um loop que vai de 0 a 52, 36 00:01:30,990 --> 00:01:33,394 e eu lidar um cartão. 37 00:01:33,394 --> 00:01:35,310 Bem, nós temos uma magia número aqui, certo. 38 00:01:35,310 --> 00:01:38,790 Você vê o que o número mágico é? 39 00:01:38,790 --> 00:01:42,280 Ou, mais importante, você ver qual é o problema aqui? 40 00:01:42,280 --> 00:01:44,310 Particularmente, se esta é apenas uma função 41 00:01:44,310 --> 00:01:48,030 em seu próprio arquivo em uma pasta que contém 42 00:01:48,030 --> 00:01:49,970 um monte de diferente arquivos, cada um dos quais 43 00:01:49,970 --> 00:01:51,670 faz outra coisa a um baralho de cartas. 44 00:01:51,670 --> 00:01:57,310 Talvez ele embaralha-los, ou negocia uma mão de cinco cartas, em vez de um único cartão. 45 00:01:57,310 --> 00:01:59,420 >> Você vê o que o problema poderia estar aqui? 46 00:01:59,420 --> 00:02:03,220 Você vê o número mágico Eu tenho injetado no código? 47 00:02:03,220 --> 00:02:04,390 É 52, à direita. 48 00:02:04,390 --> 00:02:06,440 >> Como, intuitivamente você provavelmente sabe, OK. 49 00:02:06,440 --> 00:02:09,740 Como uma plataforma padrão de cartões contém 52 cartas. 50 00:02:09,740 --> 00:02:12,570 Mas, no nosso programa, é só tipo de flutuante em torno de lá. 51 00:02:12,570 --> 00:02:15,280 É como se, de repente, há um 52. 52 00:02:15,280 --> 00:02:18,290 >> Uma maneira de resolver este problema é fazer isso. 53 00:02:18,290 --> 00:02:22,724 Estamos muito explicitamente agora chamando o tamanho da plataforma como 52. 54 00:02:22,724 --> 00:02:25,390 Dá-lhe um pouco mais intuitivo ou seja, quando no loop for 55 00:02:25,390 --> 00:02:28,650 Mais tarde, em seguida, dizer, i é menor do que o tamanho da plataforma. 56 00:02:28,650 --> 00:02:32,666 Ela só parece melhor do que dizer 52. 57 00:02:32,666 --> 00:02:34,290 Agora isso realmente corrigir o problema. 58 00:02:34,290 --> 00:02:38,460 Ele dá alguns simbólico significado para a constante. 59 00:02:38,460 --> 00:02:40,820 Mas ele faz tipo de realmente introduzir um outro problema 60 00:02:40,820 --> 00:02:43,770 que pode não ser imediatamente aparente. 61 00:02:43,770 --> 00:02:45,859 Mesmo que esta variável é declarado globally-- 62 00:02:45,859 --> 00:02:47,650 você se lembra o que significa que quando nós declaramos 63 00:02:47,650 --> 00:02:50,500 uma variável global contra localmente? 64 00:02:50,500 --> 00:02:53,340 Mesmo que declarar uma variável globalmente, o que se há 65 00:02:53,340 --> 00:02:55,500 outra função no nosso conjunto de funções 66 00:02:55,500 --> 00:02:59,750 que lidam com CARTOMAGIA que, inadvertidamente, muda o tamanho da plataforma, 67 00:02:59,750 --> 00:03:02,727 ou por ele aumenta- 1 ou diminui-lo por um. 68 00:03:02,727 --> 00:03:04,060 Isso poderia causar problemas, certo? 69 00:03:04,060 --> 00:03:08,261 Especialmente se estamos lidando com um conjunto de cartões onde baralhar o baralho completo 70 00:03:08,261 --> 00:03:08,760 É necessário. 71 00:03:08,760 --> 00:03:12,804 Se o tamanho da plataforma é diminuída 1 por, por exemplo, a 51, 72 00:03:12,804 --> 00:03:14,970 nós não estamos realmente baralhar Todos os cartões Possivelmente. 73 00:03:14,970 --> 00:03:16,500 Estamos deixando um deles para fora. 74 00:03:16,500 --> 00:03:21,680 E esse valor talvez pudesse ser do previsto ou explorado por um ator ruim. 75 00:03:21,680 --> 00:03:24,920 >> C fornece o que é chamado um pré-processador diretiva, que 76 00:03:24,920 --> 00:03:27,764 é também chamado de uma macro para criação de constantes simbólicas. 77 00:03:27,764 --> 00:03:30,180 E, de fato, você já visto um pré-processador diretiva, 78 00:03:30,180 --> 00:03:32,916 mesmo se você nunca ouviu falar nisso chamado que com #include. 79 00:03:32,916 --> 00:03:37,150 É mais um exemplo de uma macro ou pré-processador diretiva. 80 00:03:37,150 --> 00:03:41,290 >> A maneira de criar constantes simbólicas, ou dar um nome a uma constante 81 00:03:41,290 --> 00:03:43,740 de modo que ele tenha mais ou seja, é como se segue. 82 00:03:43,740 --> 00:03:47,030 #define, nome, substituição. 83 00:03:47,030 --> 00:03:49,140 Realmente importante de lado aqui realmente rápido. 84 00:03:49,140 --> 00:03:54,180 Não coloque um ponto e vírgula no o fim de seus #defines. 85 00:03:54,180 --> 00:03:57,310 Portanto, é #define, nome, substituição. 86 00:03:57,310 --> 00:03:59,540 >> Quando o programa é compilado, o que realmente acontece 87 00:03:59,540 --> 00:04:01,740 é o compilador se vai passar por seu código 88 00:04:01,740 --> 00:04:06,770 e substituir cada instância de a palavra "nome" com o que você 89 00:04:06,770 --> 00:04:08,860 colocar como substituto. 90 00:04:08,860 --> 00:04:13,060 Analogamente, se #include é uma espécie semelhante ao de copiar e colar, 91 00:04:13,060 --> 00:04:15,700 em seguida, # define é uma espécie de semelhante para localizar e substituir, 92 00:04:15,700 --> 00:04:19,180 Se você já usou esse recurso em um programa de processamento de texto, por exemplo. 93 00:04:19,180 --> 00:04:26,345 >> Assim, por exemplo, se eu #define pi como 3.14159265, 94 00:04:26,345 --> 00:04:28,720 se você está melhor matematicamente inclinado e de repente você 95 00:04:28,720 --> 00:04:31,640 veja 3.14159265 vôo em torno de seu código, 96 00:04:31,640 --> 00:04:33,517 você provavelmente sabe que está falando pi. 97 00:04:33,517 --> 00:04:35,850 Mas talvez possamos dar-lhe um pouco significado mais simbólico. 98 00:04:35,850 --> 00:04:39,850 E podemos dizer, em vez #define pi como a boca cheia de números 99 00:04:39,850 --> 00:04:42,110 que eu não vou continuar ler mais e mais. 100 00:04:42,110 --> 00:04:45,560 >> E o que vai acontecer em seguida, em é o tempo de compilação quando o programa está 101 00:04:45,560 --> 00:04:48,530 compilado, a primeira coisa que vai acontecer é que vai passar por 102 00:04:48,530 --> 00:04:51,520 e ele irá substituir cada vez ele vê P maiúsculo, principal mim, 103 00:04:51,520 --> 00:04:55,610 ele vai literalmente substituí-lo com 3,14 e assim por diante, de modo que você 104 00:04:55,610 --> 00:04:58,090 não precise digitá-la cada tempo, enquanto ainda o seu programa 105 00:04:58,090 --> 00:05:00,631 tem a funcionalidade de que você esperar, porque você está trabalhando 106 00:05:00,631 --> 00:05:05,090 com manipulação, multiplicando, divisão, seja o que for por pi. 107 00:05:05,090 --> 00:05:08,230 >> Não está limitado a esta substituição por apenas números. 108 00:05:08,230 --> 00:05:12,279 Por exemplo, eu poderia #define É claro que o CS50 string. 109 00:05:12,279 --> 00:05:14,070 Neste caso, quando o programa é compilado, 110 00:05:14,070 --> 00:05:16,236 #define vai passar pelo código, substitua cada vez 111 00:05:16,236 --> 00:05:19,900 ele vê "claro" com o CS50 string. 112 00:05:19,900 --> 00:05:21,720 >> Você notará aqui também que eu freqüentemente 113 00:05:21,720 --> 00:05:26,090 # define toda a minha definido simbólico constantes, por assim dizer, 114 00:05:26,090 --> 00:05:28,130 estão sempre em todos os tampões. 115 00:05:28,130 --> 00:05:28,960 É uma convenção. 116 00:05:28,960 --> 00:05:30,170 Não é necessário. 117 00:05:30,170 --> 00:05:33,900 A razão geralmente as pessoas vão usá todas as capitais quando eles estão #defining 118 00:05:33,900 --> 00:05:37,590 é só para deixar bem claro que este elemento particular do meu código 119 00:05:37,590 --> 00:05:38,820 é uma constante definida. 120 00:05:38,820 --> 00:05:43,730 Se era minúscula, é possível que que poderia ser confundida com uma variável. 121 00:05:43,730 --> 00:05:46,120 E isso é provavelmente não é uma coisa boa para fazer. 122 00:05:46,120 --> 00:05:48,910 >> Então este particular solução é muito melhor 123 00:05:48,910 --> 00:05:50,550 do que qualquer um dos anteriores. 124 00:05:50,550 --> 00:05:59,950 Se eu primeiro #define convés tamanho 52, em seguida, agora a minha utilização de 52, ou tamanho da plataforma aqui, 125 00:05:59,950 --> 00:06:01,850 é muito mais intuitivo e muito mais seguro. 126 00:06:01,850 --> 00:06:03,280 Você não pode manipular uma constante. 127 00:06:03,280 --> 00:06:05,259 Você não pode dizer 52 plus plus. 128 00:06:05,259 --> 00:06:06,800 Isso não vai convertê-lo para 53. 129 00:06:06,800 --> 00:06:09,390 Você não pode mudar de 52 para algo. 130 00:06:09,390 --> 00:06:12,470 >> Você pode alterar uma variável cujo valor é de 52, 131 00:06:12,470 --> 00:06:14,870 que foi a primeira correção que tínhamos antes. 132 00:06:14,870 --> 00:06:17,000 E você pode aumentar essa variável para 53. 133 00:06:17,000 --> 00:06:21,100 Mas você não pode dizer 52 plus plus e tem que, de repente virar 52 em 53. 134 00:06:21,100 --> 00:06:23,350 52 é sempre 52. 135 00:06:23,350 --> 00:06:28,860 E então você não pode alterar inadvertidamente tamanho da plataforma aqui, manipulando-o, 136 00:06:28,860 --> 00:06:29,940 137 00:06:29,940 --> 00:06:32,390 >> Outro lado bom efeito desta, porém, é 138 00:06:32,390 --> 00:06:38,310 que você está ciente de que não todos os países ao redor do mundo 139 00:06:38,310 --> 00:06:40,690 usar um baralho de cartas de tamanho 52? 140 00:06:40,690 --> 00:06:45,630 Por exemplo, é muito comum em Alemanha para usar um tamanho baralho de 32, 141 00:06:45,630 --> 00:06:48,020 onde tira alguns das cartas de menor valor. 142 00:06:48,020 --> 00:06:50,960 E, neste caso, eu queria porto minha suíte 143 00:06:50,960 --> 00:06:55,390 das funções que lidam com CARTOMAGIA para a Alemanha. 144 00:06:55,390 --> 00:06:59,440 Eu poderia, no primeiro caso, mostrou, tenho que ir e substituí- 145 00:06:59,440 --> 00:07:03,570 todas as instâncias de 52 no meu código com 32. 146 00:07:03,570 --> 00:07:07,940 >> Mas aqui, se eu #define tamanho da plataforma como 32 no topo do meu código, 147 00:07:07,940 --> 00:07:11,730 se eu preciso mudá-lo, eu posso basta ir e mudar isso uma coisa. 148 00:07:11,730 --> 00:07:15,010 Recompilar o meu código, e todos repente ele se propaga através. 149 00:07:15,010 --> 00:07:18,850 Na verdade, podemos mudar convés tamanho para qualquer valor que queremos. 150 00:07:18,850 --> 00:07:22,500 >> Posso interessá-lo em jogo de tamanho da plataforma de captação? 151 00:07:22,500 --> 00:07:23,430 >> Eu sou Doug Lloyd. 152 00:07:23,430 --> 00:07:25,840 E este é CS50. 153 00:07:25,840 --> 00:07:27,772