1 00:00:00,000 --> 00:00:11,242 >> [Música tocando] 2 00:00:11,242 --> 00:00:16,630 >> DAVID J. MALAN: Tudo bem isso é CS50 e este é o início da semana, cinco. 3 00:00:16,630 --> 00:00:21,480 Então, hoje, debaixo de seus assentos, você não vai encontrar nada. 4 00:00:21,480 --> 00:00:24,790 Mas, acima, você deve encontrá-los, um pequeno sinal de nossa gratidão por 5 00:00:24,790 --> 00:00:26,970 todo o trabalho que você colocou no Jogo dos Quinze. 6 00:00:26,970 --> 00:00:30,290 Basta retirar o pequeno círculo no baixo para começar a jogar para o 7 00:00:30,290 --> 00:00:31,680 restante da classe. 8 00:00:31,680 --> 00:00:38,930 >> Então, lembro que, ou saber que problema definido quatro, que saiu este fim de semana, 9 00:00:38,930 --> 00:00:40,340 envolve a escrita de um outro jogo. 10 00:00:40,340 --> 00:00:43,740 Mas, desta vez, envolve a utilização de um interface gráfica do usuário real, e não um 11 00:00:43,740 --> 00:00:46,310 Interface textual como Jogo dos Quinze era. 12 00:00:46,310 --> 00:00:50,210 E o jogo que está à frente de você, Se você ainda não viu esta próxima, 13 00:00:50,210 --> 00:00:52,310 parece um pouco algo como isto. 14 00:00:52,310 --> 00:00:55,170 Eu estou indo para ir em meu terminal janela aqui na GDB. 15 00:00:55,170 --> 00:00:58,600 E eu estou indo para ir em frente e correr o solução pessoal, que você pode acessar 16 00:00:58,600 --> 00:01:01,010 após a execução de atualização de 50 como de costume. 17 00:01:01,010 --> 00:01:04,090 >> Mas eu vou colocá-lo em um pouco modo secreto, um pequeno ovo de Páscoa, 18 00:01:04,090 --> 00:01:08,480 o chamado modo de Deus, por colocando Deus em argv1. 19 00:01:08,480 --> 00:01:12,920 E eu tenho que seguir os meus próprios sentidos, executá-lo em minha própria 20 00:01:12,920 --> 00:01:14,220 problema de definir o diretório. 21 00:01:14,220 --> 00:01:19,190 Então agora você vê uma versão completa do jogo de Breakout. 22 00:01:19,190 --> 00:01:21,090 Na verdade, este é o modo de não-mãos. 23 00:01:21,090 --> 00:01:24,850 Portanto, é na verdade - 24 00:01:24,850 --> 00:01:26,470 empolgou que você pode ser - 25 00:01:26,470 --> 00:01:30,850 bem simples de se implementar o modo Deus no Breakout, ao contrário do jogo dos Quinze, 26 00:01:30,850 --> 00:01:33,590 que alguns de vocês podem ter abordado para a edição de hacker. 27 00:01:33,590 --> 00:01:37,890 >> Em Breakout basta em Deus modo de simplesmente fazer o que, 28 00:01:37,890 --> 00:01:41,220 intuitivamente com a pá? 29 00:01:41,220 --> 00:01:45,630 Apenas torná-lo igual a qualquer que seja o posição horizontal é de bola. 30 00:01:45,630 --> 00:01:49,220 E, desde que você faça isso em sintonia com a bola em movimento este jogo vai 31 00:01:49,220 --> 00:01:53,100 nunca, nunca, nunca perder a bola e você vai ganhar cada vez. 32 00:01:53,100 --> 00:01:55,430 >> Mas, na edição de hackers esta semana há mais do que apenas o modo de Deus. 33 00:01:55,430 --> 00:01:56,720 Há uma série de outros recursos. 34 00:01:56,720 --> 00:01:58,140 Entre eles, os lasers. 35 00:01:58,140 --> 00:02:01,070 Assim que se você realmente ficar impaciente você pode começar a derrubar os tijolos 36 00:02:01,070 --> 00:02:02,120 e alguns outros. 37 00:02:02,120 --> 00:02:04,560 E para aqueles de vocês que gostaria de calibrar padrão contra hackers 38 00:02:04,560 --> 00:02:08,750 edição, eu posso ver que esta semana edição hackers deliberadamente é um 39 00:02:08,750 --> 00:02:12,830 pouco mais factível, por exemplo, do que a Deus modo foi com Game of Quinze. 40 00:02:12,830 --> 00:02:15,300 >> Então, se você está procurando um trecho e você está procurando um pouco de diversão adicional 41 00:02:15,300 --> 00:02:18,400 características fazem do mergulho em caso de interesse. 42 00:02:18,400 --> 00:02:21,280 Agora, mais prático, deixe-me apontar fora uma coisa assim. 43 00:02:21,280 --> 00:02:24,780 GDB, que alguns de vocês podem não ter ainda tocou pessoalmente, o que é bom. 44 00:02:24,780 --> 00:02:28,530 Mas agora é realmente o tempo para se acostumar esta e confortável com esta ferramenta 45 00:02:28,530 --> 00:02:31,510 porque ele vai fazer a sua vida muito mais fácil, realmente. 46 00:02:31,510 --> 00:02:34,900 >> Por palestra de Rob em GDB um casal de semanas atrás, lembre-se 47 00:02:34,900 --> 00:02:36,810 que GDB é um depurador. 48 00:02:36,810 --> 00:02:41,230 É uma ferramenta que permite que você execute o seu programa, mas executá-lo passo a passo, linha 49 00:02:41,230 --> 00:02:45,680 por linha, de modo que você pode picar ao redor, de modo que você vê as coisas acontecendo, então 50 00:02:45,680 --> 00:02:47,310 que você pode imprimir Os valores das variáveis. 51 00:02:47,310 --> 00:02:50,580 Em suma, dá-lhe muito mais energia do que printDef faz. 52 00:02:50,580 --> 00:02:52,900 >> Agora é certo, a interface é muito misterioso. 53 00:02:52,900 --> 00:02:55,180 Interface textual preto e branco na sua maior parte. 54 00:02:55,180 --> 00:02:57,400 Os comandos são um pouco difícil lembrar em primeiro lugar. 55 00:02:57,400 --> 00:03:01,230 Mas mesmo que isso pode levar metade uma hora, uma hora, para colocar esse adiantado 56 00:03:01,230 --> 00:03:02,940 investimento de tempo para ele, confie em mim. 57 00:03:02,940 --> 00:03:06,440 Certamente até o final do semestre vai economizar uma ordem de magnitude mais 58 00:03:06,440 --> 00:03:07,600 tempo que. 59 00:03:07,600 --> 00:03:09,200 >> Então, no início da semana mergulhar dentro 60 00:03:09,200 --> 00:03:13,200 E em termos de Breakout, saiba que você pode fazer isso, desde que você tem 61 00:03:13,200 --> 00:03:18,230 o código de distribuição ou de seu próprio código em andamento no seu diretório Pst4. 62 00:03:18,230 --> 00:03:21,680 Saiba que você pode executar o gdb. / Fuga. 63 00:03:21,680 --> 00:03:23,490 >> Isso vai abrir uma janela como esta. 64 00:03:23,490 --> 00:03:25,530 Deixe-me dar-me mais de uma janela de terminal. 65 00:03:25,530 --> 00:03:27,770 E então o que eu estou indo para ir em frente e fazer, não é só executá-lo. 66 00:03:27,770 --> 00:03:30,690 Eu vou primeiro definir um ponto de ruptura recordação, o que permite que você pause 67 00:03:30,690 --> 00:03:32,500 execução em um lugar particular. 68 00:03:32,500 --> 00:03:35,750 >> Apenas para manter as coisas simples que eu vou para quebrar a linha de um apenas digitando 69 00:03:35,750 --> 00:03:37,000 o número um. 70 00:03:37,000 --> 00:03:40,080 71 00:03:40,080 --> 00:03:43,250 Permitam-me, na verdade, re-abrir esta janela porque está ficando um 72 00:03:43,250 --> 00:03:45,700 pouco pequeno lá. 73 00:03:45,700 --> 00:03:53,270 Então o que eu estou indo agora para fazer aqui é se eu abrir minha janela terminal. 74 00:03:53,270 --> 00:03:53,910 Vamos, lá vamos nós. 75 00:03:53,910 --> 00:03:59,850 >> Portanto, agora se eu voltar para dropbox, Pst4 e execute gdb. / fuga entrar, observe 76 00:03:59,850 --> 00:04:02,600 Eu vou quebrar um para definir um ponto de ruptura na linha um. 77 00:04:02,600 --> 00:04:04,840 E agora eu estou indo para ir frente e tipo de correr. 78 00:04:04,840 --> 00:04:07,370 E quando o faço, notar nada parece acontecer. 79 00:04:07,370 --> 00:04:08,120 >> Não há pop-up. 80 00:04:08,120 --> 00:04:09,790 Não há nenhuma gráfica interface com o usuário ainda. 81 00:04:09,790 --> 00:04:13,340 Mas isso é compreensível, porque eu sou literalmente na linha um no meu programa. 82 00:04:13,340 --> 00:04:17,110 E notem que eu rapidamente encaminhados, especificamente agora para 62, porque todos 83 00:04:17,110 --> 00:04:20,600 as coisas no topo desse arquivo é coisas como comentários e constantes e 84 00:04:20,600 --> 00:04:22,460 desinteressante coisas por agora. 85 00:04:22,460 --> 00:04:25,840 >> Então agora eu estou dentro do principal, ao que parece, na linha 62. 86 00:04:25,840 --> 00:04:27,960 E esta é apenas a distribuição código, recall. 87 00:04:27,960 --> 00:04:33,810 Se eu abrir isso, indo, da mesma forma, em meu diretório caixa suspensa em Pst4, 88 00:04:33,810 --> 00:04:35,450 em breakout.c. 89 00:04:35,450 --> 00:04:40,670 E se eu rolar para baixo e para baixo e para baixo, e deixe-me ir em frente e ligar 90 00:04:40,670 --> 00:04:44,990 meus números de linha. 91 00:04:44,990 --> 00:04:50,300 >> O que eu vou ver se eu rolar para baixo para linha 62, é exatamente a linha que 92 00:04:50,300 --> 00:04:50,910 nós já parou diante. 93 00:04:50,910 --> 00:04:53,720 Portanto, esta linha aqui, 62 anos, é onde estamos prestes a ser. 94 00:04:53,720 --> 00:04:57,470 Então, agora em GDB, se eu ir em frente e escrever agora seguinte, entrar ele vai 95 00:04:57,470 --> 00:04:58,450 executar essa linha. 96 00:04:58,450 --> 00:05:00,610 E pronto, temos a chamada janela g. 97 00:05:00,610 --> 00:05:02,800 Se não estão familiarizados com o que um GWindow é, não se preocupe. 98 00:05:02,800 --> 00:05:05,740 A especificação irá apresentá-lo a ele, como bem como um número de vídeos passo a passo 99 00:05:05,740 --> 00:05:06,830 incorporado na especificação. 100 00:05:06,830 --> 00:05:08,610 >> Mas agora vamos tornar este um pouco mais interessante. 101 00:05:08,610 --> 00:05:10,960 Deixe-me passar essa janela sobre para o lado um pouco. 102 00:05:10,960 --> 00:05:13,480 Deixe-me fazer a janela um pouco maior para que eu possa ver mais. 103 00:05:13,480 --> 00:05:16,140 >> E agora deixe-me ir em frente e fazer em seguida novamente. 104 00:05:16,140 --> 00:05:17,550 E lá estão os meus tijolos. 105 00:05:17,550 --> 00:05:20,490 Se eu digitar junto novamente agora eu vejo a bola. 106 00:05:20,490 --> 00:05:23,520 E se eu digitar em seguida novamente agora vejo o remo. 107 00:05:23,520 --> 00:05:26,690 >> E, felizmente, isso não é gedit realmente cooperando por me mostrar 108 00:05:26,690 --> 00:05:27,660 tudo que eu quero. 109 00:05:27,660 --> 00:05:30,820 Mas agora, se eu fizer na próxima vez, próxima vez, eu sou apenas 110 00:05:30,820 --> 00:05:32,260 declarar algumas variáveis. 111 00:05:32,260 --> 00:05:34,750 E eu posso imprimir qualquer um desses caras. 112 00:05:34,750 --> 00:05:37,170 Imprimir tijolos, gravuras vidas. 113 00:05:37,170 --> 00:05:39,910 >> E agora, se eu continuar a fazer Em seguida, observe que eu vou ser 114 00:05:39,910 --> 00:05:40,870 dentro desse circuito. 115 00:05:40,870 --> 00:05:43,380 Mas o código vai executar exatamente como eu esperava. 116 00:05:43,380 --> 00:05:45,810 Então, quando eu bati esta função, Espere para Click, que vai fazer 117 00:05:45,810 --> 00:05:46,830 literalmente isso. 118 00:05:46,830 --> 00:05:48,870 Então, eu parecia ter perdido o controle sobre o programa. 119 00:05:48,870 --> 00:05:50,480 >> GDB não está me dando outro prompt. 120 00:05:50,480 --> 00:05:51,500 Mas não se preocupe. 121 00:05:51,500 --> 00:05:53,720 Ir para o meu jogo, clique em algum lugar. 122 00:05:53,720 --> 00:05:56,270 >> E pronto, agora ele passa a linha 86. 123 00:05:56,270 --> 00:05:59,460 Então, novamente, é de valor inestimável, em última instância, para problemas de depuração. 124 00:05:59,460 --> 00:06:03,050 Porque você pode, literalmente, percorrer seu código, as coisas imprimir e muito, 125 00:06:03,050 --> 00:06:03,640 muito, muito mais. 126 00:06:03,640 --> 00:06:07,210 Mas por agora, essas ferramentas só deverá fazê-lo muito longe. 127 00:06:07,210 --> 00:06:10,050 >> Então, nós estamos, é claro, dar uma olhada em gráficos, agora, de repente. 128 00:06:10,050 --> 00:06:12,350 E agora o nosso mundo fica um pouco mais interessante. 129 00:06:12,350 --> 00:06:15,680 E você sabe, talvez, de alguns dos vídeos on-line que temos estes 130 00:06:15,680 --> 00:06:18,280 bermuda que você foi assistir como parte de conjuntos de problemas. 131 00:06:18,280 --> 00:06:20,460 >> E eles foram baleados, deliberadamente, contra um fundo branco. 132 00:06:20,460 --> 00:06:23,380 E alguns deles têm o ensino Fellows desenho algum texto na 133 00:06:23,380 --> 00:06:25,490 tela que é sobreposto no lado deles. 134 00:06:25,490 --> 00:06:27,760 Mas, claro, isso não é tudo o que interessante no mundo real. 135 00:06:27,760 --> 00:06:30,520 Esta é apenas uma sala de aula com um grande tela branca e um pano de fundo. 136 00:06:30,520 --> 00:06:33,330 E a nossa incrível equipe de produção tipo de faz tudo parecer bonito 137 00:06:33,330 --> 00:06:36,620 após o fato cortando fora ou sobreposição de qualquer coisa 138 00:06:36,620 --> 00:06:37,840 o que fazemos ou não quer. 139 00:06:37,840 --> 00:06:41,560 >> Agora é só para motivar esta semana e realmente, onde você pode ir, em última instância, 140 00:06:41,560 --> 00:06:42,560 com a ciência da computação. 141 00:06:42,560 --> 00:06:44,260 Não apenas após problema definir quatro. 142 00:06:44,260 --> 00:06:48,240 Mas depois de um outro curso ou um todo currículo é impressionante o que você pode 143 00:06:48,240 --> 00:06:51,090 fazer nos dias de hoje em termos de gráficos, em particular. 144 00:06:51,090 --> 00:06:53,440 >> Alguns de vocês podem ter visto isso flui ao redor online. 145 00:06:53,440 --> 00:06:56,240 Mas eu pensei que eu ia mostrar, por apenas um alguns minutos, um vislumbre do que 146 00:06:56,240 --> 00:07:01,890 informática e que CGI, computação gráfica pode fazer nos dias de hoje 147 00:07:01,890 --> 00:07:04,510 com uma canção familiar e talvez o filme. 148 00:07:04,510 --> 00:07:05,760 >> [MUSIC - LANA DEL RAY, "NOVO E BONITO] 149 00:07:05,760 --> 00:10:50,270 150 00:10:50,270 --> 00:10:52,470 >> COLUNA 1: É um pouco surpreendente, talvez, o quão 151 00:10:52,470 --> 00:10:52,857 onipresente - 152 00:10:52,857 --> 00:10:57,040 >> [Aplausos] 153 00:10:57,040 --> 00:10:59,230 >> COLUNA 1: Eu só baixei. 154 00:10:59,230 --> 00:11:02,920 Mas é realmente incrível, eu acho, apenas como o software onipresente e código e 155 00:11:02,920 --> 00:11:04,230 ferramentas como esta são realmente. 156 00:11:04,230 --> 00:11:07,685 Então, isso é um gosto da direção em que você pode ir. 157 00:11:07,685 --> 00:11:10,620 Oh, não mais Appliance hoje. 158 00:11:10,620 --> 00:11:14,640 Bem, isso é tempo realmente trágico dado o ponto que eu apenas tentei fazer. 159 00:11:14,640 --> 00:11:18,670 >> Tudo bem, então vamos lançar Fusão novamente. 160 00:11:18,670 --> 00:11:20,800 Lembre-me mais tarde. 161 00:11:20,800 --> 00:11:24,190 Tudo bem, e você deve ter conseguido um enviar e-mail como um aparte, se você não obter um 162 00:11:24,190 --> 00:11:25,460 perceber como esse. 163 00:11:25,460 --> 00:11:29,940 Tudo bem, então lembrar que na semana passada começamos a descascar este 164 00:11:29,940 --> 00:11:31,380 mais tarde conhecido como string. 165 00:11:31,380 --> 00:11:34,700 >> cadeia lembra um tipo de dados que é declarados na biblioteca CS50. 166 00:11:34,700 --> 00:11:37,740 E é parte das rodinhas que agora vai começar a decolar. 167 00:11:37,740 --> 00:11:41,280 Era um conceito útil no início. 168 00:11:41,280 --> 00:11:43,750 Mas agora vai ficar mais interessante e mais poderoso para 169 00:11:43,750 --> 00:11:48,330 realmente ver que debaixo do capô, uma string é apenas o que, não podemos dizer? 170 00:11:48,330 --> 00:11:50,500 >> Sim, por isso é um chamado char *. 171 00:11:50,500 --> 00:11:53,860 E o * não denota que não há algum tipo de endereço envolvidos. 172 00:11:53,860 --> 00:11:58,690 E assim, quando você diz char * que você acabou de dizer uma variável cujo tipo de dados é um 173 00:11:58,690 --> 00:11:59,290 ponteiro agora. 174 00:11:59,290 --> 00:12:01,770 O fato de que há a estrela lá Significa apenas que você está declarando uma 175 00:12:01,770 --> 00:12:03,020 assim chamado ponteiro. 176 00:12:03,020 --> 00:12:06,220 E esse ponteiro vai, aparentemente, armazenar o endereço, de 177 00:12:06,220 --> 00:12:07,810 Claro, um char. 178 00:12:07,810 --> 00:12:08,960 >> Agora, por que isso faz sentido? 179 00:12:08,960 --> 00:12:11,200 Bem, o que é uma string debaixo do capô? 180 00:12:11,200 --> 00:12:15,130 Bem, há algum tempo que venho dizendo que uma corda debaixo do capô é 181 00:12:15,130 --> 00:12:18,460 apenas h-p-l-l-o, por exemplo. 182 00:12:18,460 --> 00:12:21,585 >> Mas nós já conversamos sobre isso como sendo, essencialmente, uma matriz. 183 00:12:21,585 --> 00:12:25,410 E uma matriz, então, olhar um pouco mais como este, com cada um desses 184 00:12:25,410 --> 00:12:26,460 ocupando uma mordida. 185 00:12:26,460 --> 00:12:28,710 E então nós dissemos que não há algo especial para cá, o 186 00:12:28,710 --> 00:12:31,270 barra invertida 0, ou terminador nulo. 187 00:12:31,270 --> 00:12:35,230 >> Então todo esse tempo, isso aqui tem sido uma string. 188 00:12:35,230 --> 00:12:38,320 Mas, realmente, uma string é na verdade, um endereço. 189 00:12:38,320 --> 00:12:43,210 E endereços, como veremos, muitas vezes são prefixado com 0x por convenção. 190 00:12:43,210 --> 00:12:44,540 O que 0x denotar? 191 00:12:44,540 --> 00:12:45,970 Alguém sabe? 192 00:12:45,970 --> 00:12:47,320 >> Então, isso significa apenas hexadecimal. 193 00:12:47,320 --> 00:12:52,360 Então, você deve se lembrar, na verdade, a partir de Pst 1, eu acredito, uma das warm-up 194 00:12:52,360 --> 00:12:55,740 questões realmente perguntado sobre notação hexadecimal além 195 00:12:55,740 --> 00:12:57,100 binário e decimal. 196 00:12:57,100 --> 00:13:00,460 E o que é aqui motivação com hexadecimal você tem 16 197 00:13:00,460 --> 00:13:01,770 dígitos à sua disposição. 198 00:13:01,770 --> 00:13:07,900 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, seguido por a, b, c, d, e, f. 199 00:13:07,900 --> 00:13:10,430 >> E se você contar todos aqueles acima, você recebe um total de 16. 200 00:13:10,430 --> 00:13:13,200 Assim, isto está em contraste com decimal, onde temos 10 201 00:13:13,200 --> 00:13:14,690 dígitos, 0 a nove. 202 00:13:14,690 --> 00:13:17,750 É, em contraste com o binário onde temos apenas 0 e 1. 203 00:13:17,750 --> 00:13:21,450 >> Mas no final do dia, você pode apenas representam os mesmos números, mas 204 00:13:21,450 --> 00:13:22,500 um pouco diferente. 205 00:13:22,500 --> 00:13:25,840 E hexadecimal é comum porque, como acontece que - e vamos ver isso 206 00:13:25,840 --> 00:13:28,790 mais tarde no curso - mesmo quando chegarmos a programação web no contexto da 207 00:13:28,790 --> 00:13:32,100 HTML e códigos de cores, hexadecimal é bom. 208 00:13:32,100 --> 00:13:36,390 Como cada dígito, despeja, representa quatro bits perfeitamente. 209 00:13:36,390 --> 00:13:39,280 Por isso, apenas uma espécie de linhas até bem como vamos finalmente ver. 210 00:13:39,280 --> 00:13:44,720 Então, isso pode ser Ox123 ou algo assim, denotando endereço 123 211 00:13:44,720 --> 00:13:47,050 em algum lugar dentro do meu memória do computador. 212 00:13:47,050 --> 00:13:50,600 >> Mas, claro, surgem alguns problemas devido a esta subjacente 213 00:13:50,600 --> 00:13:51,520 implementação. 214 00:13:51,520 --> 00:13:55,930 E lembro que eu levei uma facada implementação de uma função como esta - 215 00:13:55,930 --> 00:14:00,260 comparar traço 0 ponto c na semana passada, que mesmo que parecia que era 216 00:14:00,260 --> 00:14:04,270 direito, ele simplesmente não comparar duas cordas corretamente. 217 00:14:04,270 --> 00:14:07,470 >> Eu joguei fora principal, e eu joguei embora os comentários só para se concentrar em 218 00:14:07,470 --> 00:14:08,970 o código que é de interesse aqui. 219 00:14:08,970 --> 00:14:10,660 E é em vermelho porque é buggy. 220 00:14:10,660 --> 00:14:11,670 Por que razão? 221 00:14:11,670 --> 00:14:15,890 >> Bem, no topo lá quando eu declarei uma corda, o que realmente estava acontecendo 222 00:14:15,890 --> 00:14:17,260 debaixo do capô? 223 00:14:17,260 --> 00:14:19,530 Bem, deixe-me ir para o tela aqui e chamar a isso. 224 00:14:19,530 --> 00:14:23,230 Então eu declarou, mais uma vez, GetString string s. 225 00:14:23,230 --> 00:14:26,640 >> Então, eu estou indo para ir em frente agora e desenhar s para o que ele realmente é. 226 00:14:26,640 --> 00:14:28,590 Vai ser uma praça aqui. 227 00:14:28,590 --> 00:14:30,490 E eu vou reclamar que isto é 32 bits. 228 00:14:30,490 --> 00:14:32,890 Pelo menos é geralmente, pelo menos na CS50 229 00:14:32,890 --> 00:14:34,520 aparelho em um monte de computadores. 230 00:14:34,520 --> 00:14:35,980 Vou chamá-lo s. 231 00:14:35,980 --> 00:14:39,070 >> Mas, agora, lembrar que nós chamado GetString. 232 00:14:39,070 --> 00:14:41,430 Retornos Então GetString, claro, uma string. 233 00:14:41,430 --> 00:14:45,790 Se o usuário digita h-e-l-l-o entrar a string Olá será devolvido. 234 00:14:45,790 --> 00:14:51,010 E essa string, como acabamos de dizer, termina em algum lugar na memória do seu computador 235 00:14:51,010 --> 00:14:53,240 0 com uma barra invertida no final. 236 00:14:53,240 --> 00:14:56,650 Eu vou tirar isso como a matriz - ou bloco contíguo de personagens - 237 00:14:56,650 --> 00:14:58,330 que ele realmente é. 238 00:14:58,330 --> 00:15:01,790 >> E agora, o que é GetString realmente voltando? 239 00:15:01,790 --> 00:15:04,340 Qual tem sido getString retornar todo esse tempo? 240 00:15:04,340 --> 00:15:07,520 Bem, podemos dizer, na semana anterior, ele retorna um string. 241 00:15:07,520 --> 00:15:10,250 Mas, mais tecnicamente, o que faz GetString retorno aparentemente? 242 00:15:10,250 --> 00:15:11,610 >> AUDIÊNCIA: um endereço. 243 00:15:11,610 --> 00:15:12,600 >> COLUNA 1: Um endereço. 244 00:15:12,600 --> 00:15:16,630 Especificamente, ele retorna o endereço de a primeira mordida, seja ele qual for. 245 00:15:16,630 --> 00:15:18,830 Eu continuo usando um, dois, três porque é conveniente. 246 00:15:18,830 --> 00:15:21,380 >> Devolve o endereço do primeiro caractere na seqüência. 247 00:15:21,380 --> 00:15:23,510 E nós dissemos na semana passada que que é suficiente. 248 00:15:23,510 --> 00:15:26,710 Porque sempre podemos descobrir onde o fim da cadeia apenas por 249 00:15:26,710 --> 00:15:30,150 iteração sobre isso, talvez, com a loop ou um loop while ou algo parecido 250 00:15:30,150 --> 00:15:34,990 que, só de olhar para "barra invertida 0", o caráter sentinela especial. 251 00:15:34,990 --> 00:15:37,220 >> E então nós sabemos que a cadeia passa a ser de comprimento - 252 00:15:37,220 --> 00:15:37,980 neste caso - 253 00:15:37,980 --> 00:15:38,670 cinco. 254 00:15:38,670 --> 00:15:43,800 Então, tecnicamente o que faz GetString é ele retorna Ox123 neste caso. 255 00:15:43,800 --> 00:15:53,670 E tecnicamente o que acontece então é que nós guardamos, dentro de s, Ox123. 256 00:15:53,670 --> 00:15:56,460 No final do dia, embora esta é conceito novo, ponteiros, eles são 257 00:15:56,460 --> 00:15:57,350 apenas variáveis. 258 00:15:57,350 --> 00:16:00,440 Mas eles acontecem para armazenar bits que coletivamente representam um endereço. 259 00:16:00,440 --> 00:16:03,700 Então, tecnicamente tudo o que fica armazenado em s é Ox123. 260 00:16:03,700 --> 00:16:04,680 >> Mas nós, como seres humanos - 261 00:16:04,680 --> 00:16:06,020 inclusive hoje em diante - 262 00:16:06,020 --> 00:16:09,290 são realmente não vai se importar, normalmente, qual é o endereço real é 263 00:16:09,290 --> 00:16:10,520 de algum pedaço de memória. 264 00:16:10,520 --> 00:16:14,040 É só para baixo nível de detalhe para ser intelectualmente interessante. 265 00:16:14,040 --> 00:16:15,440 Então, eu estou indo para desfazer isso. 266 00:16:15,440 --> 00:16:19,810 E, ao invés, mais alto nível, basta dizer que quando estamos falando de ponteiros 267 00:16:19,810 --> 00:16:22,170 Eu vou apenas chamar mais seta user-friendly que transmite a 268 00:16:22,170 --> 00:16:26,060 mesma idéia e abstrai os indicação de que o real 269 00:16:26,060 --> 00:16:27,700 endereço subjacente. 270 00:16:27,700 --> 00:16:33,290 >> Agora, se voltar para o código, o que aconteceu na semana passada, se tivermos corda t 271 00:16:33,290 --> 00:16:34,510 igual GetString? 272 00:16:34,510 --> 00:16:38,630 Bem, se eu novamente, digite Olá dessa vez eu vou conseguir 273 00:16:38,630 --> 00:16:40,460 outro pedaço de memória. 274 00:16:40,460 --> 00:16:44,820 h-p-l-l-o invertida 0. 275 00:16:44,820 --> 00:16:48,320 >> Mas porque eu chamei GetString uma segunda vez - 276 00:16:48,320 --> 00:16:51,100 e eu sei que isso de olhar para o código fonte para GetString - mesmo 277 00:16:51,100 --> 00:16:54,350 mas é coincidência que Olá foi digitado duas vezes, GetString não é 278 00:16:54,350 --> 00:16:55,890 vai tentar otimizar e ser inteligente. 279 00:16:55,890 --> 00:16:58,550 Ele só vai pegar outro pedaço de a memória do computador, que está 280 00:16:58,550 --> 00:16:59,640 vai ser em outro endereço. 281 00:16:59,640 --> 00:17:02,330 Vamos apenas dizer arbitrariamente 456. 282 00:17:02,330 --> 00:17:04,079 >> E então o que é que vai voltar? 283 00:17:04,079 --> 00:17:08,030 Vai voltar 456 e armazená-lo em t. 284 00:17:08,030 --> 00:17:12,010 Então, o que realmente está acontecendo, sobre o lado esquerdo é que eu tenho um outro pedaço 285 00:17:12,010 --> 00:17:14,260 de memória de 32 bits normalmente. 286 00:17:14,260 --> 00:17:16,720 E lá está a ir Ox456. 287 00:17:16,720 --> 00:17:20,140 Mas, novamente, eu não estou interessado nestes números específicos digitamos mais. 288 00:17:20,140 --> 00:17:23,069 Eu só vou abstratamente desenhá-lo como uma seta. 289 00:17:23,069 --> 00:17:25,202 >> Portanto, esta é agora uma nova explicação. 290 00:17:25,202 --> 00:17:28,735 Mas é exatamente a mesma idéia que é vem acontecendo todo esse tempo. 291 00:17:28,735 --> 00:17:33,150 E assim, a razão, então, que este primeiro versão de comparação foi buggy 292 00:17:33,150 --> 00:17:34,480 na semana passada, é por quê? 293 00:17:34,480 --> 00:17:38,000 Quando você se s é igual a igual t O que você está verdadeiramente 294 00:17:38,000 --> 00:17:40,550 debaixo do capô comparando? 295 00:17:40,550 --> 00:17:41,910 >> Você está comparando os endereços. 296 00:17:41,910 --> 00:17:47,950 E, assim, intuitivamente, claramente, Ox123 não vai igual Ox456. 297 00:17:47,950 --> 00:17:49,380 Esses números, esses bits são apenas diferentes. 298 00:17:49,380 --> 00:17:53,220 >> E assim, de forma consistente, na semana passada, ele disse você digita coisas diferentes, mesmo que a 299 00:17:53,220 --> 00:17:55,360 palavras foram literalmente o mesmo. 300 00:17:55,360 --> 00:17:58,770 Então vamos corrigir isso. 301 00:17:58,770 --> 00:18:00,120 Em termos leigos, o que era a correção? 302 00:18:00,120 --> 00:18:02,110 >> AUDIÊNCIA: Use uma função. 303 00:18:02,110 --> 00:18:02,870 >> COLUNA 1: Usar uma função. 304 00:18:02,870 --> 00:18:05,190 Ou estrelas estão definitivamente envolvidos, mas usar uma função para fazer o quê? 305 00:18:05,190 --> 00:18:05,962 >> AUDIÊNCIA: Para comparar as cordas. 306 00:18:05,962 --> 00:18:07,390 >> COLUNA 1: Para comparar as cordas. 307 00:18:07,390 --> 00:18:11,030 Assim, o problema fundamental aqui foi que eu estava apenas considerando a 308 00:18:11,030 --> 00:18:15,870 qualidade de cordas a ser definido pela comparação de seus endereços. 309 00:18:15,870 --> 00:18:18,540 E, obviamente, isso é apenas mudo agora uma vez Você entende o que está acontecendo 310 00:18:18,540 --> 00:18:19,510 debaixo do capô. 311 00:18:19,510 --> 00:18:23,270 Para comparar verdadeiramente cordas para ver se eles são iguais na maneira que um ser humano 312 00:18:23,270 --> 00:18:26,680 consideraria duas cordas para ser igual é preciso compará-los caráter para 313 00:18:26,680 --> 00:18:28,070 personagem para personagem. 314 00:18:28,070 --> 00:18:30,020 >> Agora eu poderia ter feito esta muito tedioso. 315 00:18:30,020 --> 00:18:32,240 Mas familiarmente, estamos usando um loop for. 316 00:18:32,240 --> 00:18:36,050 E basta comparar s suporte i contra t suporte i. 317 00:18:36,050 --> 00:18:39,590 s suporte de i + 1 contra t suporte i + 1, e assim por diante, para dentro 318 00:18:39,590 --> 00:18:40,580 uma espécie de loop. 319 00:18:40,580 --> 00:18:44,950 E se eu detectar quaisquer dois personagens que diferentes, ou se eu perceber que ooh, s é 320 00:18:44,950 --> 00:18:48,410 mais curta do que t ou mais que t Posso dizer imediatamente falso, 321 00:18:48,410 --> 00:18:49,390 eles não são a mesma coisa. 322 00:18:49,390 --> 00:18:55,370 >> Mas se eu passar s e t e dizer mesmo, mesmo, mesmo, mesmo, mesmo, o fim de 323 00:18:55,370 --> 00:18:58,520 ambas as cordas, o que posso dizer verdade, elas são iguais. 324 00:18:58,520 --> 00:19:01,040 Bem, felizmente, anos atrás, alguém escreveu que o código para nós. 325 00:19:01,040 --> 00:19:03,790 >> E eles chamavam isso SeqComp para cadeia de comparar. 326 00:19:03,790 --> 00:19:11,900 E mesmo que seja um pouco contra intuitiva, StrComp retorna 0 se os 327 00:19:11,900 --> 00:19:14,520 duas cadeias, s e t são o mesmo. 328 00:19:14,520 --> 00:19:18,090 Mas ele retorna valor negativo se s deve vir antes de t em ordem alfabética ou 329 00:19:18,090 --> 00:19:20,610 valor positivo se deve vir depois de t em ordem alfabética. 330 00:19:20,610 --> 00:19:24,030 >> Então, se você quiser resolver alguma coisa, verifica-se que SeqComp é útil. 331 00:19:24,030 --> 00:19:26,660 Porque não basta dizer sim ou não, iguais ou não. 332 00:19:26,660 --> 00:19:30,440 Ele lhe dá um senso de ordenação como uma força dicionário. 333 00:19:30,440 --> 00:19:33,770 Então SeqComp, s vírgula t é igual a é igual a 0 significa que o 334 00:19:33,770 --> 00:19:35,200 cordas são verdadeiramente iguais. 335 00:19:35,200 --> 00:19:38,680 Porque quem escreveu esta função anos atrás, presumivelmente utilizado um loop 336 00:19:38,680 --> 00:19:42,840 ou um loop while ou algo parecido para integrar mais os personagens novamente 337 00:19:42,840 --> 00:19:45,270 e de novo e de novo. 338 00:19:45,270 --> 00:19:47,300 >> Mas dois problemas surgiram aqui. 339 00:19:47,300 --> 00:19:48,750 Este foi copy0.c. 340 00:19:48,750 --> 00:19:51,680 E os dois está no vermelho porque é falho. 341 00:19:51,680 --> 00:19:52,800 E o que fazemos aqui? 342 00:19:52,800 --> 00:19:54,310 Bem, primeiro eu liguei GetString. 343 00:19:54,310 --> 00:19:56,255 E eu guardei o valor de retorno em s. 344 00:19:56,255 --> 00:20:00,260 Então, isso é praticamente o mesmo que esta parte superior da imagem. 345 00:20:00,260 --> 00:20:01,490 >> Mas o que vem depois disso? 346 00:20:01,490 --> 00:20:04,980 Bem, deixe-me ir em frente e se livrar de um monte de presente. 347 00:20:04,980 --> 00:20:09,650 Vamos voltar no tempo para onde nós apenas tem s, que agora é consistente com 348 00:20:09,650 --> 00:20:10,940 uma linha lá em cima. 349 00:20:10,940 --> 00:20:11,400 >> Eu verifico. 350 00:20:11,400 --> 00:20:13,450 Se s é igual é igual a 0. 351 00:20:13,450 --> 00:20:18,670 Agora, uma nota lateral rápida, quando GetString pode retornar 0? 352 00:20:18,670 --> 00:20:19,580 Não há memória suficiente. 353 00:20:19,580 --> 00:20:19,880 Certo? 354 00:20:19,880 --> 00:20:22,310 >> É raro que isso vai acontecer, certamente em um computador que é 355 00:20:22,310 --> 00:20:24,740 tem centenas de megas ou mesmo GB de RAM. 356 00:20:24,740 --> 00:20:27,080 Mas poderia, em teoria, o retorno 0, especialmente se o 357 00:20:27,080 --> 00:20:28,080 usuário não cooperar. 358 00:20:28,080 --> 00:20:31,640 Há maneiras de fingir que você não tem qualquer coisa digitada e truque 359 00:20:31,640 --> 00:20:34,100 GetString em retornar 0 eficazmente. 360 00:20:34,100 --> 00:20:35,470 >> Então ele vai para procurar isso. 361 00:20:35,470 --> 00:20:39,430 Porque se algum de vocês já começaram a se, já, falhas de segmentação - 362 00:20:39,430 --> 00:20:42,280 que provavelmente tem sido uma fonte de alguma frustração - 363 00:20:42,280 --> 00:20:46,150 esses são quase sempre o resultado de erro relacionada com a memória. 364 00:20:46,150 --> 00:20:50,440 De alguma forma, você estragou tudo no que diz respeito a um ponteiro, mesmo se você não percebeu 365 00:20:50,440 --> 00:20:51,530 houve um ponteiro. 366 00:20:51,530 --> 00:20:55,260 Então você pode ter induzido a segmentação defeitos tão cedo quanto uma semana usando 367 00:20:55,260 --> 00:21:02,100 algo como um loop ou um tempo loop e uma matriz por ir longe demais 368 00:21:02,100 --> 00:21:05,900 além dos limites da matriz que alguns você declarou, em duas semanas, em 369 00:21:05,900 --> 00:21:06,690 particular. 370 00:21:06,690 --> 00:21:09,220 >> Você pode ter feito isso mesmo problema definir quatro com Breakout. 371 00:21:09,220 --> 00:21:12,910 Mesmo que você provavelmente não viu nenhuma estrela no código de distribuição para 372 00:21:12,910 --> 00:21:17,410 Breakout, verifica-se que os GRect e Goval e outras coisas que tais, 373 00:21:17,410 --> 00:21:19,650 esses são realmente os ponteiros debaixo do capô. 374 00:21:19,650 --> 00:21:23,430 >> Mas Stanford, como nós, tipo de peles esse detalhe, pelo menos para as bibliotecas 375 00:21:23,430 --> 00:21:26,540 propósitos, muito parecido com o que fazemos para string e char *. 376 00:21:26,540 --> 00:21:30,060 Mas GRect e Goval e de todos aqueles coisas que vocês estão ou estarão usando 377 00:21:30,060 --> 00:21:32,630 esta semana são em última análise, endereços de memória. 378 00:21:32,630 --> 00:21:33,650 Você simplesmente não sabe. 379 00:21:33,650 --> 00:21:37,240 >> Portanto, não é surpreendente, então, talvez, que você pode tropeçar em algum 380 00:21:37,240 --> 00:21:38,580 falhas de segmentação. 381 00:21:38,580 --> 00:21:41,290 Mas o que é interessante aqui agora, Se depois de verificar 0 que fazemos 382 00:21:41,290 --> 00:21:43,460 corda t fica s. 383 00:21:43,460 --> 00:21:44,690 Bem, deixe-me declarar t. 384 00:21:44,690 --> 00:21:47,730 Vou desenhá-lo como um quadrado, 32 bits, chamá-lo de t. 385 00:21:47,730 --> 00:21:49,740 E então eu vou fazer se s. 386 00:21:49,740 --> 00:21:51,130 >> Bem, o que isso significa? 387 00:21:51,130 --> 00:21:53,280 Bem, é um pouco difícil pensar nisso imaginar sábio. 388 00:21:53,280 --> 00:21:55,025 Mas vamos pensar sobre o que está dentro de x? 389 00:21:55,025 --> 00:21:59,430 O que é, literalmente, dentro dessa variável? 390 00:21:59,430 --> 00:22:01,500 O valor Ox123. 391 00:22:01,500 --> 00:22:05,815 >> Portanto, quando digo corda t fica s, que apenas literalmente significa ter o número 392 00:22:05,815 --> 00:22:10,070 em s, que é Ox123 e colocá-lo Ox123. 393 00:22:10,070 --> 00:22:13,740 Ou pictoricamente, se eu tipo de abstrato longe desse detalhe tem o 394 00:22:13,740 --> 00:22:16,600 efeito de literalmente fazer isso também. 395 00:22:16,600 --> 00:22:22,110 >> Então, agora, acho que volta a semana passada, quando procedeu-se capitalista T. I 396 00:22:22,110 --> 00:22:23,800 fez T suporte 0. 397 00:22:23,800 --> 00:22:27,150 Bem, T suporte 0, mesmo que seja um ponteiro, você pode tratá-lo como se 398 00:22:27,150 --> 00:22:29,220 é uma matriz, com um quadrado notação suporte. 399 00:22:29,220 --> 00:22:31,550 >> Então, onde está T suporte 0? 400 00:22:31,550 --> 00:22:32,990 Bem, é o h. 401 00:22:32,990 --> 00:22:36,800 E assim, quando usamos essa linha de código, dois superior, que está em que c type.h 402 00:22:36,800 --> 00:22:38,460 arquivo de cabeçalho, que é onde ele é declarado. 403 00:22:38,460 --> 00:22:44,410 Você está capitalizando esta H. Mas, Claro, isso é exatamente o mesmo que h é 404 00:22:44,410 --> 00:22:46,540 s no interior de, por assim dizer. 405 00:22:46,540 --> 00:22:51,930 E agora você mudou ou capitalizados tanto o original eo 406 00:22:51,930 --> 00:22:53,120 chamado de cópia. 407 00:22:53,120 --> 00:22:56,620 Porque você não faz uma cópia na forma que um ser humano quer que seja. 408 00:22:56,620 --> 00:22:59,710 >> Então, qual foi a correção aqui, em copy1.c na semana passada? 409 00:22:59,710 --> 00:23:03,070 410 00:23:03,070 --> 00:23:05,580 Funções, para que pudéssemos realmente copiar o string. 411 00:23:05,580 --> 00:23:08,700 E, fundamentalmente, o que precisamos fazer para copiar a seqüência? 412 00:23:08,700 --> 00:23:12,070 >> Bem, nesta versão verde aqui estou vai fazê-lo muito baixo nível. 413 00:23:12,070 --> 00:23:14,260 Na verdade, existem funções eles poderiam ajudar com isso. 414 00:23:14,260 --> 00:23:17,710 Mas o mais básico eo mais um familiar, pelo menos, em breve será 415 00:23:17,710 --> 00:23:19,600 familiar para nós, é o seguinte - 416 00:23:19,600 --> 00:23:21,910 assim um na primeira linha do código em verde agora. 417 00:23:21,910 --> 00:23:23,970 >> Eu só reescreveu s como char *. 418 00:23:23,970 --> 00:23:25,250 Não há nenhum funcional diferença lá. 419 00:23:25,250 --> 00:23:28,790 Eu só joguei fora a biblioteca e CS50 Eu estou chamando-o que é, um char *. 420 00:23:28,790 --> 00:23:31,640 >> Agora, ponto, ponto, ponto, porque não havia verificação de erros que não é 421 00:23:31,640 --> 00:23:33,200 interessante para falar novamente. 422 00:23:33,200 --> 00:23:34,710 Então, agora t é declarada. 423 00:23:34,710 --> 00:23:35,780 Ele também é um char *. 424 00:23:35,780 --> 00:23:38,280 Então eu desenhei uma pequena praça em a tela como antes. 425 00:23:38,280 --> 00:23:41,870 >> Mas, no lado direito, malloc, dissemos é alocar memória. 426 00:23:41,870 --> 00:23:44,130 Então alocar algum pedaço de memória. 427 00:23:44,130 --> 00:23:48,830 E quantos bytes é que vamos realmente pretende atribuir, não parece? 428 00:23:48,830 --> 00:23:50,340 >> Bem, o comprimento da cadeia de s. 429 00:23:50,340 --> 00:23:52,310 Então, se é que é Olá vai ser cinco. 430 00:23:52,310 --> 00:23:53,950 Vamos dizer h-e-l-l-o. 431 00:23:53,950 --> 00:23:55,090 Assim, cinco bytes. 432 00:23:55,090 --> 00:23:57,960 >> Mas, então, mais uma, por 1? 433 00:23:57,960 --> 00:23:58,830 O 0 personagem. 434 00:23:58,830 --> 00:24:03,640 Se não deixar espaço para esse cara que acidentalmente pode criar uma situação 435 00:24:03,640 --> 00:24:05,600 onde a corda é h-e-l-l-o. 436 00:24:05,600 --> 00:24:08,470 E, em seguida, a próxima vez é GetString chamou e eu digitar, por exemplo, 437 00:24:08,470 --> 00:24:14,020 David, D--v-i-d, o computador vai pensar que s é realmente 438 00:24:14,020 --> 00:24:18,900 h-p-l-l-o-d-a-v-i-d, porque há sem pausa entre as palavras. 439 00:24:18,900 --> 00:24:19,810 >> Por isso, precisamos que pausa. 440 00:24:19,810 --> 00:24:20,720 Então, não queremos que cinco. 441 00:24:20,720 --> 00:24:22,100 Queremos seis bytes. 442 00:24:22,100 --> 00:24:23,110 >> E bytes que eu digo. 443 00:24:23,110 --> 00:24:25,220 Mas é o tamanho realmente o tempo do char. 444 00:24:25,220 --> 00:24:28,040 Tecnicamente char é quase sempre um byte. 445 00:24:28,040 --> 00:24:31,030 >> Mas apenas para fazer o nosso código portátil, por assim dizer, de modo que ele funciona em 446 00:24:31,030 --> 00:24:33,750 computadores diferentes, mesmo se eles podem ser um pouco diferente por baixo do 447 00:24:33,750 --> 00:24:36,590 capa, eu vou genericamente dizer o tamanho do char para que 448 00:24:36,590 --> 00:24:37,660 meu código sempre funciona. 449 00:24:37,660 --> 00:24:40,610 E eu não tenho que recompilar apenas porque eu atualizar meu computador ou utilizar 450 00:24:40,610 --> 00:24:42,140 uma plataforma diferente. 451 00:24:42,140 --> 00:24:45,300 >> Então eu tenho seis vezes o tamanho da um char, que passa a ser 1. 452 00:24:45,300 --> 00:24:47,440 Então isso significa que malloc poderia me dê seis bytes. 453 00:24:47,440 --> 00:24:49,140 O que é que realmente está fazendo? 454 00:24:49,140 --> 00:24:52,810 Bem, deixe-me retroceder no tempo aqui onde estamos na história. 455 00:24:52,810 --> 00:24:57,620 >> Então, se eu voltar aqui, eu já declarou um char * chamado t. 456 00:24:57,620 --> 00:25:00,280 Eu já chamado malloc por seis bytes. 457 00:25:00,280 --> 00:25:06,400 E agora eu vou chamar os seis bytes assim como a matriz anterior. 458 00:25:06,400 --> 00:25:10,570 Mas eu realmente não sei o que é dentro dessa matriz. 459 00:25:10,570 --> 00:25:14,640 >> Se você alocar memória verifica-se que você não pode confiar que há algum 460 00:25:14,640 --> 00:25:15,810 valor conhecido ali. 461 00:25:15,810 --> 00:25:18,400 Podia ter sido utilizado por algo outro, uma outra função, alguma outra 462 00:25:18,400 --> 00:25:19,630 linha de código que você escreveu. 463 00:25:19,630 --> 00:25:22,870 Então, vamos chamar estes geralmente lixo valores e desenhá-los, talvez, como 464 00:25:22,870 --> 00:25:26,170 pontos de interrogação, indicando apenas que não sei o que está realmente lá. 465 00:25:26,170 --> 00:25:30,390 E isso não é grande coisa contanto que são inteligentes o suficiente para substituir aqueles 466 00:25:30,390 --> 00:25:34,550 valores de lixo com números ou caracteres que se preocupam. 467 00:25:34,550 --> 00:25:36,340 >> Portanto, neste caso o que eu vou fazer? 468 00:25:36,340 --> 00:25:38,670 Bem, a minha linha de código seguinte, eu tenho quatro. 469 00:25:38,670 --> 00:25:41,350 int i obter 0, n recebe o comprimento da corda de s. 470 00:25:41,350 --> 00:25:42,750 Assim, um familiar para o loop. 471 00:25:42,750 --> 00:25:45,875 I é menor ou igual a n, que é geralmente acima. 472 00:25:45,875 --> 00:25:47,500 >> Mas desta vez é deliberada. 473 00:25:47,500 --> 00:25:51,890 I + +, e então eu simplesmente fazer t suporte i fica s. 474 00:25:51,890 --> 00:25:56,320 Porque a minha imagem se parece com isso a Neste momento, armazenado em que t é o 475 00:25:56,320 --> 00:25:59,530 endereço dessa pedaço aleatório de memória cujos valores são desconhecidos. 476 00:25:59,530 --> 00:26:03,030 Mas assim que eu faço t suporte 0 que me coloca aqui. 477 00:26:03,030 --> 00:26:07,430 >> E o que acaba sendo atraídos para lá? 478 00:26:07,430 --> 00:26:08,740 Nós acabam colocando h. 479 00:26:08,740 --> 00:26:11,170 Porque isso é o que está em s suporte 0. 480 00:26:11,170 --> 00:26:14,300 E, em seguida, a mesma coisa para e e, l, l, e o. 481 00:26:14,300 --> 00:26:17,930 >> n, por que eu vou para cima através igual a n? 482 00:26:17,930 --> 00:26:19,200 Devido ao seu carácter 0. 483 00:26:19,200 --> 00:26:23,580 Então, só para ficar claro, então, se eu realmente apagará tudo o que estes lixo 484 00:26:23,580 --> 00:26:28,870 valores e então realmente atrair o que eu espero, é s faixa 1, 2, 485 00:26:28,870 --> 00:26:32,440 3, 4, além de que é à direita novo personagem. 486 00:26:32,440 --> 00:26:36,080 >> E agora se continuássemos passado do ponto, ponto, ponto nesta versão correta 487 00:26:36,080 --> 00:26:41,930 e capitalizados t suporte 0 eu iria, de Claro, se aproveitando apenas isso 488 00:26:41,930 --> 00:26:47,050 cara aqui e que, conceitualmente, acabou por ser a meta. 489 00:26:47,050 --> 00:26:48,040 Então, isso é tudo o ponteiro está. 490 00:26:48,040 --> 00:26:51,430 >> E você tem de usá-los por semanas Agora, no contexto de cadeias. 491 00:26:51,430 --> 00:26:53,530 Mas debaixo do capô são um pouco mais complexa. 492 00:26:53,530 --> 00:26:57,520 Mas se você pensar sobre eles neste forma pictórica proponho que eles são 493 00:26:57,520 --> 00:27:01,720 provavelmente não é tão assustador como eles primeiro pode parecer à primeira vista, 494 00:27:01,720 --> 00:27:04,730 particularmente com essa nova sintaxe. 495 00:27:04,730 --> 00:27:07,290 Qualquer dúvida sobre ponteiros, cordas, ou chars? 496 00:27:07,290 --> 00:27:07,580 Sim? 497 00:27:07,580 --> 00:27:09,252 >> AUDIÊNCIA: Você pode voltar para o [inaudível]? 498 00:27:09,252 --> 00:27:10,502 >> COLUNA 1: Claro. 499 00:27:10,502 --> 00:27:14,058 500 00:27:14,058 --> 00:27:19,525 >> AUDIÊNCIA: Então como é que em sua última linha, você não tem uma linha de t * 501 00:27:19,525 --> 00:27:21,513 e * s na linha? 502 00:27:21,513 --> 00:27:23,004 Você não tem a referência para o - 503 00:27:23,004 --> 00:27:24,640 >> COLUNA 1: Ah, uma pergunta muito boa. 504 00:27:24,640 --> 00:27:26,800 Por que eu não tenho a * t * e uma s? 505 00:27:26,800 --> 00:27:30,340 Porque brevemente, na semana passada, como no nosso função de trocar, eu disse que quando 506 00:27:30,340 --> 00:27:33,350 você tem um ponteiro o meio pelo que você vai lá, como fizemos 507 00:27:33,350 --> 00:27:36,590 fisicamente no palco, era, na verdade, usar o operador estrela. 508 00:27:36,590 --> 00:27:40,570 >> Acontece que esta de colchetes notação é o que vamos chamar sintática 509 00:27:40,570 --> 00:27:44,190 açúcar, que é apenas uma maneira sexy de dizendo que é notação abreviada para 510 00:27:44,190 --> 00:27:45,950 exatamente o que você está descrevendo. 511 00:27:45,950 --> 00:27:49,385 Mas é um pouco mais intuitivo. 512 00:27:49,385 --> 00:27:53,510 E correndo o risco de fazer isso parecer mais complicado do que precisa ser, 513 00:27:53,510 --> 00:27:56,990 o que realmente está acontecendo aqui é o seguinte - 514 00:27:56,990 --> 00:28:01,450 Se eu disser * t que significa ir para o endereço armazenado em t. 515 00:28:01,450 --> 00:28:04,350 >> Então, literalmente, se t está armazenando o endereço dessa h 516 00:28:04,350 --> 00:28:07,300 Inicialmente, a * t meio aqui. 517 00:28:07,300 --> 00:28:10,730 Agora, o que t suporte 0 significa? 518 00:28:10,730 --> 00:28:11,560 Mesma coisa. 519 00:28:11,560 --> 00:28:13,510 É apenas um pouco mais user amigável para escrever. 520 00:28:13,510 --> 00:28:14,430 >> Mas eu não estou pronto ainda. 521 00:28:14,430 --> 00:28:17,800 Eu não posso simplesmente dizer * t * s fica. 522 00:28:17,800 --> 00:28:19,440 Porque o que eu estaria fazendo então? 523 00:28:19,440 --> 00:28:22,950 Eu estaria colocando h, h, h, h, h toda a coisa toda. 524 00:28:22,950 --> 00:28:22,995 Certo? 525 00:28:22,995 --> 00:28:26,020 >> Porque * t é ir para o endereço em t. 526 00:28:26,020 --> 00:28:27,580 Mas estamos dentro de um loop. 527 00:28:27,580 --> 00:28:32,150 E qual o valor que eu estou incrementando, claro, em cada iteração? 528 00:28:32,150 --> 00:28:32,690 i. 529 00:28:32,690 --> 00:28:34,590 >> Mas há uma oportunidade aqui, certo? 530 00:28:34,590 --> 00:28:37,870 Mesmo que isso parece que está ficando um pouco mais sofisticadas 531 00:28:37,870 --> 00:28:40,730 que a notação de colchetes temos usado por algum tempo - 532 00:28:40,730 --> 00:28:43,840 deixe-me desfazer minha mudança de h lá - 533 00:28:43,840 --> 00:28:48,870 mesmo que isso agora está ficando um pouco extravagante, a idéia básica, se * t 534 00:28:48,870 --> 00:28:53,630 significa aqui e * t é apenas ir para o endereço de t. 535 00:28:53,630 --> 00:28:54,990 >> Mas qual era o endereço no t? 536 00:28:54,990 --> 00:28:56,850 O número que continuar usando? 537 00:28:56,850 --> 00:29:00,540 Como Ox456, vamos trazer isso de volta apenas por uma questão de discussão. 538 00:29:00,540 --> 00:29:05,380 Bem, se eu quiser chegar ao e em t string, eu só quero ir, 539 00:29:05,380 --> 00:29:06,460 essencialmente, 456. 540 00:29:06,460 --> 00:29:09,230 >> Ou melhor, 457. 541 00:29:09,230 --> 00:29:10,590 Eu só preciso adicionar uma. 542 00:29:10,590 --> 00:29:11,790 Mas eu posso fazer isso, certo? 543 00:29:11,790 --> 00:29:14,680 Porque t, apesar de eu manter desenho agora como uma flecha, é apenas um 544 00:29:14,680 --> 00:29:16,570 número, Ox456. 545 00:29:16,570 --> 00:29:21,400 E se eu adicionar um para isso, ou mais geralmente, se eu adicionar I para que eu possa 546 00:29:21,400 --> 00:29:24,350 realmente chegar exatamente onde eu quero. 547 00:29:24,350 --> 00:29:26,260 Então, se eu realmente fazer isso - 548 00:29:26,260 --> 00:29:28,970 e isso é o que é chamado agora ponteiro aritmética - 549 00:29:28,970 --> 00:29:30,375 Eu posso remover essa linha. 550 00:29:30,375 --> 00:29:33,550 Qual é, francamente, eu acho que mais clara e um pouco mais amigável para ler. 551 00:29:33,550 --> 00:29:35,970 Mas isso não é menos correto. 552 00:29:35,970 --> 00:29:38,570 >> Esta linha de código está usando agora aritmética de ponteiro. 553 00:29:38,570 --> 00:29:40,920 Ele está dizendo que ir para o seguinte endereço - 554 00:29:40,920 --> 00:29:44,670 qualquer que seja o início do t é, que t é mais i, que inicialmente 555 00:29:44,670 --> 00:29:45,730 é 0, o que é ótimo. 556 00:29:45,730 --> 00:29:49,280 Porque o que significa o início do t mais 1, mais 2, mais 3, e assim por diante. 557 00:29:49,280 --> 00:29:51,030 E a mesma coisa com s. 558 00:29:51,030 --> 00:29:52,750 >> Então açúcar sintático para isso. 559 00:29:52,750 --> 00:29:55,900 Mas a compreensão do que realmente está acontecendo debaixo do capô, eu diria, 560 00:29:55,900 --> 00:29:57,410 é realmente útil em si mesmo. 561 00:29:57,410 --> 00:30:00,620 Porque isso significa que agora não há muito mais magia acontecendo 562 00:30:00,620 --> 00:30:01,620 debaixo do capô. 563 00:30:01,620 --> 00:30:03,920 Não vão ser muitos mais camadas que podemos descascar para você. 564 00:30:03,920 --> 00:30:04,810 Este é c. 565 00:30:04,810 --> 00:30:06,410 E esta é a programação. 566 00:30:06,410 --> 00:30:08,002 Pergunta muito boa. 567 00:30:08,002 --> 00:30:11,570 >> Tudo bem, então isso foi que de buggy programa que eu estava me referindo anteriormente. 568 00:30:11,570 --> 00:30:12,650 troca foi falho. 569 00:30:12,650 --> 00:30:14,070 Se parecia funcionar. 570 00:30:14,070 --> 00:30:17,390 Lembre-se que, assim como com o leite e o suco de laranja - que eu comecei a 571 00:30:17,390 --> 00:30:18,660 beber manifestação de hoje. 572 00:30:18,660 --> 00:30:22,220 Assim como com o suco de laranja e o leite, que teve de usar uma 573 00:30:22,220 --> 00:30:26,200 variável temporária, tmp, para realizar uma temporariamente, para que pudéssemos então 574 00:30:26,200 --> 00:30:28,820 alterar o seu valor e, em seguida, atualizar b. 575 00:30:28,820 --> 00:30:32,870 >> Mas essa função, como dissemos, ou esta programa no qual essa função é 576 00:30:32,870 --> 00:30:35,670 escrito estava errado e falho, por quê? 577 00:30:35,670 --> 00:30:38,870 578 00:30:38,870 --> 00:30:39,090 Sim? 579 00:30:39,090 --> 00:30:42,471 >> AUDIÊNCIA: [inaudível]. 580 00:30:42,471 --> 00:30:44,940 >> COLUNA 1: Exatamente, quando vocês chamam de troca - 581 00:30:44,940 --> 00:30:47,820 ou, mais geralmente, quando chamar mais qualquer função - 582 00:30:47,820 --> 00:30:51,210 se os argumentos para essa função são primitivas, por assim dizer, ints e chars 583 00:30:51,210 --> 00:30:56,740 e duplas e carros alegóricos, as coisas sem estrelas, você está passando uma cópia do 584 00:30:56,740 --> 00:30:57,540 o argumento. 585 00:30:57,540 --> 00:31:01,580 Portanto, se x e y era uma era de 2, um vai a ser 1 e b vai ser 2. 586 00:31:01,580 --> 00:31:05,250 Mas eles vão ser diferentes pedaços de bits, diferentes blocos de 587 00:31:05,250 --> 00:31:07,540 memória que venham a ser armazenando valores idênticos. 588 00:31:07,540 --> 00:31:12,160 >> Portanto, este código é super perfeito em troca de a e b. 589 00:31:12,160 --> 00:31:13,850 Isso não é bom em troca - 590 00:31:13,850 --> 00:31:15,290 no exemplo da semana passada - 591 00:31:15,290 --> 00:31:16,390 x e y. 592 00:31:16,390 --> 00:31:18,780 Porque mais uma vez, eles são no âmbito incorrecto. 593 00:31:18,780 --> 00:31:21,310 >> Agora, como é que nós vamos sobre a fixação isso? 594 00:31:21,310 --> 00:31:23,140 Tivemos que fazer a função olhar um pouco mais feio. 595 00:31:23,140 --> 00:31:25,250 Mas, novamente, considerar o que isto significa apenas. 596 00:31:25,250 --> 00:31:27,840 597 00:31:27,840 --> 00:31:31,500 >> E, na verdade, deixe-me, por coerência, mudar uma coisa assim que é idêntico ao 598 00:31:31,500 --> 00:31:33,200 o que nós fizemos. 599 00:31:33,200 --> 00:31:35,690 Como eu mencionei na semana passada, ele não importa para onde vai. 600 00:31:35,690 --> 00:31:38,120 Na verdade, normalmente você iria colocar o estrela ao lado do nome da variável. 601 00:31:38,120 --> 00:31:40,750 Mas eu acho que seria um pouco mais fácil considerar a * junto da 602 00:31:40,750 --> 00:31:44,910 tipo de dados que significa que é um ponteiro para um int neste caso. 603 00:31:44,910 --> 00:31:46,270 >> Então, o que eu estou fazendo aqui? 604 00:31:46,270 --> 00:31:49,590 Eu estou dizendo que não me dê um int seguido por outro int 605 00:31:49,590 --> 00:31:50,810 chamando-os de a e b. 606 00:31:50,810 --> 00:31:52,460 Dê-me o endereço de um int. 607 00:31:52,460 --> 00:31:53,960 Dê-me o endereço de outro int. 608 00:31:53,960 --> 00:31:56,330 Chame aqueles aborda a e b. 609 00:31:56,330 --> 00:32:00,860 >> E, em seguida, usando a notação * baixo abaixo, vá para cada um desses endereços 610 00:32:00,860 --> 00:32:05,290 conforme necessário para obter qualquer ou definir o seu valor. 611 00:32:05,290 --> 00:32:07,400 Mas há uma exceção aqui. 612 00:32:07,400 --> 00:32:11,130 Por que eu não tenho um * junto tmp? 613 00:32:11,130 --> 00:32:15,070 Por que eu não faço isso, por exemplo? 614 00:32:15,070 --> 00:32:19,370 Parece que eu deveria ir todos fora e corrigir a coisa toda. 615 00:32:19,370 --> 00:32:19,752 Sim? 616 00:32:19,752 --> 00:32:21,002 >> AUDIÊNCIA: [inaudível]. 617 00:32:21,002 --> 00:32:23,280 618 00:32:23,280 --> 00:32:25,480 >> COLUNA 1: eu não declarei tmp como uma string. 619 00:32:25,480 --> 00:32:28,830 620 00:32:28,830 --> 00:32:34,950 Portanto, este deve declarar, neste caso, um tmp para ser o endereço de um int. 621 00:32:34,950 --> 00:32:37,380 Mas isso não é bem o que eu quero, por um par de razões. 622 00:32:37,380 --> 00:32:38,616 >> AUDIÊNCIA: Você não quer trocá-los. 623 00:32:38,616 --> 00:32:41,800 >> COLUNA 1: Exatamente, eu não quero trocar nada com tmp. tmp é apenas 624 00:32:41,800 --> 00:32:42,790 -de-semana uma coisa. 625 00:32:42,790 --> 00:32:45,150 Tudo que eu quero é uma variável para armazenar um número. 626 00:32:45,150 --> 00:32:47,330 Eu não me importo sobre endereços neste momento. 627 00:32:47,330 --> 00:32:50,530 >> Eu só preciso de 32 bits ou para armazenar um int. 628 00:32:50,530 --> 00:32:56,690 E eu quero colocar nesses 32 bits tudo o que não está em uma, por assim dizer, mas 629 00:32:56,690 --> 00:33:01,260 o que está em um, apenas para ser mais preciso. 630 00:33:01,260 --> 00:33:06,420 Porque se um é um endereço *, um meio ir lá e obter o valor 1. 631 00:33:06,420 --> 00:33:10,560 Por exemplo, no exemplo da semana passada ou no caso de b, obter o valor de 2. 632 00:33:10,560 --> 00:33:11,750 >> Então, o que está realmente acontecendo? 633 00:33:11,750 --> 00:33:15,070 Deixe-me tirar uma foto aqui que vai apenas desmembrar parte de hoje. 634 00:33:15,070 --> 00:33:18,580 Mas isso vai continuar a aparecer por algum tempo. 635 00:33:18,580 --> 00:33:22,430 >> Isso, eu afirmo, é o do seu computador memória parece que quando você executar um 636 00:33:22,430 --> 00:33:24,060 programa, qualquer programa. 637 00:33:24,060 --> 00:33:28,340 Quando você executa um programa no topo de memória RAM do seu computador - para pensar 638 00:33:28,340 --> 00:33:33,530 este retângulo, verdadeiramente, como seu RAM ou a memória do computador, todos os 101 639 00:33:33,530 --> 00:33:36,920 bilhão de bytes dela, todos de dois bilhões de bytes, todos os dois gigabytes de que, 640 00:33:36,920 --> 00:33:39,910 qualquer que seja a quantidade que você tem é, vamos desenhá-la como um retângulo. 641 00:33:39,910 --> 00:33:43,260 E eu afirmo que quando você executar um programa como o Microsoft Word ou Chrome 642 00:33:43,260 --> 00:33:49,220 ou qualquer coisa assim, os bits que Microsoft ou Google que escreveu - 643 00:33:49,220 --> 00:33:50,910 nos casos dos referidos programas - 644 00:33:50,910 --> 00:33:54,490 são carregados na memória do seu computador onde eles podem ser executados mais 645 00:33:54,490 --> 00:33:57,520 rapidamente e alimentados na CPU, o que é o cérebro do computador. 646 00:33:57,520 --> 00:34:00,940 >> E na TAM eles estão armazenados no próprio topo do seu programa, por assim dizer. 647 00:34:00,940 --> 00:34:03,300 Em outras palavras, se este é um pedaço de memória, quando você clicar duas vezes sobre 648 00:34:03,300 --> 00:34:05,740 Microsoft Word, os bits vir fora do disco rígido. 649 00:34:05,740 --> 00:34:06,680 Eles são carregados na memória RAM. 650 00:34:06,680 --> 00:34:10,330 E nós vamos empurrá-los para cima no topo desse retângulo conceitualmente. 651 00:34:10,330 --> 00:34:13,010 >> Bem, o resto de sua memória é usado para coisas diferentes. 652 00:34:13,010 --> 00:34:16,460 No topo você vê inicializar dados e uninitialize dados. 653 00:34:16,460 --> 00:34:20,500 Isto tem a ver, em grande parte, com a constantes ou variáveis ​​globais 654 00:34:20,500 --> 00:34:21,340 que têm valores. 655 00:34:21,340 --> 00:34:22,980 Mas mais sobre aqueles outra vez. 656 00:34:22,980 --> 00:34:25,150 >> Então você tem a pilha, que vamos voltar. 657 00:34:25,150 --> 00:34:28,420 Mas no fundo é a parte que é particularmente pertinente neste momento. 658 00:34:28,420 --> 00:34:30,210 É o chamado pilha. 659 00:34:30,210 --> 00:34:33,850 Assim como em mais nenhuma sala D aqui na campus, você tem aquelas bandejas que 660 00:34:33,850 --> 00:34:37,210 apenas empilhar uns sobre os outros em que você pode colocar alimentos e outros enfeites. 661 00:34:37,210 --> 00:34:40,139 A pilha num sistema de computador é muito semelhante. 662 00:34:40,139 --> 00:34:42,679 Exceto enquanto a bandeja, como usamos em a sala de jantar, é claro, se entende 663 00:34:42,679 --> 00:34:45,710 para levar as coisas as bandejas ou os quadros - 664 00:34:45,710 --> 00:34:49,469 como vamos chamá-los - em um computador de memória é usado para armazenar 665 00:34:49,469 --> 00:34:51,610 variáveis ​​e valores. 666 00:34:51,610 --> 00:34:53,929 >> Então, o que realmente se passa debaixo do capô? 667 00:34:53,929 --> 00:34:55,820 Bem, deixe-me virar para a tela aqui. 668 00:34:55,820 --> 00:34:58,370 E vamos nos concentrar apenas no parte inferior por um momento. 669 00:34:58,370 --> 00:35:02,770 Se isto é a porção inferior da minha memória do computador acontece quando eu 670 00:35:02,770 --> 00:35:05,350 chamar a função principal - que acontece, francamente, 671 00:35:05,350 --> 00:35:06,950 automaticamente para mim - 672 00:35:06,950 --> 00:35:10,510 Recebo um bloco de memória no fundo da minha memória RAM por assim dizer. 673 00:35:10,510 --> 00:35:13,390 E é aí principal é variáveis ​​locais ir. 674 00:35:13,390 --> 00:35:16,770 É onde argc e argv talvez ir, e todas as variáveis ​​I 675 00:35:16,770 --> 00:35:18,170 declarar dentro do principal. 676 00:35:18,170 --> 00:35:20,260 Eles acabam no fundo de RAM do meu computador. 677 00:35:20,260 --> 00:35:25,040 >> Agora, suponha que o principal chama uma função como swap, como fez na semana passada? 678 00:35:25,040 --> 00:35:30,620 Bem, essencialmente, colocar um novo tabuleiro, um novo quadro, no meu pedaço de memória. 679 00:35:30,620 --> 00:35:34,160 E eu vou descrever isso como pertencentes à função swap. 680 00:35:34,160 --> 00:35:35,770 >> Agora, o que está dentro de swap? 681 00:35:35,770 --> 00:35:39,240 Bem, com base no programa da semana passada e o que acabamos de ver um trecho, 682 00:35:39,240 --> 00:35:46,590 dentro da estrutura de swap, ou troca de bandeja, o que são variáveis? 683 00:35:46,590 --> 00:35:47,970 Bem, a e b. 684 00:35:47,970 --> 00:35:51,850 Porque aqueles eram seus argumentos locais, além de um terço, tmp. 685 00:35:51,850 --> 00:35:54,470 Então, realmente, eu poderia desenhar esse um pouco mais limpa. 686 00:35:54,470 --> 00:35:56,680 Deixe-me ir em frente e desfazer o rótulo. 687 00:35:56,680 --> 00:35:58,520 E deixe-me dizer que você sabe o quê? 688 00:35:58,520 --> 00:36:00,560 >> um provavelmente vai acabar aqui. 689 00:36:00,560 --> 00:36:02,160 B vai acabar aqui. 690 00:36:02,160 --> 00:36:03,810 E tmp vai acabar aqui. 691 00:36:03,810 --> 00:36:05,160 Agora, a ordem pode ser um pouco diferente. 692 00:36:05,160 --> 00:36:06,840 Mas conceitualmente essa é a idéia. 693 00:36:06,840 --> 00:36:11,490 >> E só coletivamente, isto é o que vamos chamá-estrutura de swap, ou 694 00:36:11,490 --> 00:36:12,136 bandeja de refeitório. 695 00:36:12,136 --> 00:36:13,150 E a mesma coisa com o principal. 696 00:36:13,150 --> 00:36:14,040 Mas eu não vou redesenhar isso. 697 00:36:14,040 --> 00:36:17,810 Mas é aí que argc e argv e qualquer das suas variáveis ​​locais, como x e y 698 00:36:17,810 --> 00:36:18,940 Pode ser assim. 699 00:36:18,940 --> 00:36:22,170 >> Então agora considerar o que realmente está acontecendo quando você chama swap. 700 00:36:22,170 --> 00:36:26,370 Quando você chama swap, o código executado como isso, você está passando, no 701 00:36:26,370 --> 00:36:30,670 versão com bugs, a e b como cópias de x e y. 702 00:36:30,670 --> 00:36:34,300 Então, se eu faço agora desenhar esse na tela - 703 00:36:34,300 --> 00:36:36,700 tem que ficar melhor com isso - 704 00:36:36,700 --> 00:36:40,850 assim a história que eu estava dizendo para mim mesmo Foi nesta versão com bugs, quando 705 00:36:40,850 --> 00:36:46,130 chamar trocar passando literalmente a e b como inteiros, o que está realmente acontecendo? 706 00:36:46,130 --> 00:36:48,250 >> Bem, o que está realmente acontecendo é isso. 707 00:36:48,250 --> 00:36:52,850 Deixe-me ir em frente e desfazer apenas para limpar algum espaço aqui. 708 00:36:52,850 --> 00:36:54,720 Portanto, esta é a memória do meu computador. 709 00:36:54,720 --> 00:36:57,510 >> Então, se eu tiver, por exemplo - 710 00:36:57,510 --> 00:36:58,910 na verdade, vamos fazê-lo desta forma - 711 00:36:58,910 --> 00:37:02,690 se eu afirmar que esta é x, armazenando o valor 1, assim como na semana passada. 712 00:37:02,690 --> 00:37:05,930 E isto é y, armazenando o valor 2 assim como na semana passada. 713 00:37:05,930 --> 00:37:11,370 E isso é o principal, quando eu chamo swap, dando-me, assim, o acesso a um e 714 00:37:11,370 --> 00:37:15,150 b e tmp, eu vou afirmar que este é um e este é um. 715 00:37:15,150 --> 00:37:16,080 >> Este é b. 716 00:37:16,080 --> 00:37:17,010 Esta é 2. 717 00:37:17,010 --> 00:37:18,370 Isto é chamado tmp. 718 00:37:18,370 --> 00:37:23,360 >> E, inicialmente, tem algum valor lixo até que eu realmente armazenar nele um, 719 00:37:23,360 --> 00:37:24,450 que é 1. 720 00:37:24,450 --> 00:37:28,320 Então eu vou em frente e mudar a ser o que? 721 00:37:28,320 --> 00:37:29,720 Valor de B. 722 00:37:29,720 --> 00:37:31,980 >> E agora eu tenho dois aqui. 723 00:37:31,980 --> 00:37:34,050 E então nós dissemos b fica tmp. 724 00:37:34,050 --> 00:37:37,670 Mais uma vez, assim como uma verificação de sanidade, o terceiro linha de código aqui é simplesmente isto 725 00:37:37,670 --> 00:37:39,440 um, b fica tmp. 726 00:37:39,440 --> 00:37:41,730 >> E assim, finalmente, o que eu faço? 727 00:37:41,730 --> 00:37:46,800 Eu vou em frente e mudar b para ser o que o valor de TMP é, o que é um. 728 00:37:46,800 --> 00:37:48,390 Eu não toco tmp novamente. 729 00:37:48,390 --> 00:37:54,100 >> Mas agora, o problema é que assim como swap retorna, porque não está entregando 730 00:37:54,100 --> 00:37:57,540 voltar algum valor, não há retorno instrução explicitamente na mesma. 731 00:37:57,540 --> 00:37:59,080 O que está realmente acontecendo? 732 00:37:59,080 --> 00:38:03,480 Bem, essencialmente, tudo isso de memória - 733 00:38:03,480 --> 00:38:07,410 OK, aparentemente, a borracha gosta apenas um dedo de cada vez - 734 00:38:07,410 --> 00:38:08,180 simplesmente desaparece. 735 00:38:08,180 --> 00:38:10,070 >> Agora, na realidade, não é vai a lugar nenhum. 736 00:38:10,070 --> 00:38:11,810 Mas você pode pensar nisso agora, como pontos de interrogação. 737 00:38:11,810 --> 00:38:14,040 Porque ele não é mais realmente em uso. 738 00:38:14,040 --> 00:38:17,470 E nada é feito com esses valores. 739 00:38:17,470 --> 00:38:21,920 >> Assim, no caso da versão verde esse código, que está a ser, em vez 740 00:38:21,920 --> 00:38:24,640 passou para swap? 741 00:38:24,640 --> 00:38:25,770 Então resolve. 742 00:38:25,770 --> 00:38:28,520 Assim, o endereço de xe o endereço do y. 743 00:38:28,520 --> 00:38:35,790 Então, se nós re-contar a história de um passado tempo, e eu realmente chamar a troca novamente, 744 00:38:35,790 --> 00:38:44,620 mas com ponteiros, sendo este um, isto sendo b, e sendo esta tmp, o que é 745 00:38:44,620 --> 00:38:49,080 realmente armazenados em um nesta verde versão do meu código onde eu estou passando 746 00:38:49,080 --> 00:38:52,110 em endereços? 747 00:38:52,110 --> 00:38:53,780 >> Vai ser um ponteiro para x. 748 00:38:53,780 --> 00:38:54,890 Então, eu poderia desenhar uma seta. 749 00:38:54,890 --> 00:38:57,310 Mas vamos usar o mesmo arbitrária exemplo, como antes. 750 00:38:57,310 --> 00:39:01,220 Digamos que este é algo como Ox123. 751 00:39:01,220 --> 00:39:04,970 E isso vai ser Ox127 porque é quatro bytes para longe, porque é uma 752 00:39:04,970 --> 00:39:07,370 Cont, tão Ox127. 753 00:39:07,370 --> 00:39:09,080 >> E novamente, eu estou tomando algumas liberdades com os números. 754 00:39:09,080 --> 00:39:11,430 Eles são muito menores do que seria e, na verdade, ser numa ordem diferente. 755 00:39:11,430 --> 00:39:14,350 Mas é assim que a imagem agora é diferente. 756 00:39:14,350 --> 00:39:19,060 >> Mas quando eu uso esse código verde e eu int tmp conseguir * a. 757 00:39:19,060 --> 00:39:25,010 * Um meio para fazer o seguinte, pegue a resolver isso em um e ir para ele, 758 00:39:25,010 --> 00:39:26,190 que é 1. 759 00:39:26,190 --> 00:39:28,480 E isso é o que eu, em seguida, colocar em tmp. 760 00:39:28,480 --> 00:39:32,480 Enquanto isso, na próxima linha de código aqui, * a recebe b, o que isso significa? 761 00:39:32,480 --> 00:39:36,910 >> Bem, * a, por isso aqui fica * b, o que significa ir para lá. 762 00:39:36,910 --> 00:39:39,310 E isso significa colocar o valor lá. 763 00:39:39,310 --> 00:39:43,670 Finalmente, a última linha de código disse simplesmente * b recebe tmp. 764 00:39:43,670 --> 00:39:48,900 >> Então b diz para ir lá e substituí-lo com tmp que, neste caso, vai 765 00:39:48,900 --> 00:39:51,520 para ser, de novo, 1. 766 00:39:51,520 --> 00:39:54,920 E é por isso que a versão verde de nossas obras de código, enquanto que o vermelho 767 00:39:54,920 --> 00:39:56,010 versão nunca fez. 768 00:39:56,010 --> 00:39:59,020 Tudo isso só se resume à forma como o memória é gerida e onde é 769 00:39:59,020 --> 00:40:02,580 realmente colocado em seu RAM do computador. 770 00:40:02,580 --> 00:40:07,270 E, por enquanto, isso é uma das coisas que a pilha está sendo utilizado. 771 00:40:07,270 --> 00:40:09,225 >> Perguntas sobre o layout? 772 00:40:09,225 --> 00:40:10,380 Em ponteiros? 773 00:40:10,380 --> 00:40:11,630 Ou em swap? 774 00:40:11,630 --> 00:40:13,740 775 00:40:13,740 --> 00:40:17,043 >> Tudo bem, então malloc, aviso, fez algo parecido com isso. 776 00:40:17,043 --> 00:40:18,260 Este foi um super exemplo simples. 777 00:40:18,260 --> 00:40:20,550 E isso foi o que Binky nos apresentou, ainda que bastante 778 00:40:20,550 --> 00:40:21,870 rapidamente, no final da classe. 779 00:40:21,870 --> 00:40:24,480 Droga, lá vamos nós de novo. 780 00:40:24,480 --> 00:40:28,780 >> Então, lembrar que este foi o exemplo que Binky nos apresentou, embora 781 00:40:28,780 --> 00:40:30,360 um tanto rapidamente no fim da classe. 782 00:40:30,360 --> 00:40:33,640 E aqui nós usamos malloc realmente , pela segunda vez. 783 00:40:33,640 --> 00:40:37,330 Porque a primeira vez que é usado para criar RAM suficiente, alocar memória RAM suficiente 784 00:40:37,330 --> 00:40:38,340 para armazenar uma string. 785 00:40:38,340 --> 00:40:40,250 >> Desta vez Binky manteve simples. 786 00:40:40,250 --> 00:40:42,465 Então é para armazenar apenas um int, aparentemente. 787 00:40:42,465 --> 00:40:43,510 E isso é totalmente bom. 788 00:40:43,510 --> 00:40:46,560 É um pouco estranho, francamente, para usar malloc para alocar um int. 789 00:40:46,560 --> 00:40:50,650 Mas o ponto de claymation do Nick foi realmente apenas contar a história do que 790 00:40:50,650 --> 00:40:53,830 acontece ou não acontece quando você maltratar memória. 791 00:40:53,830 --> 00:40:56,520 >> Portanto, neste caso, este programa fiz algumas coisas. 792 00:40:56,520 --> 00:41:01,580 No primeiro caso, aqui, que declara um ponteiro chamado x para um int. 793 00:41:01,580 --> 00:41:04,480 Em seguida, ele declara um ponteiro chamado y para um int. 794 00:41:04,480 --> 00:41:06,150 Em seguida, armazena em x, o quê? 795 00:41:06,150 --> 00:41:07,110 Alguém agora. 796 00:41:07,110 --> 00:41:09,685 O que fica armazenado em x de acordo com a a terceira linha deste programa? 797 00:41:09,685 --> 00:41:12,380 >> AUDIÊNCIA: [inaudível]. 798 00:41:12,380 --> 00:41:14,130 >> COLUNA 1: Bem, não exatamente bytes, por assim dizer. 799 00:41:14,130 --> 00:41:16,760 Ser mais preciso agora. 800 00:41:16,760 --> 00:41:18,325 O que fica armazenado em x? 801 00:41:18,325 --> 00:41:21,000 802 00:41:21,000 --> 00:41:22,060 Um endereço, eu acho que ouvi-lo. 803 00:41:22,060 --> 00:41:23,570 >> Então, o que malloc retornar? 804 00:41:23,570 --> 00:41:26,030 malloc aloca comportamentalmente um pedaço de memória. 805 00:41:26,030 --> 00:41:27,850 Mas como isso dá-lhe acesso a ele? 806 00:41:27,850 --> 00:41:29,460 Ele retorna o quê? 807 00:41:29,460 --> 00:41:32,000 O endereço do primeiro byte no pedaço de memória. 808 00:41:32,000 --> 00:41:33,020 >> Agora, isso é super simples. 809 00:41:33,020 --> 00:41:35,380 É apenas um byte, que significa que o abordar estamos ficando para trás é o 810 00:41:35,380 --> 00:41:37,300 endereço da coisa toda. 811 00:41:37,300 --> 00:41:42,070 Então armazenado em x, então, é o endereço desse pedaço de memória. 812 00:41:42,070 --> 00:41:43,400 Enquanto isso, o que acontece? 813 00:41:43,400 --> 00:41:45,890 Então, na verdade, vamos em frente e chamar isso muito rápido. 814 00:41:45,890 --> 00:41:52,490 >> Então, se passar para a tela aqui e vamos jogar isso int * x e y int * 815 00:41:52,490 --> 00:41:53,740 vai fazer o que para mim? 816 00:41:53,740 --> 00:41:58,280 Eu afirmo que ele só vai fazer algo como isso e chamá-lo de x, e 817 00:41:58,280 --> 00:42:00,010 isso e chamá-lo de y. 818 00:42:00,010 --> 00:42:03,110 Enquanto isso, a terceira linha de código é vai afectar o tamanho de um int 819 00:42:03,110 --> 00:42:06,160 que passa a ser - desculpe se eu dissesse um antes que eu quis dizer um int - 820 00:42:06,160 --> 00:42:08,280 quatro bytes em um computador típico. 821 00:42:08,280 --> 00:42:09,720 Pelo menos com o aparelho CS50. 822 00:42:09,720 --> 00:42:11,490 >> Então, isso vai alocar , quem sabe? 823 00:42:11,490 --> 00:42:12,800 Em algum lugar por aqui. 824 00:42:12,800 --> 00:42:15,780 E esta é armazenada em algum endereço de Boi, quem sabe? 825 00:42:15,780 --> 00:42:18,330 Mas o que está acontecendo para se voltou é esse endereço. 826 00:42:18,330 --> 00:42:22,270 Mas vamos tirar isso pictoricamente apenas como uma flecha assim. 827 00:42:22,270 --> 00:42:25,430 >> Agora, na próxima linha * x recebe 42. 828 00:42:25,430 --> 00:42:29,400 O que * x significa em termos leigos? 829 00:42:29,400 --> 00:42:30,040 Basta ir lá. 830 00:42:30,040 --> 00:42:30,960 Vá para esse endereço. 831 00:42:30,960 --> 00:42:35,900 Ou, por outras palavras, a seguir seta e colocar 42 lá. 832 00:42:35,900 --> 00:42:38,140 Mas então algo de ruim aconteceu para Binky, certo? 833 00:42:38,140 --> 00:42:43,950 >> Lembre-se de que a linha cinco aqui, * y recebe 13, na verdade um número de azar, 834 00:42:43,950 --> 00:42:44,760 fez o que para nós? 835 00:42:44,760 --> 00:42:47,320 Bem, * y significa ir até lá. 836 00:42:47,320 --> 00:42:50,460 Bem, este não tem sido dada ainda um valor, certo? 837 00:42:50,460 --> 00:42:54,090 O código não tem y sendo inicializado para nada. 838 00:42:54,090 --> 00:42:56,120 Tínhamos x sendo inicializado para um endereço. 839 00:42:56,120 --> 00:42:57,640 Mas y foi declarado em cima. 840 00:42:57,640 --> 00:43:00,250 Mas, então, um ponto e vírgula, sem valor foi realmente colocar nele. 841 00:43:00,250 --> 00:43:02,330 Portanto, é justo chamar esta um valor de lixo. 842 00:43:02,330 --> 00:43:03,430 Quem sabe o que é? 843 00:43:03,430 --> 00:43:07,160 São os restos de bits que foram utilizados por alguma linha de código anterior em 844 00:43:07,160 --> 00:43:08,300 meu programa. 845 00:43:08,300 --> 00:43:13,250 >> Então, se eu disser que ir lá, isso é como, Eu não tenho nenhuma idéia de onde essa seta é 846 00:43:13,250 --> 00:43:14,490 vai acabar. 847 00:43:14,490 --> 00:43:17,720 E é aí que você normalmente obter uma falha de segmentação. 848 00:43:17,720 --> 00:43:22,430 Se você acidentalmente desreferenciava, por assim falar, ou ir para um endereço que não é 849 00:43:22,430 --> 00:43:25,400 na verdade, um endereço legítimo, coisas ruins acontecem. 850 00:43:25,400 --> 00:43:27,550 >> E isso é exatamente o que aconteceu pensar Binky. 851 00:43:27,550 --> 00:43:31,060 Então, lembrar que a história de que Nick era dizendo aqui foi a mesma idéia que o 852 00:43:31,060 --> 00:43:34,050 Eu desenhei com a ilusão de giz no quadro lá. 853 00:43:34,050 --> 00:43:35,960 X e Y são declarados. 854 00:43:35,960 --> 00:43:39,690 >> Em seguida, atribuído ao tamanho dos um int e armazenado em x. 855 00:43:39,690 --> 00:43:42,130 Em seguida, a próxima linha que fizemos * x. 856 00:43:42,130 --> 00:43:46,070 Esta foi a varinha mágica de Nick de dereferencing. 857 00:43:46,070 --> 00:43:49,780 Que colocou 42 na memória apontado por x. 858 00:43:49,780 --> 00:43:51,600 >> Mas este é o lugar onde as coisas deu terrivelmente errado. 859 00:43:51,600 --> 00:43:51,820 Certo? 860 00:43:51,820 --> 00:43:53,550 Tentamos desreferenciava y. 861 00:43:53,550 --> 00:43:55,620 Mas y tinha algum valor falso, certo? 862 00:43:55,620 --> 00:43:57,720 >> Que a seta no canto inferior esquerdo canto, não é 863 00:43:57,720 --> 00:43:58,950 na verdade, apontando para qualquer coisa. 864 00:43:58,950 --> 00:44:01,520 É uma espécie de fazer o que eu fiz aqui no conselho. 865 00:44:01,520 --> 00:44:05,900 Então, as coisas ruins acontecem, a segmentação falha ou avaria Chupeta, neste caso. 866 00:44:05,900 --> 00:44:10,800 >> Mas se, em seguida, corrigir isso, fazendo x fica y como é que a mudança de história? 867 00:44:10,800 --> 00:44:15,760 Bem, se eu fizer x recebe y, que é efetivamente o mesmo que dizer 868 00:44:15,760 --> 00:44:19,235 o que é isso, Ox-algo vai ser a mesma coisa aqui, 869 00:44:19,235 --> 00:44:20,080 Ox-alguma coisa. 870 00:44:20,080 --> 00:44:22,970 Ou pictoricamente vamos desenhar uma seta. 871 00:44:22,970 --> 00:44:25,530 >> Então, aqui na placa com Binky, com a próxima linha de 872 00:44:25,530 --> 00:44:28,350 código, * y significa ir até lá. 873 00:44:28,350 --> 00:44:29,400 Onde é que há? 874 00:44:29,400 --> 00:44:30,820 Significa aqui. 875 00:44:30,820 --> 00:44:36,050 >> E quando nós atualizamos que ser 13 que envolve apenas indo e 876 00:44:36,050 --> 00:44:39,470 13 escrever aqui agora. 877 00:44:39,470 --> 00:44:44,130 Por isso, talvez não completamente simples à primeira vista. 878 00:44:44,130 --> 00:44:47,740 Mas para recapitular e usar o mesmo jargão que Binky estava usando aqui, então 879 00:44:47,740 --> 00:44:50,485 os dois primeiros alocar os ponteiros, x e y, mas não os pointees. 880 00:44:50,485 --> 00:44:54,750 E pointees não faz geralmente utilizado prazo. 881 00:44:54,750 --> 00:44:56,120 Mas é absolutamente ponteiro. 882 00:44:56,120 --> 00:44:59,200 Mas é o que está sendo apontado no da nomenclatura de Binky. 883 00:44:59,200 --> 00:45:01,660 >> Esta próxima linha, é claro, aloca um pointee int. 884 00:45:01,660 --> 00:45:04,840 Assim, um pedaço de memória - como atraiu mais em o lado direito lá - e um conjunto 885 00:45:04,840 --> 00:45:06,470 x igual a apontar para ele. 886 00:45:06,470 --> 00:45:11,350 Este desreferencia x para armazenar 42 em a memória que ele está apontando. 887 00:45:11,350 --> 00:45:13,380 E depois disso, é claro, era uma coisa ruim. 888 00:45:13,380 --> 00:45:15,600 Porque y não estava apontando em nada ainda. 889 00:45:15,600 --> 00:45:16,530 Isso resolve o problema. 890 00:45:16,530 --> 00:45:18,240 Portanto, este ainda é o programa de buggy. 891 00:45:18,240 --> 00:45:21,580 Só porque estamos soprando através do código linha por linha e dizer: oh bem, 892 00:45:21,580 --> 00:45:22,690 deixá-lo cair lá. 893 00:45:22,690 --> 00:45:23,420 Isso é uma coisa ruim. 894 00:45:23,420 --> 00:45:26,790 As probabilidades são o programa só vai interromper completamente a essa linha. 895 00:45:26,790 --> 00:45:30,550 Mas se você fosse para remover o acidente de linha e substituí-lo com os dois últimos 896 00:45:30,550 --> 00:45:32,470 linhas lá você atribui - 897 00:45:32,470 --> 00:45:35,310 com atribuição de ponteiro - y para apontar para x como ponto de t. 898 00:45:35,310 --> 00:45:39,280 E então você desreferenciava y de uma forma muito segura. 899 00:45:39,280 --> 00:45:41,520 >> Então onde é que isto nos deixa? 900 00:45:41,520 --> 00:45:45,350 Bem, acontece que debaixo do capô na biblioteca CS50, os ponteiros são 901 00:45:45,350 --> 00:45:46,320 utilizado ao longo. 902 00:45:46,320 --> 00:45:48,910 E nós vamos realmente começar a descascar de volta a camada antes do tempo. 903 00:45:48,910 --> 00:45:51,740 Mas acontece também, uma expressão que alguns de vocês podem estar familiarizados com, 904 00:45:51,740 --> 00:45:54,580 particularmente aqueles mais confortável, que é na verdade de uma muito popular 905 00:45:54,580 --> 00:45:56,390 website, ou estouro de pilha, nos dias de hoje. 906 00:45:56,390 --> 00:45:58,720 >> Mas isso realmente não tem muito significado técnico. 907 00:45:58,720 --> 00:46:00,160 Sabemos agora que a pilha é. 908 00:46:00,160 --> 00:46:02,550 É como uma pilha de bandejas dentro de uma sala de jantar. 909 00:46:02,550 --> 00:46:05,140 >> Ou dentro do seu computador de memória its os quadros 910 00:46:05,140 --> 00:46:06,900 que são utilizados por funções. 911 00:46:06,900 --> 00:46:10,760 Bem, acontece que por causa disso muito simples implementação de 912 00:46:10,760 --> 00:46:14,970 memória e dos quadros na chamada empilhar, você pode realmente assumir o controle 913 00:46:14,970 --> 00:46:17,050 de um sistema de computador com bastante facilidade. 914 00:46:17,050 --> 00:46:22,180 Você pode invadir um sistema, se as pessoas como nós não escrevemos o nosso código 915 00:46:22,180 --> 00:46:23,300 particularmente bem. 916 00:46:23,300 --> 00:46:26,670 >> Se pessoas como nós usamos pedaços de memória ou usar matrizes - 917 00:46:26,670 --> 00:46:27,810 ainda mais comumente - 918 00:46:27,810 --> 00:46:31,800 mas às vezes se esqueça de verificar a limites de nossa matriz como você pode 919 00:46:31,800 --> 00:46:38,470 tem-se, por vezes, e reiterou muito longe após o final de um array. 920 00:46:38,470 --> 00:46:40,520 Na melhor das hipóteses, o seu programa só poderia falhar. 921 00:46:40,520 --> 00:46:42,280 Falha de segmentação, tipo constrangedor. 922 00:46:42,280 --> 00:46:45,480 Não é ótimo, mas não é necessariamente uma coisa extremamente ruim. 923 00:46:45,480 --> 00:46:49,480 >> Mas se o seu programa é realmente a verdadeira computadores dos usuários, se ele está funcionando 924 00:46:49,480 --> 00:46:53,070 em um site que as pessoas aleatórias reais na internet estão batendo, deixando 925 00:46:53,070 --> 00:46:56,690 pessoas induzir coisas ruins em seu código é geralmente não é uma coisa boa, porque 926 00:46:56,690 --> 00:46:59,930 isso significa uma oportunidade para tomar o controlo do computador. 927 00:46:59,930 --> 00:47:01,350 E isso vai ficar um pouco enigmática. 928 00:47:01,350 --> 00:47:04,570 Mas eu pensei que eu iria assustá-lo com Neste último exemplo aqui. 929 00:47:04,570 --> 00:47:05,650 >> Aqui está um exemplo de código. 930 00:47:05,650 --> 00:47:07,370 E há uma boa Wikipedia artigo que percorre 931 00:47:07,370 --> 00:47:08,530 isto com mais detalhe. 932 00:47:08,530 --> 00:47:13,890 Tenho principal no chamado fundo foo, passando argv de 1. 933 00:47:13,890 --> 00:47:15,750 E isso é apenas para que você possa executar o programa e passar 934 00:47:15,750 --> 00:47:17,080 uma entrada arbitrária. 935 00:47:17,080 --> 00:47:20,180 >> E então foo é declarado em cima como aceitar uma string, ou mais 936 00:47:20,180 --> 00:47:21,700 precisamente, um char *. 937 00:47:21,700 --> 00:47:23,860 Em seguida, ele declara uma matriz de caracteres. 938 00:47:23,860 --> 00:47:27,130 Chamá-lo de um buffer, de modo mais geral, de tamanho 12. 939 00:47:27,130 --> 00:47:30,900 Então, 12 caracteres pode caber dentro desse array chamado c. 940 00:47:30,900 --> 00:47:33,510 >> E então ele usa essa nova função, que é novo, mas não é difícil 941 00:47:33,510 --> 00:47:34,930 entender, cópia de memória. 942 00:47:34,930 --> 00:47:39,290 Ele copia a memória do bar, que era passado variável n, seja qual for o 943 00:47:39,290 --> 00:47:42,080 usuário digitou em uma argv em c. 944 00:47:42,080 --> 00:47:43,090 Quantos bytes? 945 00:47:43,090 --> 00:47:44,260 O comprimento da corda de bar. 946 00:47:44,260 --> 00:47:48,380 >> Portanto, em outras palavras, se o usuário digita em h-e-l-l-o enter, o comprimento da corda 947 00:47:48,380 --> 00:47:49,260 Olá é de cinco anos. 948 00:47:49,260 --> 00:47:52,790 Então, cinco desses bytes vai ficar copiado para o array chamado c, que 949 00:47:52,790 --> 00:47:54,110 é de tamanho 12. 950 00:47:54,110 --> 00:47:58,710 Mas o que o usuário digita em um tempo muito mais palavra que é de 13 caracteres ou 14 951 00:47:58,710 --> 00:48:01,250 caracteres ou 100 caracteres ou mais? 952 00:48:01,250 --> 00:48:02,660 >> Onde eles estão indo? 953 00:48:02,660 --> 00:48:06,090 Bem, esse quadro, que a bandeja na pilha de refeitório, 954 00:48:06,090 --> 00:48:06,930 eles estão indo para lá. 955 00:48:06,930 --> 00:48:10,080 E isso só vai começar a substituir outras coisas que já está 956 00:48:10,080 --> 00:48:12,880 nessa pilha, transbordando da pilha, por assim dizer. 957 00:48:12,880 --> 00:48:14,780 >> Então, pictoricamente, pense nisso dessa forma. 958 00:48:14,780 --> 00:48:17,970 Esta é apenas uma versão colorida de a imagem que estamos desenhando. 959 00:48:17,970 --> 00:48:20,060 Na parte inferior, digamos, é o principal. 960 00:48:20,060 --> 00:48:24,690 E na parte superior, o que você está vendo agora é o quadro, codificados por cores agora, por um 961 00:48:24,690 --> 00:48:26,090 função chamada foo. 962 00:48:26,090 --> 00:48:30,170 Mas o que é interessante aqui sobre foo é que aqui é o seu quadro. 963 00:48:30,170 --> 00:48:32,860 Então, ele é desenhado como eu fez, mas em azul claro. 964 00:48:32,860 --> 00:48:35,220 E agora esse é o lugar onde c suporte 0 vai. 965 00:48:35,220 --> 00:48:37,410 E é aí que c suporte 11 vai acabar. 966 00:48:37,410 --> 00:48:39,670 >> Em outras palavras, isso acontece ser representado como um quadrado. 967 00:48:39,670 --> 00:48:42,320 Mas se você apenas manter estatelando bytes para baixo - ou caracteres - eles vão acabar 968 00:48:42,320 --> 00:48:46,070 se na posição 0 todo o caminho até a 11 porque é 0 indexado. 969 00:48:46,070 --> 00:48:49,170 >> Mas onde está o caráter 13 vai acabar? 970 00:48:49,170 --> 00:48:50,310 Cadê o 14? 971 00:48:50,310 --> 00:48:52,430 Onde está o caráter 50 vai acabar? 972 00:48:52,430 --> 00:48:54,070 >> Ele vai continuar a descer. 973 00:48:54,070 --> 00:48:57,350 Porque mesmo que tenha desenhado o imagem com a pilha crescendo, o 974 00:48:57,350 --> 00:48:59,920 endereços, verifica-se, ir de pequenas endereços, pequenas 975 00:48:59,920 --> 00:49:01,830 ponteiros, para grandes endereços. 976 00:49:01,830 --> 00:49:03,540 Então, ele simplesmente continua indo para cima e para cima. 977 00:49:03,540 --> 00:49:05,660 >> Portanto, se o usuário digita em Olá, isso é ótimo. 978 00:49:05,660 --> 00:49:08,650 No bug, não há problema, seguro de todos. 979 00:49:08,650 --> 00:49:11,940 Mas se o usuário digita em que vamos chamar o código do contraditório, representado 980 00:49:11,940 --> 00:49:16,040 genericamente como, ataque, ataque, ataque, ataque, o que pode acontecer? 981 00:49:16,040 --> 00:49:19,760 >> Ora, se toda a entrada que o utilizador digitado não é apenas um amigável 982 00:49:19,760 --> 00:49:21,540 ou string ofensiva de caracteres. 983 00:49:21,540 --> 00:49:24,050 É, na verdade, uma sequência de caracteres que se compilou, 984 00:49:24,050 --> 00:49:26,050 ele realmente é um código. 985 00:49:26,050 --> 00:49:29,570 Talvez seja o código que exclui toda a arquivos em seu disco rígido ou envia spams 986 00:49:29,570 --> 00:49:30,810 ou algo assim. 987 00:49:30,810 --> 00:49:35,110 Observe que o que é importante aqui é que se o bandido teve sorte o suficiente para 988 00:49:35,110 --> 00:49:37,830 substituir o pedaço vermelho de memória - 989 00:49:37,830 --> 00:49:41,080 que eu não desenhei na minha imagem, mas esta imagem Wikipedia aqui tem - 990 00:49:41,080 --> 00:49:42,890 seu chamado endereço de retorno. 991 00:49:42,890 --> 00:49:47,470 >> Quando retorna de alimentos, quando retorna de swap, Como o computador sabe que ir de 992 00:49:47,470 --> 00:49:49,790 aqui em cima até aqui em baixo? 993 00:49:49,790 --> 00:49:52,920 Ou no segmento de tecnologia em cima, como ele sabe que vão desde a troca de 994 00:49:52,920 --> 00:49:54,870 código - o 0 e 1 do que compõem troca - 995 00:49:54,870 --> 00:49:56,020 de volta ao principal? 996 00:49:56,020 --> 00:50:00,450 Há um chamado endereço de retorno armazenado no mesmo quadro de pilha, em 997 00:50:00,450 --> 00:50:02,140 a mesma bandeja cafeteria. 998 00:50:02,140 --> 00:50:06,080 >> Então, se o bandido é inteligente o suficiente para colocar um código de ataque, um código de ataque, ataque 999 00:50:06,080 --> 00:50:07,960 código, e ter sorte o suficiente - 1000 00:50:07,960 --> 00:50:11,630 muitas vezes através de tentativa e erro - a sobrescrever o endereço de retorno vermelho, 1001 00:50:11,630 --> 00:50:14,360 com o endereço eo aviso o topo. 1002 00:50:14,360 --> 00:50:16,830 Observe 0835C080. 1003 00:50:16,830 --> 00:50:20,650 Está escrito para trás em cima de razões que vamos talvez revisitar. 1004 00:50:20,650 --> 00:50:22,050 Este número é o que. 1005 00:50:22,050 --> 00:50:25,790 >> Então, se o bandido tem sorte o suficiente ou é inteligente o suficiente para substituir o vermelho 1006 00:50:25,790 --> 00:50:29,480 tira de memória com o endereço de código que ele ou ela tem de alguma forma 1007 00:50:29,480 --> 00:50:34,980 injetado em seu computador, acho que quem código vai ser devolvido 1008 00:50:34,980 --> 00:50:38,260 assim foo é feito de execução? 1009 00:50:38,260 --> 00:50:39,440 >> Código do bandido. 1010 00:50:39,440 --> 00:50:43,610 Portanto, este código de ataque, AAA, mais uma vez, poder enviar spam, pode apagar todos os arquivos 1011 00:50:43,610 --> 00:50:44,500 em seu disco rígido. 1012 00:50:44,500 --> 00:50:48,740 Mas isso é o que realmente um estouro de pilha é, ou um estouro de buffer, ou um 1013 00:50:48,740 --> 00:50:51,060 ataque de estouro de buffer. 1014 00:50:51,060 --> 00:50:54,400 >> E é incrivelmente, incrivelmente comum para este dia com os programas escritos em 1015 00:50:54,400 --> 00:50:58,220 C, C + +, e até mesmo algumas outras línguas. 1016 00:50:58,220 --> 00:51:02,275 Na mesma nota assustador, vamos termina com uma piada. 1017 00:51:02,275 --> 00:51:03,230 >> [Risos] 1018 00:51:03,230 --> 00:51:04,550 >> Vejo você na quarta-feira. 1019 00:51:04,550 --> 00:51:07,920 1020 00:51:07,920 --> 00:51:10,310 Na próxima CS50 - 1021 00:51:10,310 --> 00:51:15,920 Então, eu estou fora de lâmpadas disco hoje, mas esperar, livre de gordura do leite, metade do telefone 1022 00:51:15,920 --> 00:51:17,850 livro, o suco de laranja que eu bebi hoje. 1023 00:51:17,850 --> 00:51:20,370 1024 00:51:20,370 --> 00:51:22,780 Cabo USB, uma chave inglesa. 1025 00:51:22,780 --> 00:51:24,800 >> [Música tocando]