>> [Música tocando]
DOUG LLOYD: Tudo bem.
Tipo de um tema estranho, certo?
Números mágicos.
O que doe ele quer dizer quando ele é falando de números mágicos?
Bem, alguns dos programas que temos escrito em CS50
até agora têm tido algum estranho números tipo de jogado neles.
Talvez por razões que não fazer inteiramente compreender agora.
Por exemplo, o problema em Mario, nós tampado a altura da pirâmide a 23.
Nós explicitamente disse que não pode ir mais alto do que 23.
>> Mas o que significa 23 significa?
Bem, se você ler o especificação cuidado, você
pode ter visto que o razão pela qual ele tampou a 23
é porque a altura padrão de uma janela do terminal é de 24.
E por isso, se temos a pirâmide ser mais alto do que isso,
ele pode fazer essa coisa estranha onde ele é executado fora da tela.
E você sabe, o que faz isso significa no contexto, certo?
>> É o significado de 23 imediatamente óbvio para alguém que olha para o seu programa
e talvez um diferente possui janela de terminal tamanho?
Provavelmente não.
Parece que, OK.
Bem, por que é pouco menos de 23?
Em geral, é uma espécie de um mau hábito, na verdade,
para escrever constantes em seu código.
Ao fazê-lo, quando você realmente fazê- escrever uma constante em seu código,
às vezes é referido como usar números mágicos, o que é algo
que geralmente quer tentar e evitar.
>> Por exemplo, vamos dar uma olhada nesta função simples aqui.
Obviamente, não há dados tipo em C chamado cartão ou deck.
Então, só tenha paciência comigo.
É um pouco de pseudocódigo misturados aqui.
Esta é uma função chamada lidar cartão que aparentemente
leva um deck como parâmetro, e saída vontade de me um único cartão.
>> E eu estou fazendo algo aqui onde eu tenho um loop que vai de 0 a 52,
e eu lidar um cartão.
Bem, nós temos uma magia número aqui, certo.
Você vê o que o número mágico é?
Ou, mais importante, você ver qual é o problema aqui?
Particularmente, se esta é apenas uma função
em seu próprio arquivo em uma pasta que contém
um monte de diferente arquivos, cada um dos quais
faz outra coisa a um baralho de cartas.
Talvez ele embaralha-los, ou negocia uma mão de cinco cartas, em vez de um único cartão.
>> Você vê o que o problema poderia estar aqui?
Você vê o número mágico Eu tenho injetado no código?
É 52, à direita.
>> Como, intuitivamente você provavelmente sabe, OK.
Como uma plataforma padrão de cartões contém 52 cartas.
Mas, no nosso programa, é só tipo de flutuante em torno de lá.
É como se, de repente, há um 52.
>> Uma maneira de resolver este problema é fazer isso.
Estamos muito explicitamente agora chamando o tamanho da plataforma como 52.
Dá-lhe um pouco mais intuitivo ou seja, quando no loop for
Mais tarde, em seguida, dizer, i é menor do que o tamanho da plataforma.
Ela só parece melhor do que dizer 52.
Agora isso realmente corrigir o problema.
Ele dá alguns simbólico significado para a constante.
Mas ele faz tipo de realmente introduzir um outro problema
que pode não ser imediatamente aparente.
Mesmo que esta variável é declarado globally--
você se lembra o que significa que quando nós declaramos
uma variável global contra localmente?
Mesmo que declarar uma variável globalmente, o que se há
outra função no nosso conjunto de funções
que lidam com CARTOMAGIA que, inadvertidamente, muda o tamanho da plataforma,
ou por ele aumenta- 1 ou diminui-lo por um.
Isso poderia causar problemas, certo?
Especialmente se estamos lidando com um conjunto de cartões onde baralhar o baralho completo
É necessário.
Se o tamanho da plataforma é diminuída 1 por, por exemplo, a 51,
nós não estamos realmente baralhar Todos os cartões Possivelmente.
Estamos deixando um deles para fora.
E esse valor talvez pudesse ser do previsto ou explorado por um ator ruim.
>> C fornece o que é chamado um pré-processador diretiva, que
é também chamado de uma macro para criação de constantes simbólicas.
E, de fato, você já visto um pré-processador diretiva,
mesmo se você nunca ouviu falar nisso chamado que com #include.
É mais um exemplo de uma macro ou pré-processador diretiva.
>> A maneira de criar constantes simbólicas, ou dar um nome a uma constante
de modo que ele tenha mais ou seja, é como se segue.
#define, nome, substituição.
Realmente importante de lado aqui realmente rápido.
Não coloque um ponto e vírgula no o fim de seus #defines.
Portanto, é #define, nome, substituição.
>> Quando o programa é compilado, o que realmente acontece
é o compilador se vai passar por seu código
e substituir cada instância de a palavra "nome" com o que você
colocar como substituto.
Analogamente, se #include é uma espécie semelhante ao de copiar e colar,
em seguida, # define é uma espécie de semelhante para localizar e substituir,
Se você já usou esse recurso em um programa de processamento de texto, por exemplo.
>> Assim, por exemplo, se eu #define pi como 3.14159265,
se você está melhor matematicamente inclinado e de repente você
veja 3.14159265 vôo em torno de seu código,
você provavelmente sabe que está falando pi.
Mas talvez possamos dar-lhe um pouco significado mais simbólico.
E podemos dizer, em vez #define pi como a boca cheia de números
que eu não vou continuar ler mais e mais.
>> E o que vai acontecer em seguida, em é o tempo de compilação quando o programa está
compilado, a primeira coisa que vai acontecer é que vai passar por
e ele irá substituir cada vez ele vê P maiúsculo, principal mim,
ele vai literalmente substituí-lo com 3,14 e assim por diante, de modo que você
não precise digitá-la cada tempo, enquanto ainda o seu programa
tem a funcionalidade de que você esperar, porque você está trabalhando
com manipulação, multiplicando, divisão, seja o que for por pi.
>> Não está limitado a esta substituição por apenas números.
Por exemplo, eu poderia #define É claro que o CS50 string.
Neste caso, quando o programa é compilado,
#define vai passar pelo código, substitua cada vez
ele vê "claro" com o CS50 string.
>> Você notará aqui também que eu freqüentemente
# define toda a minha definido simbólico constantes, por assim dizer,
estão sempre em todos os tampões.
É uma convenção.
Não é necessário.
A razão geralmente as pessoas vão usá todas as capitais quando eles estão #defining
é só para deixar bem claro que este elemento particular do meu código
é uma constante definida.
Se era minúscula, é possível que que poderia ser confundida com uma variável.
E isso é provavelmente não é uma coisa boa para fazer.
>> Então este particular solução é muito melhor
do que qualquer um dos anteriores.
Se eu primeiro #define convés tamanho 52, em seguida, agora a minha utilização de 52, ou tamanho da plataforma aqui,
é muito mais intuitivo e muito mais seguro.
Você não pode manipular uma constante.
Você não pode dizer 52 plus plus.
Isso não vai convertê-lo para 53.
Você não pode mudar de 52 para algo.
>> Você pode alterar uma variável cujo valor é de 52,
que foi a primeira correção que tínhamos antes.
E você pode aumentar essa variável para 53.
Mas você não pode dizer 52 plus plus e tem que, de repente virar 52 em 53.
52 é sempre 52.
E então você não pode alterar inadvertidamente tamanho da plataforma aqui, manipulando-o,
>> Outro lado bom efeito desta, porém, é
que você está ciente de que não todos os países ao redor do mundo
usar um baralho de cartas de tamanho 52?
Por exemplo, é muito comum em Alemanha para usar um tamanho baralho de 32,
onde tira alguns das cartas de menor valor.
E, neste caso, eu queria porto minha suíte
das funções que lidam com CARTOMAGIA para a Alemanha.
Eu poderia, no primeiro caso, mostrou, tenho que ir e substituí-
todas as instâncias de 52 no meu código com 32.
>> Mas aqui, se eu #define tamanho da plataforma como 32 no topo do meu código,
se eu preciso mudá-lo, eu posso basta ir e mudar isso uma coisa.
Recompilar o meu código, e todos repente ele se propaga através.
Na verdade, podemos mudar convés tamanho para qualquer valor que queremos.
>> Posso interessá-lo em jogo de tamanho da plataforma de captação?
>> Eu sou Doug Lloyd.
E este é CS50.