1 00:00:00,000 --> 00:00:11,200 2 00:00:11,200 --> 00:00:12,580 >> DAVID MALAN: Tudo bem, bem-vindo de volta. 3 00:00:12,580 --> 00:00:13,290 Isto é CS50. 4 00:00:13,290 --> 00:00:15,130 Este é o início da semana de sete. 5 00:00:15,130 --> 00:00:18,890 Por isso, já faz um tempo, então pensei que tinha fazer um passeio turbilhão de onde nós 6 00:00:18,890 --> 00:00:20,760 parou e para onde estamos indo agora. 7 00:00:20,760 --> 00:00:23,310 >> Então, essa coisa aqui pode ter causou alguma angústia em primeiro lugar. 8 00:00:23,310 --> 00:00:27,680 Mas espero que, você está começando a aclimatar com o que isso denota aqui - 9 00:00:27,680 --> 00:00:32,670 estrela que representa um ponteiro, o qual é o que, em termos mais leigos? 10 00:00:32,670 --> 00:00:33,400 Portanto, é um endereço. 11 00:00:33,400 --> 00:00:35,490 >> Portanto, é o endereço de algo em memória. 12 00:00:35,490 --> 00:00:38,260 E começamos a descascar as camadas um par de semanas atrás, coisas como 13 00:00:38,260 --> 00:00:41,800 GetString e outras funções tais todo esse tempo foram retornando 14 00:00:41,800 --> 00:00:46,010 endereços de coisas na memória, como o endereço do primeiro caractere 15 00:00:46,010 --> 00:00:46,990 alguma seqüência. 16 00:00:46,990 --> 00:00:50,360 >> Então, nós também introduziu valgrind, que você vai começar a usar para este problema 17 00:00:50,360 --> 00:00:53,380 definido, em particular para a próxima conjunto de problemas também. 18 00:00:53,380 --> 00:00:54,980 E valgrind faz o que para nós? 19 00:00:54,980 --> 00:00:57,520 20 00:00:57,520 --> 00:01:01,020 Ele verifica se há vazamentos de memória, e também verifica a existência de abuso de memória. 21 00:01:01,020 --> 00:01:05,890 >> É possível, com alguma probabilidade, se detectar seu código vai tocar de memória 22 00:01:05,890 --> 00:01:07,100 que simplesmente não deveria. 23 00:01:07,100 --> 00:01:10,410 Então, não necessariamente uma fuga, mas se você ir além das fronteiras de alguns 24 00:01:10,410 --> 00:01:14,730 array, e você realmente executar valgrind e induzir a que o comportamento enquanto 25 00:01:14,730 --> 00:01:17,870 valgrind está sendo executado em seu programa rodando dentro dele, você vai ter 26 00:01:17,870 --> 00:01:21,460 mensagens como esta - "inválido de escrever tamanho 4 ", que, lembre-se de um par de 27 00:01:21,460 --> 00:01:25,880 semanas atrás significava que eu tinha acidentalmente procura de um int demasiado 28 00:01:25,880 --> 00:01:27,250 além dos limites de um array. 29 00:01:27,250 --> 00:01:30,790 E assim tamanho 4 significa aqui o tamanho de que int particular. 30 00:01:30,790 --> 00:01:35,260 >> Então dê confiança no fato de que saída do valgrind, o formato do mesmo, 31 00:01:35,260 --> 00:01:36,170 é simplesmente atroz. 32 00:01:36,170 --> 00:01:40,180 É realmente difícil de ver através da bagunça pela informação interessante. 33 00:01:40,180 --> 00:01:42,910 Então, o que temos feito aqui é apenas trecho alguns dos pares de mais 34 00:01:42,910 --> 00:01:43,850 linhas interessantes. 35 00:01:43,850 --> 00:01:46,760 Mas percebemos que 80% dos valgrind de saída vai ser um pouco de 36 00:01:46,760 --> 00:01:47,650 distração. 37 00:01:47,650 --> 00:01:52,820 >> Basta olhar para os padrões como estes - inválido direita, inválido ler, 40 bytes 38 00:01:52,820 --> 00:01:56,690 e um certo número de blocos são definitivamente perdido, palavras-chave como essa. 39 00:01:56,690 --> 00:02:01,920 E o que você espera ver alguma tipo de vestígio de que a função do 40 00:02:01,920 --> 00:02:03,340 erro é realmente dentro 41 00:02:03,340 --> 00:02:07,195 Neste caso, aqui, no qual a linha de meu código era aparentemente o erro? 42 00:02:07,195 --> 00:02:09,729 43 00:02:09,729 --> 00:02:14,130 >> 26 em um arquivo chamado memory.c, que era o exemplo que estavam brincando com 44 00:02:14,130 --> 00:02:14,890 no momento. 45 00:02:14,890 --> 00:02:16,460 Portanto, não é, provavelmente, em malloc. 46 00:02:16,460 --> 00:02:18,630 Foi provavelmente no meu código em seu lugar. 47 00:02:18,630 --> 00:02:20,910 Então, vamos ver isso de novo e novamente em pouco tempo. 48 00:02:20,910 --> 00:02:24,080 >> Então scanf, esta surgiu em um algumas formas até agora. 49 00:02:24,080 --> 00:02:26,410 Vimos sscanf brevemente. 50 00:02:26,410 --> 00:02:28,330 Era algo que uma série de você mergulhou em sua 51 00:02:28,330 --> 00:02:29,535 preparativos para o teste. 52 00:02:29,535 --> 00:02:33,130 E scanf é realmente o que o CS50 biblioteca está usando por baixo da 53 00:02:33,130 --> 00:02:36,560 capa por algum tempo, a fim para obter a entrada do usuário. 54 00:02:36,560 --> 00:02:40,420 >> Por exemplo, se eu passar para o CS50 aparelho aqui, deixe-me abrir uma 55 00:02:40,420 --> 00:02:45,315 exemplo, hoje, que é chamado de scanf-0.C E é super simples. 56 00:02:45,315 --> 00:02:46,590 É apenas algumas linhas de código. 57 00:02:46,590 --> 00:02:50,880 Mas ele demonstra realmente como getInt vem trabalhando todo esse tempo. 58 00:02:50,880 --> 00:02:54,710 >> Neste programa aqui, na linha 16 , Repare que eu declarar um int. 59 00:02:54,710 --> 00:02:57,270 Assim, não ponteiros, nada de mágico lá, apenas um int. 60 00:02:57,270 --> 00:03:00,330 Em seguida, na linha 17, que solicitará ao usuário para um número, por favor. 61 00:03:00,330 --> 00:03:02,930 Então, no final de 18, eu uso o scanf aqui. 62 00:03:02,930 --> 00:03:06,910 E eu especifiquei, tipo como printf, que eu estou esperando Citação 63 00:03:06,910 --> 00:03:08,110 unquote por cento i. 64 00:03:08,110 --> 00:03:10,920 >> Assim por cento de i, é claro, denota um int. 65 00:03:10,920 --> 00:03:14,580 Mas note que a segunda argumento de scanf é. 66 00:03:14,580 --> 00:03:17,350 Como você descreveria o segundo argumento depois da vírgula? 67 00:03:17,350 --> 00:03:19,450 O que é isso? 68 00:03:19,450 --> 00:03:20,670 >> É o endereço de x. 69 00:03:20,670 --> 00:03:25,490 Então, isso é útil porque fornecendo scanf com o endereço de x, o que faz 70 00:03:25,490 --> 00:03:29,560 que capacitam essa função para fazer? 71 00:03:29,560 --> 00:03:33,010 Não é só ir lá, mas também fazer o quê? 72 00:03:33,010 --> 00:03:34,060 >> Fazer uma mudança para ela. 73 00:03:34,060 --> 00:03:38,080 Porque você pode ir lá, é uma espécie de como um mapa para a localização na memória. 74 00:03:38,080 --> 00:03:41,900 E assim, desde que você forneça scanf, ou qualquer função com um tal mapa, isto 75 00:03:41,900 --> 00:03:45,840 função pode ir lá, e não só olhar para o valor, mas também pode 76 00:03:45,840 --> 00:03:49,670 alterar esse valor, o que é útil quando a propósito na vida de scanf é 77 00:03:49,670 --> 00:03:53,060 digitalizar a entrada do utilizador, especificamente a partir do teclado. 78 00:03:53,060 --> 00:03:57,830 E o f denota formatado, assim como printf, o f denota uma formatado 79 00:03:57,830 --> 00:03:58,930 string que você deseja imprimir. 80 00:03:58,930 --> 00:04:04,430 >> Assim, em breve, essa linha 18 simplesmente diz: tente ler um int do usuário do 81 00:04:04,430 --> 00:04:10,420 teclado e armazená-lo dentro de x, em qualquer endereço x acontece a viver em. 82 00:04:10,420 --> 00:04:14,860 E então, finalmente, a linha 19 apenas diz: obrigado pela int, neste caso. 83 00:04:14,860 --> 00:04:15,940 >> Então deixe-me ir em frente e fazer isso. 84 00:04:15,940 --> 00:04:18,570 Então faça scanf 0. 85 00:04:18,570 --> 00:04:20,130 Deixe me ir em frente e zoom in 86 00:04:20,130 --> 00:04:22,960 Vou correr com esta pontos cortar scanf 0. 87 00:04:22,960 --> 00:04:24,020 Número, por favor? 88 00:04:24,020 --> 00:04:24,720 50. 89 00:04:24,720 --> 00:04:25,730 Obrigado pela 50. 90 00:04:25,730 --> 00:04:27,270 Por isso, é muito simples. 91 00:04:27,270 --> 00:04:28,160 >> Agora, o que é que não está fazendo? 92 00:04:28,160 --> 00:04:29,940 Ele não está fazendo um grupo inteiro de verificação de erros. 93 00:04:29,940 --> 00:04:33,000 Por exemplo, se eu não cooperar, e eu não digitar um número, mas 94 00:04:33,000 --> 00:04:37,860 em vez disso, escrever algo como "Olá", isso é apenas uma espécie de estranho. 95 00:04:37,860 --> 00:04:41,130 E assim, uma das coisas que o CS50 biblioteca tem vindo a fazer para nós por algum 96 00:04:41,130 --> 00:04:43,440 tempo é que reprompting e reprompting. 97 00:04:43,440 --> 00:04:49,320 >> A nova tentativa frase foi retirada em cs50.c, e essa é a razão que getInt em 98 00:04:49,320 --> 00:04:51,670 a biblioteca CS50 é realmente um conjunto bando de longas filas, porque nós somos 99 00:04:51,670 --> 00:04:53,190 verificação de coisas estúpidas como esta. 100 00:04:53,190 --> 00:04:55,730 Será que o usuário não dar nós, na verdade, um int? 101 00:04:55,730 --> 00:04:57,910 Será que ele ou ela nos dar algo como uma letra alfabética? 102 00:04:57,910 --> 00:05:01,410 Se assim for, queremos detectar isso e gritar com eles. 103 00:05:01,410 --> 00:05:03,915 >> Mas as coisas ficam mais interessantes Neste próximo exemplo. 104 00:05:03,915 --> 00:05:09,840 Se eu for para scanf-1.c, que é a única coisa que mudou fundamentalmente em 105 00:05:09,840 --> 00:05:11,135 Neste próximo exemplo? 106 00:05:11,135 --> 00:05:13,690 107 00:05:13,690 --> 00:05:16,010 Estou usando char *, é claro, em vez de int. 108 00:05:16,010 --> 00:05:19,210 >> Então, isso é interessante, porque char *, recordo, é realmente apenas o 109 00:05:19,210 --> 00:05:20,190 mesma coisa que a string. 110 00:05:20,190 --> 00:05:23,840 Então, parece que talvez isso seja um super implementação simples de GetString. 111 00:05:23,840 --> 00:05:26,010 Mas eu desmascarado a camada da biblioteca CS50, por isso estou 112 00:05:26,010 --> 00:05:27,550 chamando este char * agora. 113 00:05:27,550 --> 00:05:30,070 Então vamos ver onde, se em qualquer lugar, nós erramos. 114 00:05:30,070 --> 00:05:30,840 >> Linha 17 - 115 00:05:30,840 --> 00:05:33,950 Volto a dizer, por favor, me dar alguma coisa, neste caso, uma cadeia de caracteres. 116 00:05:33,950 --> 00:05:37,940 E, em seguida, na linha seguinte, eu chamo scanf, mais uma vez, dando-lhe um código de formato, 117 00:05:37,940 --> 00:05:39,310 mas desta vez por cento s. 118 00:05:39,310 --> 00:05:41,900 E, em seguida, desta vez, eu sou dando-lhe tampão. 119 00:05:41,900 --> 00:05:43,550 >> Agora note, eu não estou usando o comercial. 120 00:05:43,550 --> 00:05:47,120 Mas por que é que, provavelmente, OK aqui? 121 00:05:47,120 --> 00:05:49,760 Porque o que é já tampão? 122 00:05:49,760 --> 00:05:50,770 Já é um ponteiro. 123 00:05:50,770 --> 00:05:51,650 Já é um endereço. 124 00:05:51,650 --> 00:05:54,510 >> E vamos a palavra "confundir", deixe-me basta chamá-lo s, por exemplo, para 125 00:05:54,510 --> 00:05:55,050 simplicidade. 126 00:05:55,050 --> 00:05:58,250 Mas eu chamei-tampão porque em geral, na programação, se você tiver um 127 00:05:58,250 --> 00:06:02,130 pedaço de memória, que uma seqüência realmente apenas é, você pode chamá-lo de um buffer. 128 00:06:02,130 --> 00:06:04,460 É um lugar para armazenar informações. 129 00:06:04,460 --> 00:06:07,400 >> Semelhante a coisas como o YouTube, quando eles estão de tamponamento, por assim dizer, que 130 00:06:07,400 --> 00:06:10,270 significa apenas que ele está baixando pedaços de a internet e armazená-los em um 131 00:06:10,270 --> 00:06:14,160 array local, um pedaço locais de memória para que você pode vê-lo mais tarde, sem 132 00:06:14,160 --> 00:06:16,830 ele pular ou pendurado você durante a reprodução. 133 00:06:16,830 --> 00:06:20,930 >> Portanto, há um problema aqui, porém, porque eu estou dizendo scanf, esperar um 134 00:06:20,930 --> 00:06:22,320 corda do usuário. 135 00:06:22,320 --> 00:06:24,410 Aqui está o endereço do um pedaço de memória. 136 00:06:24,410 --> 00:06:26,180 Coloque a corda lá. 137 00:06:26,180 --> 00:06:31,230 Por que é que bound dar nos problemas, embora? 138 00:06:31,230 --> 00:06:33,490 >> O que é isso? 139 00:06:33,490 --> 00:06:35,510 Tenho permissão para acessar que parte da memória? 140 00:06:35,510 --> 00:06:36,250 Você sabe, eu não sei. 141 00:06:36,250 --> 00:06:39,210 Porque tem tampão foi inicializado para alguma coisa? 142 00:06:39,210 --> 00:06:39,820 Não é verdade. 143 00:06:39,820 --> 00:06:43,090 E por isso é que temos vindo a chamar um valor de lixo, que 144 00:06:43,090 --> 00:06:44,040 não é uma palavra formal. 145 00:06:44,040 --> 00:06:49,200 Significa apenas que nós não temos nenhuma idéia do que pedaços estão dentro das quatro bytes 146 00:06:49,200 --> 00:06:51,240 Tenho alocado como buffer. 147 00:06:51,240 --> 00:06:52,450 >> Eu não chamei malloc. 148 00:06:52,450 --> 00:06:53,940 Eu definitivamente não é chamado GetString. 149 00:06:53,940 --> 00:06:56,380 Então, quem sabe o que é realmente dentro de tampão de? 150 00:06:56,380 --> 00:07:00,550 E ainda dizendo scanf cegamente, vai lá e colocar o que o usuário digitou. 151 00:07:00,550 --> 00:07:04,460 >> Então, o que é susceptível de causar em nosso código, se executá-lo? 152 00:07:04,460 --> 00:07:05,700 Provavelmente um segfault. 153 00:07:05,700 --> 00:07:07,970 Talvez não, mas provavelmente um segfault. 154 00:07:07,970 --> 00:07:10,620 E eu digo talvez não, porque às vezes você faz, às vezes 155 00:07:10,620 --> 00:07:11,380 você não tem um segfault. 156 00:07:11,380 --> 00:07:14,280 Às vezes você apenas ter sorte, mas é mesmo assim vai ser 157 00:07:14,280 --> 00:07:15,340 um bug no nosso programa. 158 00:07:15,340 --> 00:07:17,060 >> Então deixe-me ir em frente e compilar isso. 159 00:07:17,060 --> 00:07:18,280 Eu vou fazer do jeito old school. 160 00:07:18,280 --> 00:07:23,825 Então bumbum traço 0, scanf-1, scanf-1.c, Enter. 161 00:07:23,825 --> 00:07:24,720 Opa, escola muito antiga. 162 00:07:24,720 --> 00:07:26,550 Vamos ver. 163 00:07:26,550 --> 00:07:28,440 Onde é que eu vou? 164 00:07:28,440 --> 00:07:29,700 Oh, buffer de char *. 165 00:07:29,700 --> 00:07:33,595 166 00:07:33,595 --> 00:07:35,130 Oh, thank you - 167 00:07:35,130 --> 00:07:36,930 Salvar, OK - 168 00:07:36,930 --> 00:07:37,690 escola muito antiga. 169 00:07:37,690 --> 00:07:38,900 Tudo bem, isso já faz um tempo. 170 00:07:38,900 --> 00:07:41,720 >> Então, eu acabei de salvar o arquivo depois fazendo que temporária 171 00:07:41,720 --> 00:07:42,700 mudar de um momento atrás. 172 00:07:42,700 --> 00:07:46,090 E agora eu compilei ele manualmente com Clang. 173 00:07:46,090 --> 00:07:49,500 E agora eu estou indo para ir em frente e executar scanf-1, Enter. 174 00:07:49,500 --> 00:07:50,290 Cordas favor. 175 00:07:50,290 --> 00:07:51,600 Eu vou digitar "Olá". 176 00:07:51,600 --> 00:07:54,070 >> E agora, aqui está em que, francamente, printf pode é um pouco irritante. 177 00:07:54,070 --> 00:07:56,020 Não está indo realmente para segfault neste caso. 178 00:07:56,020 --> 00:07:59,860 Printf é um pouco especial, porque é tão super comumente utilizado, que 179 00:07:59,860 --> 00:08:03,570 essencialmente printf está fazendo -nos um favor e perceber, 180 00:08:03,570 --> 00:08:04,830 isso não é um ponteiro válido. 181 00:08:04,830 --> 00:08:09,080 Deixe-me levá-la a mim apenas para imprimir em parênteses nulo, mesmo 182 00:08:09,080 --> 00:08:13,340 embora não seja necessariamente o que que nos esperava. 183 00:08:13,340 --> 00:08:16,940 >> Portanto, não podemos muito facilmente induzir um segfault com isso, mas claramente este 184 00:08:16,940 --> 00:08:18,600 não é o comportamento que eu queria. 185 00:08:18,600 --> 00:08:19,800 Então, qual é a solução mais simples? 186 00:08:19,800 --> 00:08:25,650 Bem, em scanf-2, deixe-me propor que em vez de verdade, apenas a atribuição de uma 187 00:08:25,650 --> 00:08:30,100 char *, deixe-me ser um pouco mais esperto sobre isso, e deixe-me alocar buffer 188 00:08:30,100 --> 00:08:32,940 como uma seqüência de 16 caracteres. 189 00:08:32,940 --> 00:08:34,200 >> Então, eu posso fazer isso de duas maneiras. 190 00:08:34,200 --> 00:08:35,610 Eu absolutamente poderia usar malloc. 191 00:08:35,610 --> 00:08:38,980 Mas eu posso voltar a duas semanas, quando Eu só precisava de um monte de 192 00:08:38,980 --> 00:08:39,620 caracteres. 193 00:08:39,620 --> 00:08:40,860 Isso é apenas uma matriz. 194 00:08:40,860 --> 00:08:44,870 Então me deixe em vez redefinir tampão a ser uma matriz de 16 caracteres. 195 00:08:44,870 --> 00:08:47,340 >> E agora, quando eu passar tampão in - 196 00:08:47,340 --> 00:08:49,940 e isso é algo que não fez falar em duas semanas - 197 00:08:49,940 --> 00:08:53,730 mas você pode tratar uma variedade de mas é um endereço. 198 00:08:53,730 --> 00:08:56,390 Tecnicamente, como vimos, eles são um pouco diferente. 199 00:08:56,390 --> 00:09:01,290 Mas scanf não vai se importar se você passá-lo o nome de um array, porque o que 200 00:09:01,290 --> 00:09:05,030 Clang fará por nós é essencialmente tratar o nome do array como o 201 00:09:05,030 --> 00:09:08,280 endereço do bloco de 16 bytes. 202 00:09:08,280 --> 00:09:09,550 >> Portanto, este é melhor. 203 00:09:09,550 --> 00:09:12,110 Isto significa que agora que eu espero que possa faça o seguinte. 204 00:09:12,110 --> 00:09:16,800 Deixe-me afastar por um momento e fazem scanf-2, compilada OK. 205 00:09:16,800 --> 00:09:19,390 Agora, deixe-me que tenho barra scanf-2. 206 00:09:19,390 --> 00:09:22,430 Cordas favor. "Olá". E parecia estar a trabalhar neste momento. 207 00:09:22,430 --> 00:09:26,020 >> Mas alguém pode propor um cenário em que não pode ainda funciona? 208 00:09:26,020 --> 00:09:28,550 Sim? 209 00:09:28,550 --> 00:09:30,640 Algo mais do que 16 caracteres. 210 00:09:30,640 --> 00:09:32,020 E, na verdade, podemos ser um pouco mais precisa. 211 00:09:32,020 --> 00:09:36,540 Algo mais então 15 personagens, porque realmente precisamos ter em mente 212 00:09:36,540 --> 00:09:39,920 que precisamos que barra invertida de zero implicitamente no final da cadeia, 213 00:09:39,920 --> 00:09:42,950 que é um aparte scanf irá tipicamente cuidar para nós. 214 00:09:42,950 --> 00:09:46,210 >> Então deixe-me fazer algo assim - 215 00:09:46,210 --> 00:09:48,040 Às vezes, podemos apenas deixá-lo assim. 216 00:09:48,040 --> 00:09:50,630 OK, então nós agora induzido nossa falha de segmentação. 217 00:09:50,630 --> 00:09:51,000 Por quê? 218 00:09:51,000 --> 00:09:54,940 Porque eu digitei a mais de 15 caracteres, e por isso nós realmente 219 00:09:54,940 --> 00:09:58,280 memória tocado que eu realmente não deveria ter. 220 00:09:58,280 --> 00:10:00,180 >> Então, qual é realmente a solução aqui? 221 00:10:00,180 --> 00:10:02,210 Bem, e se precisamos de uma seqüência mais longa? 222 00:10:02,210 --> 00:10:03,960 Bem, talvez torná-lo 32 bytes. 223 00:10:03,960 --> 00:10:05,160 Bem, e se isso não é o suficiente? 224 00:10:05,160 --> 00:10:06,040 Como cerca de 64 bytes? 225 00:10:06,040 --> 00:10:07,080 E se isso não é o suficiente? 226 00:10:07,080 --> 00:10:09,640 Como cerca de 128 bytes ou 200? 227 00:10:09,640 --> 00:10:12,660 O que é realmente a solução aqui no caso geral, se não sabemos em 228 00:10:12,660 --> 00:10:14,460 avançar o que o usuário vai digitar? 229 00:10:14,460 --> 00:10:20,000 230 00:10:20,000 --> 00:10:23,050 >> É apenas uma espécie de grande dor na bunda, para ser honesto, é por isso que o 231 00:10:23,050 --> 00:10:29,050 Biblioteca CS50 tem algumas dezenas de linhas de código que implementar coletivamente 232 00:10:29,050 --> 00:10:32,390 GetString cordas de uma forma que nós não tem que saber com antecedência o que o 233 00:10:32,390 --> 00:10:33,430 de usuário vai digitar. 234 00:10:33,430 --> 00:10:37,370 Em particular, se você olhar para trás, cs50.c de duas semanas atrás, você vai ver 235 00:10:37,370 --> 00:10:40,480 GetString que realmente faz Não utilizar scanf desta maneira. 236 00:10:40,480 --> 00:10:43,720 Em vez disso, ele lê um caractere de cada vez. 237 00:10:43,720 --> 00:10:46,010 >> Porque a única coisa agradável sobre leitura de um personagem é o que pudermos 238 00:10:46,010 --> 00:10:48,490 nós garantimos para sempre ter pelo menos um caractere. 239 00:10:48,490 --> 00:10:51,740 Eu só posso declarar um char, e em seguida, tomar estes passos verdadeiramente bebê para apenas 240 00:10:51,740 --> 00:10:54,380 leia um personagem em um tempo a partir do teclado. 241 00:10:54,380 --> 00:10:58,240 E então, o que você vai ver GetString faz é cada vez ficar sem, 242 00:10:58,240 --> 00:11:02,280 digamos, 16 bytes de memória, ele usa malloc, ou um seu primo, a 243 00:11:02,280 --> 00:11:06,810 alocar mais memória, copiando o antigo memória para o novo, e, em seguida, rastejando 244 00:11:06,810 --> 00:11:09,900 junto, obtendo um personagem de cada vez, e quando ele é executado fora do que 245 00:11:09,900 --> 00:11:13,370 pedaço de memória, joga fora, agarra uma fatia maior de memória, copia velho 246 00:11:13,370 --> 00:11:14,750 em novos e repete. 247 00:11:14,750 --> 00:11:18,480 E é realmente uma dor de verdade implementar algo tão simples como 248 00:11:18,480 --> 00:11:19,710 se a entrada de um usuário. 249 00:11:19,710 --> 00:11:21,090 >> Então você pode usar scanf. 250 00:11:21,090 --> 00:11:22,430 Você pode usar outras funções semelhantes. 251 00:11:22,430 --> 00:11:25,420 E um monte de livros e on-line exemplos fazer, mas todos eles são 252 00:11:25,420 --> 00:11:27,210 vulnerável a problemas como este. 253 00:11:27,210 --> 00:11:29,550 E finalmente, se um segfault é meio chato. 254 00:11:29,550 --> 00:11:30,680 Não é bom para o usuário. 255 00:11:30,680 --> 00:11:33,560 >> Mas, na pior das hipóteses, o que faz fundamentalmente coloque o 256 00:11:33,560 --> 00:11:37,160 codificar em risco de? 257 00:11:37,160 --> 00:11:39,250 Algum tipo de ataque, potencialmente. 258 00:11:39,250 --> 00:11:41,680 Nós conversamos sobre um tal ataque - transbordamento da pilha. 259 00:11:41,680 --> 00:11:44,660 Mas, em geral, se você está autorizado a estourar um buffer, como nós fizemos um 260 00:11:44,660 --> 00:11:48,070 Algumas semanas atrás, com apenas escrever mais do que "Olá" na pilha, você 261 00:11:48,070 --> 00:11:52,330 pode realmente assumir, potencialmente, um computador, ou pelo menos começar a dados 262 00:11:52,330 --> 00:11:53,510 não pertence a você. 263 00:11:53,510 --> 00:11:55,970 >> Então, em suma, é por isso que temos essas rodinhas. 264 00:11:55,970 --> 00:11:59,090 Mas, agora, começamos a tirá-las, como os nossos programas não precisa mais, 265 00:11:59,090 --> 00:12:00,610 necessariamente, a entrada do utilizador. 266 00:12:00,610 --> 00:12:03,960 Mas, no caso de problema de definir seis, sua contribuição virá de uma enorme 267 00:12:03,960 --> 00:12:07,520 arquivo de dicionário com 150 alguns ímpares mil palavras. 268 00:12:07,520 --> 00:12:10,330 >> Assim, você não terá que se preocupar com entrada arbitrária do utilizador. 269 00:12:10,330 --> 00:12:13,720 Nós vamos dar-lhe algumas suposições sobre esse arquivo. 270 00:12:13,720 --> 00:12:20,340 Qualquer dúvida sobre ponteiros ou scanf ou a entrada do usuário em geral? 271 00:12:20,340 --> 00:12:24,450 >> Tudo bem, então um olhar rápido, em seguida, em um fuga tópico de duas semanas atrás. 272 00:12:24,450 --> 00:12:28,590 E que era essa noção de um struct. 273 00:12:28,590 --> 00:12:34,180 Não que - esta noção de um struct, o que era o quê? 274 00:12:34,180 --> 00:12:35,430 O que struct fazer por nós? 275 00:12:35,430 --> 00:12:39,280 276 00:12:39,280 --> 00:12:39,860 >> Definir - 277 00:12:39,860 --> 00:12:41,710 arrependido? 278 00:12:41,710 --> 00:12:42,820 Definir um tipo de variável. 279 00:12:42,820 --> 00:12:44,410 Então, mais ou menos. 280 00:12:44,410 --> 00:12:46,180 Na verdade, estamos combinando dois tópicos. 281 00:12:46,180 --> 00:12:49,510 Assim, com typedef, lembre-se que podemos declarar um tipo de nossa própria, como um 282 00:12:49,510 --> 00:12:51,500 sinônimo, como string para char *. 283 00:12:51,500 --> 00:12:56,200 Mas o uso de typedef e struct, podemos realmente criar nossas próprias estruturas de dados. 284 00:12:56,200 --> 00:12:59,600 >> Por exemplo, se eu voltar para o gedit aqui só por um momento, e eu ir em frente 285 00:12:59,600 --> 00:13:08,230 e fazer algo assim, deixe-me salvar isso como, digamos, structs.c 286 00:13:08,230 --> 00:13:10,840 temporariamente, eu só vou para ir em frente e incluem 287 00:13:10,840 --> 00:13:14,360 standardio.h, int void main. 288 00:13:14,360 --> 00:13:18,960 E então, aqui, vamos supor que eu quero para escrever um programa que armazena 289 00:13:18,960 --> 00:13:21,840 vários alunos de vários casas, por exemplo. 290 00:13:21,840 --> 00:13:24,430 Então, é como um registrarial banco de dados de algum tipo. 291 00:13:24,430 --> 00:13:29,550 >> Então, se eu preciso do nome de um estudante, eu poderia fazer algo parecido com o nome de char *, 292 00:13:29,550 --> 00:13:31,570 e eu vou fazer algo parecido - 293 00:13:31,570 --> 00:13:34,410 na verdade, vamos usar a biblioteca CS50 por apenas um momento para fazer deste um 294 00:13:34,410 --> 00:13:38,380 pouco mais simples, para que possamos emprestar essas dezenas de linhas de código. 295 00:13:38,380 --> 00:13:39,340 E vamos mantê-lo simples. 296 00:13:39,340 --> 00:13:42,610 Vamos mantê-lo string, e agora GetString. 297 00:13:42,610 --> 00:13:47,420 >> Então eu afirmo agora que eu tenho guardado o nome de algum aluno, ea casa de 298 00:13:47,420 --> 00:13:50,240 algum aluno, simplesmente usando variáveis como fizemos e em uma semana. 299 00:13:50,240 --> 00:13:52,370 Mas suponho que agora querem apoiar vários alunos. 300 00:13:52,370 --> 00:13:58,460 Tudo bem, então meus instintos estão a fazer corda nome2, fica GetString, corda 301 00:13:58,460 --> 00:14:01,370 house2 fica GetString. 302 00:14:01,370 --> 00:14:05,850 E então o nosso terceiro estudante, vamos fazer name3 GetString. 303 00:14:05,850 --> 00:14:09,170 >> Certo, então isso é sorte impressionante lo como uma espécie de idiota, 304 00:14:09,170 --> 00:14:11,580 porque este processo é realmente nunca vai acabar, e ela só vai 305 00:14:11,580 --> 00:14:13,130 fazer o meu código parece pior e pior e pior. 306 00:14:13,130 --> 00:14:14,810 Mas nós resolvemos isso também em duas semanas. 307 00:14:14,810 --> 00:14:19,450 Qual foi a nossa solução relativamente limpa quando tivemos múltiplas variáveis ​​do 308 00:14:19,450 --> 00:14:23,580 mesmo tipo de dados que estão relacionados, mas nós não queremos essa confusão atroz 309 00:14:23,580 --> 00:14:26,870 de variáveis ​​de nome semelhante? 310 00:14:26,870 --> 00:14:30,060 O que vamos fazer em vez disso? 311 00:14:30,060 --> 00:14:31,260 >> Então, eu acho que eu ouvi alguns lugares. 312 00:14:31,260 --> 00:14:32,590 Tivemos uma matriz. 313 00:14:32,590 --> 00:14:37,110 Se você quiser várias instâncias do alguma coisa, por que não vamos limpar isso tudo 314 00:14:37,110 --> 00:14:39,540 e apenas dizer, me dar array chamado nomes? 315 00:14:39,540 --> 00:14:41,640 >> E, por enquanto, vamos 3 código rígido. 316 00:14:41,640 --> 00:14:44,450 E então me dar outro array chamados casas, e deixe-me por 317 00:14:44,450 --> 00:14:45,800 agora rígido código 3. 318 00:14:45,800 --> 00:14:49,220 E eu maciçamente limpou o bagunça que acabou de criar. 319 00:14:49,220 --> 00:14:52,400 Agora, eu ainda codificado 3, mas mesmo o 3 poderia vir dinamicamente a partir do 320 00:14:52,400 --> 00:14:54,350 utilizador, ou argv, ou semelhantes. 321 00:14:54,350 --> 00:14:55,720 Então, isso já é mais limpo. 322 00:14:55,720 --> 00:15:00,100 >> Mas o que é irritante sobre isso é que agora, mesmo que um nome é de alguma forma 323 00:15:00,100 --> 00:15:02,280 fundamentalmente ligada à casa de um aluno - 324 00:15:02,280 --> 00:15:04,720 é um estudante que eu realmente deseja representar - 325 00:15:04,720 --> 00:15:08,080 Agora tenho duas matrizes que são paralelas no sentido de que eles são os 326 00:15:08,080 --> 00:15:13,930 mesmo tamanho, e os nomes de suporte 0 presumivelmente mapas para casas suporte 0, 327 00:15:13,930 --> 00:15:16,600 e os nomes de Suporte 1 mapas às casas suporte 1. 328 00:15:16,600 --> 00:15:19,280 Em outras palavras, que o aluno vive em aquela casa, e que outro aluno 329 00:15:19,280 --> 00:15:20,530 que vive em outra casa. 330 00:15:20,530 --> 00:15:23,720 Mas, certamente, isso poderia ser feito ainda mais limpa. 331 00:15:23,720 --> 00:15:24,990 >> Bem, isso pode, de fato. 332 00:15:24,990 --> 00:15:28,730 E deixe-me ir em frente e abrir se structs.h, e você vai 333 00:15:28,730 --> 00:15:31,130 veja essa idéia aqui. 334 00:15:31,130 --> 00:15:34,905 Repare que eu usei typedef, como você aludiu há pouco para declarar o nosso 335 00:15:34,905 --> 00:15:35,570 tipo de dados próprio. 336 00:15:35,570 --> 00:15:39,660 Mas eu também estou usando essa outra palavra-chave chamado struct que me dá uma nova 337 00:15:39,660 --> 00:15:40,790 estrutura de dados. 338 00:15:40,790 --> 00:15:43,980 >> E essa estrutura de dados que afirmam que vai ter duas coisas no interior da 339 00:15:43,980 --> 00:15:47,060 - uma string chamada nome, e uma série chamada casa. 340 00:15:47,060 --> 00:15:49,820 E o nome que eu vou dar para esta estrutura de dados que vai 341 00:15:49,820 --> 00:15:51,005 a ser chamado de estudante. 342 00:15:51,005 --> 00:15:54,030 Eu poderia chamá-lo de qualquer coisa que eu quero, mas semanticamente fazer 343 00:15:54,030 --> 00:15:55,810 sentido para mim em minha mente. 344 00:15:55,810 --> 00:15:59,160 >> Então, agora, se eu abrir uma versão melhor do programa comecei a escrever 345 00:15:59,160 --> 00:16:00,390 lá, deixe-me ir até o topo. 346 00:16:00,390 --> 00:16:03,190 E há mais algumas linhas de código aqui, mas deixe-me concentrar para 347 00:16:03,190 --> 00:16:04,160 o momento em um. 348 00:16:04,160 --> 00:16:07,790 Eu já declarou uma constante chamada estudantes e codificado 3 por enquanto. 349 00:16:07,790 --> 00:16:11,110 Mas agora, observe como limpo meu código começa a ficar. 350 00:16:11,110 --> 00:16:15,030 >> Na linha 22, declaro conjunto de alunos. 351 00:16:15,030 --> 00:16:18,760 E notem que o aluno é, aparentemente, agora um tipo de dados. 352 00:16:18,760 --> 00:16:23,360 Porque no início deste arquivo, observe Eu incluí o arquivo de cabeçalho 353 00:16:23,360 --> 00:16:24,820 que eu puxei apenas um momento atrás. 354 00:16:24,820 --> 00:16:28,820 E esse arquivo de cabeçalho simplesmente tinha esta definição de um estudante. 355 00:16:28,820 --> 00:16:32,470 >> Então, agora, eu criei meus próprios dados personalizados tipo que os autores do C anos 356 00:16:32,470 --> 00:16:33,890 atrás não pensar com antecedência. 357 00:16:33,890 --> 00:16:34,570 Mas não há problema. 358 00:16:34,570 --> 00:16:35,870 Eu posso fazer isso sozinho. 359 00:16:35,870 --> 00:16:39,050 Portanto, esta é uma matriz chamada estudantes, cada um dos membros cujos 360 00:16:39,050 --> 00:16:41,100 é uma estrutura do estudante. 361 00:16:41,100 --> 00:16:44,270 E eu quero que três desses na matriz. 362 00:16:44,270 --> 00:16:46,030 >> E agora, o que faz o resto deste programa faz? 363 00:16:46,030 --> 00:16:47,550 Eu precisava de algo um pouco arbitrária. 364 00:16:47,550 --> 00:16:51,450 Assim, a partir online 24 em diante, Eu iterar de 0 a 3. 365 00:16:51,450 --> 00:16:54,000 Eu, então, pedir ao usuário para o nome do aluno. 366 00:16:54,000 --> 00:16:56,110 E então eu uso GetString como antes. 367 00:16:56,110 --> 00:16:59,410 Então eu pergunto para a casa do aluno, e eu uso GetString como antes. 368 00:16:59,410 --> 00:17:01,780 >> Mas aviso - um pouco nova pedaço de sintaxe - 369 00:17:01,780 --> 00:17:07,010 Ainda posso índice para o i-th estudante, mas como faço para obter os dados específicos 370 00:17:07,010 --> 00:17:08,354 campo dentro da estrutura? 371 00:17:08,354 --> 00:17:11,770 Bem, o que é, aparentemente, a nova peça de sintaxe? 372 00:17:11,770 --> 00:17:13,339 É apenas o operador ponto. 373 00:17:13,339 --> 00:17:14,510 >> Nós não temos realmente visto isso antes. 374 00:17:14,510 --> 00:17:17,819 Você já vi isso em pset cinco, se você tem mergulhou já com arquivos de bitmap. 375 00:17:17,819 --> 00:17:22,372 Mas o ponto significa apenas dentro deste struct ou vários campos, dar ponto 376 00:17:22,372 --> 00:17:24,510 nome, ou me dar dot casa. 377 00:17:24,510 --> 00:17:28,690 Isso significa ir para dentro da estrutura e obter os campos específicos. 378 00:17:28,690 --> 00:17:30,200 >> O que faz o resto deste programa faz? 379 00:17:30,200 --> 00:17:31,190 Não é tudo o que sexy. 380 00:17:31,190 --> 00:17:34,640 Observe que uma iteração de 0 a 3, novamente, e eu simplesmente criar um Inglês 381 00:17:34,640 --> 00:17:40,500 frase como fulano de tal está em tal e tal casa, passando em nome de ponto de 382 00:17:40,500 --> 00:17:43,320 o i-th aluno e sua casa também. 383 00:17:43,320 --> 00:17:47,560 >> E então, finalmente, agora vamos começar a ter anal com isso, agora que estamos 384 00:17:47,560 --> 00:17:49,580 familiarizado com o que malloc e outras funções tenham sido 385 00:17:49,580 --> 00:17:50,570 fazendo todo esse tempo. 386 00:17:50,570 --> 00:17:54,220 Por que eu tenho de libertar tanto o nome ea casa, apesar de eu 387 00:17:54,220 --> 00:17:56,960 não chamar malloc? 388 00:17:56,960 --> 00:17:58,020 >> GetString fez. 389 00:17:58,020 --> 00:18:00,930 E esse foi o pequeno segredo sujo para várias semanas, mas tem GetString 390 00:18:00,930 --> 00:18:03,530 sido vazamento de memória em todo o colocar todo o semestre até o momento. 391 00:18:03,530 --> 00:18:05,990 E Valgrand vai finalmente revelar isso para nós. 392 00:18:05,990 --> 00:18:10,730 >> Mas não é um grande negócio, porque eu sei que eu posso simplesmente liberar o nome 393 00:18:10,730 --> 00:18:15,750 ea casa, apesar de, tecnicamente, a ser super, super seguro, eu deveria ser 394 00:18:15,750 --> 00:18:17,890 fazer alguma verificação de erros aqui. 395 00:18:17,890 --> 00:18:19,040 Quais são os seus instintos lhe dizendo? 396 00:18:19,040 --> 00:18:22,480 O que devo estar verificando antes de liberar o que é um 397 00:18:22,480 --> 00:18:25,470 string, aka que um char *? 398 00:18:25,470 --> 00:18:33,460 >> Eu realmente deveria estar verificando se os alunos suporte i nome dot não 399 00:18:33,460 --> 00:18:34,840 igual nulo. 400 00:18:34,840 --> 00:18:40,400 Em seguida, ele vai ficar bem para ir em frente e livre esse ponteiro, e o mesmo ou outro 401 00:18:40,400 --> 00:18:41,160 um bem. 402 00:18:41,160 --> 00:18:46,860 Se os alunos suporte i dot casa não é igual a zero, isso agora vai proteger 403 00:18:46,860 --> 00:18:52,520 contra o canto caso em que GetString retorna algo como nulo. 404 00:18:52,520 --> 00:18:57,310 E vimos há pouco, printf vai proteger-nos aqui apenas dizendo 405 00:18:57,310 --> 00:18:58,990 nulo, o que vai ficar estranho. 406 00:18:58,990 --> 00:19:02,340 Mas pelo menos ele não vai segfault, como já vimos. 407 00:19:02,340 --> 00:19:05,990 >> Bem, deixe me fazer uma outra coisa aqui. structs-0 é um tipo de programa estúpido 408 00:19:05,990 --> 00:19:09,700 porque eu entro todos esses dados e, em seguida, ele perdeu uma vez o programa termina. 409 00:19:09,700 --> 00:19:10,940 Mas deixe-me ir em frente e fazer isso. 410 00:19:10,940 --> 00:19:12,830 Deixe-me fazer o terminal janela um pouco maior. 411 00:19:12,830 --> 00:19:17,000 Deixe-me fazer-estruturas 1, que é uma nova versão deste. 412 00:19:17,000 --> 00:19:18,520 >> Vou ampliar um pouco. 413 00:19:18,520 --> 00:19:21,620 E agora deixe-me correr dot reduzir structs-1. 414 00:19:21,620 --> 00:19:22,590 Nome do aluno - 415 00:19:22,590 --> 00:19:31,500 David Mather, vamos fazer Rob Kirkland, vamos fazer Lauren Leverett. 416 00:19:31,500 --> 00:19:33,650 O que é interessante agora é prévio - 417 00:19:33,650 --> 00:19:35,540 e eu só sei disso porque Eu escrevi o programa - 418 00:19:35,540 --> 00:19:38,930 há um arquivo agora na minha atual diretório chamado students.csv. 419 00:19:38,930 --> 00:19:40,420 Alguns de vocês podem ter visto estas no mundo real. 420 00:19:40,420 --> 00:19:42,980 >> O que é um arquivo CSV? 421 00:19:42,980 --> 00:19:44,170 Valores separados por vírgulas. 422 00:19:44,170 --> 00:19:46,670 É como uma espécie de homem pobre versão de um arquivo Excel. 423 00:19:46,670 --> 00:19:50,580 É uma tabela de linhas e colunas que você pode abrir em um programa como o Excel, 424 00:19:50,580 --> 00:19:51,800 ou os números em um Mac. 425 00:19:51,800 --> 00:19:55,180 >> E se eu abrir esse arquivo aqui no gedit, prévio - e os números não estão lá. 426 00:19:55,180 --> 00:19:57,360 Isso é apenas gedit dizendo me os números das linhas. 427 00:19:57,360 --> 00:19:59,740 Repare na primeira linha deste arquivo é David e Mather. 428 00:19:59,740 --> 00:20:01,450 A próxima linha é Rob vírgula Kirkland. 429 00:20:01,450 --> 00:20:04,170 E a terceira linha é Lauren vírgula Leverett. 430 00:20:04,170 --> 00:20:05,480 >> Então, o que eu criei? 431 00:20:05,480 --> 00:20:09,580 Eu já escrevi um programa em C que efetivamente pode gerar planilhas 432 00:20:09,580 --> 00:20:11,840 que pode ser aberto numa programa como o Excel. 433 00:20:11,840 --> 00:20:15,520 Nem tudo o que obrigar um conjunto de dados, mas se você tem pedaços muito maiores de 434 00:20:15,520 --> 00:20:18,440 dados que você realmente quer manipular e fazer gráficos de e 435 00:20:18,440 --> 00:20:21,260 gosto, este é talvez um maneira de criar esses dados. 436 00:20:21,260 --> 00:20:25,370 Além disso, CSVs são realmente super-comum apenas para armazenar dados simples - 437 00:20:25,370 --> 00:20:28,940 Yahoo Finance, por exemplo, se você receber cotações de ações através de seu chamado 438 00:20:28,940 --> 00:20:33,180 API, o serviço gratuito que permite que você esteja em stock, up-to-the-data atual 439 00:20:33,180 --> 00:20:35,650 citações para as empresas, que dar os dados de volta no 440 00:20:35,650 --> 00:20:37,800 Super formato CSV simples. 441 00:20:37,800 --> 00:20:39,380 >> Então, como vamos fazer isso? 442 00:20:39,380 --> 00:20:42,530 Bem notar, a maior parte deste programa de quase a mesma. 443 00:20:42,530 --> 00:20:46,870 Mas note-se aqui, ao invés de impressão os alunos para fora, na linha 35 444 00:20:46,870 --> 00:20:51,040 em diante, eu afirmo que estou guardando o estudantes em disco, para salvar um arquivo. 445 00:20:51,040 --> 00:20:53,630 >> Então, repare que eu estou declarando um FILE * - 446 00:20:53,630 --> 00:20:57,260 Agora, isso é uma espécie de anomalia no C. Por alguma razão, o FILE é todas as tampas, 447 00:20:57,260 --> 00:21:00,690 o que não é como a maioria dos outros tipos de dados em C. Mas este é um built-in 448 00:21:00,690 --> 00:21:02,320 tipo de dados, FILE *. 449 00:21:02,320 --> 00:21:05,900 E eu estou declarando um ponteiro para um arquivo, é como você pode pensar isso. 450 00:21:05,900 --> 00:21:08,070 >> fopen significa arquivo aberto. 451 00:21:08,070 --> 00:21:09,470 O arquivo que você quer abrir? 452 00:21:09,470 --> 00:21:12,620 Eu quero abrir um arquivo que eu vou arbitrariamente chamar students.csv. 453 00:21:12,620 --> 00:21:14,480 Eu poderia chamar isso de qualquer coisa que eu quiser. 454 00:21:14,480 --> 00:21:15,200 >> E, em seguida, dar um palpite. 455 00:21:15,200 --> 00:21:18,960 O que faz o segundo argumento para fopen provavelmente significa? 456 00:21:18,960 --> 00:21:21,480 Certo, w para escrever, poderia ser r para leitura. 457 00:21:21,480 --> 00:21:24,120 Há uma para anexar se deseja adicionar linhas e não 458 00:21:24,120 --> 00:21:25,200 substituir a coisa toda. 459 00:21:25,200 --> 00:21:28,005 >> Mas eu só quero criar este arquivo uma vez, por isso vou usar citação unquote w. 460 00:21:28,005 --> 00:21:31,880 E eu sei que só de ter lido a documentação, ou a página de manual. 461 00:21:31,880 --> 00:21:35,100 Se o arquivo não é nulo - em outras palavras, Se nada deu errado lá - 462 00:21:35,100 --> 00:21:37,820 deixe-me repetir ao longo do os alunos de 0 a 3. 463 00:21:37,820 --> 00:21:40,410 >> E agora percebe que há algo sempre assim ligeiramente diferente 464 00:21:40,410 --> 00:21:42,110 sobre a linha 41 aqui. 465 00:21:42,110 --> 00:21:42,960 Não é printf. 466 00:21:42,960 --> 00:21:46,530 É fprintf para o arquivo printf. 467 00:21:46,530 --> 00:21:47,790 Então, ele vai gravar no arquivo. 468 00:21:47,790 --> 00:21:48,860 Que arquivo? 469 00:21:48,860 --> 00:21:53,630 Aquele cujo ponteiro que você especifique como o primeiro argumento. 470 00:21:53,630 --> 00:21:55,940 >> Então nós especificar uma seqüência de formato. 471 00:21:55,940 --> 00:21:59,660 Então nós especificamos o que queremos cadeia plug-in para o primeiro por cento s, e 472 00:21:59,660 --> 00:22:04,320 em seguida, uma outra variável ou o segundo por cento s. 473 00:22:04,320 --> 00:22:06,760 Depois, feche o arquivo com fclose. 474 00:22:06,760 --> 00:22:09,380 Que eu liberar a memória como antes, embora Eu deveria voltar e adicionar 475 00:22:09,380 --> 00:22:10,540 algumas verificações para null. 476 00:22:10,540 --> 00:22:12,090 >> E é isso. 477 00:22:12,090 --> 00:22:16,960 fopen, fprintf, fclose me dá a capacidade de criar arquivos de texto. 478 00:22:16,960 --> 00:22:19,640 Agora, você vai ver problema em conjunto de cinco, que envolve imagens, que você vai usar 479 00:22:19,640 --> 00:22:20,990 arquivos binários vez. 480 00:22:20,990 --> 00:22:24,200 Mas, fundamentalmente, a idéia é a mesma, mesmo que as funções que você vai 481 00:22:24,200 --> 00:22:28,710 ver é um pouco diferente. 482 00:22:28,710 --> 00:22:32,580 >> Então rápido tour, mas você vai ter muito familiarizado com o arquivo I/O-- 483 00:22:32,580 --> 00:22:34,960 entrada e saída - com pset cinco. 484 00:22:34,960 --> 00:22:38,607 E qualquer dúvida sobre a fundamentos iniciais aqui? 485 00:22:38,607 --> 00:22:39,857 Sim? 486 00:22:39,857 --> 00:22:41,880 487 00:22:41,880 --> 00:22:43,710 >> E se você tentar libertar um valor nulo? 488 00:22:43,710 --> 00:22:48,880 Eu acredito que, a menos que tenha obtido a livre pouco mais user-friendly, você pode 489 00:22:48,880 --> 00:22:49,890 potencialmente segfault. 490 00:22:49,890 --> 00:22:54,160 Passando-o nulo é ruim porque eu não acreditam livre preocupa em verificar para você, 491 00:22:54,160 --> 00:22:57,330 porque seria potencialmente um desperdício de tempo para que ele faça a si mesmo para 492 00:22:57,330 --> 00:22:59,022 todos no mundo. 493 00:22:59,022 --> 00:23:00,590 Boa pergunta, no entanto. 494 00:23:00,590 --> 00:23:04,300 >> Tudo bem, então esse tipo de fica nos a um tema interessante. 495 00:23:04,300 --> 00:23:07,010 O tema do conjunto de problemas cinco é forense. 496 00:23:07,010 --> 00:23:08,420 Pelo menos essa é a parte do conjunto de problemas. 497 00:23:08,420 --> 00:23:12,030 Forensics geralmente se refere à recuperação de informações que podem ou 498 00:23:12,030 --> 00:23:14,110 não pode ter sido excluído deliberadamente. 499 00:23:14,110 --> 00:23:18,680 E então eu pensei que eu iria dar-lhe um rápido gosto do que realmente está acontecendo em todos os 500 00:23:18,680 --> 00:23:21,230 desta vez sob o capa de seu computador. 501 00:23:21,230 --> 00:23:23,960 >> Por exemplo, se você tem dentro do seu laptop ou computador de mesa a 502 00:23:23,960 --> 00:23:28,040 disco rígido, ou é um mecânico dispositivo que realmente gira - 503 00:23:28,040 --> 00:23:31,650 há coisas circulares chamados platters que parece muito com o que eu 504 00:23:31,650 --> 00:23:34,540 só tinha acima na tela aqui, embora esta é a escola cada vez mais velho. 505 00:23:34,540 --> 00:23:37,370 Esta é uma de três e meia polegadas disco rígido. 506 00:23:37,370 --> 00:23:40,070 E três centímetros e meio refere-se de com a coisa quando você instalá-lo 507 00:23:40,070 --> 00:23:40,890 em um computador. 508 00:23:40,890 --> 00:23:44,890 >> Muitos de vocês em seus laptops agora têm drives de estado sólido, ou SSD, 509 00:23:44,890 --> 00:23:46,260 que não têm partes móveis. 510 00:23:46,260 --> 00:23:49,170 Eles são mais como RAM e menos como estes dispositivos mecânicos. 511 00:23:49,170 --> 00:23:51,450 Mas as idéias ainda são os mesmos, certamente como eles se relacionam 512 00:23:51,450 --> 00:23:52,790 para o problema de definir cinco. 513 00:23:52,790 --> 00:23:57,400 >> E se você pensar agora um disco rígido representa ser um círculo, que 514 00:23:57,400 --> 00:23:58,930 Eu vou desenhar como este aqui. 515 00:23:58,930 --> 00:24:02,290 Quando você cria um arquivo no seu computador, se é um SSD, ou em 516 00:24:02,290 --> 00:24:06,610 Neste caso, uma antiga escola de disco rígido, esse arquivo é composto por vários bits. 517 00:24:06,610 --> 00:24:10,510 Vamos dizer que é este 0 e 1, um monte de 0s e 1s. 518 00:24:10,510 --> 00:24:11,660 Portanto, este é o meu disco rígido inteiro. 519 00:24:11,660 --> 00:24:13,225 Isto é, aparentemente, um arquivo muito grande. 520 00:24:13,225 --> 00:24:18,080 E ele está usando a 0s e 1s em que porção do prato física. 521 00:24:18,080 --> 00:24:19,750 >> Bem, o que é a parte física? 522 00:24:19,750 --> 00:24:25,310 Bem, acontece que em um disco rígido, pelo menos deste tipo, não há 523 00:24:25,310 --> 00:24:27,340 essas minúsculas partículas magnéticas. 524 00:24:27,340 --> 00:24:32,630 E eles têm essencialmente norte e pólos sul para eles, de modo que se você 525 00:24:32,630 --> 00:24:35,710 transformar uma dessas partículas magnéticas Desta forma, pode-se dizer que é 526 00:24:35,710 --> 00:24:36,720 representando um 1. 527 00:24:36,720 --> 00:24:39,340 E se está de cabeça para baixo para o sul para norte, você poderia dizer que é 528 00:24:39,340 --> 00:24:40,390 representa um 0. 529 00:24:40,390 --> 00:24:43,660 >> Assim, no mundo físico real, que é como você pode representar algo em 530 00:24:43,660 --> 00:24:45,670 estado binário de 0 a 1 e um. 531 00:24:45,670 --> 00:24:46,720 Então, isso é tudo que um arquivo é. 532 00:24:46,720 --> 00:24:49,300 Há um monte de magnético partículas que são deste modo ou sua 533 00:24:49,300 --> 00:24:51,920 Desta forma, a criação de padrões de 0s e 1s. 534 00:24:51,920 --> 00:24:56,760 >> Mas acontece quando você salvar um arquivo, algumas informações são salvas separadamente. 535 00:24:56,760 --> 00:25:00,000 Portanto, esta é uma pequena mesa, um diretório, por assim dizer. 536 00:25:00,000 --> 00:25:05,810 E eu vou chamar este nome de coluna e Vou ligar para este local coluna. 537 00:25:05,810 --> 00:25:08,850 >> E eu vou dizer, suponha este é o meu currículo. 538 00:25:08,850 --> 00:25:14,050 Meu RESUME.DOC é armazenado a localização, vamos dizer 123. 539 00:25:14,050 --> 00:25:15,390 Eu sempre vou para esse número. 540 00:25:15,390 --> 00:25:18,810 Mas basta dizer que, assim como na memória RAM, você pode levar um disco rígido 541 00:25:18,810 --> 00:25:22,350 isso é um gigabyte ou 200 gigabytes ou um terabyte, e você pode 542 00:25:22,350 --> 00:25:23,750 número de todos os bytes. 543 00:25:23,750 --> 00:25:26,480 Você pode enumerar todos os blocos de 8 bits. 544 00:25:26,480 --> 00:25:29,030 >> Então, vamos dizer que este é a localização 123. 545 00:25:29,030 --> 00:25:32,070 Portanto, este diretório dentro da minha operação sistema lembra que o meu 546 00:25:32,070 --> 00:25:34,250 currículo é no local 123. 547 00:25:34,250 --> 00:25:36,850 Mas fica interessante quando você apaga um arquivo. 548 00:25:36,850 --> 00:25:37,820 >> Assim, por exemplo - 549 00:25:37,820 --> 00:25:40,790 e, felizmente, a maior parte do mundo tem peguei para isso - o que acontece quando 550 00:25:40,790 --> 00:25:45,040 você arrastar um arquivo para seu sistema operacional Mac Trash ou a sua Lixeira do Windows? 551 00:25:45,040 --> 00:25:48,290 552 00:25:48,290 --> 00:25:50,510 Qual é a finalidade de fazer isso? 553 00:25:50,510 --> 00:25:53,860 É, obviamente, para livrar-se do arquivo, mas o que faz o ato de arrastar e 554 00:25:53,860 --> 00:25:57,550 cair em seu lixo ou o seu Lixeira fazer em um computador? 555 00:25:57,550 --> 00:25:59,230 >> Absolutamente nada, na verdade. 556 00:25:59,230 --> 00:26:00,320 É como uma pasta. 557 00:26:00,320 --> 00:26:01,800 É uma pasta especial, para ter certeza. 558 00:26:01,800 --> 00:26:04,460 Mas será que isso realmente excluir o arquivo? 559 00:26:04,460 --> 00:26:06,780 >> Bem, não, porque alguns de vocês provavelmente ter sido, oh caramba, você não fez 560 00:26:06,780 --> 00:26:07,420 quero fazer isso. 561 00:26:07,420 --> 00:26:09,130 Assim que você clicar duas vezes o Trash ou Lixeira. 562 00:26:09,130 --> 00:26:11,630 Você já cutucou ao redor e você recuperou o arquivo apenas arrastando-o 563 00:26:11,630 --> 00:26:12,110 de lá. 564 00:26:12,110 --> 00:26:14,420 Então, claramente, não é necessariamente excluí-lo. 565 00:26:14,420 --> 00:26:15,990 >> OK, você é mais esperto do que isso. 566 00:26:15,990 --> 00:26:18,860 Você sabe que apenas arrastando-o para o Trash ou Lixeira não significa 567 00:26:18,860 --> 00:26:19,930 você esvaziar a lixeira. 568 00:26:19,930 --> 00:26:24,110 Então você vai até o menu, e você diz Esvaziar Lixeira ou Esvaziar Lixeira. 569 00:26:24,110 --> 00:26:25,360 Então o que acontece? 570 00:26:25,360 --> 00:26:29,070 571 00:26:29,070 --> 00:26:32,530 >> Sim, por isso é eliminada mais. 572 00:26:32,530 --> 00:26:37,660 Mas tudo o que acontece é o seguinte. 573 00:26:37,660 --> 00:26:45,350 O computador se esquece de onde RESUME.DOC era. 574 00:26:45,350 --> 00:26:47,400 >> Mas o que não mudou, aparentemente, na foto? 575 00:26:47,400 --> 00:26:51,390 576 00:26:51,390 --> 00:26:55,570 Os bits, os 0s e 1s que eu afirmo é no local de algum aspecto físico 577 00:26:55,570 --> 00:26:56,280 o hardware. 578 00:26:56,280 --> 00:26:57,110 Eles ainda estão lá. 579 00:26:57,110 --> 00:26:58,930 É apenas o computador tem esqueceu o que eles são. 580 00:26:58,930 --> 00:27:03,160 >> Portanto, é essencialmente livre do arquivo bits de modo que eles podem ser reutilizados. 581 00:27:03,160 --> 00:27:06,940 Mas não até que você crie mais arquivos, e mais arquivos e mais arquivos serão 582 00:27:06,940 --> 00:27:12,150 probabilisticamente, os 0s e 1s, aquelas partículas magnéticas, são reutilizados, 583 00:27:12,150 --> 00:27:16,220 de cabeça ou do lado direito para cima, para outros arquivos, 0s e 1s. 584 00:27:16,220 --> 00:27:17,980 >> Então você tem essa janela de tempo. 585 00:27:17,980 --> 00:27:19,860 E não é de previsível comprimento, realmente. 586 00:27:19,860 --> 00:27:22,240 Depende do tamanho do seu disco unidade e quantos arquivos você tem e 587 00:27:22,240 --> 00:27:23,490 o quão rápido você fazer novos. 588 00:27:23,490 --> 00:27:27,050 Mas há esta janela de tempo durante o que esse arquivo ainda é perfeitamente 589 00:27:27,050 --> 00:27:27,770 recuperável. 590 00:27:27,770 --> 00:27:31,050 >> Então, se você nunca usar programas como o McAfee ou Norton para tentar recuperar 591 00:27:31,050 --> 00:27:35,680 de dados, tudo o que estamos fazendo é tentando recuperar este chamado diretório para 592 00:27:35,680 --> 00:27:37,340 descobrir onde o arquivo foi. 593 00:27:37,340 --> 00:27:40,605 E às vezes Norton e dirá: do arquivo é de 93% recuperável. 594 00:27:40,605 --> 00:27:42,020 Bem, o que isso significa? 595 00:27:42,020 --> 00:27:45,690 Isso só significa que algum outro arquivo coincidentemente acabou usando, por exemplo, 596 00:27:45,690 --> 00:27:48,920 esses bits fora do seu arquivo original. 597 00:27:48,920 --> 00:27:51,950 >> Então, o que está realmente envolvido na recuperação de dados? 598 00:27:51,950 --> 00:27:55,720 Bem, se você não tem algo parecido Norton pré-instalado em seu computador, 599 00:27:55,720 --> 00:27:59,510 o melhor que você às vezes pode fazer é olhar em todo o disco rígido à procura de 600 00:27:59,510 --> 00:28:00,510 padrões de bits. 601 00:28:00,510 --> 00:28:05,350 E um dos temas do conjunto de problemas cinco é que você vai pesquisar a 602 00:28:05,350 --> 00:28:09,570 equivalente a um disco rígido, um forense imagem de um cartão de memória flash compacto a partir de um 603 00:28:09,570 --> 00:28:13,660 câmera digital, buscando a 0s 1s e que normalmente, com elevada 604 00:28:13,660 --> 00:28:16,720 probabilidade, representam o início de uma imagem JPEG. 605 00:28:16,720 --> 00:28:21,120 >> E vocês podem recuperar aquelas imagens por supondo que, se eu vejo esse padrão de 606 00:28:21,120 --> 00:28:24,380 bits na imagem forense, com elevada probabilidade, que marca 607 00:28:24,380 --> 00:28:25,650 o início de um JPEG. 608 00:28:25,650 --> 00:28:29,520 E se eu ver o mesmo padrão de novo, que provavelmente marca o início de 609 00:28:29,520 --> 00:28:32,440 outro JPEG, e outro JPEG, e outro JPEG. 610 00:28:32,440 --> 00:28:34,970 E este é tipicamente como recuperação de dados vai funcionar. 611 00:28:34,970 --> 00:28:37,870 O que é agradável sobre JPEGs é mesmo o formato de arquivo em si é um pouco 612 00:28:37,870 --> 00:28:44,400 complexo, no início de cada tal arquivo é realmente bastante identificável 613 00:28:44,400 --> 00:28:47,370 e simples, como você vai ver, Se você não tiver já. 614 00:28:47,370 --> 00:28:50,270 >> Então, vamos dar uma olhada embaixo o capô como a exatamente o que tem sido 615 00:28:50,270 --> 00:28:53,360 acontecendo, e que estes 0s e 1s são, para lhe dar um pouco mais de um 616 00:28:53,360 --> 00:28:55,330 contexto para este desafio particular. 617 00:28:55,330 --> 00:28:55,510 >> [REPRODUÇÃO] 618 00:28:55,510 --> 00:28:58,700 >> -Onde seu PC armazena mais dos seus dados permanentes. 619 00:28:58,700 --> 00:29:03,390 Para isso, os dados viajam de RAM juntamente com os sinais de software que contam 620 00:29:03,390 --> 00:29:06,110 o disco rígido como armazenar esses dados. 621 00:29:06,110 --> 00:29:09,410 Os circuitos do disco rígido traduzir esses sinais em tensão 622 00:29:09,410 --> 00:29:10,870 flutuações. 623 00:29:10,870 --> 00:29:14,970 Estes, por sua vez, controlam o disco rígido do partes móveis, alguns dos poucos 624 00:29:14,970 --> 00:29:17,910 partes móveis deixados no computador moderno. 625 00:29:17,910 --> 00:29:22,130 >> Alguns dos sinais de controlo de um motor que gira bandejas de metal revestidas. 626 00:29:22,130 --> 00:29:25,470 Seus dados são realmente armazenados sobre estas travessas. 627 00:29:25,470 --> 00:29:28,610 Outros sinais de mover a leitura / gravação cabeças de leitura ou 628 00:29:28,610 --> 00:29:30,710 gravar dados sobre os pratos. 629 00:29:30,710 --> 00:29:35,450 Esta máquina tão preciso que um ser humano cabelo não poderia mesmo passar entre a 630 00:29:35,450 --> 00:29:37,280 cabeças e pratos giratórios. 631 00:29:37,280 --> 00:29:40,316 No entanto, tudo funciona em velocidades incríveis. 632 00:29:40,316 --> 00:29:40,660 >> [FIM REPRODUÇÃO DE VÍDEO] 633 00:29:40,660 --> 00:29:42,190 >> DAVID MALAN: Zoom em um pouco mais profunda agora o que está 634 00:29:42,190 --> 00:29:44,360 realmente nesses pratos. 635 00:29:44,360 --> 00:29:44,720 >> [REPRODUÇÃO] 636 00:29:44,720 --> 00:29:47,660 >> -Vejamos o que acabamos de vi em câmera lenta. 637 00:29:47,660 --> 00:29:51,710 Quando um breve pulso de eletricidade é enviado para a cabeça de leitura / gravação, se vira 638 00:29:51,710 --> 00:29:54,650 em uma pequena electromagnética para uma fração de segundo. 639 00:29:54,650 --> 00:29:58,970 O ímã cria um campo, que muda a polaridade de um pequeno, minúsculo 640 00:29:58,970 --> 00:30:02,850 parte das partículas metálicas que casaco de cada superfície do prato. 641 00:30:02,850 --> 00:30:05,940 >> A série padrão desses pequenos, cobrada até áreas no disco 642 00:30:05,940 --> 00:30:08,470 representa um único bit dados no número binário 643 00:30:08,470 --> 00:30:10,530 sistema usado pelos computadores. 644 00:30:10,530 --> 00:30:13,775 Agora, se a corrente é enviada uma maneira através da leitura / escrita cabeça, a área 645 00:30:13,775 --> 00:30:15,970 é polarizada em uma direção. 646 00:30:15,970 --> 00:30:17,950 Se a corrente é enviada na sentido oposto, o 647 00:30:17,950 --> 00:30:19,930 polarização é invertida. 648 00:30:19,930 --> 00:30:22,370 >> Como você obter dados fora do disco rígido? 649 00:30:22,370 --> 00:30:24,090 Apenas reverter o processo. 650 00:30:24,090 --> 00:30:26,550 Por isso é que as partículas no disco que obtenha a corrente no 651 00:30:26,550 --> 00:30:27,960 leitura / escrita cabeça se movendo. 652 00:30:27,960 --> 00:30:30,700 Juntos milhões destes segmentos magnetizados e 653 00:30:30,700 --> 00:30:32,160 você tem um arquivo. 654 00:30:32,160 --> 00:30:36,060 >> Agora, as peças de um único arquivo pode ser espalhados por toda a unidade de 655 00:30:36,060 --> 00:30:39,970 pratos, como o tipo de bagunça de papéis em sua mesa. 656 00:30:39,970 --> 00:30:43,500 Assim, um arquivo muito especial mantém o controle de onde está tudo. 657 00:30:43,500 --> 00:30:45,985 Você não gostaria de ter algo assim? 658 00:30:45,985 --> 00:30:46,470 >> [FIM REPRODUÇÃO DE VÍDEO] 659 00:30:46,470 --> 00:30:47,820 >> DAVID MALAN: OK, provavelmente não. 660 00:30:47,820 --> 00:30:52,070 Assim como muitos de vocês Cresci com isso? 661 00:30:52,070 --> 00:30:53,970 OK, por isso é cada vez menos mãos a cada ano. 662 00:30:53,970 --> 00:30:56,550 Mas eu estou feliz que você esteja pelo menos familiarizado com eles, porque este e a nossa própria 663 00:30:56,550 --> 00:31:00,520 demonstração livro, infelizmente, estão morrendo muito retardar a morte aqui de familiaridade. 664 00:31:00,520 --> 00:31:04,010 >> Mas isso é o que eu, pelo menos, de volta ensino médio, o uso usada para backups. 665 00:31:04,010 --> 00:31:08,110 E foi incrível, porque você pode armazenar 1,4 megabytes em 666 00:31:08,110 --> 00:31:08,930 este disco em particular. 667 00:31:08,930 --> 00:31:12,260 E esta foi a versão de alta densidade, como indicado pela HD, que tem 668 00:31:12,260 --> 00:31:14,240 ou seja, antes de videos de hoje em HD. 669 00:31:14,240 --> 00:31:16,400 >> Densidade padrão era de 800 kilobytes. 670 00:31:16,400 --> 00:31:18,640 E antes disso, havia Discos de 400 kilobytes. 671 00:31:18,640 --> 00:31:23,120 E antes disso, havia 5 e 1/4 discos polegadas, que eram verdadeiramente flexível, 672 00:31:23,120 --> 00:31:25,680 e um pouco mais largo e mais alto que essas coisas aqui. 673 00:31:25,680 --> 00:31:29,150 Mas você pode realmente ver o chamado aspecto disquete destes discos. 674 00:31:29,150 --> 00:31:32,630 >> E funcionalmente, eles são realmente bastante semelhante ao de discos rígidos de pelo 675 00:31:32,630 --> 00:31:33,570 menos deste tipo. 676 00:31:33,570 --> 00:31:37,270 Mais uma vez, os SSDs em computadores mais novos trabalhar um pouco diferente. 677 00:31:37,270 --> 00:31:41,530 Mas se você se move, que guia de metal pouco, você pode realmente ver um pouco de biscoito, 678 00:31:41,530 --> 00:31:42,560 ou travessa. 679 00:31:42,560 --> 00:31:43,830 >> Não é de metal como este. 680 00:31:43,830 --> 00:31:46,000 Este é realmente um pouco mais barato material plástico. 681 00:31:46,000 --> 00:31:46,750 E você pode tipo de manobra-lo. 682 00:31:46,750 --> 00:31:50,310 E você trully apenas limpou alguns número de bits ou partículas magnéticas 683 00:31:50,310 --> 00:31:51,220 a partir deste disco. 684 00:31:51,220 --> 00:31:52,710 >> Então, graças a Deus, não há nada sobre ele. 685 00:31:52,710 --> 00:31:55,790 Se aquela coisa está no caminho - e cobrir seus olhos e os de seu vizinho - 686 00:31:55,790 --> 00:31:58,865 você pode apenas puxar este tipo de toda off bainha assim. 687 00:31:58,865 --> 00:32:01,900 Mas há uma pequena mola, que assim seja ciente de que, com os seus olhos. 688 00:32:01,900 --> 00:32:03,620 Então agora você tem realmente um disquete. 689 00:32:03,620 --> 00:32:07,090 >> E o que é notável sobre esta é que, na medida em que este é um 690 00:32:07,090 --> 00:32:10,830 representação em pequena escala de uma maior disco rígido, essas coisas são super, 691 00:32:10,830 --> 00:32:11,590 super simples. 692 00:32:11,590 --> 00:32:15,170 Se você apertar a parte inferior do mesmo, agora que que coisa de metal está fora, e descasque 693 00:32:15,170 --> 00:32:20,990 las abertas, tudo o que há é duas peças de feltros e o chamado disquete 694 00:32:20,990 --> 00:32:22,930 com uma peça de metal no interior. 695 00:32:22,930 --> 00:32:25,990 >> E lá se vai metade do conteúdo do meu disco. 696 00:32:25,990 --> 00:32:27,540 Lá vai outra metade deles. 697 00:32:27,540 --> 00:32:31,375 Mas isso é tudo o que estava girando dentro de seu computador no passado. 698 00:32:31,375 --> 00:32:35,220 699 00:32:35,220 --> 00:32:38,310 >> E, novamente, para colocar isto em perspectiva, quão grande é a maioria de seu 700 00:32:38,310 --> 00:32:39,560 discos rígidos de hoje em dia? 701 00:32:39,560 --> 00:32:41,960 702 00:32:41,960 --> 00:32:46,230 500 gigabytes, um terabyte, talvez em um computador desktop, dois terabytes, 3 703 00:32:46,230 --> 00:32:47,630 terabytes, 4 terabytes, certo? 704 00:32:47,630 --> 00:32:52,480 Este é um megabyte, mais ou menos, que não pode sequer colocar um MP3 típico 705 00:32:52,480 --> 00:32:55,310 digitamos mais alguns dias ou algumas arquivo de música similar. 706 00:32:55,310 --> 00:32:59,500 >> Assim, uma pequena lembrança para você hoje, e também para ajudar a contextualizar o 707 00:32:59,500 --> 00:33:03,570 nós vamos tomar para concedido agora no problema definir cinco. 708 00:33:03,570 --> 00:33:04,820 Portanto, estas são de sua propriedade. 709 00:33:04,820 --> 00:33:07,340 710 00:33:07,340 --> 00:33:13,370 Então deixe-me transição para onde será passar a próxima pset bem. 711 00:33:13,370 --> 00:33:18,470 Então, nós temos agora definir esta página para - oh, um par de anúncios rapidamente. 712 00:33:18,470 --> 00:33:21,730 >> Nesta sexta-feira, se você quiser se juntar a CS50 para o almoço, vá para o lugar de costume, 713 00:33:21,730 --> 00:33:23,610 cs50.net/rsvp. 714 00:33:23,610 --> 00:33:25,100 E projeto final - 715 00:33:25,100 --> 00:33:28,520 então por o programa, nós postamos o especificação do projeto final já. 716 00:33:28,520 --> 00:33:31,410 Perceba que isso não significa que é devido particularmente em breve. 717 00:33:31,410 --> 00:33:33,990 Está publicado, na verdade, apenas para obter vocês pensando nisso. 718 00:33:33,990 --> 00:33:37,620 E, de fato, um super significativa percentagem será enfrentar 719 00:33:37,620 --> 00:33:40,780 projetos finais de material que nem sequer chegou a na classe, 720 00:33:40,780 --> 00:33:42,730 mas será já na próxima semana. 721 00:33:42,730 --> 00:33:45,530 >> Observe, porém, que a especificação exige alguns componentes diferentes do 722 00:33:45,530 --> 00:33:46,190 projeto final. 723 00:33:46,190 --> 00:33:49,590 A primeira, em algumas semanas, é um pré-proposta, um e-mail muito casual para 724 00:33:49,590 --> 00:33:52,760 o TF para lhe dizer ou o que você está pensando para o seu projeto, com 725 00:33:52,760 --> 00:33:53,650 nenhum compromisso. 726 00:33:53,650 --> 00:33:56,710 Proposta será seu especial compromisso, dizendo, aqui, é isso que 727 00:33:56,710 --> 00:33:57,770 Eu gostaria de fazer para o meu projeto. 728 00:33:57,770 --> 00:33:58,250 O que você acha? 729 00:33:58,250 --> 00:33:58,650 Muito grande? 730 00:33:58,650 --> 00:33:59,145 Muito pequena? 731 00:33:59,145 --> 00:34:00,330 É viável? 732 00:34:00,330 --> 00:34:02,230 E você vê a especificação para mais detalhes. 733 00:34:02,230 --> 00:34:05,060 >> Duas semanas após o que é o estado relatório, que é uma forma semelhante 734 00:34:05,060 --> 00:34:08,260 email casual para o seu TF para dizer o quão muito para trás você está no seu final, 735 00:34:08,260 --> 00:34:12,360 implementação do projeto, seguido por o CS50 Hackathon para o qual todos 736 00:34:12,360 --> 00:34:17,520 é convidado, que será um evento de 20:00 em uma noite até 07:00 737 00:34:17,520 --> 00:34:19,150 AM na manhã seguinte. 738 00:34:19,150 --> 00:34:22,560 Pizza, como eu já mencionei na semana zero, wil ser servido às 9:00 horas, 739 00:34:22,560 --> 00:34:24,120 Comida chinesa em 1h00. 740 00:34:24,120 --> 00:34:27,929 E se você ainda estiver acordado à 5h00, vamos levá-lo para IHOP no café da manhã. 741 00:34:27,929 --> 00:34:31,310 >> Assim, o Hackathon é um dos mais experiências memoráveis ​​na classe. 742 00:34:31,310 --> 00:34:35,290 Em seguida, a implementação é devido, e em seguida, o CS50 Fair clímax. 743 00:34:35,290 --> 00:34:38,070 Mais detalhes sobre todos esses nas semanas que virão. 744 00:34:38,070 --> 00:34:40,739 >> Mas vamos voltar para algo escola de idade - 745 00:34:40,739 --> 00:34:41,920 outra vez, uma matriz. 746 00:34:41,920 --> 00:34:45,040 Assim, uma matriz foi bom, porque ele resolve problemas como vimos apenas um 747 00:34:45,040 --> 00:34:49,290 momento atrás, com estruturas estudantis ficando um pouco fora de controle se 748 00:34:49,290 --> 00:34:52,405 quer ter um aluno, estudante dois, estudante três, estudante dot dot dot, 749 00:34:52,405 --> 00:34:54,400 um número arbitrário de alunos. 750 00:34:54,400 --> 00:34:58,850 >> Então, matrizes, algumas semanas atrás, mergulhou em e resolveu todos os nossos problemas de não 751 00:34:58,850 --> 00:35:03,340 sabendo de antemão quantas coisas de algum tipo que pode querer. 752 00:35:03,340 --> 00:35:07,390 E temos visto que estruturas pode nos ajudar ainda organizar e manter o nosso código 753 00:35:07,390 --> 00:35:11,660 variáveis ​​conceitualmente semelhantes, como a nome e uma casa, em conjunto, de modo que podemos 754 00:35:11,660 --> 00:35:15,570 pode tratá-los como uma entidade, dentro dos quais existem pedaços menores. 755 00:35:15,570 --> 00:35:17,810 >> Mas matrizes têm algumas desvantagens. 756 00:35:17,810 --> 00:35:19,780 Quais são algumas das desvantagens nós encontramos 757 00:35:19,780 --> 00:35:22,320 com matrizes até agora? 758 00:35:22,320 --> 00:35:23,450 O que é isso? 759 00:35:23,450 --> 00:35:28,130 Tamanho fixo - isso mesmo que você poderia ser capaz de alocar memória para um 760 00:35:28,130 --> 00:35:32,310 matriz, uma vez que você sabe quantos alunos você tem, quantos caracteres você tem 761 00:35:32,310 --> 00:35:35,460 do usuário, uma vez que você tenha alocado a matriz, você tipo de pintado 762 00:35:35,460 --> 00:35:36,740 sozinho em um canto. 763 00:35:36,740 --> 00:35:40,600 >> Porque você não pode inserir novos elementos no meio de uma matriz. 764 00:35:40,600 --> 00:35:43,660 Você não pode inserir mais elementos no final de uma matriz. 765 00:35:43,660 --> 00:35:47,750 Realmente, você tem que recorrer à criação de um Toda nova matriz, como já discutido, 766 00:35:47,750 --> 00:35:49,320 copiando o antigo para o novo. 767 00:35:49,320 --> 00:35:52,610 E mais uma vez, que é a dor de cabeça que Lida com GetString para você. 768 00:35:52,610 --> 00:35:56,170 >> Mas, novamente, você não pode ainda inserir algo no meio da matriz 769 00:35:56,170 --> 00:35:58,200 se a taxa não está completamente cheia. 770 00:35:58,200 --> 00:36:03,010 Por exemplo, se essa matriz aqui de tamanho seis tem apenas cinco coisas nele, 771 00:36:03,010 --> 00:36:06,080 Bem, você pode apenas alinhavar algo para o efeito. 772 00:36:06,080 --> 00:36:08,200 Mas e se você quiser inserir algo no meio da 773 00:36:08,200 --> 00:36:11,280 matriz, embora possa ter cinco dos seis coisas nele? 774 00:36:11,280 --> 00:36:14,250 >> Bem, o que nós fizemos quando tivemos tudo dos nossos voluntários humanos no palco 775 00:36:14,250 --> 00:36:15,110 semana passado? 776 00:36:15,110 --> 00:36:18,710 Se quiséssemos colocar alguém aqui, também essas pessoas como mover este 777 00:36:18,710 --> 00:36:22,540 modo, ou essas pessoas como mover este forma, e que se tornou caro. 778 00:36:22,540 --> 00:36:26,950 O deslocamento de pessoas no interior de um série acabou somando e custando 779 00:36:26,950 --> 00:36:31,240 nos tempo, portanto, muito do nosso n ao quadrado vezes funcionando como um tipo de inserção, por 780 00:36:31,240 --> 00:36:32,550 exemplo, no pior dos casos. 781 00:36:32,550 --> 00:36:36,520 Assim, as matrizes são grandes, mas você tem que saber de antemão o quão grande você quiser. 782 00:36:36,520 --> 00:36:38,030 >> Então, bem, aqui está a solução. 783 00:36:38,030 --> 00:36:43,860 Se eu não saber de antemão quantos os alunos que eu poderia ter, e eu sei que uma vez 784 00:36:43,860 --> 00:36:47,870 Eu decido, porém, eu estou preso com que muitos estudantes, por que não eu sempre 785 00:36:47,870 --> 00:36:51,740 alocar o dobro do espaço como eu poderia pensar que eu preciso? 786 00:36:51,740 --> 00:36:54,450 Isso não é uma solução razoável? 787 00:36:54,450 --> 00:36:58,240 >> Na realidade, eu não acho que nós somos vai precisar de mais de 50 vagas 788 00:36:58,240 --> 00:37:02,190 em uma matriz para uma classe de tamanho médio, então vamos arredondar para cima. 789 00:37:02,190 --> 00:37:07,040 Vou fazer 100 slots em meu array, apenas para que possamos definitivamente o 790 00:37:07,040 --> 00:37:10,330 número de alunos que esperam ser, de alguma classe de tamanho médio. 791 00:37:10,330 --> 00:37:14,320 Então por que não reunir e alocar mais memória, tipicamente, por uma matriz 792 00:37:14,320 --> 00:37:16,290 que você acha que pode até mesmo precisar? 793 00:37:16,290 --> 00:37:20,190 O que é isso pushback simples a essa idéia? 794 00:37:20,190 --> 00:37:21,440 >> Você está apenas perdendo memória. 795 00:37:21,440 --> 00:37:25,350 Literalmente todos os programas que você escreve, em seguida, é talvez usando o dobro da memória como 796 00:37:25,350 --> 00:37:26,680 você realmente precisa. 797 00:37:26,680 --> 00:37:28,990 E isso só não se sente como um particularmente solução elegante. 798 00:37:28,990 --> 00:37:31,990 Além disso, apenas diminui o probabilidade de um problema. 799 00:37:31,990 --> 00:37:35,300 Se acontecer de você ter um curso popular um semestre e tem 101 800 00:37:35,300 --> 00:37:39,610 estudantes, o programa ainda é fundamentalmente enfrentando o mesmo problema. 801 00:37:39,610 --> 00:37:44,280 >> Então, felizmente, há uma solução para Esse anúncio todos os nossos problemas, na forma 802 00:37:44,280 --> 00:37:46,790 de estruturas de dados que são mais complexos do que os 803 00:37:46,790 --> 00:37:47,970 temos visto até agora. 804 00:37:47,970 --> 00:37:50,530 Isso, eu afirmo, é uma lista encadeada. 805 00:37:50,530 --> 00:37:51,920 Esta é uma lista de números - 806 00:37:51,920 --> 00:37:54,970 9, 17, 22, 26 e 34 - 807 00:37:54,970 --> 00:38:00,120 que foram ligadas entre si por forma do que eu desenhei como flechas. 808 00:38:00,120 --> 00:38:03,580 >> Em outras palavras, se eu queria representar uma matriz, que eu poderia fazer 809 00:38:03,580 --> 00:38:04,910 algo como isto. 810 00:38:04,910 --> 00:38:07,310 E eu vou colocar isso a sobrecarga em apenas um momento. 811 00:38:07,310 --> 00:38:09,970 Eu poderia fazer - 812 00:38:09,970 --> 00:38:12,520 Olá, tudo bem. 813 00:38:12,520 --> 00:38:14,470 Stand by. 814 00:38:14,470 --> 00:38:17,360 Novo computador aqui, claro - 815 00:38:17,360 --> 00:38:18,090 tudo bem. 816 00:38:18,090 --> 00:38:21,730 >> Então, se eu tenho esses números em ordem - 817 00:38:21,730 --> 00:38:28,880 9, 17, 22, 26, 24 - 818 00:38:28,880 --> 00:38:30,530 não necessariamente à escala. 819 00:38:30,530 --> 00:38:33,730 Tudo bem, isso aqui é minha matriz - 820 00:38:33,730 --> 00:38:34,980 oh meu deus. 821 00:38:34,980 --> 00:38:38,700 822 00:38:38,700 --> 00:38:40,395 Tudo bem, isso aqui é minha matriz. 823 00:38:40,395 --> 00:38:44,110 824 00:38:44,110 --> 00:38:45,050 Oh meu deus. 825 00:38:45,050 --> 00:38:48,820 >> [Risos] 826 00:38:48,820 --> 00:38:49,440 >> DAVID MALAN: Pretend. 827 00:38:49,440 --> 00:38:52,330 É muito esforço para voltar e corrigir isso, então lá - 828 00:38:52,330 --> 00:38:54,290 26. 829 00:38:54,290 --> 00:38:57,650 Então nós temos esse conjunto de 9, 17, 22, 26, e 34. 830 00:38:57,650 --> 00:39:00,260 Para aqueles de vocês pode ver o erro embaraçoso que acabou de fazer, 831 00:39:00,260 --> 00:39:00,830 aí está. 832 00:39:00,830 --> 00:39:04,490 >> Então, eu afirmo que este é um solução muito eficiente. 833 00:39:04,490 --> 00:39:07,310 Eu alocado como muitos ints como Eu preciso - um, dois, três, 834 00:39:07,310 --> 00:39:09,100 quatro, cinco ou seis - 835 00:39:09,100 --> 00:39:11,660 e eu então armazenados os números dentro dessa matriz. 836 00:39:11,660 --> 00:39:15,220 Mas vamos supor que, então, eu quero inserir um valor como o número 8? 837 00:39:15,220 --> 00:39:16,100 Bem, para onde ela vai? 838 00:39:16,100 --> 00:39:18,530 Suponha que eu queira inserir um número como 20. 839 00:39:18,530 --> 00:39:19,790 Bem, para onde ele vai? 840 00:39:19,790 --> 00:39:23,160 Em algum lugar no meio, ou o número 35 tem de passar 841 00:39:23,160 --> 00:39:24,010 algures no final. 842 00:39:24,010 --> 00:39:25,320 Mas eu estou fora do espaço. 843 00:39:25,320 --> 00:39:29,120 >> E por isso este é um desafio fundamental das matrizes que não são a solução. 844 00:39:29,120 --> 00:39:32,280 Afirmei há pouco, GetString resolve este problema. 845 00:39:32,280 --> 00:39:37,380 Se você deseja inserir um sexto número nessa matriz, o que é, pelo menos, um 846 00:39:37,380 --> 00:39:40,090 solução que você pode voltar a cair, com certeza, assim como fazemos com GetString? 847 00:39:40,090 --> 00:39:44,340 848 00:39:44,340 --> 00:39:46,030 O que é isso? 849 00:39:46,030 --> 00:39:48,190 >> Bem, torná-lo maior é mais fácil de dizer do que fazer. 850 00:39:48,190 --> 00:39:52,810 Nós não podemos necessariamente fazer a matriz maior, mas o que podemos fazer? 851 00:39:52,810 --> 00:39:56,570 Faça uma nova matriz que é maior, de tamanho 6, ou talvez tamanho 10, se quisermos 852 00:39:56,570 --> 00:40:00,490 para chegar à frente das coisas, e então copie o array antigo para o novo, e, em seguida, 853 00:40:00,490 --> 00:40:01,680 libertar a antiga matriz. 854 00:40:01,680 --> 00:40:05,770 >> Mas o que é o tempo de execução agora desse processo? 855 00:40:05,770 --> 00:40:09,870 É grande S de n, porque a cópia vai lhe custar algumas unidades de 856 00:40:09,870 --> 00:40:13,480 tempo, por isso não é tão ideal, se for preciso alocar uma nova matriz, o que está acontecendo 857 00:40:13,480 --> 00:40:15,610 para consumir o dobro memória temporária. 858 00:40:15,610 --> 00:40:16,660 Copie velho em novo - 859 00:40:16,660 --> 00:40:18,800 Quero dizer, é só uma dor de cabeça, que é, mais uma vez, por que nós escrevemos 860 00:40:18,800 --> 00:40:19,920 GetString para você. 861 00:40:19,920 --> 00:40:21,380 >> Então, o que podemos fazer em vez disso? 862 00:40:21,380 --> 00:40:25,000 Bem, e se a nossa estrutura de dados na verdade, tem lacunas nele? 863 00:40:25,000 --> 00:40:30,790 Suponha que eu relaxo meu objetivo de ter blocos contíguos de memória, onde 9 864 00:40:30,790 --> 00:40:34,500 é bem próximo a 17, o que é ao lado 22, e assim por diante. 865 00:40:34,500 --> 00:40:39,570 >> E suponha que 9 pode ser aqui em RAM, e 17 pode ser aqui na RAM, 866 00:40:39,570 --> 00:40:40,990 e 22 pode ser aqui na RAM. 867 00:40:40,990 --> 00:40:43,610 Em outras palavras, eu não preciso deles mesmo voltar para trás mais. 868 00:40:43,610 --> 00:40:47,850 Eu só tenho que de alguma forma enfiar uma agulha através de cada um desses números, ou cada 869 00:40:47,850 --> 00:40:51,010 desses nós, como vamos chamar o retângulos como eu desenhei-los, para 870 00:40:51,010 --> 00:40:55,670 lembrar de como chegar até o último tal nó do primeiro. 871 00:40:55,670 --> 00:40:59,940 >> Então o que é construir a programação vimos há pouco tempo com o qual eu 872 00:40:59,940 --> 00:41:03,030 pode implementar esse segmento, ou traçada aqui, com o qual eu posso 873 00:41:03,030 --> 00:41:05,430 implementar essas flechas? 874 00:41:05,430 --> 00:41:06,500 Ponteiros assim, certo? 875 00:41:06,500 --> 00:41:09,560 Se eu não alocar apenas um int, mas um nó - e por 876 00:41:09,560 --> 00:41:10,810 nó, eu só quero dizer container. 877 00:41:10,810 --> 00:41:12,900 E visualmente, eu quero dizer um retângulo. 878 00:41:12,900 --> 00:41:16,420 Assim, um nó aparentemente precisa para conter dois valores - 879 00:41:16,420 --> 00:41:21,490 o próprio int, e então, como se conclui da a metade inferior do retângulo, 880 00:41:21,490 --> 00:41:23,010 espaço suficiente para um int. 881 00:41:23,010 --> 00:41:26,130 >> Então, basta pensar no futuro aqui, quão grande é este nó, este 882 00:41:26,130 --> 00:41:27,170 recipiente em questão? 883 00:41:27,170 --> 00:41:29,250 Quantos bytes para o int? 884 00:41:29,250 --> 00:41:31,310 Presumivelmente, 4, se é o mesmo que o habitual. 885 00:41:31,310 --> 00:41:33,270 E então quantos bytes para o ponteiro? 886 00:41:33,270 --> 00:41:33,650 4. 887 00:41:33,650 --> 00:41:37,940 Portanto, este recipiente, ou esse nó, é vai ser uma estrutura de 8 bytes. 888 00:41:37,940 --> 00:41:41,760 Oh, e isso é uma feliz coincidência que que acaba de introduzir a noção de 889 00:41:41,760 --> 00:41:44,400 uma estrutura, ou uma estrutura C. 890 00:41:44,400 --> 00:41:48,890 >> Então eu reclamar que eu quero dar um passo para isso mais sofisticado 891 00:41:48,890 --> 00:41:52,560 implementação de uma lista de números, um lista encadeada de números, eu preciso fazer uma 892 00:41:52,560 --> 00:41:56,920 pouco mais o pensamento na frente e declarar não apenas um int, mas um struct 893 00:41:56,920 --> 00:41:58,620 que eu ligo, convencionalmente aqui nó. 894 00:41:58,620 --> 00:42:01,630 Poderíamos chamá-lo de qualquer coisa que quisermos, mas nó vai ser temática em um monte 895 00:42:01,630 --> 00:42:03,560 das coisas que começar a olhar para agora. 896 00:42:03,560 --> 00:42:06,480 >> Dentro desse nó é um int n. 897 00:42:06,480 --> 00:42:09,350 E então essa sintaxe, um pouco estranho à primeira vista - 898 00:42:09,350 --> 00:42:12,960 struct node * seguinte. 899 00:42:12,960 --> 00:42:16,900 Bem pictoricamente, o que é isso? 900 00:42:16,900 --> 00:42:21,000 Essa é a metade inferior da o retângulo que vimos 901 00:42:21,000 --> 00:42:22,730 apenas um momento atrás. 902 00:42:22,730 --> 00:42:27,600 >> Mas por que estou dizendo struct node * ao invés de apenas nó *? 903 00:42:27,600 --> 00:42:31,370 Porque se esse ponteiro está apontando em outro nó, ele é apenas o 904 00:42:31,370 --> 00:42:32,760 endereço de um nó. 905 00:42:32,760 --> 00:42:35,630 Isso é consistente com o que nós temos discutido sobre ponteiros até o momento. 906 00:42:35,630 --> 00:42:39,690 Mas por que, se eu reclamar esta estrutura é chamado de nó, que eu tenho a dizer struct 907 00:42:39,690 --> 00:42:42,660 nó aqui dentro? 908 00:42:42,660 --> 00:42:43,190 >> Exatamente. 909 00:42:43,190 --> 00:42:46,490 É uma espécie de uma realidade estúpida C. O typedef, por assim dizer, não tem 910 00:42:46,490 --> 00:42:47,220 aconteceu ainda. 911 00:42:47,220 --> 00:42:48,510 C é super literal. 912 00:42:48,510 --> 00:42:51,050 Ele lê o seu código para cima baixo, da esquerda para a direita. 913 00:42:51,050 --> 00:42:54,930 E até atingir esse ponto e vírgula no linha de fundo, acho que não funciona 914 00:42:54,930 --> 00:42:57,590 existir como um tipo de dados? 915 00:42:57,590 --> 00:42:59,060 Nó, o nó entre aspas. 916 00:42:59,060 --> 00:43:03,050 >> Mas por causa da mais detalhado declaração que eu fiz na primeira linha - 917 00:43:03,050 --> 00:43:05,340 typedef struct node - 918 00:43:05,340 --> 00:43:08,790 porque que veio primeiro, antes do chaves, que é uma espécie de como 919 00:43:08,790 --> 00:43:11,800 pré-educar Clang isso, você Sabe, me dê um struct 920 00:43:11,800 --> 00:43:13,570 chamado nó struct. 921 00:43:13,570 --> 00:43:16,270 Francamente, eu não gosto de coisas que chamam struct node, struct node tudo 922 00:43:16,270 --> 00:43:17,090 todo o meu código. 923 00:43:17,090 --> 00:43:20,660 Mas eu só vou usá-lo uma vez, apenas dentro, para que eu possa efetivamente 924 00:43:20,660 --> 00:43:25,010 criar uma espécie de referência circular, não um ponteiro para mim mesmo, por si só, mas uma 925 00:43:25,010 --> 00:43:29,400 apontador para outra um do mesmo tipo. 926 00:43:29,400 --> 00:43:32,330 >> Assim, verifica-se que em uma estrutura de dados assim, há alguns 927 00:43:32,330 --> 00:43:34,470 as operações que podem ser de interesse para nós. 928 00:43:34,470 --> 00:43:37,460 Podemos querer inserir em uma lista como esta. 929 00:43:37,460 --> 00:43:39,850 Podemos querer apagar a partir de uma lista como esta. 930 00:43:39,850 --> 00:43:43,490 Podemos querer pesquisar a lista para um valor, ou, mais geralmente, travessia. 931 00:43:43,490 --> 00:43:46,410 E transversal é apenas uma maneira elegante de dizendo início à esquerda e mover todos 932 00:43:46,410 --> 00:43:47,650 o caminho para a direita. 933 00:43:47,650 --> 00:43:52,640 >> E notem, mesmo com esse pouco mais estrutura de dados sofisticado, vamos 934 00:43:52,640 --> 00:43:56,510 me propor que podemos emprestar alguns dos as idéias das últimas duas semanas e 935 00:43:56,510 --> 00:43:58,410 implementar uma função chamada pesquisa como esta. 936 00:43:58,410 --> 00:44:01,360 Vai retornar verdadeiro ou falsa, indicando, sim ou 937 00:44:01,360 --> 00:44:03,390 n, n está na lista. 938 00:44:03,390 --> 00:44:05,960 O segundo argumento é um ponteiro para a própria lista, de modo a 939 00:44:05,960 --> 00:44:07,920 ponteiro para um nó. 940 00:44:07,920 --> 00:44:10,350 >> Tudo o que eu vou fazer em seguida é declarar uma variável temporária. 941 00:44:10,350 --> 00:44:12,730 Vamos chamá-lo de ptr por convenção, para ponteiro. 942 00:44:12,730 --> 00:44:15,220 E eu atribuí-lo igual ao início da lista. 943 00:44:15,220 --> 00:44:16,680 >> E agora observe o loop while. 944 00:44:16,680 --> 00:44:20,640 Enquanto o ponteiro não é igual como nulo, vou verificar. 945 00:44:20,640 --> 00:44:24,520 É ponteiro de seta n igual a o n que foi passado em? 946 00:44:24,520 --> 00:44:26,410 E espere um minuto - novo pedaço de sintaxe. 947 00:44:26,410 --> 00:44:29,324 Qual é a flecha de repente? 948 00:44:29,324 --> 00:44:30,574 Sim? 949 00:44:30,574 --> 00:44:34,200 950 00:44:34,200 --> 00:44:34,810 >> Exatamente. 951 00:44:34,810 --> 00:44:38,860 Assim, enquanto a poucos minutos atrás, usamos a notação de ponto para acessar algo 952 00:44:38,860 --> 00:44:43,080 o interior de uma estrutura, se a variável você não é o struct 953 00:44:43,080 --> 00:44:47,420 si mesmo, mas um ponteiro para um struct, felizmente, um pedaço de sintaxe que 954 00:44:47,420 --> 00:44:48,620 finalmente faz sentido intuitivo. 955 00:44:48,620 --> 00:44:52,360 A seta significa seguir o ponteiro, como nossas flechas normalmente significa 956 00:44:52,360 --> 00:44:56,570 pictoricamente, e ir em campo de dados no interior. 957 00:44:56,570 --> 00:44:59,700 Então seta é a mesma coisa que ponto, mas você usá-lo quando você tem um ponteiro. 958 00:44:59,700 --> 00:45:05,270 >> Então, só para recapitular, então, se o campo de n dentro da estrutura chamada de ponteiro 959 00:45:05,270 --> 00:45:07,760 é igual a igual a n, retorna true. 960 00:45:07,760 --> 00:45:11,970 Caso contrário, essa linha aqui - ponteiro igual ponteiro próximo. 961 00:45:11,970 --> 00:45:17,540 Então o que está fazendo, o aviso prévio, é que se eu atualmente estou apontando para a estrutura 962 00:45:17,540 --> 00:45:21,430 contendo 9 e 9 não é o número Estou procurando - suponho que eu estou procurando 963 00:45:21,430 --> 00:45:22,830 para n igual a 50 - 964 00:45:22,830 --> 00:45:25,930 Eu vou atualizar meu ponteiro temporário para não apontar para este nó 965 00:45:25,930 --> 00:45:31,190 mais, mas ponteiro seta ao lado, que vai me colocar aqui. 966 00:45:31,190 --> 00:45:34,270 >> Agora, percebi que é um turbilhão introdução. 967 00:45:34,270 --> 00:45:37,380 Na quarta-feira, vamos realmente fazer isso com alguns seres humanos, e com um pouco mais 968 00:45:37,380 --> 00:45:38,900 código em um ritmo mais lento. 969 00:45:38,900 --> 00:45:42,990 Mas percebo, agora estamos fazendo os nossos dados estruturas mais complexas para que o nosso 970 00:45:42,990 --> 00:45:45,780 algoritmos podem ficar mais eficiente, o que vai ser requisito para 971 00:45:45,780 --> 00:45:50,500 pset seis anos, quando nós carregamos dentro, mais uma vez, aqueles 150 mil palavras, mas precisa fazê-lo 972 00:45:50,500 --> 00:45:55,650 de forma eficiente e, idealmente, criar um programa que é executado para os nossos usuários não em 973 00:45:55,650 --> 00:46:00,460 linear, não em n ao quadrado, mas, em constante de tempo, no ideal. 974 00:46:00,460 --> 00:46:02,300 >> Vemo-nos na quarta-feira. 975 00:46:02,300 --> 00:46:07,240 >> Palestrante: Na próxima CS50, David esquece o seu caso base. 976 00:46:07,240 --> 00:46:12,770 >> DAVID MALAN: E é assim que você envia mensagens de texto com C. Que - 977 00:46:12,770 --> 00:46:14,020 >> [VÁRIOS MENSAGEM DE TEXTO Sons de notificação] 978 00:46:14,020 --> 00:46:19,734