1 00:00:00,000 --> 00:00:10,970 >> [Música tocando] 2 00:00:10,970 --> 00:00:12,536 >> DAVID J. MALAN: Tudo bem. 3 00:00:12,536 --> 00:00:13,392 >> [Risos] 4 00:00:13,392 --> 00:00:14,240 >> Bem-vindo de volta. 5 00:00:14,240 --> 00:00:14,990 Isto é CS50. 6 00:00:14,990 --> 00:00:16,890 E este final de semana cinco. 7 00:00:16,890 --> 00:00:20,020 E até agora, temos praticamente tomado como certo que há 8 00:00:20,020 --> 00:00:23,480 existe este compilador Clang, que você tem foi invocar por meio deste 9 00:00:23,480 --> 00:00:27,100 outra ferramenta chamada Verifique que de alguma forma magicamente transforma seu código-fonte 10 00:00:27,100 --> 00:00:31,350 em código objeto, os zeros e uns que o seu CPU de computadores, centrais 11 00:00:31,350 --> 00:00:33,410 unidade de processamento, realmente entende. 12 00:00:33,410 --> 00:00:36,770 Mas acontece que há um número que é acontecendo debaixo do capô em 13 00:00:36,770 --> 00:00:38,690 entre a entrada ea saída. 14 00:00:38,690 --> 00:00:41,800 >> E eu gostaria de propor que a carne que em um pouco mais de detalhes em 15 00:00:41,800 --> 00:00:45,130 estas quatro etapas, tem uma coisa chamada pré-tratamento, algo 16 00:00:45,130 --> 00:00:48,300 chamado de compilação, o que vimos, algo chamado montagem e 17 00:00:48,300 --> 00:00:49,420 algo chamado de ligação. 18 00:00:49,420 --> 00:00:53,270 Então, até agora, em alguns dos nossos programas, tivemos afiada inclui. 19 00:00:53,270 --> 00:00:56,650 Mais recentemente tivemos alguns sharp define para constantes. 20 00:00:56,650 --> 00:01:00,660 Assim, verifica-se que as coisas que são prefixados com o símbolo de hash ou 21 00:01:00,660 --> 00:01:04,150 o símbolo de libra são pré-processador directivas. 22 00:01:04,150 --> 00:01:07,960 Isso é apenas uma maneira elegante de dizer que é uma linha de código que é realmente 23 00:01:07,960 --> 00:01:12,280 convertido em outra coisa antes do computador até tentar converter seu 24 00:01:12,280 --> 00:01:13,800 programa em zeros e uns. 25 00:01:13,800 --> 00:01:19,000 >> Por exemplo, afiado inclui padrão I / O. H, praticamente significa apenas ir 26 00:01:19,000 --> 00:01:24,010 à frente, pegue o conteúdo dos arquivos STDIO.H e colá-los ali mesmo. 27 00:01:24,010 --> 00:01:25,880 Portanto, não zeros e uns nesse ponto ainda. 28 00:01:25,880 --> 00:01:27,470 É realmente apenas uma substituição. 29 00:01:27,470 --> 00:01:30,790 E isso é feito durante a chamada fase de pré-processamento, quando você 30 00:01:30,790 --> 00:01:34,230 realmente executado Clang ou especificamente Fazer na maioria dos casos. 31 00:01:34,230 --> 00:01:36,950 Então, tudo isso que vem acontecendo primeiro automaticamente até o momento. 32 00:01:36,950 --> 00:01:38,800 >> Em seguida, vem a etapa de compilação. 33 00:01:38,800 --> 00:01:40,920 Mas temos sido simplificada compilação. 34 00:01:40,920 --> 00:01:45,060 Compilando um programa realmente significa levá-lo de algo como C, o 35 00:01:45,060 --> 00:01:48,430 o código-fonte que tenho escrito, para baixo a algo chamado montagem. 36 00:01:48,430 --> 00:01:52,900 Linguagem assembly é um nível inferior linguagem que, felizmente, não vamos 37 00:01:52,900 --> 00:01:55,480 têm muita oportunidade de escrever este semestre. 38 00:01:55,480 --> 00:01:59,100 Mas é no nível mais baixo da sensação de que você, literalmente, começar a escrever 39 00:01:59,100 --> 00:02:04,270 somar e subtrair e multiplicar e carregar da memória e guardar a memória, o 40 00:02:04,270 --> 00:02:08,259 instruções muito básicas que um computador, debaixo do capô, 41 00:02:08,259 --> 00:02:09,639 realmente entende. 42 00:02:09,639 --> 00:02:14,930 >> Por último, a montagem leva essa língua para os zeros e uns que temos sido 43 00:02:14,930 --> 00:02:16,190 descrevendo assim longe. 44 00:02:16,190 --> 00:02:19,270 E, na verdade, por último, há o chamado ligando fase, que vamos 45 00:02:19,270 --> 00:02:22,360 ver em apenas um momento, que combina os zeros e uns com zeros e 46 00:02:22,360 --> 00:02:24,870 as outras pessoas antes que você criou. 47 00:02:24,870 --> 00:02:26,660 >> Por isso, considero este programa super simples. 48 00:02:26,660 --> 00:02:27,560 Foi da Semana 1. 49 00:02:27,560 --> 00:02:29,610 Ele apenas disse: Olá Mundo, no ecrã. 50 00:02:29,610 --> 00:02:30,920 Nós rodamos este através Clang. 51 00:02:30,920 --> 00:02:33,200 Ou corremos através Fazer que decorreu Clang. 52 00:02:33,200 --> 00:02:36,170 E transmitido no momento em que alguns zeros e uns. 53 00:02:36,170 --> 00:02:38,100 Mas acontece que há um passo intermediário. 54 00:02:38,100 --> 00:02:40,460 Se eu passar por aqui - oops, não quero vê-lo ainda. 55 00:02:40,460 --> 00:02:44,800 Se eu passar por aqui para o meu aparelho e eu abrir hello.c, aqui 56 00:02:44,800 --> 00:02:46,160 é o mesmo programa. 57 00:02:46,160 --> 00:02:48,600 E o que eu vou fazer no meu terminal janela é aqui que eu vou 58 00:02:48,600 --> 00:02:51,430 executar Clang ao invés de fazer, que automatiza todos os quatro 59 00:02:51,430 --> 00:02:52,870 esses passos para nós. 60 00:02:52,870 --> 00:02:58,620 E eu vou fazer clang-S e então hello.c e depois entrar. 61 00:02:58,620 --> 00:03:00,590 >> E eu fico um prompt piscando novamente, o que é bom. 62 00:03:00,590 --> 00:03:05,280 E agora em uma janela um pouco maior, Vou abrir gedit aqui. 63 00:03:05,280 --> 00:03:09,610 E eu vou abrir um arquivo que, Acontece, é chamado hello.s esta 64 00:03:09,610 --> 00:03:11,870 que contém linguagem assembly Me referi anteriormente. 65 00:03:11,870 --> 00:03:15,060 E isso é o que é chamado de montagem linguagem, nível bastante baixo 66 00:03:15,060 --> 00:03:18,470 instruções que seu processador Intel ou seja o que for que está dentro 67 00:03:18,470 --> 00:03:19,350 entende. 68 00:03:19,350 --> 00:03:24,480 Mov e é para o movimento. chamada é para chamando uma função de nível muito baixo. 69 00:03:24,480 --> 00:03:26,380 sub é para subtrair. 70 00:03:26,380 --> 00:03:30,370 >> Então, quando você tem um determinado CPU dentro do seu computador, o que o torna 71 00:03:30,370 --> 00:03:34,300 distintas, contra outro CPUs no mercado, é que as instruções que 72 00:03:34,300 --> 00:03:39,460 entende e muitas vezes o quão eficiente ele é, o quão rápido é a execução de alguns 73 00:03:39,460 --> 00:03:40,380 dessas instruções. 74 00:03:40,380 --> 00:03:45,150 Agora, para saber mais sobre isso, você pode ter próximo CS61 queda na faculdade. 75 00:03:45,150 --> 00:03:48,170 Mas aqui temos, por exemplo, alguns identificadores que pode parecer familiar. 76 00:03:48,170 --> 00:03:50,150 ola.c é o nome do programa. 77 00:03:50,150 --> 00:03:51,070 >> . Texto - 78 00:03:51,070 --> 00:03:54,190 não há muito interesse lá agora, lembre-se que o texto 79 00:03:54,190 --> 00:03:59,190 segmento, de segunda-feira, é quando em memória de seu programa realmente acaba. 80 00:03:59,190 --> 00:04:01,330 Então é isso, pelo menos vagamente familiarizados lá. 81 00:04:01,330 --> 00:04:03,730 Aqui, é claro, é uma menção da nossa função principal. 82 00:04:03,730 --> 00:04:07,220 Rolagem para baixo, estes referem-se a coisas chamados registros, muito pequenos pedaços de 83 00:04:07,220 --> 00:04:09,190 memória dentro de sua CPU atual. 84 00:04:09,190 --> 00:04:12,930 E se rolar mesmo Além disso, eu vejo algum tipo 85 00:04:12,930 --> 00:04:14,240 menção indireta de ASCII. 86 00:04:14,240 --> 00:04:17,120 E há, de fato, é que a string, Olá, vírgula mundo. 87 00:04:17,120 --> 00:04:20,079 >> Assim, longa história curta, esta tem sido acontecendo para você, automaticamente, 88 00:04:20,079 --> 00:04:22,140 debaixo da capa de todo este tempo. 89 00:04:22,140 --> 00:04:26,450 E o que está acontecendo realmente é uma vez você correr Clang, ou por meio de 90 00:04:26,450 --> 00:04:29,150 Faça, você está ficando em primeiro lugar, a partir do código fonte, o 91 00:04:29,150 --> 00:04:30,700 assim chamado em linguagem assembly. 92 00:04:30,700 --> 00:04:35,210 Então Clang é converter esta assembléia linguagem de baixo para zeros e uns. 93 00:04:35,210 --> 00:04:38,340 E este é o slide que começamos nossa discussão na Semana 0 em - 94 00:04:38,340 --> 00:04:39,840 e, em seguida, em uma semana. 95 00:04:39,840 --> 00:04:44,030 E então, finalmente, aqueles zeros e uns são combinados com os zeros e uns 96 00:04:44,030 --> 00:04:47,190 a partir dessas bibliotecas que temos vindo a tomar para concedido como Padrão I / O ou a 97 00:04:47,190 --> 00:04:50,010 Biblioteca de corda ou mesmo a biblioteca de CS50. 98 00:04:50,010 --> 00:04:54,200 >> Então, para pintar o quadro mais visualmente, temos hello.c. 99 00:04:54,200 --> 00:04:57,220 E, é claro, usa o printf funcionar a dizer, Olá mundo. 100 00:04:57,220 --> 00:05:01,810 A etapa de compilação leva-lo até o arquivo que acabamos de ver hello.s, mesmo 101 00:05:01,810 --> 00:05:04,290 Apesar de que é normalmente suprimido automaticamente para você. 102 00:05:04,290 --> 00:05:06,050 Mas esse é o código de montagem no passo de meio. 103 00:05:06,050 --> 00:05:09,750 E então, quando nós montamos a montagem linguagem, por assim dizer, que é quando você 104 00:05:09,750 --> 00:05:10,830 obter os zeros e uns. 105 00:05:10,830 --> 00:05:13,920 Então, nós temos ampliado de forma eficaz hoje em o que temos vindo a tomar para concedido, 106 00:05:13,920 --> 00:05:16,430 significa passar o código-fonte do código-objeto. 107 00:05:16,430 --> 00:05:18,850 >> Mas, finalmente, agora que mesmo quadro - vamos empurrá-la para 108 00:05:18,850 --> 00:05:20,020 o lado esquerdo. 109 00:05:20,020 --> 00:05:22,880 E note que no topo há Mencionei stdio.h. 110 00:05:22,880 --> 00:05:25,030 Isso é um arquivo que nós incluímos em quase todos os 111 00:05:25,030 --> 00:05:26,250 programas que você escreveu. 112 00:05:26,250 --> 00:05:28,830 E esse é o arquivo cujo conteúdo Obter cópia colado, 113 00:05:28,830 --> 00:05:30,350 eficazmente sobre seu código. 114 00:05:30,350 --> 00:05:34,170 Mas verifica-se que, em um computador sistema em algum lugar, há provavelmente um 115 00:05:34,170 --> 00:05:39,150 arquivo stdio.c que alguém escreveu anos há que implementa todas as 116 00:05:39,150 --> 00:05:41,870 funções que foram declaradas em stdio.h. 117 00:05:41,870 --> 00:05:45,465 >> Agora, na realidade não é, provavelmente, em seu Mac ou PC ou até mesmo no 118 00:05:45,465 --> 00:05:47,660 CS50 aparelho é um código C cru. 119 00:05:47,660 --> 00:05:52,710 Alguém já compilou e incluiu . O arquivo de código-objeto ou. Uma 120 00:05:52,710 --> 00:05:56,020 arquivo, que refere-se a uma biblioteca compartilhada que foi pré-instalado e 121 00:05:56,020 --> 00:05:57,240 pré-compilados para você. 122 00:05:57,240 --> 00:06:01,950 Mas suponha que há de fato existe no nosso stdio.c computador em paralelo 123 00:06:01,950 --> 00:06:02,650 com Clang. 124 00:06:02,650 --> 00:06:04,960 Seu código está sendo compilado e montado. 125 00:06:04,960 --> 00:06:09,200 código stdio.c 's está sendo compilado e montado, de modo que este último 126 00:06:09,200 --> 00:06:13,730 passo, aqui, temos que de alguma forma link, por assim dizer, os seus zeros e uns 127 00:06:13,730 --> 00:06:18,430 com seus zeros e uns em uma programa simples que, finalmente, é 128 00:06:18,430 --> 00:06:20,540 Olá chamado apenas. 129 00:06:20,540 --> 00:06:23,340 >> Então essa é toda a magia que é vem acontecendo até agora. 130 00:06:23,340 --> 00:06:26,430 E vai continuar a tomar estes processos de concessão, mas perceber 131 00:06:26,430 --> 00:06:28,750 há um monte de detalhes suculentos acontecendo debaixo lá. 132 00:06:28,750 --> 00:06:31,920 E é isso que faz com que seu computador com Intel inside 133 00:06:31,920 --> 00:06:33,940 particularmente distinta. 134 00:06:33,940 --> 00:06:37,020 >> Então, com essa nota, se você gostaria de se juntar a nós para o almoço desta sexta-feira, fazer ir 135 00:06:37,020 --> 00:06:41,570 para o local cs50.net/rsvp habitual, 13:15 desta sexta-feira. 136 00:06:41,570 --> 00:06:43,400 E agora alguns anúncios. 137 00:06:43,400 --> 00:06:44,670 Portanto, temos uma boa notícia. 138 00:06:44,670 --> 00:06:45,970 E nós temos uma má notícia. 139 00:06:45,970 --> 00:06:47,260 Comece com uma boa notícia aqui. 140 00:06:47,260 --> 00:06:52,038 141 00:06:52,038 --> 00:06:54,510 >> [Gemendo] 142 00:06:54,510 --> 00:06:54,710 >> Tudo bem. 143 00:06:54,710 --> 00:06:56,670 Bem, é tecnicamente um feriado, assim não é tanto um presente de nós. 144 00:06:56,670 --> 00:06:58,030 Mas, então, a má notícia é claro. 145 00:06:58,030 --> 00:07:00,550 146 00:07:00,550 --> 00:07:01,880 >> [Gemendo] 147 00:07:01,880 --> 00:07:03,530 >> Passei um monte de tempo nestas animações. 148 00:07:03,530 --> 00:07:04,690 >> [Risos] 149 00:07:04,690 --> 00:07:07,000 >> Haverá uma sessão de avaliação esta próxima segunda-feira. 150 00:07:07,000 --> 00:07:08,340 Vai estar em 5:30 PM. 151 00:07:08,340 --> 00:07:11,210 Nós vos fará lembrar de todos esses detalhes via e-mail sobre o curso de 152 00:07:11,210 --> 00:07:13,470 site em apenas um par de dias. 153 00:07:13,470 --> 00:07:16,610 Ele será filmado e disponibilizado pouco depois. 154 00:07:16,610 --> 00:07:19,200 Então, se você não pode fazer que segunda-feira slot de noite, não se preocupe. 155 00:07:19,200 --> 00:07:22,270 Seções na próxima semana também vai concentrar-se em revisão para o teste. 156 00:07:22,270 --> 00:07:25,670 Se a sua seção é na segunda-feira, que é de fato férias da universidade, vamos 157 00:07:25,670 --> 00:07:26,920 ainda reunir-se em seção. 158 00:07:26,920 --> 00:07:28,890 Se você simplesmente não pode fazer isso seção, porque você vai 159 00:07:28,890 --> 00:07:29,860 de distância, isso é bom. 160 00:07:29,860 --> 00:07:33,710 Participar de uma seção de terça-feira ou domingo ou tune-se para a seção de Jason, que é 161 00:07:33,710 --> 00:07:35,110 disponível online. 162 00:07:35,110 --> 00:07:37,490 >> Assim, mais uma má notícia. 163 00:07:37,490 --> 00:07:41,960 Assim, de acordo com o plano de estudos, temos palestra na próxima sexta-feira. 164 00:07:41,960 --> 00:07:43,690 Mas a boa notícia - 165 00:07:43,690 --> 00:07:44,860 claramente, eu passei muito tempo com isso. 166 00:07:44,860 --> 00:07:45,280 >> [Risos] 167 00:07:45,280 --> 00:07:47,140 >> Vamos cancelar próxima palestras de sexta-feira. 168 00:07:47,140 --> 00:07:50,590 Assim que será um presente para nós, de modo que você pode realmente ter um bom descanso em 169 00:07:50,590 --> 00:07:52,990 entre esta semana e duas semanas daí. 170 00:07:52,990 --> 00:07:57,460 Portanto, não palestras na próxima semana, apenas uma pequena pouco quiz, para o qual deve ser 171 00:07:57,460 --> 00:07:59,030 ficando cada vez mais animado. 172 00:07:59,030 --> 00:08:03,870 >> Então, vamos agora voltar nossa atenção para algo que é realmente mais visual 173 00:08:03,870 --> 00:08:06,990 e mais emocionante e para definir o estágio para o que vai estar no horizonte 174 00:08:06,990 --> 00:08:08,420 em apenas um par de semanas. 175 00:08:08,420 --> 00:08:12,160 Após o primeiro teste, vamos transformar o foco da nossa conjuntos de problemas para outro 176 00:08:12,160 --> 00:08:16,710 problema específico do domínio, que de forense ou de segurança em geral. 177 00:08:16,710 --> 00:08:19,550 >> Na verdade, o tractor com este problema conjunto é para mim um dos 178 00:08:19,550 --> 00:08:24,850 ensinando companheiro ou CAs para atravessar campus tirar algumas fotografias 179 00:08:24,850 --> 00:08:29,450 identificáveis, mas não as pessoas óbvias, lugares ou coisas, então todo ano eu 180 00:08:29,450 --> 00:08:34,520 de alguma forma conseguem apagar acidentalmente ou danificar o cartão de mídia digital 181 00:08:34,520 --> 00:08:35,720 que está dentro da nossa câmera. 182 00:08:35,720 --> 00:08:36,860 Mas não é grande coisa. 183 00:08:36,860 --> 00:08:39,200 I pode ir em frente e ligue que no meu computador. 184 00:08:39,200 --> 00:08:43,010 Eu posso fazer uma imagem forense do mesmo, assim para falar, copiando os zeros e 185 00:08:43,010 --> 00:08:46,830 aqueles fora do que o cartão de memória, seja é um cartão SD ou cartão de memória flash compacto ou 186 00:08:46,830 --> 00:08:48,100 o que você está familiarizado. 187 00:08:48,100 --> 00:08:49,300 E então podemos entregar isso. 188 00:08:49,300 --> 00:08:53,190 >> E assim o desafio à frente, entre outros coisas para você, será para escrever 189 00:08:53,190 --> 00:08:58,630 Código C, que se recupera de um monte de JPEGs para mim e revelou será 190 00:08:58,630 --> 00:09:00,190 essas pessoas, lugares ou coisas. 191 00:09:00,190 --> 00:09:03,340 E também vou falar, neste problema definir e nos dias que virão, sobre 192 00:09:03,340 --> 00:09:04,440 gráficos em geral. 193 00:09:04,440 --> 00:09:06,140 Nós usamos eles, um curso, para sair. 194 00:09:06,140 --> 00:09:09,080 Mas você espécie de dado adquirido existe estas noções de alto nível 195 00:09:09,080 --> 00:09:10,680 de retângulos e ovais. 196 00:09:10,680 --> 00:09:12,450 Mas debaixo do capô existem pixels. 197 00:09:12,450 --> 00:09:14,370 E você tinha que começar pensando sobre isso. 198 00:09:14,370 --> 00:09:18,800 Ou você vai para a p-set 4 tem que pensar sobre a diferença entre os tijolos, como 199 00:09:18,800 --> 00:09:21,990 rapidamente você está bola está se movendo através de a tela para sair. 200 00:09:21,990 --> 00:09:24,830 Portanto, não há essa noção de pontos em sua tela que é 201 00:09:24,830 --> 00:09:26,290 entram em jogo já. 202 00:09:26,290 --> 00:09:29,430 >> Agora o que se vê, porém, é o que você chegar em uma tela de computador. 203 00:09:29,430 --> 00:09:33,680 Se você já assistiu a algum bem ou TV ruim, as chances são eles praticamente 204 00:09:33,680 --> 00:09:36,280 tratar o público como technophobes que realmente não 205 00:09:36,280 --> 00:09:37,630 sei muito sobre informática. 206 00:09:37,630 --> 00:09:40,840 E por isso é muito fácil para a polícia detetive para dizer, não é 207 00:09:40,840 --> 00:09:41,710 limpar isso para mim? 208 00:09:41,710 --> 00:09:42,710 Ou melhorar, certo? 209 00:09:42,710 --> 00:09:45,550 Melhorar é como a palavra da moda em mais qualquer programa relacionado crime. 210 00:09:45,550 --> 00:09:49,240 E a realidade é que se você demorar muito imagem borrada de um suspeito de fazer 211 00:09:49,240 --> 00:09:51,620 algo ruim, você não pode apenas melhorá-lo. 212 00:09:51,620 --> 00:09:53,080 Você não pode ampliar infinitamente. 213 00:09:53,080 --> 00:09:56,350 Você não pode ver o brilho de alguém da olho que cometeu que 214 00:09:56,350 --> 00:09:59,860 determinado crime, apesar da prevalência desta na TV. 215 00:09:59,860 --> 00:10:04,110 >> E assim, com que vamos motivar que próximo conjunto de problemas com um vislumbre 216 00:10:04,110 --> 00:10:05,765 alguns shows com o qual você pode estar familiarizado. 217 00:10:05,765 --> 00:10:06,500 >> [REPRODUÇÃO] 218 00:10:06,500 --> 00:10:07,835 >> -OK. 219 00:10:07,835 --> 00:10:09,956 Agora, vamos dar uma boa olhada em você. 220 00:10:09,956 --> 00:10:17,060 221 00:10:17,060 --> 00:10:17,766 >> -Espere. 222 00:10:17,766 --> 00:10:18,658 Correr de volta. 223 00:10:18,658 --> 00:10:19,550 >> -Espere um minuto. 224 00:10:19,550 --> 00:10:21,580 Vá para a direita. 225 00:10:21,580 --> 00:10:21,800 >> -Não. 226 00:10:21,800 --> 00:10:22,690 Congelar isso. 227 00:10:22,690 --> 00:10:23,692 >> Ecrã completo. 228 00:10:23,692 --> 00:10:23,846 >> -OK. 229 00:10:23,846 --> 00:10:24,154 Congelar isso. 230 00:10:24,154 --> 00:10:25,140 >> Aperte-se sobre isso, sim? 231 00:10:25,140 --> 00:10:27,090 >> -Vector na nessa cara pela roda traseira. 232 00:10:27,090 --> 00:10:29,730 >> -Zoom em direito aqui neste local. 233 00:10:29,730 --> 00:10:33,700 >> -Com o equipamento certo, a fotografada pode ser ampliada e afiadas. 234 00:10:33,700 --> 00:10:34,490 >> -O que é isso? 235 00:10:34,490 --> 00:10:35,870 >> -É um programa de melhoramento. 236 00:10:35,870 --> 00:10:36,793 >> -Você pode esclarecer isso qualquer? 237 00:10:36,793 --> 00:10:38,560 >> -Eu não sei. 238 00:10:38,560 --> 00:10:39,090 Vamos melhorá-lo. 239 00:10:39,090 --> 00:10:41,690 >> Seção A-6-Enhance. 240 00:10:41,690 --> 00:10:43,510 >> -Eu aumentei os detalhes e - 241 00:10:43,510 --> 00:10:44,456 >> -Eu acho que é o suficiente para melhorar. 242 00:10:44,456 --> 00:10:45,402 Liberá-lo para minha tela. 243 00:10:45,402 --> 00:10:47,300 >> -Melhorar a reflexão em seus olhos. 244 00:10:47,300 --> 00:10:49,330 >> -Vamos fazer isso através de aprimoramento de vídeo. 245 00:10:49,330 --> 00:10:50,340 >> -Edgar, você pode melhorar isso? 246 00:10:50,340 --> 00:10:52,320 >> -Segurem-se. 247 00:10:52,320 --> 00:10:54,290 >> -Tenho vindo a trabalhar sobre esta reflexão. 248 00:10:54,290 --> 00:10:55,560 >> -Alguém reflexão de. 249 00:10:55,560 --> 00:10:56,440 >> -Reflexão. 250 00:10:56,440 --> 00:10:57,940 >> -Há uma reflexão do rosto do homem. 251 00:10:57,940 --> 00:10:58,860 >> -A reflexão. 252 00:10:58,860 --> 00:10:59,710 >> -Há uma reflexão. 253 00:10:59,710 --> 00:11:00,900 >> -Dê um zoom no espelho. 254 00:11:00,900 --> 00:11:03,500 >> -Você pode ver uma reflexão. 255 00:11:03,500 --> 00:11:04,700 >> -Você pode melhorar a imagem a partir daqui? 256 00:11:04,700 --> 00:11:05,700 >> -Pode aumentar ele aqui? 257 00:11:05,700 --> 00:11:06,500 >> -Você pode melhorá-lo? 258 00:11:06,500 --> 00:11:07,380 >> -Você pode melhorá-lo? 259 00:11:07,380 --> 00:11:08,190 >> -Podemos melhorar isso? 260 00:11:08,190 --> 00:11:08,940 >> -Você pode melhorá-lo? 261 00:11:08,940 --> 00:11:10,280 >> -Espere um segundo, eu vou melhorar. 262 00:11:10,280 --> 00:11:11,570 >> -Zoom na porta. 263 00:11:11,570 --> 00:11:12,180 >> -X10. 264 00:11:12,180 --> 00:11:13,052 >> -Zoom. 265 00:11:13,052 --> 00:11:13,197 >> [Risos] 266 00:11:13,197 --> 00:11:14,360 >> -Mover-se dentro 267 00:11:14,360 --> 00:11:15,100 >> -Espere, pare. 268 00:11:15,100 --> 00:11:15,740 >> -Parar. 269 00:11:15,740 --> 00:11:16,290 >> -Pausa-lo. 270 00:11:16,290 --> 00:11:19,390 >> Girar em torno de 75 graus por favor, o vertical. 271 00:11:19,390 --> 00:11:19,886 >> [Risos] 272 00:11:19,886 --> 00:11:24,350 >> -Pare, e de volta para a parte sobre a porta novamente. 273 00:11:24,350 --> 00:11:26,330 >> -Tem um intensificador de imagem que pode bitmap? 274 00:11:26,330 --> 00:11:28,990 >> -Talvez possamos usar o Pradeep Sen método para ver nas janelas. 275 00:11:28,990 --> 00:11:30,680 >> -Este software é o estado da arte. 276 00:11:30,680 --> 00:11:31,676 >> -O valor ícone está desligado. 277 00:11:31,676 --> 00:11:34,166 >> -Com a combinação certa de algoritmos. 278 00:11:34,166 --> 00:11:38,399 >> -Ele levou algoritmos de iluminação para o próximo nível e posso usá-los para 279 00:11:38,399 --> 00:11:38,648 melhorar esta fotografia. 280 00:11:38,648 --> 00:11:42,050 >> -Lock e ampliar o eixo z. 281 00:11:42,050 --> 00:11:42,760 >> -Melhorar. 282 00:11:42,760 --> 00:11:43,060 >> -Melhorar. 283 00:11:43,060 --> 00:11:43,760 >> -Melhorar. 284 00:11:43,760 --> 00:11:45,010 >> Congelamento e melhorar. 285 00:11:45,010 --> 00:11:47,470 286 00:11:47,470 --> 00:11:47,910 >> [FIM REPRODUÇÃO DE VÍDEO] 287 00:11:47,910 --> 00:11:51,470 >> DAVID J. MALAN: Então Set Problem 5 é o que está por vir lá. 288 00:11:51,470 --> 00:11:55,260 Então, vamos em breve ter uma melhor compreensão de quando e por que você pode 289 00:11:55,260 --> 00:11:57,300 ea nossa não pode melhorar nesse sentido. 290 00:11:57,300 --> 00:12:00,090 Mas, primeiro, vamos voltar nossa atenção para alguns dos blocos de construção vamos 291 00:12:00,090 --> 00:12:02,250 precisa ser capaz de contar essa história. 292 00:12:02,250 --> 00:12:05,580 >> Então, lembro que tirei esta imagem em Segunda-feira e um pouco na semana passada. 293 00:12:05,580 --> 00:12:09,970 E isso descreve o layout das coisas na memória do seu computador quando 294 00:12:09,970 --> 00:12:11,000 execução de algum programa. 295 00:12:11,000 --> 00:12:14,310 O segmento de tecnologia em cima, aviso, refere-se para os zeros e uns reais 296 00:12:14,310 --> 00:12:16,000 que compõem o seu programa. 297 00:12:16,000 --> 00:12:19,340 Há, abaixo, alguns inicializado ou dados não inicializados, que tipicamente 298 00:12:19,340 --> 00:12:22,910 refere-se a coisas como constantes ou strings ou variáveis ​​globais que têm 299 00:12:22,910 --> 00:12:24,200 previamente declarado. 300 00:12:24,200 --> 00:12:26,500 Há a pilha, mas nós vamos chegar de volta para que daqui a pouco. 301 00:12:26,500 --> 00:12:27,410 >> E depois há a pilha. 302 00:12:27,410 --> 00:12:30,660 Muito parecido com uma pilha de bandejas no cafeteria, este é o lugar onde a memória fica 303 00:12:30,660 --> 00:12:33,610 em camadas e camadas sempre você faz o que em um programa? 304 00:12:33,610 --> 00:12:36,380 305 00:12:36,380 --> 00:12:37,730 Qual é o uso de pilha para? 306 00:12:37,730 --> 00:12:39,320 >> Sim? 307 00:12:39,320 --> 00:12:40,000 >> Chamada de função. 308 00:12:40,000 --> 00:12:42,890 Toda vez que você chamar uma função, é dado ao pedaço de memória para o seu 309 00:12:42,890 --> 00:12:45,020 variáveis ​​locais ou seus parâmetros. 310 00:12:45,020 --> 00:12:48,810 E pictoricamente, vemos que a cada Função chamada sucessiva, quando A 311 00:12:48,810 --> 00:12:52,520 chamadas B chama C chamadas D, eles se em camadas na pilha. 312 00:12:52,520 --> 00:12:55,630 E dentro de cada uma das referidas fatias de memória é essencialmente uma extensão única 313 00:12:55,630 --> 00:12:58,590 para essa função, o que, evidentemente, é problemático se você quiser entregar 314 00:12:58,590 --> 00:13:01,850 a partir de uma função para outra Um pedaço de dados que você quer que ele 315 00:13:01,850 --> 00:13:03,500 para mutar ou alterar. 316 00:13:03,500 --> 00:13:08,060 >> Então, qual foi a nossa solução de possibilitar Uma função representada por uma pilha 317 00:13:08,060 --> 00:13:11,390 quadro para alterar a memória dentro de outro quadro de pilha? 318 00:13:11,390 --> 00:13:14,590 Como os dois falam um para o outro? 319 00:13:14,590 --> 00:13:18,510 Assim, por meio de ponteiros ou endereços, que, novamente, apenas descrever o local onde em 320 00:13:18,510 --> 00:13:22,280 memória, por meio de um específico número mordida, o particular 321 00:13:22,280 --> 00:13:23,830 valor pode ser encontrado. 322 00:13:23,830 --> 00:13:26,860 Então lembro da última vez também continuamos a história e olhou para a 323 00:13:26,860 --> 00:13:28,280 bastante programa de buggy. 324 00:13:28,280 --> 00:13:32,900 E este programa é buggy para poucos razões, mas o mais preocupante é 325 00:13:32,900 --> 00:13:34,620 porque ele não consegue verificar o que? 326 00:13:34,620 --> 00:13:39,111 327 00:13:39,111 --> 00:13:40,450 >> Sim, ele não consegue verificar a entrada. 328 00:13:40,450 --> 00:13:41,870 Desculpe? 329 00:13:41,870 --> 00:13:43,880 >> Se for mais de 12 caracteres. 330 00:13:43,880 --> 00:13:47,260 Então, muito esperta, ao chamar memcopy, que, como o nome sugere, apenas 331 00:13:47,260 --> 00:13:50,630 memória cópias de seu segundo argumento em seu primeiro argumento. 332 00:13:50,630 --> 00:13:54,730 O terceiro argumento, muito esperta, é verificado para se certificar de que você não 333 00:13:54,730 --> 00:13:59,400 copiar mais do que, no presente caso, o comprimento de bar, número de caracteres, 334 00:13:59,400 --> 00:14:03,810 para o destino, o que é isto série C. Mas o problema é que o que 335 00:14:03,810 --> 00:14:07,230 se a própria C não é grande o suficiente para lidar com isso? 336 00:14:07,230 --> 00:14:09,900 Você vai copiar o número de bytes que você já foi dado. 337 00:14:09,900 --> 00:14:13,040 Mas o que você realmente tem mais bytes que você tem espaço para? 338 00:14:13,040 --> 00:14:16,770 >> Bem, este programa muito tolamente apenas cegamente passa a ter tudo o que é 339 00:14:16,770 --> 00:14:20,650 dado, Olá barra invertida é 0 ótimo se string é curto 340 00:14:20,650 --> 00:14:22,040 suficiente, como cinco caracteres. 341 00:14:22,040 --> 00:14:26,470 Mas se é realmente 12 caracteres ou 1200 caracteres, vimos da última vez 342 00:14:26,470 --> 00:14:29,380 que você está indo só para completamente sobrescrever a memória que 343 00:14:29,380 --> 00:14:30,470 não pertence a você. 344 00:14:30,470 --> 00:14:34,390 E o pior caso, se você substituir esse parte vermelha lá que chamamos de 345 00:14:34,390 --> 00:14:35,380 endereço do remetente - 346 00:14:35,380 --> 00:14:38,370 isso é apenas onde o computador automaticamente, para você, por trás da 347 00:14:38,370 --> 00:14:43,130 cenas, dobras de distância um valor de 32 bits que lembra-lo para o endereço que deveria 348 00:14:43,130 --> 00:14:47,080 voltar quando foo, esta outra função, é feito de execução. 349 00:14:47,080 --> 00:14:49,320 É uma migalha de pão de tipo ao qual ela retorna. 350 00:14:49,320 --> 00:14:52,490 Se você substituir o que, potencialmente, se você é o cara mau, pode poderia 351 00:14:52,490 --> 00:14:54,750 potencialmente assumir computador de alguém. 352 00:14:54,750 --> 00:14:58,020 E você vai certamente lançá-lo na maioria dos casos. 353 00:14:58,020 --> 00:15:01,690 >> Agora, este problema só foi agravado como começamos a conversar sobre a memória 354 00:15:01,690 --> 00:15:03,010 gestão em geral. 355 00:15:03,010 --> 00:15:07,150 E malloc, para alocação de memória, é uma função que podemos usar para alocar 356 00:15:07,150 --> 00:15:11,260 memória quando não sabemos com antecedência que pode precisar de algum. 357 00:15:11,260 --> 00:15:13,960 Assim, por exemplo, se eu voltar para o aparelho aqui. 358 00:15:13,960 --> 00:15:21,010 E eu abrir a partir do último hello2.c tempo, recordar este programa, que parecia 359 00:15:21,010 --> 00:15:23,500 um pouco algo como isto, apenas três linhas - 360 00:15:23,500 --> 00:15:27,940 indicar o seu nome, o nome string, no lado esquerdo, é igual a getstring. 361 00:15:27,940 --> 00:15:29,690 E, então, imprimi-lo, o nome do utilizador. 362 00:15:29,690 --> 00:15:31,170 >> Portanto, este era um super programa simples. 363 00:15:31,170 --> 00:15:34,870 Para ser claro, deixe-me ir em frente e torná-Olá-2. 364 00:15:34,870 --> 00:15:36,680 Eu vou fazer o ponto barra Olá-2. 365 00:15:36,680 --> 00:15:37,750 Diga seu nome - 366 00:15:37,750 --> 00:15:38,140 David. 367 00:15:38,140 --> 00:15:38,840 Enter. 368 00:15:38,840 --> 00:15:39,540 Olá David. 369 00:15:39,540 --> 00:15:41,060 Parece que funciona OK. 370 00:15:41,060 --> 00:15:43,140 Mas o que realmente está acontecendo sob capô aqui? 371 00:15:43,140 --> 00:15:44,670 Primeiro vamos descascar algumas camadas. 372 00:15:44,670 --> 00:15:48,380 String é apenas um sinônimo temos percebi para quê? 373 00:15:48,380 --> 00:15:49,110 Estrela Char. 374 00:15:49,110 --> 00:15:52,740 Então, vamos torná-lo um pouco mais misterioso mas tecnicamente mais correto que este 375 00:15:52,740 --> 00:15:55,570 é uma estrela char, o que significa que nome, sim, é uma variável. 376 00:15:55,570 --> 00:15:59,920 Mas o que armazena o nome é o endereço de um char, que se sente um pouco estranho 377 00:15:59,920 --> 00:16:01,050 porque eu estou recebendo de volta uma string. 378 00:16:01,050 --> 00:16:03,580 Eu estou voltando múltipla caracteres não um char. 379 00:16:03,580 --> 00:16:07,400 >> Mas, claro, você só precisa do primeiro endereço do char para lembrar de onde o 380 00:16:07,400 --> 00:16:08,870 corda toda é porque porquê? 381 00:16:08,870 --> 00:16:12,700 Como você descobrir onde está o fim do a string é saber o começo? 382 00:16:12,700 --> 00:16:13,630 A barra invertida zero. 383 00:16:13,630 --> 00:16:17,260 Assim, com essas duas pistas que você descobrir antes do começo e do fim da 384 00:16:17,260 --> 00:16:20,280 qualquer seqüência são, contanto que eles são formada adequadamente com que null 385 00:16:20,280 --> 00:16:22,110 terminador, que invertida zero. 386 00:16:22,110 --> 00:16:24,520 >> Mas isso está chamando getstring. 387 00:16:24,520 --> 00:16:28,020 E verifica-se que getstring todo esse tempo tem sido uma espécie de 388 00:16:28,020 --> 00:16:28,820 batota para nós. 389 00:16:28,820 --> 00:16:32,460 Ele vem fazendo este trabalho, com certeza, recebendo uma string do usuário. 390 00:16:32,460 --> 00:16:34,580 Mas onde é que a memória vindo de? 391 00:16:34,580 --> 00:16:38,440 Se voltarmos para a imagem aqui e aplicar a definição de apenas um 392 00:16:38,440 --> 00:16:42,610 há pouco, que a pilha é onde memória acontece quando as funções são chamadas, 393 00:16:42,610 --> 00:16:45,370 por essa lógica, quando você chama getstring, e então eu digitar 394 00:16:45,370 --> 00:16:50,900 D-V-A-I-D Enter, em que é D-A-V-I-D barra invertida a zero armazenado, com base no 395 00:16:50,900 --> 00:16:53,480 história que nos disse até agora? 396 00:16:53,480 --> 00:16:55,190 >> Parece estar em a pilha, certo? 397 00:16:55,190 --> 00:16:58,120 Quando você liga para obter corda você tem um pequeno pedaço de memória na pilha. 398 00:16:58,120 --> 00:17:01,630 Então, é lógico que a D-A-V-I-D invertida zero é armazenado 399 00:17:01,630 --> 00:17:02,770 existe na pilha. 400 00:17:02,770 --> 00:17:07,680 Mas espere um minuto, getString retornos essa seqüência, por assim dizer, o que significa 401 00:17:07,680 --> 00:17:11,700 é bandeja da cafeteria é retirado da pilha. 402 00:17:11,700 --> 00:17:14,560 E disse da última vez que tão logo a função retorna, e você ter que 403 00:17:14,560 --> 00:17:20,109 tabuleiro, por assim dizer, fora da pilha, o que você pode assumir sobre os restos de 404 00:17:20,109 --> 00:17:21,819 que a memória? 405 00:17:21,819 --> 00:17:25,160 Eu meio que redesenhou-os como pontos de interrogação porque efetivamente se tornar 406 00:17:25,160 --> 00:17:26,250 valores desconhecidos. 407 00:17:26,250 --> 00:17:29,500 Eles podem ser reutilizados quando alguns próxima função é chamada. 408 00:17:29,500 --> 00:17:31,870 >> Em outras palavras, se acontecer a armazenagem - 409 00:17:31,870 --> 00:17:34,350 Eu vou tirar uma foto rápida aqui da pilha. 410 00:17:34,350 --> 00:17:38,690 Se acontecer de estar chegando ao fundo do meu segmento de memória, e vamos dizer 411 00:17:38,690 --> 00:17:42,230 que este é o local de memória ocupado pelo principal e talvez arg c e 412 00:17:42,230 --> 00:17:46,790 arg v e qualquer outra coisa no programa, getstring quando é chamado, 413 00:17:46,790 --> 00:17:51,120 presumivelmente getstring fica um bloco de memória aqui. 414 00:17:51,120 --> 00:17:53,940 E então D-A-V-I-D alguma forma termina nesta função. 415 00:17:53,940 --> 00:17:55,320 E eu vou simplificar. 416 00:17:55,320 --> 00:18:00,050 Mas vamos supor que o seu D-A-V-I-D barra invertida zero. 417 00:18:00,050 --> 00:18:03,500 Então isso muitos bytes são usados ​​em o quadro para getstring. 418 00:18:03,500 --> 00:18:08,270 >> Mas, tão logo retorna getString, nós disse da última vez que essa memória sobre 419 00:18:08,270 --> 00:18:11,340 aqui tudo se torna - woops! - 420 00:18:11,340 --> 00:18:14,270 tudo se torna efetivamente apagados. 421 00:18:14,270 --> 00:18:17,220 E podemos pensar nisso agora como questão marcas porque quem sabe 422 00:18:17,220 --> 00:18:18,720 o que vai tornar-se de que a memória. 423 00:18:18,720 --> 00:18:22,130 Na verdade, eu muitas vezes chamar funções excepto getstring. 424 00:18:22,130 --> 00:18:24,750 E assim que eu chamo algum outro função de getstring, talvez não em 425 00:18:24,750 --> 00:18:28,860 este programa específico que apenas olhou mas em alguns outros, certamente alguma outra 426 00:18:28,860 --> 00:18:34,180 função pode acabar sendo dado este ponto seguinte na pilha. 427 00:18:34,180 --> 00:18:39,410 >> Portanto, não pode ser que as lojas getString D-A-V-I-D na pilha, porque eu faria 428 00:18:39,410 --> 00:18:41,040 imediatamente perder acesso a ela. 429 00:18:41,040 --> 00:18:43,720 Mas nós sabemos que eles getString só retorna o que? 430 00:18:43,720 --> 00:18:47,220 Ele não está voltando para me seis caracteres. 431 00:18:47,220 --> 00:18:51,090 O que é que realmente se voltando conclui-se da última vez? 432 00:18:51,090 --> 00:18:52,480 O endereço do primeiro. 433 00:18:52,480 --> 00:18:56,650 Então, de alguma forma, quando você chamou getstring, é alocar um bloco de memória para 434 00:18:56,650 --> 00:18:59,620 a corda que o tipo e os usuários endereço, em seguida, retornar dela. 435 00:18:59,620 --> 00:19:02,930 E verifica-se que quando você quer funcionar para alocar memória neste 436 00:19:02,930 --> 00:19:08,390 caminho e voltar para a pessoa que ligou essa função, o endereço 437 00:19:08,390 --> 00:19:11,870 que pedaço de memória, é absolutamente não pode colocá-lo na pilha no 438 00:19:11,870 --> 00:19:14,750 baixo, porque funcionalmente é apenas vai se tornar o seu muito 439 00:19:14,750 --> 00:19:17,800 rapidamente, assim que você pode provavelmente adivinhar onde estamos indo provavelmente para lançá-lo 440 00:19:17,800 --> 00:19:20,130 em vez disso, a chamada pilha. 441 00:19:20,130 --> 00:19:25,290 >> Então, entre o fundo da sua memória de layout e do alto de sua memória do 442 00:19:25,290 --> 00:19:26,820 disposição são um monte de segmentos. 443 00:19:26,820 --> 00:19:29,270 Uma delas é a pilha, e à direita acima, é o heap. 444 00:19:29,270 --> 00:19:33,680 E pilha é apenas um pedaço diferente de memória que não é usado para funções 445 00:19:33,680 --> 00:19:34,770 quando eles são chamados. 446 00:19:34,770 --> 00:19:38,100 É usado para a memória de longo prazo, quando você quer uma função para pegar alguns 447 00:19:38,100 --> 00:19:42,700 memória e ser capaz de segurá-la sem perder o controle sobre ele. 448 00:19:42,700 --> 00:19:45,550 >> Agora você poderia talvez imediatamente ver que esta não é 449 00:19:45,550 --> 00:19:48,060 necessariamente um design perfeito. 450 00:19:48,060 --> 00:19:51,350 Tal como o seu programa de memória alocada em a pilha, ou como vocês chamam mais e 451 00:19:51,350 --> 00:19:55,540 mais funções, ou como você alocar memória na pilha com malloc fora como 452 00:19:55,540 --> 00:20:00,690 getstring está fazendo, o que claramente parece ser problema inevitável? 453 00:20:00,690 --> 00:20:00,860 >> Certo. 454 00:20:00,860 --> 00:20:03,150 Como o fato de que essas setas estão apontando um para o outro 455 00:20:03,150 --> 00:20:04,380 não augura nada de bom. 456 00:20:04,380 --> 00:20:08,630 E, de fato, nós poderíamos bater muito rapidamente um programa em qualquer número de maneiras. 457 00:20:08,630 --> 00:20:12,050 Na verdade, eu acho que pode ter acidentalmente uma vez feito isso. 458 00:20:12,050 --> 00:20:14,020 Ou se não, vamos fazê-lo deliberadamente agora. 459 00:20:14,020 --> 00:20:21,330 Deixe-me ir em frente e escrever super-rápida um programa chamado dontdothis.c. 460 00:20:21,330 --> 00:20:26,730 E agora eu vou entrar aqui e não afiada incluir stdio.h. 461 00:20:26,730 --> 00:20:32,620 Vamos declarar a função foo leva Sem argumentos, o que é 462 00:20:32,620 --> 00:20:34,040 denotado como bem por nula. 463 00:20:34,040 --> 00:20:37,830 >> E a única coisa foo vai fazer é chamada foo, o que provavelmente não é o 464 00:20:37,830 --> 00:20:39,100 mais inteligente idéia, mas que assim seja. 465 00:20:39,100 --> 00:20:40,490 Ent void main. 466 00:20:40,490 --> 00:20:45,270 Agora a única coisa principal que vai a fazer é chamar foo bem. 467 00:20:45,270 --> 00:20:51,050 E, apenas por diversão, eu vou à frente e dizer printf "Olá a partir de 468 00:20:51,050 --> 00:20:52,340 foo ". 469 00:20:52,340 --> 00:20:52,890 >> OK. 470 00:20:52,890 --> 00:21:00,160 Então, se eu não cometer erros, Faça dontdothis dot barra. 471 00:21:00,160 --> 00:21:01,960 E vamos fazê-lo em uma janela maior - 472 00:21:01,960 --> 00:21:03,210 dot slash, dontdothis. 473 00:21:03,210 --> 00:21:07,590 474 00:21:07,590 --> 00:21:08,840 Vamos. 475 00:21:08,840 --> 00:21:10,940 476 00:21:10,940 --> 00:21:11,890 Uh oh. 477 00:21:11,890 --> 00:21:13,100 Aparentemente, você pode fazer isso. 478 00:21:13,100 --> 00:21:15,190 Droga. 479 00:21:15,190 --> 00:21:16,190 OK. 480 00:21:16,190 --> 00:21:16,580 Espere. 481 00:21:16,580 --> 00:21:17,370 Stand by. 482 00:21:17,370 --> 00:21:18,270 Será que nós - 483 00:21:18,270 --> 00:21:20,110 Fizemos usá-lo com Make. 484 00:21:20,110 --> 00:21:22,050 >> [Suspira] 485 00:21:22,050 --> 00:21:25,110 >> Eu sei, mas eu acho que nós acabei de excluir isso. 486 00:21:25,110 --> 00:21:28,410 Uh, sim. 487 00:21:28,410 --> 00:21:30,660 Droga. 488 00:21:30,660 --> 00:21:32,640 Resolva este Rob. 489 00:21:32,640 --> 00:21:34,678 O quê? 490 00:21:34,678 --> 00:21:35,928 É muito simples. 491 00:21:35,928 --> 00:21:43,820 492 00:21:43,820 --> 00:21:47,360 Sim, voltamos a otimização off. 493 00:21:47,360 --> 00:21:48,970 OK, stand bye. 494 00:21:48,970 --> 00:21:49,950 Agora sinto-me melhor. 495 00:21:49,950 --> 00:21:51,390 OK. 496 00:21:51,390 --> 00:21:51,780 Tudo bem. 497 00:21:51,780 --> 00:21:53,430 >> Então, vamos recompilar isso - 498 00:21:53,430 --> 00:21:55,880 Faça você dontdothis. 499 00:21:55,880 --> 00:22:00,090 Você pode ter que mudar o nome deste para dothis.c em apenas um momento. 500 00:22:00,090 --> 00:22:00,710 Lá vamos nós. 501 00:22:00,710 --> 00:22:01,240 Obrigado. 502 00:22:01,240 --> 00:22:02,050 OK. 503 00:22:02,050 --> 00:22:05,480 Assim, o fato de que eu estava imprimindo algo foi realmente apenas 504 00:22:05,480 --> 00:22:08,150 retardando o processo pelo qual nós teria chegado a esse ponto. 505 00:22:08,150 --> 00:22:08,510 OK. 506 00:22:08,510 --> 00:22:08,870 Ufa! 507 00:22:08,870 --> 00:22:11,180 >> Então, o que está realmente acontecendo? 508 00:22:11,180 --> 00:22:14,440 A razão lá, assim como um aparte, é fazer qualquer coisa em termos de entrada e 509 00:22:14,440 --> 00:22:17,270 produção tende a ser mais lento, porque você tem que escrever caracteres para o 510 00:22:17,270 --> 00:22:18,600 tela, tem que rolar. 511 00:22:18,600 --> 00:22:21,720 Assim, longa história curta, eu tinha realmente Aconteceu tão impaciente, teríamos 512 00:22:21,720 --> 00:22:23,260 vi esse resultado final também. 513 00:22:23,260 --> 00:22:26,220 Agora que eu tenho passeio dos print-ups, vemo-lo imediatamente. 514 00:22:26,220 --> 00:22:28,410 Então, por que isso está acontecendo. 515 00:22:28,410 --> 00:22:31,300 Pois bem, a explicação simples, é claro, foo é que provavelmente não deveria 516 00:22:31,300 --> 00:22:32,500 ser que se autodenomina. 517 00:22:32,500 --> 00:22:34,470 >> Agora, em termos gerais, esta é a recursividade. 518 00:22:34,470 --> 00:22:36,970 E nós pensamos que algumas semanas atrás recursiva é bom. 519 00:22:36,970 --> 00:22:40,330 Recursividade é dessa forma mágica de expressar-se de super sucinta. 520 00:22:40,330 --> 00:22:41,400 E ele simplesmente funciona. 521 00:22:41,400 --> 00:22:45,060 Mas há uma característica fundamental de todos os programas recursivos com quem falamos 522 00:22:45,060 --> 00:22:48,260 cerca e olhou para, até agora, o que era que eles tinham o quê? 523 00:22:48,260 --> 00:22:52,610 Um caso base, que era um pouco difícil coded caso o referido em algumas situações 524 00:22:52,610 --> 00:22:56,210 não chamar foo, o que é claramente não é o caso aqui. 525 00:22:56,210 --> 00:22:58,920 >> Então, o que está realmente acontecendo em termos de esta imagem? 526 00:22:58,920 --> 00:23:01,790 Bem, quando principal chama foo, que recebe uma fatia de memória. 527 00:23:01,790 --> 00:23:04,150 Quando chama foo foo, ele fica uma fatia de memória. 528 00:23:04,150 --> 00:23:06,430 Quando chama foo foo, ele recebe uma fatia. 529 00:23:06,430 --> 00:23:07,080 Ela recebe uma fatia. 530 00:23:07,080 --> 00:23:08,120 Ela recebe uma fatia. 531 00:23:08,120 --> 00:23:09,460 Porque foo nunca está voltando. 532 00:23:09,460 --> 00:23:12,160 Nós nunca está apagando um daqueles quadros da pilha. 533 00:23:12,160 --> 00:23:15,930 Então, nós estamos soprando através da pilha, não de mencionar quem sabe o que mais, e 534 00:23:15,930 --> 00:23:19,600 estamos ultrapassando os limites do nosso o chamado segmento de memória. 535 00:23:19,600 --> 00:23:21,790 Erro ir segmentação falsa. 536 00:23:21,790 --> 00:23:24,110 >> Portanto, a solução há claramente, não faça isso. 537 00:23:24,110 --> 00:23:28,830 Mas a maior implicação é que, sim, não é absolutamente um limite, 538 00:23:28,830 --> 00:23:32,470 mesmo se ele não está bem definido, a forma como muitas funções que você pode chamar de uma 539 00:23:32,470 --> 00:23:34,970 programa, quantas vezes uma função pode chamar a si mesma. 540 00:23:34,970 --> 00:23:38,430 Assim, mesmo que fizemos pregar recursão como essa coisa mágica potencialmente um 541 00:23:38,430 --> 00:23:41,870 par de semanas atrás para o sigma função, e quando tivermos os dados 542 00:23:41,870 --> 00:23:45,270 estruturas e CS50, você verá outro aplicações para ele, não é 543 00:23:45,270 --> 00:23:46,500 necessariamente a melhor coisa. 544 00:23:46,500 --> 00:23:50,070 Porque se uma função chama a si mesmo, chama-se, mesmo se não houver uma base 545 00:23:50,070 --> 00:23:54,860 caso, se você não acertar que caso base para 1.000 chamadas ou 10.000 chamadas, por 546 00:23:54,860 --> 00:23:58,800 que o tempo que você pode ter executado fora da sala em seu chamado pilha e sucesso 547 00:23:58,800 --> 00:24:00,400 alguns outros segmentos de memória. 548 00:24:00,400 --> 00:24:03,950 Por isso, também é um projeto de trade-off entre elegância e entre 549 00:24:03,950 --> 00:24:06,920 robustez de seu especial implementação. 550 00:24:06,920 --> 00:24:10,780 >> Portanto, não há outra desvantagem ou Outra pegadinha com o que temos 551 00:24:10,780 --> 00:24:11,720 vindo a fazer até agora. 552 00:24:11,720 --> 00:24:12,980 Quando liguei getstring - 553 00:24:12,980 --> 00:24:15,120 deixe-me voltar em Olá-2. 554 00:24:15,120 --> 00:24:18,170 Repare que eu estou chamando getstring, que está retornando um endereço. 555 00:24:18,170 --> 00:24:20,730 E afirmamos hoje que o endereço é a partir do heap. 556 00:24:20,730 --> 00:24:24,480 E agora eu estou imprimindo a cadeia nesse endereço. 557 00:24:24,480 --> 00:24:27,000 Mas nós nunca chamou a oposto getstring. 558 00:24:27,000 --> 00:24:30,850 Nós nunca tivemos a calll uma função como ungetstring, onde a mão de volta 559 00:24:30,850 --> 00:24:31,610 essa memória. 560 00:24:31,610 --> 00:24:33,250 Mas, francamente, nós provavelmente deveria ter sido. 561 00:24:33,250 --> 00:24:37,390 Porque se continuar perguntando o computador para a memória, por meio de alguém como 562 00:24:37,390 --> 00:24:40,830 getstring mas nunca devolvê-lo, com certeza isso também é obrigado a levar a 563 00:24:40,830 --> 00:24:42,970 problemas em que corremos de memória. 564 00:24:42,970 --> 00:24:46,140 >> E, de fato, podemos olhar para estes problemas com a nova ferramenta, cujo uso 565 00:24:46,140 --> 00:24:47,640 é um pouco enigmática para digitar. 566 00:24:47,640 --> 00:24:50,960 Mas deixe-me ir em frente e molhe-se na tela em apenas um momento. 567 00:24:50,960 --> 00:24:56,940 Eu estou indo para ir em frente e correr Valgrind com parâmetro cujo primeiro comando 568 00:24:56,940 --> 00:25:00,260 argumento de linha é o nome desse programa Olá-2. 569 00:25:00,260 --> 00:25:02,650 E, infelizmente, é saída é atrozmente 570 00:25:02,650 --> 00:25:04,290 complexo sem uma boa razão. 571 00:25:04,290 --> 00:25:06,280 Assim, vemos toda essa confusão. 572 00:25:06,280 --> 00:25:07,530 David é expor meu nome. 573 00:25:07,530 --> 00:25:09,760 Então esse é o programa realmente funcionando. 574 00:25:09,760 --> 00:25:11,180 E agora temos essa saída. 575 00:25:11,180 --> 00:25:13,400 >> Então Valgrind é semelhante em espírito de GDB. 576 00:25:13,400 --> 00:25:14,950 Não é um depurador per se. 577 00:25:14,950 --> 00:25:16,270 Mas é um verificador de memória. 578 00:25:16,270 --> 00:25:20,140 É um programa que vai executar o seu programar e dizer-lhe se você perguntasse a um 579 00:25:20,140 --> 00:25:23,860 computador para a memória e nunca entregou para trás, ou seja, assim que você tem 580 00:25:23,860 --> 00:25:24,570 um vazamento de memória. 581 00:25:24,570 --> 00:25:26,240 E vazamentos de memória tendem a ser ruim. 582 00:25:26,240 --> 00:25:29,120 E você é que os usuários de computadores têm provavelmente sentiu isso, se você tem um 583 00:25:29,120 --> 00:25:30,300 Mac ou um PC. 584 00:25:30,300 --> 00:25:33,730 Alguma vez você já usou o computador para tempo e não reiniciado em vários 585 00:25:33,730 --> 00:25:36,820 dias, ou você só tem um monte de programas em execução, ea coisa maldita 586 00:25:36,820 --> 00:25:42,360 desacelera para uma parada, ou pelo menos é super chato de usar, porque 587 00:25:42,360 --> 00:25:44,350 tudo ficou super lento. 588 00:25:44,350 --> 00:25:46,260 >> Agora que pode ser qualquer número de razões. 589 00:25:46,260 --> 00:25:49,600 Poderia ser um loop infinito, um bug no código de alguém, ou, mais simplesmente, 590 00:25:49,600 --> 00:25:53,250 pode significar que você está usando mais memória, ou tentar, do que o seu 591 00:25:53,250 --> 00:25:54,920 computador realmente tem. 592 00:25:54,920 --> 00:25:57,770 E talvez há um bug em algum programa que continuo a perguntar para a memória. 593 00:25:57,770 --> 00:26:02,480 Browsers há anos eram notórios por este, pedindo mais e mais memória 594 00:26:02,480 --> 00:26:03,870 mas nunca entregá-lo de volta. 595 00:26:03,870 --> 00:26:07,220 Certamente, se você tiver apenas um finito quantidade de memória, você não pode pedir 596 00:26:07,220 --> 00:26:09,990 infinitamente muitas vezes para alguma dessa memória. 597 00:26:09,990 --> 00:26:13,070 >> E assim, o que você vê aqui, embora novamente a saída do Valgrind é 598 00:26:13,070 --> 00:26:17,490 desnecessariamente complexo para olhar em primeiro lugar, esta é a parte interessante. 599 00:26:17,490 --> 00:26:18,890 Heap - 600 00:26:18,890 --> 00:26:20,060 em uso na saída. 601 00:26:20,060 --> 00:26:22,810 Então aqui é o quanto de memória foi em uso na pilha no 602 00:26:22,810 --> 00:26:24,300 tempo meu programa saiu - 603 00:26:24,300 --> 00:26:27,280 aparentemente, seis bytes em um bloco. 604 00:26:27,280 --> 00:26:28,710 Então eu vou para acenar as mãos em que um bloco é. 605 00:26:28,710 --> 00:26:31,270 Pense que é apenas um pedaço, um mais palavra técnica para pedaço. 606 00:26:31,270 --> 00:26:33,140 Mas, seis bytes - 607 00:26:33,140 --> 00:26:36,870 quais são os seis bytes que ainda estavam em uso? 608 00:26:36,870 --> 00:26:37,390 >> Exatamente. 609 00:26:37,390 --> 00:26:41,520 D-A-V-I-D barra invertida zero, cinco letras nome mais o terminador nulo. 610 00:26:41,520 --> 00:26:46,350 Portanto, este programa Valgrind notado que eu perguntou por seis bytes, aparentemente, por 611 00:26:46,350 --> 00:26:48,950 forma de getstring, mas nunca deu-lhes de volta. 612 00:26:48,950 --> 00:26:52,030 E, na verdade, isso não pode ser assim óbvio, se o meu programa não é três 613 00:26:52,030 --> 00:26:53,590 linhas, mas é 300 linhas. 614 00:26:53,590 --> 00:26:56,920 Assim, podemos realmente dar outro comando argumento de linha de Valgrind para 615 00:26:56,920 --> 00:26:58,290 torná-lo mais detalhado. 616 00:26:58,290 --> 00:26:59,760 É um pouco chato para se lembrar. 617 00:26:59,760 --> 00:27:01,580 Mas se eu fizer - 618 00:27:01,580 --> 00:27:01,930 vamos ver. 619 00:27:01,930 --> 00:27:03,540 Vazamento - 620 00:27:03,540 --> 00:27:05,030 Foi ele vazar - 621 00:27:05,030 --> 00:27:07,580 mesmo que eu não me lembro o que é fora de mão. 622 00:27:07,580 --> 00:27:08,550 >> - Vazamento de verificação é igual a integral. 623 00:27:08,550 --> 00:27:10,180 Sim, obrigado. 624 00:27:10,180 --> 00:27:12,520 - Vazamento de verificação é igual a integral. 625 00:27:12,520 --> 00:27:13,800 Enter. 626 00:27:13,800 --> 00:27:14,940 Mesmo programa está sendo executado. 627 00:27:14,940 --> 00:27:16,180 Digite David novamente. 628 00:27:16,180 --> 00:27:17,660 Agora eu vejo um pouco mais detalhadamente. 629 00:27:17,660 --> 00:27:20,890 Mas abaixo o resumo do heap, que é idêntica à de quatro - ah, 630 00:27:20,890 --> 00:27:22,120 isso é bem legal. 631 00:27:22,120 --> 00:27:25,460 Agora Valgrind está realmente procurando um pouco mais no meu código. 632 00:27:25,460 --> 00:27:29,580 E ele está dizendo que, aparentemente, malloc em linha - 633 00:27:29,580 --> 00:27:30,580 que diminuir o zoom. 634 00:27:30,580 --> 00:27:31,980 Na linha - 635 00:27:31,980 --> 00:27:32,930 não vemos que linha é. 636 00:27:32,930 --> 00:27:35,110 Mas malloc é o primeiro culpado. 637 00:27:35,110 --> 00:27:38,630 Há um blog em malloc. 638 00:27:38,630 --> 00:27:39,810 >> Tudo bem? 639 00:27:39,810 --> 00:27:40,450 OK, não. 640 00:27:40,450 --> 00:27:40,940 Certo? 641 00:27:40,940 --> 00:27:42,520 Liguei getString. 642 00:27:42,520 --> 00:27:44,460 getstring aparentemente chama malloc. 643 00:27:44,460 --> 00:27:47,800 Então, qual linha de código é, aparentemente, a culpa por ter 644 00:27:47,800 --> 00:27:49,050 alocados essa memória? 645 00:27:49,050 --> 00:27:51,560 646 00:27:51,560 --> 00:27:55,540 Vamos supor que quem escreveu malloc tem sido em torno de tempo suficiente para que seja 647 00:27:55,540 --> 00:27:56,390 não é culpa deles. 648 00:27:56,390 --> 00:27:57,520 Por isso, é provavelmente a minha. 649 00:27:57,520 --> 00:28:02,000 getString em cs50.c - o que é uma arquivo em algum lugar no computador - 650 00:28:02,000 --> 00:28:05,210 na linha 286 parece ser o culpado. 651 00:28:05,210 --> 00:28:08,140 Agora vamos supor que CS50 tem sido em torno de quantidade razoável de tempo, então 652 00:28:08,140 --> 00:28:09,720 nós também somos infalíveis. 653 00:28:09,720 --> 00:28:14,080 E por isso não é, provavelmente, em getString que o erro se encontra, mas sim em 654 00:28:14,080 --> 00:28:17,810 Olá linha-2.c 18. 655 00:28:17,810 --> 00:28:20,670 >> Então, vamos dar uma olhada o que que a linha 18 era. 656 00:28:20,670 --> 00:28:21,130 Oh. 657 00:28:21,130 --> 00:28:27,130 De alguma forma, esta linha não é necessariamente carrinho, por si só, mas é a razão 658 00:28:27,130 --> 00:28:28,630 por trás desse vazamento de memória. 659 00:28:28,630 --> 00:28:32,140 Tão super simples, o que faria intuitivamente ser a solução aqui? 660 00:28:32,140 --> 00:28:34,710 Se nós estamos pedindo para a memória, nunca foram dando-lhe de volta, o que parece ser um 661 00:28:34,710 --> 00:28:37,940 problema, porque ao longo do tempo o meu computador pode ficar sem memória, pode diminuir 662 00:28:37,940 --> 00:28:42,110 para baixo, coisas ruins podem acontecer, bem, qual é a solução simples e intuitiva? 663 00:28:42,110 --> 00:28:43,140 Basta dar-lhe de volta. 664 00:28:43,140 --> 00:28:44,770 >> Como você liberar essa memória? 665 00:28:44,770 --> 00:28:49,970 Bem, felizmente, é muito simples apenas para dizer o nome livre. 666 00:28:49,970 --> 00:28:51,260 E nós nunca fiz isso antes. 667 00:28:51,260 --> 00:28:55,890 Mas você pode pensar essencialmente de livre como o oposto do malloc. 668 00:28:55,890 --> 00:28:58,030 livre é o oposto do alocação de memória. 669 00:28:58,030 --> 00:28:59,540 Então, agora deixe-me recompilar isso. 670 00:28:59,540 --> 00:29:02,050 Faça Olá-2. 671 00:29:02,050 --> 00:29:04,620 Deixe-me executá-lo novamente. Olá-2 David. 672 00:29:04,620 --> 00:29:07,290 Assim, parece que trabalhar em exatamente da mesma maneira. 673 00:29:07,290 --> 00:29:11,180 Mas se eu voltar para Valgrind e re-executar esse mesmo comando no meu recém- 674 00:29:11,180 --> 00:29:14,720 compilado programa, digitando em meu nome como antes - 675 00:29:14,720 --> 00:29:15,370 Nice. 676 00:29:15,370 --> 00:29:16,760 Resumo Heap - 677 00:29:16,760 --> 00:29:17,740 em uso na saída - 678 00:29:17,740 --> 00:29:19,370 zero bytes, em blocos zero. 679 00:29:19,370 --> 00:29:21,840 E isso é super legal, todos blocos de pilha foram libertados. 680 00:29:21,840 --> 00:29:23,480 Sem vazamentos são possíveis. 681 00:29:23,480 --> 00:29:27,200 >> Então, chegando-se, não com Problema Set 4, mas com Problem Set 5, as forense 682 00:29:27,200 --> 00:29:30,740 e para a frente, isso também vai se tornar um medida da justeza de sua 683 00:29:30,740 --> 00:29:33,630 programa, se você tem ou não ou não tem vazamentos de memória. 684 00:29:33,630 --> 00:29:36,900 Mas, felizmente, não só você pode raciocinar através deles, intuitivamente, que 685 00:29:36,900 --> 00:29:40,430 é, sem dúvida, mais fácil para pequenos programas mas mais difícil para programas maiores, 686 00:29:40,430 --> 00:29:43,860 Valgrind, para esses programas maiores, pode ajudar a identificar 687 00:29:43,860 --> 00:29:45,360 o problema particular. 688 00:29:45,360 --> 00:29:47,500 >> Mas há um outro problema que possa surgir. 689 00:29:47,500 --> 00:29:51,245 Deixe-me abrir este arquivo aqui, que é, mais uma vez, um exemplo um tanto simples. 690 00:29:51,245 --> 00:29:53,760 Mas vamos nos concentrar no que este programa faz. 691 00:29:53,760 --> 00:29:55,190 Isto é chamado memory.c. 692 00:29:55,190 --> 00:29:58,380 Vamos postar mais tarde hoje no zip do código-fonte de hoje. 693 00:29:58,380 --> 00:30:01,610 E notem que eu tenho uma função chamada f que não recebe argumentos e 694 00:30:01,610 --> 00:30:02,800 retorna nada. 695 00:30:02,800 --> 00:30:07,240 Na linha 20, eu estou aparentemente declarar uma ponteiro para um int e chamando-x. 696 00:30:07,240 --> 00:30:09,570 Estou atribuindo é o retorno valor de malloc. 697 00:30:09,570 --> 00:30:14,590 E só para ficar claro, quantos bytes sou Eu provavelmente voltando de malloc 698 00:30:14,590 --> 00:30:17,080 nesta situação? 699 00:30:17,080 --> 00:30:18,040 >> Provavelmente 40. 700 00:30:18,040 --> 00:30:18,840 Onde você tirou isso? 701 00:30:18,840 --> 00:30:22,410 Bem, se você se lembra que um int é muitas vezes 4 bytes, pelo menos é na 702 00:30:22,410 --> 00:30:25,110 aparelho, 10 vezes 4 é, obviamente, 40. 703 00:30:25,110 --> 00:30:28,920 Então malloc está retornando um endereço de um bloco de memória e armazenamento que 704 00:30:28,920 --> 00:30:30,800 resolver em última instância, x. 705 00:30:30,800 --> 00:30:32,570 Então, para ser claro, o que então está acontecendo? 706 00:30:32,570 --> 00:30:34,990 Bem, deixe-me voltar a nossa imagem aqui. 707 00:30:34,990 --> 00:30:38,150 Deixe-me não apenas tirar do fundo do meu memória do computador, deixe-me ir em frente e 708 00:30:38,150 --> 00:30:42,990 tirar todo o retângulo que representa toda a minha RAM. 709 00:30:42,990 --> 00:30:44,790 >> Vamos dizer que a pilha É na parte inferior. 710 00:30:44,790 --> 00:30:47,010 E há um segmento de texto em os dados não inicializados. 711 00:30:47,010 --> 00:30:49,880 Mas eu só vou abstracto, aquelas outras coisas como ponto de distância, dot dot. 712 00:30:49,880 --> 00:30:53,470 Eu estou indo só para se referir a este como a pilha na parte superior. 713 00:30:53,470 --> 00:30:57,070 E, em seguida, na parte inferior da imagem, para representar o principal, eu vou 714 00:30:57,070 --> 00:30:59,880 para dar-lhe uma memória fatias na pilha. 715 00:30:59,880 --> 00:31:03,150 Para f, eu vou dar-lhe uma fatia de memória na pilha. 716 00:31:03,150 --> 00:31:05,140 Agora, eu tenho que consultar meu código fonte novamente. 717 00:31:05,140 --> 00:31:07,170 Quais são as variáveis ​​locais para o principal? 718 00:31:07,170 --> 00:31:10,710 Aparentemente nada, então essa fatia é efetivamente vazio ou nem tão grande 719 00:31:10,710 --> 00:31:11,600 como eu desenhei isso. 720 00:31:11,600 --> 00:31:15,730 Mas, na f, eu tenho uma variável local, que é chamado de x. 721 00:31:15,730 --> 00:31:20,410 Então, eu estou indo para ir em frente e dar f um bloco de memória, chamando-x. 722 00:31:20,410 --> 00:31:24,680 >> E agora malloc de 10 vezes 4, Então malloc 40, onde está o 723 00:31:24,680 --> 00:31:25,430 memória vem? 724 00:31:25,430 --> 00:31:27,530 Nós não temos tirado uma foto como este antes. 725 00:31:27,530 --> 00:31:31,140 Mas vamos supor que é efetivamente vindo aqui, então um, 726 00:31:31,140 --> 00:31:33,170 dois, três, quatro, cinco. 727 00:31:33,170 --> 00:31:34,680 E agora eu preciso de 40 deles. 728 00:31:34,680 --> 00:31:37,540 Então eu vou fazer ponto, ponto, ponto de sugerir que há ainda mais memória 729 00:31:37,540 --> 00:31:39,350 voltando do heap. 730 00:31:39,350 --> 00:31:40,710 Agora, qual é o endereço? 731 00:31:40,710 --> 00:31:42,620 Vamos escolher o nosso arbitrária abordar como sempre - 732 00:31:42,620 --> 00:31:46,310 Ox123, embora ele provavelmente vai ser algo completamente diferente. 733 00:31:46,310 --> 00:31:50,420 Esse é o endereço do primeiro byte no memória que eu estou pedindo para malloc. 734 00:31:50,420 --> 00:31:53,630 >> Assim, em breve, uma vez que a linha 20 é executada, o que é literalmente 735 00:31:53,630 --> 00:31:57,170 armazenado dentro de x aqui? 736 00:31:57,170 --> 00:31:58,730 Ox123. 737 00:31:58,730 --> 00:32:00,370 Ox123. 738 00:32:00,370 --> 00:32:01,550 E o boi é desinteressante. 739 00:32:01,550 --> 00:32:03,200 Significa apenas que aqui está um número hexadecimal. 740 00:32:03,200 --> 00:32:06,490 Mas o que é fundamental é que o que eu tenho loja em x, o que é uma variável local. 741 00:32:06,490 --> 00:32:10,260 Mas seu tipo de dados, uma vez mais, é um endereço de um int. 742 00:32:10,260 --> 00:32:12,710 Bem, eu estou indo para armazenar Ox123. 743 00:32:12,710 --> 00:32:16,610 Mas, novamente, se isso é um pouco demais desnecessariamente complicado, se eu rolar 744 00:32:16,610 --> 00:32:21,490 para trás, podemos abstrair esta muito longe razoável e apenas dizer que x é um 745 00:32:21,490 --> 00:32:23,910 ponteiro para esse pedaço de memória. 746 00:32:23,910 --> 00:32:24,070 >> OK. 747 00:32:24,070 --> 00:32:26,230 Agora, a questão em apreço é o seguinte - 748 00:32:26,230 --> 00:32:29,910 linha 21, ao que parece, é buggy. 749 00:32:29,910 --> 00:32:31,160 Por quê? 750 00:32:31,160 --> 00:32:34,890 751 00:32:34,890 --> 00:32:36,930 >> Desculpe? 752 00:32:36,930 --> 00:32:38,640 Ele não tem - 753 00:32:38,640 --> 00:32:40,390 dizer que uma vez mais. 754 00:32:40,390 --> 00:32:41,240 Bem, isso não acontece gratuitamente. 755 00:32:41,240 --> 00:32:42,350 Então esse é o segundo, mas. 756 00:32:42,350 --> 00:32:45,000 Portanto, há um outro, mas especificamente na linha 21. 757 00:32:45,000 --> 00:32:49,480 758 00:32:49,480 --> 00:32:50,040 >> Exatamente. 759 00:32:50,040 --> 00:32:54,980 Este simples linha de código é apenas uma buffer overflow, uma saturação de buffer. 760 00:32:54,980 --> 00:32:57,050 Um buffer significa apenas um pedaço da memória. 761 00:32:57,050 --> 00:33:01,520 Mas esse pedaço de memória é de tamanho 10, 10 inteiros, o que significa que se 762 00:33:01,520 --> 00:33:05,350 índice nele usando o açúcar sintático de notação de matriz, a praça 763 00:33:05,350 --> 00:33:09,220 parênteses, você tem acesso a x suporte 0 x suporte 1 x, 764 00:33:09,220 --> 00:33:10,390 suporte de ponto, ponto, ponto. 765 00:33:10,390 --> 00:33:13,270 x suporte 9 é o maior deles. 766 00:33:13,270 --> 00:33:17,680 Então, se eu fizer x suporte de 10, onde Na verdade, estou indo na memória? 767 00:33:17,680 --> 00:33:19,120 >> Bem, se eu tiver 10 int - 768 00:33:19,120 --> 00:33:21,070 vamos realmente tirar tudo destes aqui. 769 00:33:21,070 --> 00:33:22,700 Então, essa foi a primeira de cinco anos. 770 00:33:22,700 --> 00:33:24,660 Aqui estão os outros cinco inteiros. 771 00:33:24,660 --> 00:33:29,580 Então x 0 suporte está aqui. x suporte 1 é aqui. x suporte 9 é aqui. x suporte 772 00:33:29,580 --> 00:33:37,960 10 está aqui, o que significa que eu estou dizendo, na linha 21, o computador de inserir a 773 00:33:37,960 --> 00:33:39,400 número para onde? 774 00:33:39,400 --> 00:33:42,010 O número 0 para onde? 775 00:33:42,010 --> 00:33:43,380 Bem, é 0, sim. 776 00:33:43,380 --> 00:33:45,460 Mas só o fato de que sua 0 é uma espécie de coincidência. 777 00:33:45,460 --> 00:33:47,140 Poderia ser o número 50, para todos nós nos importamos. 778 00:33:47,140 --> 00:33:50,480 Mas estamos tentando colocá-lo no suporte x 10, que é o local onde esta 779 00:33:50,480 --> 00:33:53,700 ponto de interrogação é elaborada, que não é uma coisa boa. 780 00:33:53,700 --> 00:33:57,070 Este programa pode muito bem falhar como resultado. 781 00:33:57,070 --> 00:33:59,400 >> Agora, vamos em frente e ver se isso é, na verdade, o que acontece. 782 00:33:59,400 --> 00:34:02,600 Fazer memória, uma vez que o arquivo é chamado memory.c. 783 00:34:02,600 --> 00:34:05,950 Vamos em frente e correr a memória do programa. 784 00:34:05,950 --> 00:34:08,239 Então, nós tivemos muita sorte, na verdade, ao que parece. 785 00:34:08,239 --> 00:34:09,340 Nós tivemos sorte. 786 00:34:09,340 --> 00:34:11,060 Mas vamos ver se agora executar Valgrind. 787 00:34:11,060 --> 00:34:14,170 À primeira vista, o meu programa pode parece ser perfeitamente correcto. 788 00:34:14,170 --> 00:34:18,010 Mas deixe-me correr Valgrind com o - Vazamento de verificação é igual a plena memória. 789 00:34:18,010 --> 00:34:20,110 >> E agora, quando eu executar este - 790 00:34:20,110 --> 00:34:21,030 interessante. 791 00:34:21,030 --> 00:34:26,800 Inválido escrever de tamanho 4 a linha 21 do memory.c. 792 00:34:26,800 --> 00:34:29,284 Linha 21 do memory.c é qual? 793 00:34:29,284 --> 00:34:30,340 Oh, interessante. 794 00:34:30,340 --> 00:34:31,080 Mas espere. 795 00:34:31,080 --> 00:34:32,389 Tamanho 4, o que é que se refere? 796 00:34:32,389 --> 00:34:34,969 Eu só fiz uma gravação, mas é do tamanho 4. 797 00:34:34,969 --> 00:34:36,889 Por que é 4? 798 00:34:36,889 --> 00:34:39,280 É porque é um int, que é, outra vez, quatro bytes. 799 00:34:39,280 --> 00:34:42,510 Então Valgrind encontrado um bug que eu, olhando para o meu código, não o fizeram. 800 00:34:42,510 --> 00:34:45,040 E talvez o seu TF iria ou não. 801 00:34:45,040 --> 00:34:48,469 Mas o que Valgrind com certeza descobriu que fizemos um erro lá, mesmo 802 00:34:48,469 --> 00:34:52,719 embora nós tivemos muita sorte, eo computador decidiu, eh, eu não vou falhar 803 00:34:52,719 --> 00:34:57,470 só porque você tocou em um byte, uma o valor do int de memória que você não fez 804 00:34:57,470 --> 00:34:58,550 realmente possui. 805 00:34:58,550 --> 00:35:00,380 >> Bem, o que mais é buggy aqui. 806 00:35:00,380 --> 00:35:01,180 Endereço - 807 00:35:01,180 --> 00:35:03,190 este é um endereço de vista louco em hexadecimal. 808 00:35:03,190 --> 00:35:06,890 Isso significa apenas que em algum lugar na pilha é zero bytes após um bloco de tamanho 40 809 00:35:06,890 --> 00:35:07,620 é alocado. 810 00:35:07,620 --> 00:35:10,610 Deixe-me afastar aqui e ver se isso é um pouco mais útil. 811 00:35:10,610 --> 00:35:11,410 Interessante. 812 00:35:11,410 --> 00:35:15,600 40 bytes são definitivamente perdidos no registro de uma perda de 1. 813 00:35:15,600 --> 00:35:17,840 Novamente, mais palavras do que é útil aqui. 814 00:35:17,840 --> 00:35:21,350 Mas, com base nas linhas destacadas, onde eu deveria focar meu 815 00:35:21,350 --> 00:35:24,070 atenção para um outro bug? 816 00:35:24,070 --> 00:35:26,570 Parece que a linha 20 do memory.c. 817 00:35:26,570 --> 00:35:30,990 >> Então, se nós voltar para a linha 20, que é o aquele que você identificou anteriormente. 818 00:35:30,990 --> 00:35:33,030 E isso não é necessariamente buggy. 819 00:35:33,030 --> 00:35:35,160 Mas nós temos este inverteu seus efeitos. 820 00:35:35,160 --> 00:35:38,790 Então, como faço para corrigir pelo menos um desses erros? 821 00:35:38,790 --> 00:35:42,240 O que eu poderia fazer depois linha 21? 822 00:35:42,240 --> 00:35:47,110 Eu poderia fazer livre de x, por isso é para dar a volta essa memória. 823 00:35:47,110 --> 00:35:49,230 E como faço para corrigir este erro? 824 00:35:49,230 --> 00:35:52,120 Eu definitivamente deveria ir mais longe do que 0. 825 00:35:52,120 --> 00:35:53,670 Então deixe-me tentar e re-executar esta. 826 00:35:53,670 --> 00:35:56,080 Desculpe, definitivamente não mais do que 9. 827 00:35:56,080 --> 00:35:57,510 Fazer memória. 828 00:35:57,510 --> 00:36:00,650 Deixe-me reprise Valgrind em uma janela maior. 829 00:36:00,650 --> 00:36:01,580 E agora olhe. 830 00:36:01,580 --> 00:36:02,250 Nice. 831 00:36:02,250 --> 00:36:03,270 Todos os blocos de heap foram libertados. 832 00:36:03,270 --> 00:36:04,270 Sem vazamentos são possíveis. 833 00:36:04,270 --> 00:36:07,520 E lá em cima aqui, não há nenhuma menção mais do direito inválido. 834 00:36:07,520 --> 00:36:09,820 >> Só para ficar ganancioso, e vamos ver se outra demonstração 835 00:36:09,820 --> 00:36:11,050 não vai tão pretendido - 836 00:36:11,050 --> 00:36:12,560 Eu tive sorte de um momento atrás. 837 00:36:12,560 --> 00:36:15,530 E o fato de que este é 0 é talvez desnecessariamente enganosa. 838 00:36:15,530 --> 00:36:20,650 Vamos fazer 50 anos, um tanto arbitrária número, fazer memória memória dot slash - 839 00:36:20,650 --> 00:36:21,410 ainda ter sorte. 840 00:36:21,410 --> 00:36:22,510 Nada está falhando. 841 00:36:22,510 --> 00:36:26,150 Suponha que eu simplesmente fazer algo realmente tolo, e eu faço 100. 842 00:36:26,150 --> 00:36:30,360 Deixe-me refazer a memória, dot memória slash - 843 00:36:30,360 --> 00:36:31,075 teve sorte novamente. 844 00:36:31,075 --> 00:36:32,800 Como cerca de 1000? 845 00:36:32,800 --> 00:36:35,370 ints além de, aproximadamente, onde eu deveria estar? 846 00:36:35,370 --> 00:36:37,410 Fazer memória - 847 00:36:37,410 --> 00:36:38,570 caramba. 848 00:36:38,570 --> 00:36:39,920 >> [Risos] 849 00:36:39,920 --> 00:36:41,270 >> OK. 850 00:36:41,270 --> 00:36:43,920 Não vamos mexer mais. 851 00:36:43,920 --> 00:36:45,120 Reprise de memória. 852 00:36:45,120 --> 00:36:45,840 Lá vamos nós. 853 00:36:45,840 --> 00:36:46,410 Tudo bem. 854 00:36:46,410 --> 00:36:52,500 Então, aparentemente, você índice 100.000 ints além de onde deveria ter sido em 855 00:36:52,500 --> 00:36:54,410 memória, coisas ruins acontecem. 856 00:36:54,410 --> 00:36:56,430 Assim, este não é obviamente , uma regra rápida duro. 857 00:36:56,430 --> 00:36:58,190 Eu era uma espécie de utilizar julgamento e erro para chegar lá. 858 00:36:58,190 --> 00:37:02,230 Mas isso é porque, longa história curta, memória do computador também é dividido 859 00:37:02,230 --> 00:37:03,580 para estes segmentos chamados coisas. 860 00:37:03,580 --> 00:37:07,260 E, às vezes, o computador realmente deu-lhe um pouco mais de memória 861 00:37:07,260 --> 00:37:08,400 do que você pedir. 862 00:37:08,400 --> 00:37:12,170 Mas, para a eficiência, é apenas mais fácil obter mais memória, mas apenas dizer-lhe 863 00:37:12,170 --> 00:37:13,780 que você está recebendo uma parte dele. 864 00:37:13,780 --> 00:37:16,370 >> E se você tiver sorte, às vezes, portanto, você pode ser capaz de tocar 865 00:37:16,370 --> 00:37:17,795 memória que não pertence a você. 866 00:37:17,795 --> 00:37:21,860 Você não tem nenhuma garantia de que o valor você colocar lá vai ficar lá, porque 867 00:37:21,860 --> 00:37:25,080 o computador ainda pensa que não é seu, mas não é necessariamente vai 868 00:37:25,080 --> 00:37:29,910 para atingir um outro segmento de memória no computador e induzir a um erro como 869 00:37:29,910 --> 00:37:31,710 este aqui. 870 00:37:31,710 --> 00:37:32,060 Tudo bem. 871 00:37:32,060 --> 00:37:37,240 Todas as perguntas, em seguida, sobre a memória? 872 00:37:37,240 --> 00:37:37,590 >> Tudo bem. 873 00:37:37,590 --> 00:37:40,610 Vamos dar uma olhada aqui, então, a algo que temos vindo a tomar para 874 00:37:40,610 --> 00:37:48,361 concedido por algum tempo, o que É neste arquivo chamado cs50.h. 875 00:37:48,361 --> 00:37:49,420 Portanto, este é um arquivo. 876 00:37:49,420 --> 00:37:51,130 Estes são apenas um bando inteiro dos comentários em cima. 877 00:37:51,130 --> 00:37:53,900 E você pode ter olhado para isso se você remexia no aparelho. 878 00:37:53,900 --> 00:37:57,000 Mas verifica-se que o tempo todo, quando nós costumávamos usar string como um 879 00:37:57,000 --> 00:38:01,130 sinônimo, o meio pelo qual nós declaramos que era sinônimo com este 880 00:38:01,130 --> 00:38:03,990 palavra-chave typedef, para definição do tipo. 881 00:38:03,990 --> 00:38:07,500 E nós estamos dizendo essencialmente, fazer amarrar um sinônimo para a estrela de char. 882 00:38:07,500 --> 00:38:11,190 Que os meios pelos quais a pilha criou essas rodinhas conhecidos como 883 00:38:11,190 --> 00:38:12,040 a string. 884 00:38:12,040 --> 00:38:14,830 >> Agora aqui é apenas um protótipo para getchar. 885 00:38:14,830 --> 00:38:17,350 Poderíamos tê-lo visto antes, mas que é na verdade o que ele faz. getchar 886 00:38:17,350 --> 00:38:19,070 não tem argumentos, retorna um char. 887 00:38:19,070 --> 00:38:21,340 GetDouble não tem argumentos, retorna um double. 888 00:38:21,340 --> 00:38:24,440 GetFloat não recebe argumentos, retorna uma bóia, e assim por diante. 889 00:38:24,440 --> 00:38:27,270 getInt está aqui. getlonglong é aqui. 890 00:38:27,270 --> 00:38:28,820 E getstring está aqui. 891 00:38:28,820 --> 00:38:29,420 E é isso. 892 00:38:29,420 --> 00:38:33,080 Esta linha roxa é outro pré-processador directiva por causa do 893 00:38:33,080 --> 00:38:35,550 hashtag no início do mesmo. 894 00:38:35,550 --> 00:38:35,870 >> Tudo bem. 895 00:38:35,870 --> 00:38:38,380 Então, agora deixe-me entrar em cs50.c. 896 00:38:38,380 --> 00:38:40,400 E não vamos falar muito sobre isso. 897 00:38:40,400 --> 00:38:43,280 Mas para lhe dar um vislumbre do que está vem acontecendo tudo isso 898 00:38:43,280 --> 00:38:46,434 tempo, deixe-me ir para - 899 00:38:46,434 --> 00:38:48,250 vamos fazer getchar. 900 00:38:48,250 --> 00:38:51,050 Então getchar é mais comentários. 901 00:38:51,050 --> 00:38:52,060 Mas parece que isso. 902 00:38:52,060 --> 00:38:54,800 Portanto, esta é a função real getchar que temos sido 903 00:38:54,800 --> 00:38:56,055 tendo por certo existe. 904 00:38:56,055 --> 00:38:59,370 E mesmo que não use este que, muitas vezes, se alguma vez, é pelo menos 905 00:38:59,370 --> 00:39:00,470 relativamente simples. 906 00:39:00,470 --> 00:39:02,580 Então, vale a pena dar uma rápida olhada aqui. 907 00:39:02,580 --> 00:39:06,540 >> Então getchar tem um loop infinito, deliberadamente de modo aparentemente. 908 00:39:06,540 --> 00:39:10,050 Em seguida, chama - e este é um tipo de bom reutilização de código que nos escreveu. 909 00:39:10,050 --> 00:39:11,220 Ele chama getstring. 910 00:39:11,220 --> 00:39:12,460 Porque o que faz significa obter um char? 911 00:39:12,460 --> 00:39:14,730 Bem, assim como você pode tentar obter uma linha inteira de texto do usuário e 912 00:39:14,730 --> 00:39:16,940 em seguida, basta olhar para um desses caracteres. 913 00:39:16,940 --> 00:39:19,170 Na linha 60, aqui está um pouco pouco mais de um teste de sanidade. 914 00:39:19,170 --> 00:39:21,610 Se getstring retornou nulo, não vamos continuar. 915 00:39:21,610 --> 00:39:22,820 Algo deu errado. 916 00:39:22,820 --> 00:39:28,120 >> Agora, isso é um pouco chato, mas convencional em C. carbonizar max provavelmente 917 00:39:28,120 --> 00:39:29,960 o que representa apenas com base em seu nome? 918 00:39:29,960 --> 00:39:31,670 É uma constante. 919 00:39:31,670 --> 00:39:36,040 É como se o valor numérico do maior de char você pode representar com 920 00:39:36,040 --> 00:39:40,370 uma mordida, o que provavelmente é o número 255, que é o maior número que 921 00:39:40,370 --> 00:39:42,720 representam oito bits, a partir de zero. 922 00:39:42,720 --> 00:39:47,460 Então eu usar isso, nesta função, quando escrever este código, só porque 923 00:39:47,460 --> 00:39:51,753 se algo der errado em getchar mas seu propósito na vida é voltar a 924 00:39:51,753 --> 00:39:54,830 char, você precisa de alguma forma ser capaz para sinalizar ao usuário que 925 00:39:54,830 --> 00:39:55,840 algo deu errado. 926 00:39:55,840 --> 00:39:56,970 Nós não podemos retornar nulo. 927 00:39:56,970 --> 00:39:58,480 Acontece que nulo é um ponteiro. 928 00:39:58,480 --> 00:40:01,030 E, novamente, getchar tem para retornar um char. 929 00:40:01,030 --> 00:40:04,760 >> Assim, a convenção, se algo der errado, é você, o programador, ou em 930 00:40:04,760 --> 00:40:08,160 Neste caso, me com a biblioteca, eu tive a apenas decidir arbitrariamente, se 931 00:40:08,160 --> 00:40:12,230 algo der errado, eu vou retornar o número 255, o que é verdadeiramente 932 00:40:12,230 --> 00:40:17,240 significa que não pode, o usuário não pode digitar o caracter representado pela 933 00:40:17,240 --> 00:40:21,410 número 255, porque tivemos um roubá-lo como o chamado valor de sentinela para 934 00:40:21,410 --> 00:40:23,410 representam um problema. 935 00:40:23,410 --> 00:40:27,010 Agora, descobre-se que o caráter 255 não é algo que você pode digitar no 936 00:40:27,010 --> 00:40:28,380 seu teclado, por isso não é grande coisa. 937 00:40:28,380 --> 00:40:30,910 O usuário não percebe que Eu roubei esse personagem. 938 00:40:30,910 --> 00:40:34,620 Mas se você já viu nas páginas de homem em uma sistema de computador alguma referência a um 939 00:40:34,620 --> 00:40:38,560 todas as tampas constante como este que diz: em casos de erro esta força constante 940 00:40:38,560 --> 00:40:42,720 ser devolvido, isso é tudo que algum ser humano fez anos atrás, foi decidido arbitrariamente 941 00:40:42,720 --> 00:40:45,680 retornar esse valor especial e chamá-lo de uma constante no caso 942 00:40:45,680 --> 00:40:46,840 algo der errado. 943 00:40:46,840 --> 00:40:48,580 >> Agora a mágica acontece por aqui. 944 00:40:48,580 --> 00:40:52,600 Em primeiro lugar, eu estou declarando na linha 67 dois personagens, C1 e C2. 945 00:40:52,600 --> 00:40:57,080 E então, em linha 68, há realmente uma linha de código que é uma reminiscência de 946 00:40:57,080 --> 00:41:01,140 nosso amigo printf, uma vez que tem por cento Cs entre aspas. 947 00:41:01,140 --> 00:41:06,490 Mas note o que está acontecendo aqui. sscanf significa varredura string - 948 00:41:06,490 --> 00:41:11,690 significa digitalizar um formato string, sscanf ergo. 949 00:41:11,690 --> 00:41:12,590 O que significa isso? 950 00:41:12,590 --> 00:41:16,310 Isso significa que você passa para sscanf uma string. 951 00:41:16,310 --> 00:41:18,420 E linha é o que o usuário digita pol 952 00:41:18,420 --> 00:41:23,520 Você passa a sscanf uma seqüência de formato como isso que diz a scanf quais são 953 00:41:23,520 --> 00:41:25,870 Você está esperando que o usuário tenha digitado dentro 954 00:41:25,870 --> 00:41:29,730 Você, então, passar-nos os endereços de dois pedaços de memória, neste caso, 955 00:41:29,730 --> 00:41:31,150 porque eu tenho dois espaços reservados. 956 00:41:31,150 --> 00:41:34,610 Então eu vou dar-lhe o endereço de C1 e o endereço de C2. 957 00:41:34,610 --> 00:41:37,700 >> E lembrar que você dá em função da endereço de alguma variável, o que é 958 00:41:37,700 --> 00:41:38,950 a implicação? 959 00:41:38,950 --> 00:41:41,400 960 00:41:41,400 --> 00:41:45,050 O que pode fazer essa função, como resultado de dar-lhe o endereço de um 961 00:41:45,050 --> 00:41:48,170 variável, ao contrário a própria variável? 962 00:41:48,170 --> 00:41:49,450 É possível alterá-lo, certo? 963 00:41:49,450 --> 00:41:53,250 Se você tivesse alguém um mapa para a física endereço, eles podem ir lá e fazer 964 00:41:53,250 --> 00:41:54,750 o que eles querem naquele endereço. 965 00:41:54,750 --> 00:41:55,800 A mesma idéia aqui. 966 00:41:55,800 --> 00:41:59,950 Se passarmos a sscanf, o endereço de dois pedaços de memória, mesmo estes pequenos 967 00:41:59,950 --> 00:42:03,585 pequenos pedaços de memória, C1 e C2, mas nós dizemos que o endereço deles, 968 00:42:03,585 --> 00:42:05,170 sscanf pode mudá-lo. 969 00:42:05,170 --> 00:42:08,530 >> Assim, o propósito de sscanf na vida, se lermos a página principal, é ler o que o 970 00:42:08,530 --> 00:42:13,420 usuário digitou, esperança para que o usuário tenha digitados em um personagem e talvez 971 00:42:13,420 --> 00:42:16,470 outro personagem, e tudo o que o usuário digitado, o primeiro personagem vai 972 00:42:16,470 --> 00:42:19,310 aqui, o segundo personagem vai aqui. 973 00:42:19,310 --> 00:42:22,470 Agora, como um aparte, isso, e se fosse só sei que a partir da documentação, 974 00:42:22,470 --> 00:42:25,570 o fato de eu colocar um espaço em branco lá Significa apenas que eu não me importo se 975 00:42:25,570 --> 00:42:28,440 o usuário pressiona a barra de espaço um pouco vezes antes que ele ou ela tem um 976 00:42:28,440 --> 00:42:30,400 personagem, eu vou ignorar qualquer espaço em branco. 977 00:42:30,400 --> 00:42:32,510 De modo que, eu sei que a partir de a documentação. 978 00:42:32,510 --> 00:42:36,570 >> O fato de que há uma segunda% c seguido de espaço em branco é realmente 979 00:42:36,570 --> 00:42:37,410 deliberada. 980 00:42:37,410 --> 00:42:41,190 Eu quero ser capaz de detectar se o usuário asneira ou não cooperar. 981 00:42:41,190 --> 00:42:45,630 Então, eu estou esperando que o usuário só digitado em um personagem, portanto, eu estou esperando 982 00:42:45,630 --> 00:42:50,640 sscanf que só vai voltar a valor 1, porque, mais uma vez, se eu ler 983 00:42:50,640 --> 00:42:55,400 a documentação, o propósito de sscanf em vida é devolver ao número de 984 00:42:55,400 --> 00:42:59,170 As variáveis ​​que foram preenchidos com a entrada do usuário. 985 00:42:59,170 --> 00:43:02,270 >> Passei em duas variáveis endereços, C1 e C2. 986 00:43:02,270 --> 00:43:06,420 Espero, porém, que apenas uma das deles é morto, porque se sscanf 987 00:43:06,420 --> 00:43:11,130 retorna 2, o que presumivelmente a implicação lógica? 988 00:43:11,130 --> 00:43:14,600 Que o usuário não apenas dar-me uma personagem como eu disse a ele ou ela. 989 00:43:14,600 --> 00:43:17,860 Eles provavelmente digitado no menos dois caracteres. 990 00:43:17,860 --> 00:43:22,430 Então, se eu, em vez não teve a segunda % C, eu só tinha um, que 991 00:43:22,430 --> 00:43:25,370 francamente, seria mais intuitivo abordagem, acho que a primeira vista, 992 00:43:25,370 --> 00:43:30,220 você não vai ser capaz de detectar se o usuário foi dando-lhe mais 993 00:43:30,220 --> 00:43:31,780 input do que você realmente queria. 994 00:43:31,780 --> 00:43:34,100 Portanto, esta é uma forma implícita de verificação de erros. 995 00:43:34,100 --> 00:43:35,640 >> Mas note que eu faço aqui. 996 00:43:35,640 --> 00:43:39,970 Uma vez que eu tenho certeza que o usuário me deu um personagem, eu liberar a linha, fazendo 997 00:43:39,970 --> 00:43:44,450 o oposto de getstring, que por sua vez usa malloc, e depois eu volto 998 00:43:44,450 --> 00:43:51,030 C1, o personagem que eu esperava que o fornecido pelo usuário e somente fornecido. 999 00:43:51,030 --> 00:43:54,680 Então, um rápido relance apenas, mas qualquer dúvida sobre getchar? 1000 00:43:54,680 --> 00:43:57,450 1001 00:43:57,450 --> 00:43:59,590 Nós vamos voltar a alguns dos outros. 1002 00:43:59,590 --> 00:44:03,770 >> Bem, deixe-me ir em frente e fazer isso - Suponha agora, apenas para motivar o nosso 1003 00:44:03,770 --> 00:44:08,910 a discussão de uma semana, mais tempo, esta é um arquivo chamado structs.h. 1004 00:44:08,910 --> 00:44:11,440 E, novamente, esta é apenas uma amostra de algo que está por vir. 1005 00:44:11,440 --> 00:44:13,090 Mas note que um monte isto é comentários. 1006 00:44:13,090 --> 00:44:17,440 Então deixe-me destacar apenas o parte interessante por enquanto. 1007 00:44:17,440 --> 00:44:18,020 typedef - 1008 00:44:18,020 --> 00:44:19,700 há essa mesma palavra-chave novamente. 1009 00:44:19,700 --> 00:44:23,100 typedef que usamos para declarar cadeia como um tipo de dados especial. 1010 00:44:23,100 --> 00:44:27,490 Você pode usar typedef para criar nova marca tipos de dados que não existiam quando 1011 00:44:27,490 --> 00:44:28,570 C foi inventada. 1012 00:44:28,570 --> 00:44:32,520 Por exemplo, int vem com C. carvão vem com C. dupla vem com C. Mas 1013 00:44:32,520 --> 00:44:34,000 não há nenhuma noção de um estudante. 1014 00:44:34,000 --> 00:44:37,230 E ainda seria muito útil para ser capaz de escrever um programa que armazena 1015 00:44:37,230 --> 00:44:40,440 em uma variável, número de identificação do aluno, seu nome, e sua casa. 1016 00:44:40,440 --> 00:44:42,890 Em outras palavras, três pedaços de dados, como um int e um 1017 00:44:42,890 --> 00:44:44,420 corda e outra string. 1018 00:44:44,420 --> 00:44:48,220 >> Com typedef, o que é muito poderoso sobre isso e a palavra-chave para sturct 1019 00:44:48,220 --> 00:44:53,660 estrutura, você, o programador em 2013, pode realmente definir o seu próprio 1020 00:44:53,660 --> 00:44:57,530 tipos de dados que não existiam anos atrás, mas que atendam às suas finalidades. 1021 00:44:57,530 --> 00:45:01,910 E aqui, em linhas 13 a 19, estamos declarando um novo tipo de dados, como 1022 00:45:01,910 --> 00:45:04,320 um int, mas chamando-o de estudante. 1023 00:45:04,320 --> 00:45:09,310 E dentro desta variável vai ser três coisas - um int, string 1024 00:45:09,310 --> 00:45:09,930 e uma corda. 1025 00:45:09,930 --> 00:45:13,040 Então você pode pensar que é realmente aconteceu aqui, mesmo que este é um 1026 00:45:13,040 --> 00:45:17,160 bit de uma simplificação para hoje, um aluno é essencialmente indo 1027 00:45:17,160 --> 00:45:19,450 para ficar assim. 1028 00:45:19,450 --> 00:45:22,580 Que vai ser um pedaço de com uma memória de identificação, um nome 1029 00:45:22,580 --> 00:45:25,580 campo, e um campo de casa. 1030 00:45:25,580 --> 00:45:30,670 E nós vamos ser capazes de usar esses pedaços de memória e acessá-los como se segue. 1031 00:45:30,670 --> 00:45:38,870 >> Se eu entrar em struct0.c, aqui está uma relativamente longo, mas depois de um 1032 00:45:38,870 --> 00:45:42,630 padrão, de código que usa esse novo truque. 1033 00:45:42,630 --> 00:45:45,790 Então, primeiro, deixe-me chamar a sua atenção para as partes interessantes em cima. 1034 00:45:45,790 --> 00:45:49,670 Afiada define três estudantes, declara um constantes chamadas de alunos e cessionários 1035 00:45:49,670 --> 00:45:53,450 ele arbitrariamente o número 3, apenas então eu tenho três alunos que utilizam 1036 00:45:53,450 --> 00:45:54,830 este programa por enquanto. 1037 00:45:54,830 --> 00:45:55,960 Aí vem o principal. 1038 00:45:55,960 --> 00:45:58,860 E note, como faço para declarar uma matriz de estudantes? 1039 00:45:58,860 --> 00:46:00,480 Bem, eu só usar a mesma sintaxe. 1040 00:46:00,480 --> 00:46:02,110 O estudante palavra é, obviamente, nova. 1041 00:46:02,110 --> 00:46:04,790 Mas o estudante, classe, estudantes suporte. 1042 00:46:04,790 --> 00:46:06,720 >> Então, infelizmente, há muito de reutilização de termos aqui. 1043 00:46:06,720 --> 00:46:07,660 Este é apenas um número. 1044 00:46:07,660 --> 00:46:09,040 Então, isso é como dizer que três. 1045 00:46:09,040 --> 00:46:11,430 Classe é apenas o que eu quero para chamar a variável. 1046 00:46:11,430 --> 00:46:12,840 Eu poderia chamá-lo de alunos. 1047 00:46:12,840 --> 00:46:15,880 Mas classe, isto não é uma classe numa orientada a objetos Java tipo de caminho. 1048 00:46:15,880 --> 00:46:17,220 É apenas uma turma de alunos. 1049 00:46:17,220 --> 00:46:20,590 E o tipo de cada elemento de dados nessa matriz é estudante. 1050 00:46:20,590 --> 00:46:23,040 Portanto, este é um pouco diferente e de dizer algo 1051 00:46:23,040 --> 00:46:25,250 assim, é apenas - 1052 00:46:25,250 --> 00:46:29,500 Eu estou dizendo que me dar três alunos e chamar essa classe array. 1053 00:46:29,500 --> 00:46:29,800 >> Tudo bem. 1054 00:46:29,800 --> 00:46:30,680 Ora aqui está uma de quatro loop. 1055 00:46:30,680 --> 00:46:33,480 Familiarizado desse cara - iterate de zero a três, no máximo. 1056 00:46:33,480 --> 00:46:35,160 E aqui está a nova peça de sintaxe. 1057 00:46:35,160 --> 00:46:37,710 O programa vai me pedir, o ser humano, para dar-lhe um estudante 1058 00:46:37,710 --> 00:46:39,200 ID, que é um int. 1059 00:46:39,200 --> 00:46:44,650 E aqui está a sintaxe com a qual você pode armazenar algo no campo ID em 1060 00:46:44,650 --> 00:46:48,630 localização classe suporte I. Então essa sintaxe não é nova. 1061 00:46:48,630 --> 00:46:51,450 Isto significa apenas dar-me a oitava aluno da classe. 1062 00:46:51,450 --> 00:46:52,940 Mas este símbolo é nova. 1063 00:46:52,940 --> 00:46:56,320 Até agora, nós não pode ser usado ponto, pelo menos em um código como este. 1064 00:46:56,320 --> 00:47:01,490 Isto significa ir para a struct conhecido como um estudante e colocar alguma coisa lá. 1065 00:47:01,490 --> 00:47:05,670 Da mesma forma, nesta linha seguinte, 31, ir em frente e colocar o que o usuário digita 1066 00:47:05,670 --> 00:47:10,530 um nome aqui eo que eles fazem para casa, a mesma coisa, vá em frente e 1067 00:47:10,530 --> 00:47:13,230 colocá-lo em. casa. 1068 00:47:13,230 --> 00:47:15,955 >> Então, o que faz este programa finalmente fazer? 1069 00:47:15,955 --> 00:47:17,220 Você pode ver um pouco de provocação lá. 1070 00:47:17,220 --> 00:47:24,780 Deixe-me ir em frente e fazem estruturas 0 dot barra struct 0, ID do aluno 1, 1071 00:47:24,780 --> 00:47:28,250 diz David Mather, estudante ID 2. 1072 00:47:28,250 --> 00:47:32,070 Rob Kirkland, estudante ID 3. 1073 00:47:32,070 --> 00:47:35,010 Lauren Leverit - 1074 00:47:35,010 --> 00:47:38,380 ea única coisa que este programa fez, que é apenas completamente arbitrário, é 1075 00:47:38,380 --> 00:47:40,980 Eu queria fazer alguma coisa com esses dados, agora que eu já nos ensinou como 1076 00:47:40,980 --> 00:47:43,450 usar estruturas, é que eu só tinha este ciclo extra aqui. 1077 00:47:43,450 --> 00:47:45,260 Eu iterar sobre o conjunto de alunos. 1078 00:47:45,260 --> 00:47:49,170 Eu usei o nosso, amigo talvez agora familiar, String de comparação, a stircomp 1079 00:47:49,170 --> 00:47:53,780 cheque é a casa de 8 estudantes igual a Mather? 1080 00:47:53,780 --> 00:47:56,760 E se assim for, basta imprimir algo arbitrariamente gosta, sim, é. 1081 00:47:56,760 --> 00:47:59,430 Mas, novamente, apenas me dando oportunidades de utilizar e reutilizar e 1082 00:47:59,430 --> 00:48:02,270 reutilizar esta nova notação de ponto. 1083 00:48:02,270 --> 00:48:03,250 >> Então, quem se importa, certo? 1084 00:48:03,250 --> 00:48:06,270 Chegando-se com um programa de estudante é um tanto arbitrária, mas acontece 1085 00:48:06,270 --> 00:48:09,800 que podemos fazer coisas úteis com isto, por exemplo, como se segue. 1086 00:48:09,800 --> 00:48:14,600 Esta é uma estrutura muito mais complicada em C. Tem uma dúzia ou mais campos, 1087 00:48:14,600 --> 00:48:15,880 um tanto enigmaticamente chamado. 1088 00:48:15,880 --> 00:48:20,110 Mas se você já ouviu falar de uma gráfica formato de arquivo chamado bitmap, BMP, ele 1089 00:48:20,110 --> 00:48:22,830 Acontece que o formato de arquivo bitmap se parece muito com que este. 1090 00:48:22,830 --> 00:48:24,200 É um pouco cara Smiley estúpido. 1091 00:48:24,200 --> 00:48:27,840 É uma pequena imagem que eu tenho ampliado em muito grande para que eu pudesse ver cada 1092 00:48:27,840 --> 00:48:30,410 dos pontos ou pixels individuais. 1093 00:48:30,410 --> 00:48:33,800 Agora, acontece que pode representar uma ponto preto com, digamos, o número 0. 1094 00:48:33,800 --> 00:48:35,520 E um ponto branco com o número 1. 1095 00:48:35,520 --> 00:48:39,140 >> Portanto, em outras palavras, se você quiser chamar um Rosto sorridente e salvar a imagem em um 1096 00:48:39,140 --> 00:48:42,680 computador, é suficiente para armazenar e zeros aqueles que se parecem com esta, onde, 1097 00:48:42,680 --> 00:48:45,250 mais uma vez, os são brancos e zeros são negros. 1098 00:48:45,250 --> 00:48:48,290 E juntos, se você efetivamente tem um cinge de uns e zeros, você tem um 1099 00:48:48,290 --> 00:48:51,030 grade de pixels, e se você colocar -los, você tem um bonito 1100 00:48:51,030 --> 00:48:52,560 rostinho Smiley. 1101 00:48:52,560 --> 00:48:58,150 Agora, o formato de arquivo de bitmap, BMP, é efetivamente que, sob o capô, 1102 00:48:58,150 --> 00:49:00,970 mas com mais pixels sot que você pode realmente representar as cores. 1103 00:49:00,970 --> 00:49:05,170 >> Mas quando você tem mais sofisticado formatos como JPEG e BMP e GIF 1104 00:49:05,170 --> 00:49:09,360 com o qual você pode estar familiarizado, aqueles arquivos no disco normalmente não só 1105 00:49:09,360 --> 00:49:13,760 tem zeros e uns para os pixels, mas eles têm alguns metadados, bem como - 1106 00:49:13,760 --> 00:49:16,960 meta no sentido de que não é realmente dados, mas é útil para ter. 1107 00:49:16,960 --> 00:49:21,370 Então, esses campos aqui são o que implica, e vamos ver isso com mais detalhe na P-set 1108 00:49:21,370 --> 00:49:25,810 5, que antes dos zeros e uns que representar os pixels de uma imagem, 1109 00:49:25,810 --> 00:49:29,110 há um monte de metadados como o tamanho da imagem e o 1110 00:49:29,110 --> 00:49:30,250 largura da imagem. 1111 00:49:30,250 --> 00:49:32,910 E notem que eu estou arrancando fora de alguns coisas arbitrárias aqui - 1112 00:49:32,910 --> 00:49:34,260 largura e altura. 1113 00:49:34,260 --> 00:49:36,160 Contagem de bits e algumas outras coisas. 1114 00:49:36,160 --> 00:49:37,840 Portanto, há alguns metadados em um arquivo. 1115 00:49:37,840 --> 00:49:41,470 >> Mas por entender como os arquivos são colocados fora dessa forma, você pode realmente 1116 00:49:41,470 --> 00:49:45,890 em seguida, manipular imagens, recuperar imagens do disco, redimensionar imagens. 1117 00:49:45,890 --> 00:49:47,560 Mas você não pode necessariamente melhorá-los. 1118 00:49:47,560 --> 00:49:48,480 Eu precisava de uma fotografia. 1119 00:49:48,480 --> 00:49:52,840 Então eu voltei para RJ aqui, que você viu na tela há algum tempo atrás. 1120 00:49:52,840 --> 00:49:57,160 E se eu abrir Keynote aqui, este é o que acontece se você tentar ampliar e 1121 00:49:57,160 --> 00:49:59,380 melhorar RJ. 1122 00:49:59,380 --> 00:50:01,480 Ele não está ficando melhor realmente. 1123 00:50:01,480 --> 00:50:06,240 Agora Keynote é uma espécie de esbater-se um pouco, apenas para encobrir o 1124 00:50:06,240 --> 00:50:11,040 facto de RJ não fica particularmente maior quando você zoom in 1125 00:50:11,040 --> 00:50:13,310 E se fizer dessa forma, ver as praças? 1126 00:50:13,310 --> 00:50:15,490 Sim, você pode definitivamente ver os quadrados em um projetor. 1127 00:50:15,490 --> 00:50:17,690 >> Isso é o que você começa quando você melhorar. 1128 00:50:17,690 --> 00:50:22,570 Mas no entendimento de como o nosso RJ ou o Smiley face é implementado nos deixa 1129 00:50:22,570 --> 00:50:24,950 realmente escrever o código que manipula essas coisas. 1130 00:50:24,950 --> 00:50:29,970 E eu pensei que eu ia acabar com esta nota, com 55 segundo de uma melhorar isso, 1131 00:50:29,970 --> 00:50:31,230 Atrevo-me, por exemplo, em vez enganosa. 1132 00:50:31,230 --> 00:50:32,990 >> [REPRODUÇÃO] 1133 00:50:32,990 --> 00:50:34,790 >> -Ele está mentindo. 1134 00:50:34,790 --> 00:50:38,310 Sobre o quê, eu não sei. 1135 00:50:38,310 --> 00:50:41,200 >> -Então, o que nós sabemos? 1136 00:50:41,200 --> 00:50:45,280 >> -Isso às 9:15 Ray Santoya estava no caixa eletrônico. 1137 00:50:45,280 --> 00:50:47,830 >> -Então, a pergunta é o que que ele estava fazendo em 9:16? 1138 00:50:47,830 --> 00:50:50,750 >> Tiro-a nove milímetros em alguma coisa. 1139 00:50:50,750 --> 00:50:52,615 Talvez ele viu o atirador. 1140 00:50:52,615 --> 00:50:54,760 >> -Ou foi trabalhar com ele. 1141 00:50:54,760 --> 00:50:56,120 >> -Espere. 1142 00:50:56,120 --> 00:50:57,450 Volte um. 1143 00:50:57,450 --> 00:50:58,700 >> -O que você vê? 1144 00:50:58,700 --> 00:51:05,530 1145 00:51:05,530 --> 00:51:09,490 >> -Trazer o rosto, tela cheia. 1146 00:51:09,490 --> 00:51:09,790 >> -Seus óculos. 1147 00:51:09,790 --> 00:51:11,040 >> -Há uma reflexão. 1148 00:51:11,040 --> 00:51:21,790 1149 00:51:21,790 --> 00:51:23,520 >> -Esse é o time de beisebol Neuvitas. 1150 00:51:23,520 --> 00:51:24,530 Esse é o seu logotipo. 1151 00:51:24,530 --> 00:51:27,040 >> -E ele está falando com quem quer que esteja usando aquela jaqueta. 1152 00:51:27,040 --> 00:51:27,530 >> [FIM REPRODUÇÃO DE VÍDEO] 1153 00:51:27,530 --> 00:51:29,180 >> DAVID J. MALAN: Isto ser Problem Set 5. 1154 00:51:29,180 --> 00:51:30,720 Vamos vê-lo na próxima semana. 1155 00:51:30,720 --> 00:51:32,330 >> Falante masculino: Na próxima CS50. 1156 00:51:32,330 --> 00:51:39,240 >> [Grilos cantando] 1157 00:51:39,240 --> 00:51:41,270 >> [Música tocando]