1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Review] [0 Quiz] 2 00:00:03,000 --> 00:00:05,000 >> [Lexi Ross, Tommy MacWilliam, Lucas Freitas, José Ong] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 >> [Esta é CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:10,000 >> Ei, todo mundo. 5 00:00:10,000 --> 00:00:15,000 Bem-vindo à sessão de revisão para Quiz 0, o que está a ter lugar esta quarta-feira. 6 00:00:15,000 --> 00:00:19,000 O que vamos fazer hoje à noite, eu estou com três TFs outros, 7 00:00:19,000 --> 00:00:24,000 e juntos vamos passar por uma revisão do que fizemos no curso até o momento. 8 00:00:24,000 --> 00:00:27,000 Não vai ser 100% completa, mas deve dar-lhe uma idéia melhor 9 00:00:27,000 --> 00:00:31,000 do que você já tem para baixo e que você ainda precisa estudar antes de quarta-feira. 10 00:00:31,000 --> 00:00:34,000 E sinta-se livre para levantar a mão com perguntas como estamos indo, 11 00:00:34,000 --> 00:00:38,000 mas tenha em mente que nós também vamos ter um pouco de tempo no fim- 12 00:00:38,000 --> 00:00:41,000 se acabar com alguns minutos de sobra para fazer perguntas gerais, 13 00:00:41,000 --> 00:00:47,000 de modo manter isso em mente, e por isso estamos indo para começar no início com a Semana 0. 14 00:00:47,000 --> 00:00:50,000 >> [Questionário 0 comentário!] [Parte 0] [Lexi Ross] Mas antes de fazer isso, vamos falar sobre 15 00:00:50,000 --> 00:00:53,000 a logística do quiz. 16 00:00:53,000 --> 00:00:55,000 >> [Logística] [quiz ocorre na quarta-feira 10/10, em vez da palestra] 17 00:00:55,000 --> 00:00:57,000 >> [(Veja http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf para mais detalhes)] É quarta-feira, 10 de outubro. 18 00:00:57,000 --> 00:01:00,000 >> Isso é nesta quarta-feira, e se você vai para este URL aqui, 19 00:01:00,000 --> 00:01:03,000 que também é acessível a partir de CS50.net-há um link para ele- 20 00:01:03,000 --> 00:01:06,000 você pode ver informações sobre onde ir com base em 21 00:01:06,000 --> 00:01:10,000 seu sobrenome ou filiação escola, bem como 22 00:01:10,000 --> 00:01:14,000 fala sobre exatamente o que o teste irá cobrir e os tipos de perguntas que você vai conseguir. 23 00:01:14,000 --> 00:01:19,000 Tenha em mente que você também vai ter a oportunidade de rever para responder ao teste na seção, 24 00:01:19,000 --> 00:01:21,000 para que seus TFs deve ir sobre alguns problemas da prática, 25 00:01:21,000 --> 00:01:29,000 e essa é outra boa chance de ver onde você ainda precisa estudar para o quiz. 26 00:01:29,000 --> 00:01:32,000 Vamos começar no início com Bytes 'n' bits. 27 00:01:32,000 --> 00:01:35,000 Lembre-se um pouco é apenas um 0 ou um 1, 28 00:01:35,000 --> 00:01:38,000 e um byte é uma coleção de oito desses bits. 29 00:01:38,000 --> 00:01:42,000 Vamos olhar para esta coleção de bits aqui. 30 00:01:42,000 --> 00:01:44,000 Devemos ser capazes de descobrir quantos bits existem. 31 00:01:44,000 --> 00:01:48,000 Onde contamos há apenas 8 deles, oito 0 ou 1 unidades. 32 00:01:48,000 --> 00:01:51,000 E desde há 8 bits, que é 1 byte, 33 00:01:51,000 --> 00:01:53,000 e vamos convertê-lo em hexadecimal. 34 00:01:53,000 --> 00:01:58,000 Hexadecimal é base 16, e é muito fácil de se converter 35 00:01:58,000 --> 00:02:01,000 um número em binário, que é o que é, para um número em hexadecimal. 36 00:02:01,000 --> 00:02:04,000 Tudo o que fazemos é olhar para grupos de 4, 37 00:02:04,000 --> 00:02:07,000 e convertê-los para o dígito hexadecimal apropriado. 38 00:02:07,000 --> 00:02:11,000 Começamos com o grupo mais à direita de 4, portanto, 0011. 39 00:02:11,000 --> 00:02:16,000 Isso vai ser um 1 e um 2, para juntos, que faz 3. 40 00:02:16,000 --> 00:02:19,000 E então, vamos olhar para o outro bloco de 4. 41 00:02:19,000 --> 00:02:24,000 1101. Isso vai ser um 1, um 4, e um 8. 42 00:02:24,000 --> 00:02:28,000 Juntos que vai ser 13, o que torna D. 43 00:02:28,000 --> 00:02:32,000 E vamos lembrar que em hexadecimal que não basta ir de 0 a 9. 44 00:02:32,000 --> 00:02:36,000 Vamos 0 a F, então depois de 9, 10 corresponde a A, 45 00:02:36,000 --> 00:02:40,000 11 a B, et cetera, onde F é 15. 46 00:02:40,000 --> 00:02:44,000 Aqui 13 é um D, 47 00:02:44,000 --> 00:02:49,000 de modo a convertê-lo para decimal tudo o que fazemos é realmente 48 00:02:49,000 --> 00:02:52,000 tratar cada posição como uma potência de 2. 49 00:02:52,000 --> 00:02:58,000 Isso é um 1, um 2, zero 4s, zero 8s, uma 16, et cetera, 50 00:02:58,000 --> 00:03:03,000 e é um pouco difícil de calcular em sua cabeça, mas se formos para o próximo slide 51 00:03:03,000 --> 00:03:05,000 podemos ver a resposta para isso. 52 00:03:05,000 --> 00:03:09,000 >> Essencialmente nós estamos indo em frente de volta para a esquerda, 53 00:03:09,000 --> 00:03:14,000 e nós estamos multiplicando cada dígito pela potência correspondente de 2. 54 00:03:14,000 --> 00:03:19,000 E lembre-se, para hexadecimal denotamos estes números com 0x no início 55 00:03:19,000 --> 00:03:23,000 para que não se confunda com um número decimal. 56 00:03:23,000 --> 00:03:29,000 Continuando, esta é uma tabela ASCII, 57 00:03:29,000 --> 00:03:35,000 eo que nós usamos ASCII para é mapear a partir de caracteres para valores numéricos. 58 00:03:35,000 --> 00:03:39,000 Lembre-se no pset criptografia que fez uso extensivo da tabela ASCII 59 00:03:39,000 --> 00:03:43,000 a fim de utilizar vários métodos de criptografia, 60 00:03:43,000 --> 00:03:47,000 o César e a cifra de Vigenère, para converter letras diferentes 61 00:03:47,000 --> 00:03:52,000 em uma string de acordo com a chave dada pelo usuário. 62 00:03:52,000 --> 00:03:56,000 Vamos olhar um pouco de matemática ASCII. 63 00:03:56,000 --> 00:04:02,000 Olhando para 'P' + 1, na forma de caracteres, que seria Q, 64 00:04:02,000 --> 00:04:07,000 e lembre-se que '5 '≠ 5. 65 00:04:07,000 --> 00:04:10,000 E como exatamente podemos converter entre essas duas formas? 66 00:04:10,000 --> 00:04:13,000 Não é realmente muito difícil. 67 00:04:13,000 --> 00:04:16,000 A fim de obter 5 subtraímos '0 ' 68 00:04:16,000 --> 00:04:20,000 porque há cinco lugares entre o '0 'eo '5'. 69 00:04:20,000 --> 00:04:23,000 A fim de ir por outro caminho que acabamos de adicionar a 0, 70 00:04:23,000 --> 00:04:25,000 por isso é uma espécie de como aritmética regular. 71 00:04:25,000 --> 00:04:29,000 Basta lembrar que quando algo tem aspas em torno dele é um personagem 72 00:04:29,000 --> 00:04:37,000 e, portanto, corresponde a um valor na tabela ASCII. 73 00:04:37,000 --> 00:04:40,000 Movendo-se para temas mais gerais da ciência de computadores. 74 00:04:40,000 --> 00:04:43,000 Aprendemos que um algoritmo é e como usar a programação 75 00:04:43,000 --> 00:04:45,000 para implementar algoritmos. 76 00:04:45,000 --> 00:04:48,000 Alguns exemplos de algoritmos são algo realmente simples como 77 00:04:48,000 --> 00:04:51,000 verificar se um número é par ou ímpar. 78 00:04:51,000 --> 00:04:54,000 Para que lembrar que mod o número por 2 e verificar se o resultado é 0. 79 00:04:54,000 --> 00:04:57,000 Se assim for, é mesmo. Se não, é estranho. 80 00:04:57,000 --> 00:04:59,000 E isso é um exemplo de um algoritmo muito básico. 81 00:04:59,000 --> 00:05:02,000 >> Um pouco de um mais um envolvido é de busca binária, 82 00:05:02,000 --> 00:05:05,000 que nós falaremos sobre mais tarde na sessão de revisão. 83 00:05:05,000 --> 00:05:09,000 E a programação é o termo que usamos para tomar um algoritmo 84 00:05:09,000 --> 00:05:15,000 e convertê-lo para codificar o computador possa ler. 85 00:05:15,000 --> 00:05:20,000 2 exemplos de programação Scratch, 86 00:05:20,000 --> 00:05:22,000 que é o que nós fizemos na Semana 0. 87 00:05:22,000 --> 00:05:25,000 Mesmo que nós realmente não digitar o código é uma forma de implementar 88 00:05:25,000 --> 00:05:29,000 Nesse algoritmo, o qual está a imprimir os números 1-10, 89 00:05:29,000 --> 00:05:32,000 e aqui podemos fazer o mesmo na linguagem de programação C. 90 00:05:32,000 --> 00:05:41,000 Estes são funcionalmente equivalentes, apenas escrito em diferentes línguas ou de sintaxe. 91 00:05:41,000 --> 00:05:44,000 Em seguida, aprendeu sobre expressões booleanas, 92 00:05:44,000 --> 00:05:48,000 e um booleano é um valor que é verdadeiro ou falso, 93 00:05:48,000 --> 00:05:51,000 e expressões aqui muitas vezes booleanos 94 00:05:51,000 --> 00:05:55,000 ir para dentro de condições, por isso, se (x ≤ 5), 95 00:05:55,000 --> 00:06:00,000 bem, nós já definido x = 5, de modo que condição vai avaliar para true. 96 00:06:00,000 --> 00:06:03,000 E se é verdade, qualquer código que está abaixo da condição 97 00:06:03,000 --> 00:06:08,000 vai ser avaliada pelo computador, de modo que a corda que vai ser impresso 98 00:06:08,000 --> 00:06:12,000 para a saída padrão, ea condição prazo 99 00:06:12,000 --> 00:06:16,000 refere-se a tudo o que está dentro dos parênteses da declaração se. 100 00:06:16,000 --> 00:06:20,000 Lembre-se de todos os operadores. 101 00:06:20,000 --> 00:06:26,000 Lembre-se de && e | | quando estamos tentando combinar duas ou mais condições, 102 00:06:26,000 --> 00:06:30,000 = Não == para verificar se duas coisas são iguais. 103 00:06:30,000 --> 00:06:36,000 Lembre-se que é = para atribuição enquanto == é um operador booleano. 104 00:06:36,000 --> 00:06:41,000 ≤, ≥ e depois o final 2 são auto-explicativos. 105 00:06:41,000 --> 00:06:45,000 Uma revisão geral da lógica booleana aqui. 106 00:06:45,000 --> 00:06:48,000 E expressões booleanas também são importantes em loops, 107 00:06:48,000 --> 00:06:50,000 que nós vamos passar por cima agora. 108 00:06:50,000 --> 00:06:56,000 Nós aprendemos sobre três tipos de loops até agora em CS50, por enquanto, e fazer enquanto. 109 00:06:56,000 --> 00:06:59,000 E é importante saber que, embora para a maioria dos fins 110 00:06:59,000 --> 00:07:02,000 nós podemos realmente usar qualquer tipo de loop geralmente 111 00:07:02,000 --> 00:07:06,000 existem certos tipos de propósitos ou padrões comuns 112 00:07:06,000 --> 00:07:09,000 na programação que, especificamente, chamar para um desses laços 113 00:07:09,000 --> 00:07:13,000 que tornam o. mais eficiente ou elegante para codificá-lo dessa forma 114 00:07:13,000 --> 00:07:18,000 Vamos falar sobre o que cada um desses ciclos tende a ser usado para mais freqüência. 115 00:07:18,000 --> 00:07:21,000 >> Em um loop que geralmente já sabe quantas vezes queremos interagir. 116 00:07:21,000 --> 00:07:24,000 Isso é o que nós colocamos na condição. 117 00:07:24,000 --> 00:07:28,000 Para i = 0, i <10, por exemplo. 118 00:07:28,000 --> 00:07:31,000 Nós já sabemos que queremos fazer algo 10 vezes. 119 00:07:31,000 --> 00:07:34,000 Agora, para um loop while, geralmente não necessariamente 120 00:07:34,000 --> 00:07:36,000 Sabe quantas vezes queremos que o laço seja executado. 121 00:07:36,000 --> 00:07:39,000 Mas nós sabemos que algum tipo de condição que nós queremos que ele 122 00:07:39,000 --> 00:07:41,000 sempre ser verdadeiro ou ser sempre falso. 123 00:07:41,000 --> 00:07:44,000 Por exemplo, enquanto que é definido. 124 00:07:44,000 --> 00:07:46,000 Vamos dizer que é uma variável booleana. 125 00:07:46,000 --> 00:07:48,000 Enquanto isso é verdade que queremos o código para avaliar, 126 00:07:48,000 --> 00:07:52,000 assim um pouco mais extensível, um pouco mais geral do que um loop, 127 00:07:52,000 --> 00:07:55,000 mas nenhum por laço pode também ser convertido a um loop. 128 00:07:55,000 --> 00:08:00,000 Finalmente, fazer loops while, que pode ser o mais complicado de compreender de imediato, 129 00:08:00,000 --> 00:08:04,000 são usados ​​frequentemente quando queremos avaliar o primeiro código 130 00:08:04,000 --> 00:08:06,000 antes da primeira vez que verificar a condição. 131 00:08:06,000 --> 00:08:09,000 Um caso de uso comum para um fazer loop while 132 00:08:09,000 --> 00:08:12,000 é quando você deseja obter a entrada do usuário, e você sabe que você quer perguntar ao usuário 133 00:08:12,000 --> 00:08:15,000 para a entrada de pelo menos uma vez, mas se eles não dão a você uma boa entrada de imediato 134 00:08:15,000 --> 00:08:18,000 você quer continuar fazendo até que eles dão-lhe a boa entrada. 135 00:08:18,000 --> 00:08:21,000 Esse é o uso mais comum de um loop Do While, 136 00:08:21,000 --> 00:08:23,000 e vamos olhar para a estrutura real de estes laços. 137 00:08:23,000 --> 00:08:27,000 Eles normalmente sempre tendem a seguir esses padrões. 138 00:08:27,000 --> 00:08:30,000 >> No laço para dentro de você ter 3 componentes: 139 00:08:30,000 --> 00:08:35,000 inicialização, tipicamente algo como int i = 0, onde i é o contador, 140 00:08:35,000 --> 00:08:40,000 condição, onde nós queremos dizer para executar este ciclo enquanto a essa condição ainda permanece, 141 00:08:40,000 --> 00:08:44,000 como i <10, e depois, finalmente, atualização, que é como incrementar 142 00:08:44,000 --> 00:08:47,000 a variável de contador em cada ponto do ciclo. 143 00:08:47,000 --> 00:08:50,000 Uma coisa comum para ver que há é apenas i + +, 144 00:08:50,000 --> 00:08:52,000 o que significa incrementar i por uma de cada vez. 145 00:08:52,000 --> 00:08:55,000 Você também pode fazer algo como i + = 2, 146 00:08:55,000 --> 00:08:58,000 o que significa adicionar 2 a i cada vez que você passar pelo loop. 147 00:08:58,000 --> 00:09:03,000 E então a fazer isso apenas se refere a qualquer código que realmente é executado como parte do ciclo. 148 00:09:03,000 --> 00:09:09,000 E para um loop while, desta vez nós realmente temos a inicialização fora do circuito, 149 00:09:09,000 --> 00:09:12,000 assim, por exemplo, vamos dizer que estamos a tentar fazer o mesmo tipo de loop como acabei de descrever. 150 00:09:12,000 --> 00:09:16,000 Diríamos int i = 0 antes do laço começa. 151 00:09:16,000 --> 00:09:20,000 Então poderíamos dizer enquanto i <10 fazer isso, 152 00:09:20,000 --> 00:09:22,000 assim o mesmo bloco de código como antes, 153 00:09:22,000 --> 00:09:26,000 e desta vez a parte de atualização do código, por exemplo, i + +, 154 00:09:26,000 --> 00:09:29,000 realmente vai dentro do loop. 155 00:09:29,000 --> 00:09:33,000 E, finalmente, para um fazer enquanto, é semelhante ao do loop while, 156 00:09:33,000 --> 00:09:36,000 mas temos que lembrar que o código irá avaliar uma vez 157 00:09:36,000 --> 00:09:40,000 antes a condição é verificada, por isso faz muito mais sentido 158 00:09:40,000 --> 00:09:44,000 se você olhar para ele, a fim de cima para baixo. 159 00:09:44,000 --> 00:09:49,000 Em um, fazer enquanto o código loop avalia antes mesmo de olhar para a condição, enquanto 160 00:09:49,000 --> 00:09:55,000 enquanto que um loop while, ele verifica primeiro. 161 00:09:55,000 --> 00:09:59,000 Demonstrações e variáveis. 162 00:09:59,000 --> 00:10:04,000 Quando queremos criar uma nova variável que primeiro pretende para o inicializar. 163 00:10:04,000 --> 00:10:07,000 >> Por exemplo, a barra int inicializa a barra variável, 164 00:10:07,000 --> 00:10:10,000 mas não dar-lhe um valor, então o que é o valor bar agora? 165 00:10:10,000 --> 00:10:12,000 Nós não sabemos. 166 00:10:12,000 --> 00:10:14,000 Pode ser um valor de lixo que foi previamente armazenado na memória de lá, 167 00:10:14,000 --> 00:10:16,000 e nós não queremos usar essa variável 168 00:10:16,000 --> 00:10:19,000 até que, na verdade, dar-lhe um valor, 169 00:10:19,000 --> 00:10:21,000 para que declará-lo aqui. 170 00:10:21,000 --> 00:10:24,000 Em seguida, inicializar para ser 42 abaixo. 171 00:10:24,000 --> 00:10:28,000 Agora, é claro, sabemos que isso pode ser feito em uma única linha, bar int = 42. 172 00:10:28,000 --> 00:10:30,000 Mas só para ficar claro as várias etapas que estão em curso, 173 00:10:30,000 --> 00:10:34,000 a declaração e inicialização estão acontecendo separadamente aqui. 174 00:10:34,000 --> 00:10:38,000 Isso acontece em uma única etapa, e na próxima, int baz = bar + 1, 175 00:10:38,000 --> 00:10:44,000 esta declaração abaixo, que baz incrementos, para que no final do bloco de código 176 00:10:44,000 --> 00:10:48,000 se fôssemos para imprimir o valor de baz seria 44 177 00:10:48,000 --> 00:10:52,000 porque declarar e inicializar que seja uma barra de>, 178 00:10:52,000 --> 00:10:58,000 e então incrementá-lo mais uma vez com o + +. 179 00:10:58,000 --> 00:11:02,000 Nós fomos sobre isso brevemente bonito, mas é bom ter um general 180 00:11:02,000 --> 00:11:04,000 compreensão do que tópicos e eventos são. 181 00:11:04,000 --> 00:11:06,000 Nós principalmente, fez isso em Scratch, 182 00:11:06,000 --> 00:11:09,000 para que você possa pensar em tópicos como várias seqüências de código 183 00:11:09,000 --> 00:11:11,000 executando ao mesmo tempo. 184 00:11:11,000 --> 00:11:14,000 Na verdade, ele provavelmente não está funcionando, ao mesmo tempo, 185 00:11:14,000 --> 00:11:17,000 mas uma espécie de abstratamente podemos pensar nisso dessa forma. 186 00:11:17,000 --> 00:11:20,000 >> No Scratch, por exemplo, tivemos os vários sprites. 187 00:11:20,000 --> 00:11:22,000 Poderia ser de execução de código diferentes ao mesmo tempo. 188 00:11:22,000 --> 00:11:26,000 Um deles poderia ser a pé, enquanto o outro está dizendo algo 189 00:11:26,000 --> 00:11:29,000 em uma parte diferente da tela. 190 00:11:29,000 --> 00:11:34,000 Os eventos são uma outra maneira de separar a lógica 191 00:11:34,000 --> 00:11:37,000 entre os diferentes elementos do seu código, 192 00:11:37,000 --> 00:11:40,000 e em Scratch fomos capazes de simular eventos usando o Broadcast, 193 00:11:40,000 --> 00:11:43,000 e que é, na verdade, quando eu receber, não quando eu ouço, 194 00:11:43,000 --> 00:11:47,000 mas, essencialmente, é uma forma de transmitir informações 195 00:11:47,000 --> 00:11:49,000 a partir de um sprite para o outro. 196 00:11:49,000 --> 00:11:52,000 Por exemplo, você pode querer transmitir ao longo do jogo, 197 00:11:52,000 --> 00:11:56,000 e quando outro sprite recebe ao longo do jogo, 198 00:11:56,000 --> 00:11:58,000 ele responde de uma certa maneira. 199 00:11:58,000 --> 00:12:03,000 É um modelo importante para compreender para a programação. 200 00:12:03,000 --> 00:12:07,000 Só para ir durante a semana básica 0, o que já sabemos, até agora, 201 00:12:07,000 --> 00:12:10,000 vamos olhar para este programa C simples. 202 00:12:10,000 --> 00:12:14,000 O texto pode ser um pouco pequeno, a partir daqui, mas eu vou passar por isso muito rápido. 203 00:12:14,000 --> 00:12:20,000 Estamos incluindo dois arquivos de cabeçalho no topo, cs50.h e stdio.h. 204 00:12:20,000 --> 00:12:23,000 Estamos então a definição de um limite constante chamado a ser 100. 205 00:12:23,000 --> 00:12:26,000 Estamos em seguida, implementar a nossa função principal. 206 00:12:26,000 --> 00:12:29,000 Uma vez que não usar argumentos de linha de comando aqui, precisamos colocar vazio 207 00:12:29,000 --> 00:12:32,000 como os argumentos para principal. 208 00:12:32,000 --> 00:12:38,000 Vemos int acima principal. Esse é o tipo de retorno, portanto, retornar 0 na parte inferior. 209 00:12:38,000 --> 00:12:41,000 E estamos usando CS50 função de biblioteca obter int 210 00:12:41,000 --> 00:12:45,000 para pedir ao usuário para a entrada, e armazená-lo nesta variável x, 211 00:12:45,000 --> 00:12:51,000 Assim, declaramos x acima, e inicializá-lo com x = GetInt. 212 00:12:51,000 --> 00:12:53,000 >> Em seguida, verifique se o usuário nos deu uma boa entrada. 213 00:12:53,000 --> 00:12:59,000 Se é LIMITE ≥ queremos retornar um código de erro de 1 e imprimir uma mensagem de erro. 214 00:12:59,000 --> 00:13:02,000 E, finalmente, a entrada se o usuário tem nos dado boa 215 00:13:02,000 --> 00:13:08,000 vamos fazer a quadratura do número e imprima o resultado. 216 00:13:08,000 --> 00:13:11,000 Só para ter certeza de que aqueles casa hit todos 217 00:13:11,000 --> 00:13:17,000 você pode ver os rótulos de diferentes partes do código aqui. 218 00:13:17,000 --> 00:13:19,000 Mencionei constantes, arquivos de cabeçalho. 219 00:13:19,000 --> 00:13:21,000 Oh, int x. Certifique-se de lembrar que é uma variável local. 220 00:13:21,000 --> 00:13:24,000 Isso contrasta de uma variável global, o que nós vamos falar sobre 221 00:13:24,000 --> 00:13:27,000 um pouco mais tarde na sessão de revisão, 222 00:13:27,000 --> 00:13:30,000 e estamos chamando a função de biblioteca printf, 223 00:13:30,000 --> 00:13:34,000 Portanto, se não havia incluído o arquivo de cabeçalho stdio.h 224 00:13:34,000 --> 00:13:37,000 não seria capaz de chamar printf. 225 00:13:37,000 --> 00:13:42,000 E acredito que a seta que foi cortada aqui está apontando para o% d, 226 00:13:42,000 --> 00:13:45,000 que é uma cadeia de formatação no printf. 227 00:13:45,000 --> 00:13:52,000 Diz imprimir essa variável como um número% d. 228 00:13:52,000 --> 00:13:58,000 E é isso para a Semana 0. 229 00:13:58,000 --> 00:14:06,000 Agora Lucas vai continuar. 230 00:14:06,000 --> 00:14:08,000 Ei, pessoal. Meu nome é Lucas. 231 00:14:08,000 --> 00:14:10,000 Eu sou um estudante de segundo ano da melhor casa no campus, Mather, 232 00:14:10,000 --> 00:14:14,000 e eu vou falar um pouco sobre a semana 1 e 2,1. 233 00:14:14,000 --> 00:14:16,000 [Semana 1 e 2,1!] [Lucas Freitas] 234 00:14:16,000 --> 00:14:19,000 Como Lexi estava dizendo, quando começamos a traduzir o seu código a partir do zero para C 235 00:14:19,000 --> 00:14:23,000 uma das coisas que percebemos é que você não pode simplesmente 236 00:14:23,000 --> 00:14:26,000 escrever seu código e executá-lo usando uma bandeira verde mais. 237 00:14:26,000 --> 00:14:30,000 Na verdade, você tem que usar algumas medidas para tornar o seu programa C 238 00:14:30,000 --> 00:14:33,000 tornar-se um arquivo executável. 239 00:14:33,000 --> 00:14:36,000 Basicamente o que você faz quando você está escrevendo um programa é que 240 00:14:36,000 --> 00:14:40,000 você traduzir sua idéia em uma linguagem que um compilador pode entender, 241 00:14:40,000 --> 00:14:44,000 Então, quando você está escrevendo um programa em C 242 00:14:44,000 --> 00:14:47,000 o que você está fazendo é realmente escrever algo que o compilador vai entender, 243 00:14:47,000 --> 00:14:50,000 e, em seguida, o compilador vai traduzir esse código 244 00:14:50,000 --> 00:14:53,000 em algo que o computador vai entender. 245 00:14:53,000 --> 00:14:55,000 >> E a coisa é, o seu computador é realmente muito burro. 246 00:14:55,000 --> 00:14:57,000 O seu computador só pode entender 0s e 1s, 247 00:14:57,000 --> 00:15:01,000 Então, na verdade nos primeiros computadores pessoas geralmente programados 248 00:15:01,000 --> 00:15:04,000 usando 0s e 1s, mas não mais, graças a Deus. 249 00:15:04,000 --> 00:15:07,000 Não temos que memorizar seqüências de 0s e 1s 250 00:15:07,000 --> 00:15:10,000 para um loop ou de loop de tempo e assim por diante. 251 00:15:10,000 --> 00:15:13,000 É por isso que temos um compilador. 252 00:15:13,000 --> 00:15:17,000 O que um compilador faz é, basicamente, traduz o código C, 253 00:15:17,000 --> 00:15:21,000 no nosso caso, para uma linguagem que o computador vai entender, 254 00:15:21,000 --> 00:15:25,000 que é o código objeto, eo compilador que estamos usando 255 00:15:25,000 --> 00:15:30,000 é chamado de bumbum, por isso esta é, na verdade, o símbolo para o bumbum. 256 00:15:30,000 --> 00:15:33,000 Quando você tem o seu programa, você tem que fazer duas coisas. 257 00:15:33,000 --> 00:15:37,000 Primeiro, você tem de compilar o seu programa, e então você está indo para executar o seu programa. 258 00:15:37,000 --> 00:15:41,000 Para compilar seu programa que você tem um monte de opções para fazer isso. 259 00:15:41,000 --> 00:15:44,000 O primeiro é fazer program.c bumbum 260 00:15:44,000 --> 00:15:47,000 em qual programa é o nome do seu programa. 261 00:15:47,000 --> 00:15:51,000 Neste caso, você pode ver que eles estão apenas dizendo "Ei, compilar meu programa." 262 00:15:51,000 --> 00:15:56,000 Você não está dizendo "Eu quero este nome para o meu programa", ou qualquer coisa. 263 00:15:56,000 --> 00:15:58,000 >> A segunda opção é dar um nome para o seu programa. 264 00:15:58,000 --> 00:16:02,000 Você pode dizer clang-o e, em seguida, o nome que você quiser 265 00:16:02,000 --> 00:16:06,000 o arquivo executável para ser nomeado como e depois program.c. 266 00:16:06,000 --> 00:16:11,000 E você também pode fazer fazer programa, e ver como nos primeiros dois casos 267 00:16:11,000 --> 00:16:15,000 Eu coloquei. C, e no terceiro eu só tenho programas? 268 00:16:15,000 --> 00:16:18,000 Sim, você realmente não deve colocar. C quando você usa fazer. 269 00:16:18,000 --> 00:16:22,000 Caso contrário, o compilador é, na verdade, vai gritar com você. 270 00:16:22,000 --> 00:16:24,000 E também, eu não sei se vocês lembram, 271 00:16:24,000 --> 00:16:29,000 mas muitas vezes também usamos-lcs50 ou lm. 272 00:16:29,000 --> 00:16:31,000 Isso é chamado de ligação. 273 00:16:31,000 --> 00:16:35,000 Ele apenas informa o compilador que você vai usar essas bibliotecas ali, 274 00:16:35,000 --> 00:16:39,000 por isso, se você quiser usar cs50.h você realmente tem que digitar 275 00:16:39,000 --> 00:16:43,000 clang program.c-lcs50. 276 00:16:43,000 --> 00:16:45,000 Se você não fizer isso, o compilador não vai saber 277 00:16:45,000 --> 00:16:50,000 que você está usando essas funções em cs50.h. 278 00:16:50,000 --> 00:16:52,000 E quando você quer executar o programa você tem duas opções. 279 00:16:52,000 --> 00:16:57,000 Se você fez program.c clang você não dar um nome para o seu programa. 280 00:16:57,000 --> 00:17:01,000 Você tem que executá-lo usando. A.out /. 281 00:17:01,000 --> 00:17:06,000 A.out é um nome padrão que bumbum dá o seu programa se você não dar-lhe um nome. 282 00:17:06,000 --> 00:17:11,000 Caso contrário, você vai fazer. Programa / se você deu um nome para o seu programa, 283 00:17:11,000 --> 00:17:15,000 e também se você fez o nome do programa que o programa vai ficar 284 00:17:15,000 --> 00:17:23,000 já está indo para ser programado o mesmo nome que o arquivo c. 285 00:17:23,000 --> 00:17:26,000 Então nós conversamos sobre os tipos de dados e dados. 286 00:17:26,000 --> 00:17:31,000 >> Basicamente tipos de dados são a mesma coisa que eles usam pequenas caixas 287 00:17:31,000 --> 00:17:35,000 para armazenar valores, por isso os tipos de dados são, na verdade, apenas como Pokémons. 288 00:17:35,000 --> 00:17:39,000 Eles vêm em todos os tamanhos e tipos. 289 00:17:39,000 --> 00:17:43,000 Eu não sei se essa analogia faz sentido. 290 00:17:43,000 --> 00:17:46,000 O tamanho dos dados, na verdade, depende da arquitetura da máquina. 291 00:17:46,000 --> 00:17:49,000 Todos os tamanhos de dados que eu vou mostrar aqui 292 00:17:49,000 --> 00:17:53,000 são, na verdade, para uma máquina de 32 bits, que é o caso do nosso dispositivo, 293 00:17:53,000 --> 00:17:56,000 mas se você está realmente codificação do seu Mac ou do Windows também 294 00:17:56,000 --> 00:17:59,000 Provavelmente você vai ter uma máquina de 64 bits, 295 00:17:59,000 --> 00:18:03,000 para lembrar que os tamanhos de dados que eu vou mostrar aqui 296 00:18:03,000 --> 00:18:06,000 são para a máquina de 32 bits. 297 00:18:06,000 --> 00:18:08,000 O primeiro que vimos foi um int, 298 00:18:08,000 --> 00:18:10,000 que é bastante simples. 299 00:18:10,000 --> 00:18:13,000 Você usa int para armazenar um número inteiro. 300 00:18:13,000 --> 00:18:16,000 Vimos também o caráter, o char. 301 00:18:16,000 --> 00:18:20,000 Se você quiser usar uma carta ou um pequeno símbolo que você provavelmente vai usar um char. 302 00:18:20,000 --> 00:18:26,000 Um char tem 1 byte, o que significa 8 bits, como Lexi disse. 303 00:18:26,000 --> 00:18:31,000 Basicamente, temos uma tabela ASCII que tem 256 304 00:18:31,000 --> 00:18:34,000 combinações possíveis de 0s e 1s, 305 00:18:34,000 --> 00:18:37,000 e então, quando você digitar um caractere que vai traduzir 306 00:18:37,000 --> 00:18:44,000 o caráter que as entradas lhe um número que você tem na tabela ASCII, como Lexi disse. 307 00:18:44,000 --> 00:18:48,000 Temos também a bóia, que usamos para armazenar números decimais. 308 00:18:48,000 --> 00:18:53,000 Se você quer escolher 3,14, por exemplo, você vai usar um flutuador 309 00:18:53,000 --> 00:18:55,000 ou um casal que tem mais precisão. 310 00:18:55,000 --> 00:18:57,000 Uma bóia tem 4 bytes. 311 00:18:57,000 --> 00:19:01,000 A dupla tem 8 bytes, então a única diferença é a precisão. 312 00:19:01,000 --> 00:19:04,000 Temos também um comprimento que é usado para inteiros, 313 00:19:04,000 --> 00:19:09,000 e você pode ver por uma máquina de 32-bit de um int e um long têm o mesmo tamanho, 314 00:19:09,000 --> 00:19:13,000 por isso não faz muito sentido usar um longa em uma máquina de 32 bits. 315 00:19:13,000 --> 00:19:17,000 >> Mas se você estiver usando um computador Mac e 64-bit, na verdade, uma longa tem tamanho 8, 316 00:19:17,000 --> 00:19:19,000 por isso realmente depende da arquitetura. 317 00:19:19,000 --> 00:19:22,000 Para a máquina de 32 bits, não faz sentido usar um longa de verdade. 318 00:19:22,000 --> 00:19:25,000 E, em seguida, um tempo longo, por outro lado, tem 8 bytes, 319 00:19:25,000 --> 00:19:30,000 por isso é muito bom se você quiser ter um número inteiro mais. 320 00:19:30,000 --> 00:19:34,000 E, finalmente, temos string, que é na verdade um char *, 321 00:19:34,000 --> 00:19:37,000 que é um ponteiro para uma char. 322 00:19:37,000 --> 00:19:40,000 É muito fácil pensar que o tamanho da cadeia vai ser como 323 00:19:40,000 --> 00:19:42,000 o número de caracteres que você tem lá, 324 00:19:42,000 --> 00:19:45,000 mas, na verdade, * o char-se 325 00:19:45,000 --> 00:19:49,000 tem o tamanho de um ponteiro para uma char, que é de 4 bytes. 326 00:19:49,000 --> 00:19:52,000 O tamanho de uma char * é 4 bytes. 327 00:19:52,000 --> 00:19:56,000 Não importa se você tem uma pequena palavra ou uma letra ou qualquer coisa. 328 00:19:56,000 --> 00:19:58,000 Vai ser de 4 bytes. 329 00:19:58,000 --> 00:20:01,000 Nós também aprendemos um pouco sobre o elenco, 330 00:20:01,000 --> 00:20:04,000 Então, como você pode ver, se você tiver, por exemplo, um programa que diz 331 00:20:04,000 --> 00:20:08,000 int x = 3 e, em seguida printf ("% d", x / 2) 332 00:20:08,000 --> 00:20:12,000 vocês sabem o que vai imprimir na tela? 333 00:20:12,000 --> 00:20:14,000 >> Alguém? >> [Os alunos] 2. 334 00:20:14,000 --> 00:20:16,000 1. >> 1, sim. 335 00:20:16,000 --> 00:20:20,000 Quando você faz 3/2 vai obter 1,5, 336 00:20:20,000 --> 00:20:24,000 mas já que estamos usando um inteiro que vai ignorar a parte decimal, 337 00:20:24,000 --> 00:20:26,000 e você vai ter um. 338 00:20:26,000 --> 00:20:29,000 Se você não quer que isso aconteça o que você pode fazer, por exemplo, 339 00:20:29,000 --> 00:20:33,000 é declarar um float y = x. 340 00:20:33,000 --> 00:20:40,000 Então x que costumavam ser três agora vai ser 3,000 em y. 341 00:20:40,000 --> 00:20:44,000 E então você pode imprimir o y / 2. 342 00:20:44,000 --> 00:20:50,000 Na verdade, eu deveria ter um 2. lá. 343 00:20:50,000 --> 00:20:55,000 Ele vai fazer 3.00/2.00, 344 00:20:55,000 --> 00:20:58,000 e você está indo para obter 1,5. 345 00:20:58,000 --> 00:21:06,000 E temos essa f 0,2 apenas para pedir 2 unidades decimais da parte decimal. 346 00:21:06,000 --> 00:21:12,000 Se você tem 0,3 f que vai ter, na verdade, 1.500. 347 00:21:12,000 --> 00:21:16,000 Se for 2, vai ser 1,50. 348 00:21:16,000 --> 00:21:18,000 Nós também temos esse caso aqui. 349 00:21:18,000 --> 00:21:22,000 Se você fizer float x = 3,14 e então você x printf 350 00:21:22,000 --> 00:21:24,000 você está indo para obter 3.14. 351 00:21:24,000 --> 00:21:29,000 E se você fizer x = int de x, 352 00:21:29,000 --> 00:21:34,000 o que significa tratar x como um int e imprimir x agora 353 00:21:34,000 --> 00:21:36,000 você vai ter 3,00. 354 00:21:36,000 --> 00:21:38,000 Isso faz sentido? 355 00:21:38,000 --> 00:21:41,000 Porque você é primeiro tratar x como um número inteiro, então você está ignorando a parte decimal, 356 00:21:41,000 --> 00:21:45,000 e então você está imprimindo x. 357 00:21:45,000 --> 00:21:47,000 E, finalmente, você também pode fazer isso, 358 00:21:47,000 --> 00:21:52,000 int x = 65, e então você declarar um char c = x, 359 00:21:52,000 --> 00:21:56,000 e então se você imprimir o c você realmente está indo para obter 360 00:21:56,000 --> 00:21:59,000 Um, então basicamente o que você está fazendo aqui 361 00:21:59,000 --> 00:22:02,000 está traduzindo o inteiro para o personagem, 362 00:22:02,000 --> 00:22:05,000 assim como a tabela ASCII faz. 363 00:22:05,000 --> 00:22:08,000 Também falamos sobre operadores matemáticos. 364 00:22:08,000 --> 00:22:14,000 A maioria deles são bastante simples, de modo +, -, *, /, 365 00:22:14,000 --> 00:22:20,000 e também falamos sobre mod, que é o resto da divisão de dois números. 366 00:22:20,000 --> 00:22:23,000 Se tiver 10% 3, por exemplo, 367 00:22:23,000 --> 00:22:27,000 significa dividir 10 por 3, e que é a parte restante? 368 00:22:27,000 --> 00:22:30,000 Vai ser 1, por isso é realmente muito útil para um monte de programas. 369 00:22:30,000 --> 00:22:38,000 Para Vigenère e César eu tenho certeza que todos vocês utilizado mod. 370 00:22:38,000 --> 00:22:43,000 Sobre operadores matemáticos, ter muito cuidado ao combinar * e /. 371 00:22:43,000 --> 00:22:48,000 >> Por exemplo, se você faz (3/2) * 2 o que você vai conseguir? 372 00:22:48,000 --> 00:22:50,000 [Os alunos] 2. 373 00:22:50,000 --> 00:22:54,000 É, 2, por 3/2 vai ser igual a 1,5, 374 00:22:54,000 --> 00:22:57,000 mas uma vez que você está fazendo operações entre dois números inteiros 375 00:22:57,000 --> 00:22:59,000 na verdade você está indo só para considerar um, 376 00:22:59,000 --> 00:23:03,000 e 1 * 2 vai ser 2, que deve ter muito, muito cuidado 377 00:23:03,000 --> 00:23:07,000 ao fazer aritmética com inteiros porque 378 00:23:07,000 --> 00:23:12,000 você pode ter que 2 = 3, nesse caso. 379 00:23:12,000 --> 00:23:14,000 E também ter muito cuidado com a precedência. 380 00:23:14,000 --> 00:23:21,000 Normalmente deve usar parênteses para ter certeza de que você sabe o que você está fazendo. 381 00:23:21,000 --> 00:23:27,000 Alguns atalhos úteis, é claro, é um i + + ou i + = 1 382 00:23:27,000 --> 00:23:30,000 ou usando + =. 383 00:23:30,000 --> 00:23:34,000 Isso é a mesma coisa que fazer i = i + 1. 384 00:23:34,000 --> 00:23:39,000 Você também pode fazer i - ou i - = 1, 385 00:23:39,000 --> 00:23:42,000 que é a mesma coisa que i = i -1, 386 00:23:42,000 --> 00:23:46,000 algo que vocês usam um monte de loops, pelo menos. 387 00:23:46,000 --> 00:23:52,000 Além disso, para *, se você usar * = e se você, por exemplo, 388 00:23:52,000 --> 00:23:57,000 i * = 2 é a mesma coisa que dizer i = i * 2, 389 00:23:57,000 --> 00:23:59,000 ea mesma coisa para a divisão. 390 00:23:59,000 --> 00:24:08,000 Se você fizer i / = 2 é a mesma coisa que i = i / 2. 391 00:24:08,000 --> 00:24:10,000 >> Agora sobre funções. 392 00:24:10,000 --> 00:24:13,000 Vocês aprenderam que funções são uma estratégia muito boa para salvar código 393 00:24:13,000 --> 00:24:16,000 enquanto você está programando, então se você quiser executar a mesma tarefa 394 00:24:16,000 --> 00:24:20,000 no código de novo e de novo, provavelmente você quiser usar uma função 395 00:24:20,000 --> 00:24:25,000 só assim você não tem que copiar e colar o código uma e outra vez. 396 00:24:25,000 --> 00:24:28,000 Na verdade, a principal é uma função, e quando eu mostrar-lhe o formato de uma função 397 00:24:28,000 --> 00:24:32,000 você vai ver que é bastante óbvio. 398 00:24:32,000 --> 00:24:35,000 Nós também usamos funções de algumas bibliotecas, 399 00:24:35,000 --> 00:24:39,000 por exemplo, printf, Getin, que é a partir da biblioteca de CS50, 400 00:24:39,000 --> 00:24:43,000 e outras funções como toupper. 401 00:24:43,000 --> 00:24:46,000 Todas essas funções são realmente implementadas em outras bibliotecas, 402 00:24:46,000 --> 00:24:49,000 e quando você colocar esses arquivos tether no início de seu programa 403 00:24:49,000 --> 00:24:53,000 você está dizendo que você pode por favor me dar o código para essas funções 404 00:24:53,000 --> 00:24:57,000 então eu não tenho que implementá-las por mim mesmo? 405 00:24:57,000 --> 00:25:00,000 E você também pode escrever suas próprias funções, então quando você começar a programar 406 00:25:00,000 --> 00:25:04,000 você percebe que as bibliotecas não têm todas as funções que você precisa. 407 00:25:04,000 --> 00:25:10,000 Para o pset passado, por exemplo, nós escrevemos desenhar, scramble, e de pesquisa, 408 00:25:10,000 --> 00:25:13,000 e é muito, muito importante para ser capaz de escrever funções 409 00:25:13,000 --> 00:25:17,000 porque eles são úteis, e usá-los o tempo todo na programação, 410 00:25:17,000 --> 00:25:19,000 e ele salva um monte de código. 411 00:25:19,000 --> 00:25:21,000 O formato de uma função é esta. 412 00:25:21,000 --> 00:25:24,000 Temos tipo de retorno no início. Qual é o tipo de retorno? 413 00:25:24,000 --> 00:25:27,000 É apenas quando a função vai retornar. 414 00:25:27,000 --> 00:25:29,000 Se você tem uma função, por exemplo, fatorial, 415 00:25:29,000 --> 00:25:31,000 que se vai calcular uma fatorial de um número inteiro, 416 00:25:31,000 --> 00:25:34,000 provavelmente ele vai retornar um inteiro também. 417 00:25:34,000 --> 00:25:37,000 Em seguida, o tipo de retorno vai ser int. 418 00:25:37,000 --> 00:25:41,000 Printf realmente tem um tipo de retorno void 419 00:25:41,000 --> 00:25:43,000 porque você não está retornando nada. 420 00:25:43,000 --> 00:25:45,000 Você está apenas imprimir coisas na tela 421 00:25:45,000 --> 00:25:48,000 e sair da função depois. 422 00:25:48,000 --> 00:25:51,000 Então você tem o nome da função que você pode escolher. 423 00:25:51,000 --> 00:25:55,000 Você deve ser um pouco razoável, como não escolher um nome como xyz 424 00:25:55,000 --> 00:25:58,000 ou como X2F. 425 00:25:58,000 --> 00:26:02,000 Tente fazer-se um nome que faz sentido. 426 00:26:02,000 --> 00:26:04,000 >> Por exemplo, se é fatorial, dizem fatorial. 427 00:26:04,000 --> 00:26:08,000 Se é uma função que vai desenhar alguma coisa, chame-o desenhar. 428 00:26:08,000 --> 00:26:11,000 E depois temos os parâmetros, que são também chamados de argumentos, 429 00:26:11,000 --> 00:26:14,000 que são como os recursos que a sua função precisa 430 00:26:14,000 --> 00:26:17,000 a partir do seu código para executar sua tarefa. 431 00:26:17,000 --> 00:26:20,000 Se você quiser calcular o fatorial de um número 432 00:26:20,000 --> 00:26:23,000 provavelmente você precisa ter um número para calcular um fatorial. 433 00:26:23,000 --> 00:26:27,000 Um dos argumentos que você vai ter é o próprio número. 434 00:26:27,000 --> 00:26:31,000 E então ele vai fazer algo e retornar o valor no final 435 00:26:31,000 --> 00:26:35,000 a menos que seja uma função void. 436 00:26:35,000 --> 00:26:37,000 Vamos ver um exemplo. 437 00:26:37,000 --> 00:26:40,000 Se eu quiser escrever uma função que soma todos os números em um array de inteiros, 438 00:26:40,000 --> 00:26:43,000 em primeiro lugar, o tipo de retorno vai ser int 439 00:26:43,000 --> 00:26:46,000 porque eu tenho um array de inteiros. 440 00:26:46,000 --> 00:26:51,000 E então eu vou ter o nome da função como sumArray, 441 00:26:51,000 --> 00:26:54,000 e então ele vai levar o próprio array, para nums int 442 00:26:54,000 --> 00:26:58,000 e então o comprimento da matriz, então eu sei quantos números eu tenho que somar. 443 00:26:58,000 --> 00:27:02,000 Então eu tenho que inicializar uma quantia variável chamada, por exemplo, para 0, 444 00:27:02,000 --> 00:27:08,000 e cada vez que vejo um elemento na matriz Devo acrescentar que a soma, então eu fiz um loop. 445 00:27:08,000 --> 00:27:15,000 Assim como disse Lexi, você int i = 0, i comprimento 00:27:20,000 E para cada elemento da matriz que fiz soma + = nums [i], 447 00:27:20,000 --> 00:27:24,000 e depois voltei a soma, por isso é muito simples, e poupa um monte de código 448 00:27:24,000 --> 00:27:28,000 se você estiver usando esta função um monte de vezes. 449 00:27:28,000 --> 00:27:32,000 Então demos uma olhada em condições. 450 00:27:32,000 --> 00:27:38,000 Temos if, else e else if. 451 00:27:38,000 --> 00:27:42,000 Vamos ver o que é a diferença entre aqueles. 452 00:27:42,000 --> 00:27:45,000 Dê uma olhada nestes dois códigos. Qual é a diferença entre eles? 453 00:27:45,000 --> 00:27:49,000 O primeiro tem, basicamente os códigos quero que você diga 454 00:27:49,000 --> 00:27:51,000 se um número é +, -, ou 0. 455 00:27:51,000 --> 00:27:55,000 O primeiro diz se é> 0, então é positivo. 456 00:27:55,000 --> 00:28:00,000 Se é = a 0, é 0, e se for <0, então é negativo. 457 00:28:00,000 --> 00:28:04,000 >> E o outro está fazendo if, else if, else. 458 00:28:04,000 --> 00:28:07,000 A diferença entre os dois é que este está indo realmente para 459 00:28:07,000 --> 00:28:13,000 verificar se> 0, <0 = 0 ou três vezes, 460 00:28:13,000 --> 00:28:17,000 por isso, se você tem o número 2, por exemplo, ele vai vir aqui e dizer 461 00:28:17,000 --> 00:28:21,000 if (x> 0), e ele vai dizer que sim, então eu imprimir positivo. 462 00:28:21,000 --> 00:28:25,000 Mas mesmo que eu sei que é> 0 e não vai ser 0 ou <0 463 00:28:25,000 --> 00:28:29,000 Eu ainda vou fazer é 0, é <0, 464 00:28:29,000 --> 00:28:33,000 então eu estou indo realmente dentro de ifs que eu não tinha que 465 00:28:33,000 --> 00:28:38,000 porque eu já sei que não vai satisfazer qualquer uma dessas condições. 466 00:28:38,000 --> 00:28:41,000 Eu posso usar o if, else if, else comunicado. 467 00:28:41,000 --> 00:28:45,000 Ele basicamente diz que se x = 0 eu imprimir o positivo. 468 00:28:45,000 --> 00:28:48,000 Se não for, eu vou também testar isto. 469 00:28:48,000 --> 00:28:51,000 Se for 2, não vou fazer isso. 470 00:28:51,000 --> 00:28:54,000 Basicamente, se eu tinha x = 2, você diria 471 00:28:54,000 --> 00:28:57,000 if (x> 0), sim, para imprimir esta. 472 00:28:57,000 --> 00:29:00,000 Agora que eu sei que é> 0 e que satisfeito o primeiro se 473 00:29:00,000 --> 00:29:02,000 Eu não estou indo para executar este código. 474 00:29:02,000 --> 00:29:09,000 O código é executado mais rápido, na verdade, três vezes mais rápido se você usar isso. 475 00:29:09,000 --> 00:29:11,000 Também soubemos e e ou. 476 00:29:11,000 --> 00:29:15,000 Eu não vou passar por isso porque Lexi já falamos sobre eles. 477 00:29:15,000 --> 00:29:17,000 É apenas o && e operador | |. 478 00:29:17,000 --> 00:29:21,000 >> A única coisa que eu vou dizer é ter cuidado quando você tem três condições. 479 00:29:21,000 --> 00:29:24,000 Use parênteses porque é muito confuso quando você tem uma condição 480 00:29:24,000 --> 00:29:27,000 e um outro, ou um outro. 481 00:29:27,000 --> 00:29:30,000 Use parênteses apenas para ter certeza de que suas condições de fazer sentido 482 00:29:30,000 --> 00:29:34,000 porque, nesse caso, por exemplo, você pode imaginar que 483 00:29:34,000 --> 00:29:38,000 que poderia ser a primeira condição e um ou o outro 484 00:29:38,000 --> 00:29:41,000 ou as duas condições combinadas em uma e 485 00:29:41,000 --> 00:29:45,000 ou o terceiro, então tome cuidado. 486 00:29:45,000 --> 00:29:48,000 E, finalmente, nós falamos sobre opções. 487 00:29:48,000 --> 00:29:53,000 Um switch é muito útil quando você tem uma variável. 488 00:29:53,000 --> 00:29:55,000 Vamos dizer que você tem uma variável como n 489 00:29:55,000 --> 00:29:59,000 que podem ser 0, 1, ou 2, e para cada um desses casos 490 00:29:59,000 --> 00:30:01,000 você está indo para executar uma tarefa. 491 00:30:01,000 --> 00:30:04,000 Você pode dizer mudar a variável, e indica que 492 00:30:04,000 --> 00:30:08,000 o valor é, então, como valor1 eu vou fazer isso, 493 00:30:08,000 --> 00:30:12,000 e então eu quebrar, o que significa que eu não vou olhar para qualquer dos outros casos 494 00:30:12,000 --> 00:30:15,000 porque nós já convencido de que caso 495 00:30:15,000 --> 00:30:20,000 e, em seguida, valor2 e assim por diante, e também pode ter um interruptor padrão. 496 00:30:20,000 --> 00:30:24,000 Isso significa que se ela não satisfaz qualquer dos casos que eu tive 497 00:30:24,000 --> 00:30:29,000 que eu vou fazer outra coisa, mas isso é opcional. 498 00:30:29,000 --> 00:30:36,000 Isso é tudo para mim. Agora vamos ter Tommy. 499 00:30:36,000 --> 00:30:41,000 Tudo bem, isso vai ser Semana 3-ish. 500 00:30:41,000 --> 00:30:45,000 Estes são alguns dos temas que vamos cobrindo, cripto, escopo, matrizes, et cetera. 501 00:30:45,000 --> 00:30:49,000 Apenas uma palavra rápida sobre criptografia. Nós não estamos indo para martelar esta casa. 502 00:30:49,000 --> 00:30:52,000 >> Fizemos isso em pset 2, mas para o quiz certeza que você sabe a diferença 503 00:30:52,000 --> 00:30:54,000 entre a cifra de César ea cifra de Vigenère, 504 00:30:54,000 --> 00:30:57,000 como ambos os trabalhos cifras e como é para criptografar 505 00:30:57,000 --> 00:30:59,000 e descriptografar o texto usando esses dois códigos. 506 00:30:59,000 --> 00:31:03,000 Lembre-se, a cifra de César simplesmente gira cada personagem com o mesmo valor, 507 00:31:03,000 --> 00:31:06,000 certificando-se de mod pelo número de letras no alfabeto. 508 00:31:06,000 --> 00:31:09,000 E a cifra de Vigenère, por outro lado, cada roda de caracteres 509 00:31:09,000 --> 00:31:12,000 por um montante diferente, então ao invés de dizer 510 00:31:12,000 --> 00:31:15,000 a cada rodada caracteres por 3 Vigenère irá girar cada personagem 511 00:31:15,000 --> 00:31:17,000 por uma quantidade diferente dependendo de alguma palavra-chave 512 00:31:17,000 --> 00:31:20,000 onde cada letra da palavra-chave representa uma quantidade diferente 513 00:31:20,000 --> 00:31:26,000 para girar o texto claro por. 514 00:31:26,000 --> 00:31:28,000 Vamos primeiro falar sobre escopo de variáveis. 515 00:31:28,000 --> 00:31:30,000 Existem dois tipos diferentes de variáveis. 516 00:31:30,000 --> 00:31:33,000 Temos variáveis ​​locais, e estes vão ser definidos 517 00:31:33,000 --> 00:31:36,000 fora do principal ou fora de qualquer função ou bloco, 518 00:31:36,000 --> 00:31:39,000 e estas estarão acessíveis em qualquer lugar em seu programa. 519 00:31:39,000 --> 00:31:41,000 Se você tem uma função e em que função é um loop while 520 00:31:41,000 --> 00:31:44,000 a grande variável global é acessível em qualquer lugar. 521 00:31:44,000 --> 00:31:48,000 Uma variável local, por outro lado, é delimitado para o lugar onde ele está definido. 522 00:31:48,000 --> 00:31:53,000 >> Se você tem uma função aqui, por exemplo, temos esta função g, 523 00:31:53,000 --> 00:31:56,000 e dentro de g existe uma variável aqui chamada y, 524 00:31:56,000 --> 00:31:58,000 e isso significa que esta é uma variável local. 525 00:31:58,000 --> 00:32:00,000 Mesmo que esta variável é chamada y 526 00:32:00,000 --> 00:32:03,000 e esta variável é chamado Y estas duas funções 527 00:32:03,000 --> 00:32:06,000 não tenho idéia do que cada um dos outros locais são variáveis. 528 00:32:06,000 --> 00:32:10,000 Por outro lado, aqui, dizemos int x = 5, 529 00:32:10,000 --> 00:32:12,000 e isso está fora do escopo de qualquer função. 530 00:32:12,000 --> 00:32:16,000 É fora do escopo do principal, por isso esta é uma variável global. 531 00:32:16,000 --> 00:32:20,000 Isso significa que dentro destas duas funções, quando eu digo - x ou x + + 532 00:32:20,000 --> 00:32:26,000 Eu estou acessando o mesmo x y em que este e este y são variáveis ​​diferentes. 533 00:32:26,000 --> 00:32:30,000 Essa é a diferença entre uma variável global e uma variável local. 534 00:32:30,000 --> 00:32:33,000 Tanto quanto design está em causa, às vezes, é provavelmente uma idéia melhor 535 00:32:33,000 --> 00:32:37,000 para manter variáveis ​​locais sempre que você puder 536 00:32:37,000 --> 00:32:39,000 já que ter um monte de variáveis ​​globais pode ficar muito confuso. 537 00:32:39,000 --> 00:32:42,000 Se você tem um monte de funções modificando tudo a mesma coisa 538 00:32:42,000 --> 00:32:45,000 você pode esquecer o que se esta função acidentalmente modifica este global, 539 00:32:45,000 --> 00:32:47,000 e esta outra função não sabe sobre isso, 540 00:32:47,000 --> 00:32:50,000 e que o faz ficar muito confuso como você obtém mais de código. 541 00:32:50,000 --> 00:32:53,000 Mantendo variáveis ​​locais sempre que você puder 542 00:32:53,000 --> 00:32:56,000 é projeto apenas bom. 543 00:32:56,000 --> 00:33:00,000 Matrizes, lembre-se, são simplesmente listas de elementos do mesmo tipo. 544 00:33:00,000 --> 00:33:04,000 Dentro de IC não pode ter uma lista como 1, 2,0, Olá. 545 00:33:04,000 --> 00:33:06,000 Nós simplesmente não pode fazer isso. 546 00:33:06,000 --> 00:33:11,000 >> Quando declarar uma matriz em C de todos os elementos têm de ser do mesmo tipo. 547 00:33:11,000 --> 00:33:14,000 Aqui eu tenho um conjunto de 3 números inteiros. 548 00:33:14,000 --> 00:33:18,000 Aqui eu tenho o comprimento da matriz, mas se eu estou declarando-o nesta sintaxe 549 00:33:18,000 --> 00:33:21,000 onde eu especificar que todos os elementos estão tecnicamente eu não preciso deste 3. 550 00:33:21,000 --> 00:33:25,000 O compilador é inteligente o suficiente para descobrir o quão grande a matriz deve ser. 551 00:33:25,000 --> 00:33:28,000 Agora quando eu quiser obter ou definir o valor de uma matriz 552 00:33:28,000 --> 00:33:30,000 esta é a sintaxe para fazer isso. 553 00:33:30,000 --> 00:33:33,000 Isto irá efectivamente modificar o segundo elemento da matriz porque, lembrar, 554 00:33:33,000 --> 00:33:36,000 numeração começa em 0, não em 1. 555 00:33:36,000 --> 00:33:42,000 Se eu quero ler esse valor eu posso dizer algo como int x = array [1]. 556 00:33:42,000 --> 00:33:44,000 Ou se eu quiser definir esse valor, como eu estou fazendo aqui, 557 00:33:44,000 --> 00:33:47,000 Posso dizer array [1] = 4. 558 00:33:47,000 --> 00:33:50,000 Esse tempo acessar elementos pelo seu índice 559 00:33:50,000 --> 00:33:52,000 ou a sua posição, ou quando eles estão na matriz, 560 00:33:52,000 --> 00:33:57,000 e que a lista começa em 0. 561 00:33:57,000 --> 00:34:00,000 Também podemos ter matrizes de matrizes, 562 00:34:00,000 --> 00:34:03,000 e isso é chamado de matriz multi-dimensional. 563 00:34:03,000 --> 00:34:05,000 Quando temos um array multi-dimensional 564 00:34:05,000 --> 00:34:07,000 isso significa que podemos ter algo como linhas e colunas, 565 00:34:07,000 --> 00:34:11,000 e esta é apenas uma maneira de visualizar isso ou pensar sobre isso. 566 00:34:11,000 --> 00:34:14,000 Quando eu tenho um array multi-dimensional que significa que eu vou começar a precisar 567 00:34:14,000 --> 00:34:17,000 mais do que um índice, porque se eu tiver uma grade 568 00:34:17,000 --> 00:34:19,000 apenas dizendo o que linha você está em não nos dá um número. 569 00:34:19,000 --> 00:34:22,000 Isso é realmente só vai dar-nos uma lista de números. 570 00:34:22,000 --> 00:34:25,000 Vamos dizer que eu tenho essa matriz aqui. 571 00:34:25,000 --> 00:34:30,000 Eu tenho uma matriz chamada de grade, e eu estou dizendo que é duas linhas e três colunas, 572 00:34:30,000 --> 00:34:32,000 e por isso esta é uma maneira de visualizar isso. 573 00:34:32,000 --> 00:34:37,000 Quando eu digo que eu quero começar o elemento em [1] [2] 574 00:34:37,000 --> 00:34:41,000 isso significa que, porque estes são linhas e depois colunas 575 00:34:41,000 --> 00:34:44,000 Eu vou pular para a linha 1 desde que eu disse um. 576 00:34:44,000 --> 00:34:49,000 >> Então eu vou vir aqui para a coluna 2, e eu estou indo para obter o valor 6. 577 00:34:49,000 --> 00:34:51,000 Faz sentido? 578 00:34:51,000 --> 00:34:55,000 Arrays multi-dimensionais, lembre-se, são tecnicamente apenas uma matriz de matrizes. 579 00:34:55,000 --> 00:34:57,000 Podemos ter matrizes de matrizes de matrizes. 580 00:34:57,000 --> 00:35:00,000 Podemos continuar, mas realmente uma maneira de pensar 581 00:35:00,000 --> 00:35:03,000 como isso está sendo colocado para fora eo que está acontecendo é para visualizá-lo 582 00:35:03,000 --> 00:35:09,000 em uma grade como este. 583 00:35:09,000 --> 00:35:12,000 Quando passar matrizes para funções, eles vão se comportar 584 00:35:12,000 --> 00:35:16,000 um pouco diferente do que quando passar variáveis ​​para funções regulares 585 00:35:16,000 --> 00:35:18,000 como passar um int ou um float. 586 00:35:18,000 --> 00:35:21,000 Quando passamos em um tipo int ou char ou qualquer um desses outros dados 587 00:35:21,000 --> 00:35:24,000 nós apenas deu uma olhada se a função modifica 588 00:35:24,000 --> 00:35:28,000 o valor da variável que a mudança não vai propagar-se 589 00:35:28,000 --> 00:35:32,000 para a função de chamada. 590 00:35:32,000 --> 00:35:35,000 Com uma matriz, por outro lado, que acontecerá. 591 00:35:35,000 --> 00:35:39,000 Se eu passar em um array para alguma função e que função altera alguns dos elementos, 592 00:35:39,000 --> 00:35:43,000 quando eu voltar-se para a função que a chamou 593 00:35:43,000 --> 00:35:47,000 minha matriz é agora vai ser diferente, eo vocabulário para que 594 00:35:47,000 --> 00:35:50,000 é arrays são passados ​​por referência, como veremos mais tarde. 595 00:35:50,000 --> 00:35:53,000 Isso está relacionado à forma como o trabalho ponteiros, onde esses tipos de dados básicos, 596 00:35:53,000 --> 00:35:55,000 por outro lado, são passados ​​por valor. 597 00:35:55,000 --> 00:35:59,000 >> Podemos pensar que, como fazer uma cópia de alguma variável e depois passar na cópia. 598 00:35:59,000 --> 00:36:01,000 Não importa o que fazemos com essa variável. 599 00:36:01,000 --> 00:36:06,000 A função de chamada não vai estar ciente de que ele foi alterado. 600 00:36:06,000 --> 00:36:10,000 Matrizes são apenas um pouco diferente a esse respeito. 601 00:36:10,000 --> 00:36:13,000 Por exemplo, como acabamos de ver, a principal é simplesmente uma função 602 00:36:13,000 --> 00:36:15,000 que pode tomar dois argumentos. 603 00:36:15,000 --> 00:36:20,000 O primeiro argumento para a função principal é argc, ou o número de argumentos, 604 00:36:20,000 --> 00:36:23,000 eo segundo argumento é chamado argv, 605 00:36:23,000 --> 00:36:27,000 e esses são os valores reais de tais argumentos. 606 00:36:27,000 --> 00:36:30,000 Vamos dizer que eu tenho um programa chamado this.c, 607 00:36:30,000 --> 00:36:34,000 e eu digo fazer isso, e eu estou indo para executar isso na linha de comando. 608 00:36:34,000 --> 00:36:38,000 Agora, para passar alguns argumentos para o meu programa chamado isso, 609 00:36:38,000 --> 00:36:42,000 Eu poderia dizer algo como. / Este é cs 50. 610 00:36:42,000 --> 00:36:45,000 Isto é o que nós imaginamos David a fazer todos os dias no terminal. 611 00:36:45,000 --> 00:36:48,000 Mas agora, a função principal no interior do referido programa 612 00:36:48,000 --> 00:36:52,000 tem estes valores, assim argc é 4. 613 00:36:52,000 --> 00:36:56,000 Ele pode ser um pouco confuso, porque realmente estamos apenas passando é cs 50. 614 00:36:56,000 --> 00:36:58,000 Isso é apenas 3. 615 00:36:58,000 --> 00:37:02,000 Mas lembre-se que o primeiro elemento de argv ou o primeiro argumento 616 00:37:02,000 --> 00:37:05,000 é o nome da própria função. 617 00:37:05,000 --> 00:37:07,190 Então isso significa que temos quatro coisas aqui, 618 00:37:07,190 --> 00:37:10,530 eo primeiro elemento é que vai ser. / isso. 619 00:37:10,530 --> 00:37:12,970 E isso vai ser representado como uma string. 620 00:37:12,970 --> 00:37:18,590 Em seguida, os restantes elementos são o que digitado após o nome do programa. 621 00:37:18,590 --> 00:37:22,720 Assim como um aparte, como nós, provavelmente, viu em pset 2, 622 00:37:22,720 --> 00:37:28,780 lembre-se que a seqüência de 50 é a 50 ≠ inteiro. 623 00:37:28,780 --> 00:37:32,520 Portanto, não podemos dizer algo como, 'int x = argv 3.' 624 00:37:32,520 --> 00:37:36,470 >> Isso só não vai fazer sentido, porque esta é uma string, e este é um número inteiro. 625 00:37:36,470 --> 00:37:38,510 Então, se você quer converter entre o 2, lembre-se, nós vamos 626 00:37:38,510 --> 00:37:40,810 têm essa função mágica chamada atoi. 627 00:37:40,810 --> 00:37:46,270 Que recebe uma string e retorna o inteiro representado dentro dessa seqüência. 628 00:37:46,270 --> 00:37:48,360 Então, isso é um erro fácil de fazer no quiz, 629 00:37:48,360 --> 00:37:51,590 só de pensar que este será automaticamente o tipo correto. 630 00:37:51,590 --> 00:37:53,860 Mas só sei que estes serão sempre cordas 631 00:37:53,860 --> 00:38:00,920 mesmo se a cadeia contém apenas um número inteiro ou um personagem ou uma bóia. 632 00:38:00,920 --> 00:38:03,380 Então, agora vamos falar sobre o tempo de execução. 633 00:38:03,380 --> 00:38:06,700 Quando temos todos esses algoritmos que fazer todas essas coisas loucas, 634 00:38:06,700 --> 00:38:11,580 torna-se muito útil para a pergunta: "Quanto tempo eles levaram?" 635 00:38:11,580 --> 00:38:15,500 Nós representamos que com algo chamado de notação assintótica. 636 00:38:15,500 --> 00:38:18,430 Então isso significa que - bem, vamos dizer que dar o nosso algoritmo 637 00:38:18,430 --> 00:38:20,840 alguma entrada muito, muito, muito grande. 638 00:38:20,840 --> 00:38:23,840 Queremos fazer a pergunta: "Quanto tempo vai levar? 639 00:38:23,840 --> 00:38:26,370 Quantas medidas irá tomar nosso algoritmo para executar 640 00:38:26,370 --> 00:38:29,980 como uma função do tamanho da entrada? " 641 00:38:29,980 --> 00:38:33,080 Assim, a primeira forma que podemos descrever o tempo de execução é com grande O. 642 00:38:33,080 --> 00:38:35,380 E este é o nosso tempo de execução de pior caso. 643 00:38:35,380 --> 00:38:38,590 Portanto, se queremos classificar um array, e nós damos o nosso algoritmo de uma matriz 644 00:38:38,590 --> 00:38:41,000 que está em ordem decrescente, quando deveria estar em ordem ascendente, 645 00:38:41,000 --> 00:38:43,130 que vai ser o pior caso. 646 00:38:43,130 --> 00:38:49,800 Este é o nosso limite superior no tempo máximo de nosso algoritmo irá tomar. 647 00:38:49,800 --> 00:38:54,740 Por outro lado, este Ω vai descrever melhor caso tempo de execução. 648 00:38:54,740 --> 00:38:58,210 Então, se nós damos uma matriz já classificados para um algoritmo de classificação, 649 00:38:58,210 --> 00:39:00,940 quanto tempo vai demorar para resolver isso? 650 00:39:00,940 --> 00:39:06,610 E este, em seguida, descreve um limite inferior no tempo de execução. 651 00:39:06,610 --> 00:39:10,980 Então, aqui são apenas algumas palavras que descrevem algumas vezes comuns em execução. 652 00:39:10,980 --> 00:39:13,120 Estes são, em ordem crescente. 653 00:39:13,120 --> 00:39:16,060 O tempo mais rápido em execução que temos é chamado constante. 654 00:39:16,060 --> 00:39:19,800 >> Isso significa que não importa quantos elementos damos o nosso algoritmo, 655 00:39:19,800 --> 00:39:22,280 não importa quão grande é a nossa matriz, a triagem 656 00:39:22,280 --> 00:39:26,510 ou fazendo o que estamos fazendo para a matriz sempre terá a mesma quantidade de tempo. 657 00:39:26,510 --> 00:39:30,270 Assim, podemos representar que apenas com um 1, o qual é uma constante. 658 00:39:30,270 --> 00:39:32,410 Nós também olhou em tempo de execução logarítmica. 659 00:39:32,410 --> 00:39:34,800 Portanto, algo como busca binária é logarítmica, 660 00:39:34,800 --> 00:39:37,140 onde vamos cortar o problema pela metade o tempo todo 661 00:39:37,140 --> 00:39:40,970 e depois as coisas só ficam mais de lá. 662 00:39:40,970 --> 00:39:43,580 E se você está sempre escrevendo um O de qualquer algoritmo de fatorial, 663 00:39:43,580 --> 00:39:47,850 provavelmente você não deve considerar este como o seu trabalho do dia. 664 00:39:47,850 --> 00:39:53,910 Ao comparar tempos de execução é importante manter em mente essas coisas. 665 00:39:53,910 --> 00:39:57,760 Então, se eu tenho um algoritmo que é O (n), e mais alguém 666 00:39:57,760 --> 00:40:03,590 tem um algoritmo de O (2n) estes são realmente assintoticamente equivalente. 667 00:40:03,590 --> 00:40:06,590 Então, se nós imaginarmos n para ser um número grande como Eleventy bilhões: 668 00:40:06,590 --> 00:40:13,090 Então, quando estamos comparando Eleventy bilhões para algo como Eleventy bilhões + 3, 669 00:40:13,090 --> 00:40:17,640 de repente que três realmente não faz uma grande diferença mais. 670 00:40:17,640 --> 00:40:20,980 É por isso que nós vamos começar a considerar essas coisas equivalentes. 671 00:40:20,980 --> 00:40:24,220 Então, coisas como essas constantes aqui, há 2 x este, ou a adição de 3, 672 00:40:24,220 --> 00:40:27,180 estes são apenas constantes, e estes vão cair para cima. 673 00:40:27,180 --> 00:40:32,480 É por isso que todos os 3 destes tempos de execução são o mesmo que dizer que eles são O (n). 674 00:40:32,480 --> 00:40:37,490 Da mesma forma, se temos dois tempos de execução de outros, digamos O (n ³ + 2n ²), podemos adicionar 675 00:40:37,490 --> 00:40:42,070 + N, + 7, e depois temos um outro tempo de execução que é apenas O (n ³). 676 00:40:42,070 --> 00:40:46,290 Novamente, estes são a mesma coisa, porque estes - estes não são os mesmos. 677 00:40:46,290 --> 00:40:49,840 Estas são as mesmas coisas, me desculpe. Então, esses são os mesmos, porque 678 00:40:49,840 --> 00:40:53,090 este ³ n vai dominar este ² 2n. 679 00:40:53,090 --> 00:40:59,130 >> O que não é a mesma coisa é se ter executado tempos como O (n ³) e O (n ²) 680 00:40:59,130 --> 00:41:02,820 porque este ³ n é muito maior do que isto n ². 681 00:41:02,820 --> 00:41:05,470 Então, se temos expoentes, de repente, isso começa com a matéria, 682 00:41:05,470 --> 00:41:08,280 mas quando estamos lidando apenas com fatores como estamos aqui, 683 00:41:08,280 --> 00:41:12,810 então não vai importar, porque eles estão indo só para cair fora. 684 00:41:12,810 --> 00:41:16,760 Vamos dar uma olhada em alguns dos algoritmos que temos visto até agora 685 00:41:16,760 --> 00:41:19,260 e falar sobre o seu tempo de execução. 686 00:41:19,260 --> 00:41:23,850 A primeira maneira de olhar para um número em uma lista, o que vimos, foi busca linear. 687 00:41:23,850 --> 00:41:26,950 Ea implementação da busca linear é super simples. 688 00:41:26,950 --> 00:41:30,490 Nós só temos uma lista, e vamos olhar para cada elemento na lista 689 00:41:30,490 --> 00:41:34,260 até encontrar o número que estamos procurando. 690 00:41:34,260 --> 00:41:38,370 Então, o que significa que na pior das hipóteses, este O (n). 691 00:41:38,370 --> 00:41:40,860 E o pior caso aqui poderia ser se o elemento é 692 00:41:40,860 --> 00:41:45,710 o último elemento, em seguida, usando busca linear, temos de olhar para cada elemento 693 00:41:45,710 --> 00:41:50,180 até chegarmos ao último, a fim de saber que era realmente na lista. 694 00:41:50,180 --> 00:41:52,910 Nós não podemos simplesmente desistir no meio e dizer: "É, provavelmente, não existe." 695 00:41:52,910 --> 00:41:55,980 Com a busca linear temos de olhar para a coisa toda. 696 00:41:55,980 --> 00:41:59,090 O tempo de funcionamento melhor caso, por outro lado, é constante 697 00:41:59,090 --> 00:42:04,200 porque, no melhor caso, o elemento que estamos procurando é apenas o primeiro da lista. 698 00:42:04,200 --> 00:42:08,930 Por isso, vai nos levar exatamente o passo 1, não importa quão grande a lista é 699 00:42:08,930 --> 00:42:12,140 se nós estamos olhando para o primeiro elemento de cada vez. 700 00:42:12,140 --> 00:42:15,390 >> Então, quando você pesquisa, lembre-se, não exige que a nossa lista de ser classificado. 701 00:42:15,390 --> 00:42:19,430 Porque nós estamos indo simplesmente para olhar sobre cada elemento, e isso realmente não importa 702 00:42:19,430 --> 00:42:23,560 que ordem os elementos estão dentro 703 00:42:23,560 --> 00:42:28,110 Um algoritmo de busca mais inteligente é algo como pesquisa binária. 704 00:42:28,110 --> 00:42:31,500 Lembre-se, a implementação de busca binária é quando você vai 705 00:42:31,500 --> 00:42:34,320 manter a olhar para o meio da lista. 706 00:42:34,320 --> 00:42:38,000 E porque estamos a olhar para o meio, é necessário que a lista é ordenada 707 00:42:38,000 --> 00:42:40,580 ou então nós não sabemos onde o meio é, e temos que olhar por cima 708 00:42:40,580 --> 00:42:44,480 toda a lista de encontrá-lo, e então em que ponto nós estamos apenas perdendo tempo. 709 00:42:44,480 --> 00:42:48,480 Então, se temos uma lista ordenada e encontramos a meio, vamos comparar a média 710 00:42:48,480 --> 00:42:51,590 ao elemento que estamos procurando. 711 00:42:51,590 --> 00:42:54,640 Se for muito alto, então podemos esquecer a metade direita 712 00:42:54,640 --> 00:42:57,810 porque sabemos que, se o nosso elemento já é muito alta 713 00:42:57,810 --> 00:43:01,080 e tudo para a direita deste elemento é ainda maior, 714 00:43:01,080 --> 00:43:02,760 então não precisa olhar mais lá. 715 00:43:02,760 --> 00:43:05,430 Onde, por outro lado, se o nosso elemento é muito baixa, 716 00:43:05,430 --> 00:43:08,700 sabemos tudo para a esquerda do elemento que é também demasiado baixa, 717 00:43:08,700 --> 00:43:11,390 por isso realmente não faz sentido olhar para lá, também. 718 00:43:11,390 --> 00:43:15,760 Dessa forma, a cada passo e cada vez que olhar para o ponto médio da lista, 719 00:43:15,760 --> 00:43:19,060 vamos cortar pela metade o nosso problema, porque de repente sabemos 720 00:43:19,060 --> 00:43:23,040 um monte de números que não podem ser o que estamos procurando. 721 00:43:23,040 --> 00:43:26,950 >> Em pseudocódigo este seria algo parecido com isso, 722 00:43:26,950 --> 00:43:30,990 e porque estamos cortando a lista pela metade a cada momento, 723 00:43:30,990 --> 00:43:34,920 nossas pior caso de execução de saltos no tempo linear para logarítmica. 724 00:43:34,920 --> 00:43:39,260 Então, de repente, temos log-in passos para encontrar um elemento em uma lista. 725 00:43:39,260 --> 00:43:42,460 O tempo de execução de melhor caso, no entanto, ainda é constante 726 00:43:42,460 --> 00:43:45,180 porque agora, vamos apenas dizer que o elemento que estamos procurando é 727 00:43:45,180 --> 00:43:48,380 sempre meio exato da lista original. 728 00:43:48,380 --> 00:43:52,080 Assim, podemos aumentar a nossa lista tão grande como nós queremos, mas se o elemento que estamos procurando é no meio, 729 00:43:52,080 --> 00:43:54,910 então ele só vai nos levar um passo. 730 00:43:54,910 --> 00:44:00,920 Então é por isso que estamos O (log n) e Ω (1) ou constante. 731 00:44:00,920 --> 00:44:04,510 Vamos rodar busca binária nesta lista. 732 00:44:04,510 --> 00:44:08,020 Então, vamos dizer que nós estamos olhando para o elemento 164. 733 00:44:08,020 --> 00:44:11,650 A primeira coisa que vamos fazer é encontrar o ponto médio desta lista. 734 00:44:11,650 --> 00:44:15,060 O que acontece é que o ponto médio vai cair entre estes dois números, 735 00:44:15,060 --> 00:44:18,960 então vamos arbitrariamente dizer, toda vez que o ponto médio cai entre dois números, 736 00:44:18,960 --> 00:44:21,150 vamos arredondar para cima. 737 00:44:21,150 --> 00:44:24,330 Nós só precisamos ter certeza de que fazemos isso a cada passo do caminho. 738 00:44:24,330 --> 00:44:29,040 Então, vamos arredondar para cima, e nós vamos dizer que 161 é o meio de nossa lista. 739 00:44:29,040 --> 00:44:34,640 Então, 161 <164, e todos os elementos para a esquerda de 161 740 00:44:34,640 --> 00:44:39,120 também é <164, então sabemos que isso não vai nos ajudar em tudo 741 00:44:39,120 --> 00:44:42,690 para começar a olhar para aqui porque o elemento que estamos procurando não pode estar lá. 742 00:44:42,690 --> 00:44:47,060 Então o que podemos fazer é que podemos esquecer que metade toda esquerda da lista, 743 00:44:47,060 --> 00:44:51,700 e agora considerar apenas a partir da direita da frente 161. 744 00:44:51,700 --> 00:44:54,050 >> Então, novamente, este é o ponto médio; vamos arredondar para cima. 745 00:44:54,050 --> 00:44:56,260 Agora 175 é muito grande. 746 00:44:56,260 --> 00:44:59,180 Então, nós sabemos que não vai ajudar-nos a olhar aqui ou aqui, 747 00:44:59,180 --> 00:45:06,610 assim que nós podemos apenas jogar isso fora, e, eventualmente, vamos acertar o 164. 748 00:45:06,610 --> 00:45:10,560 Quaisquer dúvidas em busca binária? 749 00:45:10,560 --> 00:45:14,180 Vamos passar de busca através de uma lista já classificada 750 00:45:14,180 --> 00:45:17,660 para realmente tomar uma lista de números em qualquer ordem 751 00:45:17,660 --> 00:45:20,960 e fazer essa lista em ordem crescente. 752 00:45:20,960 --> 00:45:24,060 O primeiro algoritmo vimos foi chamado bubble sort. 753 00:45:24,060 --> 00:45:27,300 E esta seria mais simples dos algoritmos que vimos. 754 00:45:27,300 --> 00:45:32,970 Espécie de bolha, diz que quando os dois elementos dentro da lista estão fora do lugar, 755 00:45:32,970 --> 00:45:36,500 ou seja, há um maior número à esquerda de um número mais baixo, 756 00:45:36,500 --> 00:45:40,190 então nós estamos indo para trocá-los, porque isso significa que a lista será 757 00:45:40,190 --> 00:45:42,860 "Mais ordenadas" do que era antes. 758 00:45:42,860 --> 00:45:45,180 E nós apenas estamos indo para continuar este processo de novo e de novo e de novo 759 00:45:45,180 --> 00:45:52,100 até que finalmente o tipo elementos de bolha para sua localização correta e temos uma lista classificada. 760 00:45:52,100 --> 00:45:57,230 >> O tempo de execução deste vai ser O (n ²). Por quê? 761 00:45:57,230 --> 00:46:00,370 Bem, porque na pior das hipóteses, vamos tomar todos os elementos, e 762 00:46:00,370 --> 00:46:04,570 vamos acabar comparando-a com todos os outros elementos da lista. 763 00:46:04,570 --> 00:46:08,030 Mas, na melhor das hipóteses, temos uma lista já classificados, tipo de bolha 764 00:46:08,030 --> 00:46:12,230 só vai passar por uma vez, dizer "Nope. eu não fazer qualquer troca, assim que eu sou feito." 765 00:46:12,230 --> 00:46:17,410 Então, nós temos um tempo melhor caso de execução de Ω (n). 766 00:46:17,410 --> 00:46:20,680 Vamos correr espécie de bolha em uma lista. 767 00:46:20,680 --> 00:46:23,560 Ou primeiro, vamos olhar para alguns pseudocódigo muito rapidamente. 768 00:46:23,560 --> 00:46:28,160 Queremos dizer que queremos acompanhar, em cada iteração do loop, 769 00:46:28,160 --> 00:46:32,190 manter o controle da existência ou não mudamos todos os elementos. 770 00:46:32,190 --> 00:46:37,610 Assim, a razão para isso é que nós vamos parar quando não trocaram todos os elementos. 771 00:46:37,610 --> 00:46:41,980 Então, no início de nosso laço não ter trocado nada, então vamos dizer que é falso. 772 00:46:41,980 --> 00:46:47,170 Agora, vamos percorrer a lista e comparar elemento i ao elemento i + 1 773 00:46:47,170 --> 00:46:50,310 e se for o caso em que existe um maior número à esquerda de um número menor, 774 00:46:50,310 --> 00:46:52,310 então nós estamos indo só para trocá-los. 775 00:46:52,310 --> 00:46:54,490 >> E então, vamos lembrar que nós trocamos um elemento. 776 00:46:54,490 --> 00:46:58,900 Isso significa que temos de percorrer a lista pelo menos uma vez mais 777 00:46:58,900 --> 00:47:02,160 porque a condição em que se parou é quando toda a lista é já classificados, 778 00:47:02,160 --> 00:47:04,890 o que significa que não tenha feito qualquer troca. 779 00:47:04,890 --> 00:47:09,960 É por isso que a nossa condição aqui é "enquanto alguns elementos foram trocados." 780 00:47:09,960 --> 00:47:13,720 Então, agora vamos olhar para esta rodando em uma lista. 781 00:47:13,720 --> 00:47:16,640 Eu tenho a lista 5,0,1,6,4. 782 00:47:16,640 --> 00:47:19,850 Espécie de bolha vai começar todo o caminho à esquerda, e vai para comparar 783 00:47:19,850 --> 00:47:24,700 os elementos i, de modo 0 a i + 1, que é o elemento 1. 784 00:47:24,700 --> 00:47:29,020 Vai dizer, bem 5> 0, mas agora 5 é para a esquerda, 785 00:47:29,020 --> 00:47:32,500 então eu preciso trocar o 5 eo 0. 786 00:47:32,500 --> 00:47:35,470 Quando eu trocá-los, de repente, eu recebo esta lista diferente. 787 00:47:35,470 --> 00:47:38,260 Agora 5> 1, então nós estamos indo para trocá-los. 788 00:47:38,260 --> 00:47:42,160 5 não é> 6, portanto, não precisa fazer nada aqui. 789 00:47:42,160 --> 00:47:46,690 Mas 6> 4, por isso precisamos trocar. 790 00:47:46,690 --> 00:47:49,740 Mais uma vez, temos de percorrer toda a lista para, eventualmente, descobrir 791 00:47:49,740 --> 00:47:52,330 que estes estão fora de ordem, nós trocá-los, 792 00:47:52,330 --> 00:47:57,120 e neste momento temos de percorrer a lista uma vez mais 793 00:47:57,120 --> 00:48:05,390 para se certificar de que tudo está no seu fim, e neste tipo de bolha ponto de terminar. 794 00:48:05,390 --> 00:48:10,720 Um algoritmo diferente para a tomada de alguns elementos e classificá-los é uma espécie de seleção. 795 00:48:10,720 --> 00:48:15,740 A idéia por trás tipo de seleção é que nós vamos construir uma parte classificada da lista 796 00:48:15,740 --> 00:48:18,150 Um elemento de cada vez. 797 00:48:18,150 --> 00:48:23,170 >> E a maneira como vamos fazer isso é através da construção de segmento esquerdo da lista. 798 00:48:23,170 --> 00:48:27,510 E, basicamente, cada - em cada etapa, vamos levar o menor elemento que nos resta 799 00:48:27,510 --> 00:48:32,310 que não tenha sido resolvido ainda, e nós estamos indo para movê-lo para que o segmento classificado. 800 00:48:32,310 --> 00:48:35,850 Isso significa que precisamos continuamente encontrar o elemento mínimo indiferenciados 801 00:48:35,850 --> 00:48:40,720 e levar esse elemento mínimo e trocá-lo com o que 802 00:48:40,720 --> 00:48:45,090 mais à esquerda elemento que não está classificada. 803 00:48:45,090 --> 00:48:50,890 O tempo de execução deste vai ser O (n ²), porque no pior caso 804 00:48:50,890 --> 00:48:55,070 precisamos comparar cada elemento de qualquer outro elemento. 805 00:48:55,070 --> 00:48:59,250 Porque nós estamos dizendo que, se começar na metade esquerda da lista, precisamos 806 00:48:59,250 --> 00:49:02,970 que passar por todo o segmento da direita para encontrar o menor elemento. 807 00:49:02,970 --> 00:49:05,430 E então, mais uma vez, temos de passar por cima de todo o segmento direito e 808 00:49:05,430 --> 00:49:08,210 continuar mais que uma e outra e outra vez. 809 00:49:08,210 --> 00:49:11,350 Isso vai ser ² n. Nós vamos precisar de um circuito para dentro de outro loop 810 00:49:11,350 --> 00:49:13,350 o que sugere ² n. 811 00:49:13,350 --> 00:49:16,530 No pensamento melhor caso, vamos dizer que nós dar-lhe uma lista já classificados; 812 00:49:16,530 --> 00:49:19,270 nós realmente não fazer melhor do que ² n. 813 00:49:19,270 --> 00:49:21,730 Porque tipo de seleção não tem forma de saber que 814 00:49:21,730 --> 00:49:25,540 o elemento mínimo é apenas a acontecer de eu estar olhando. 815 00:49:25,540 --> 00:49:28,970 Ele ainda precisa ter certeza de que este é realmente o mínimo. 816 00:49:28,970 --> 00:49:31,670 >> E a única maneira de ter certeza de que é o mínimo, usando esse algoritmo, 817 00:49:31,670 --> 00:49:34,640 é olhar para cada elemento novo. 818 00:49:34,640 --> 00:49:38,420 Então, realmente, se você der a ele - se você der tipo de seleção uma lista já classificados, 819 00:49:38,420 --> 00:49:42,720 ele não vai fazer nada melhor do que dar-lhe uma lista que não é classificado ainda. 820 00:49:42,720 --> 00:49:46,320 By the way, se acontecer de ser o caso de que algo é O (algo) 821 00:49:46,320 --> 00:49:50,640 eo ômega de algo, podemos dizer de forma mais sucinta que é θ de algo. 822 00:49:50,640 --> 00:49:52,760 Então, se você ver que chegar em qualquer lugar, isso é o que significa apenas. 823 00:49:52,760 --> 00:49:57,580 >> Se algo é theta de n ², é tanto grande O (n ²) e Ω (n ²). 824 00:49:57,580 --> 00:49:59,790 Então, o melhor caso e pior caso, não faz diferença, 825 00:49:59,790 --> 00:50:04,400 o algoritmo vai fazer a mesma coisa o tempo todo. 826 00:50:04,400 --> 00:50:06,610 Então é isso que pseudocódigo para tipo de seleção pode parecer. 827 00:50:06,610 --> 00:50:10,630 Estamos basicamente vai dizer que eu quero iterar sobre a lista 828 00:50:10,630 --> 00:50:15,180 da esquerda para a direita, e em cada iteração do loop, eu estou indo para mover 829 00:50:15,180 --> 00:50:19,780 o elemento mínimo para esta porção da lista ordenada. 830 00:50:19,780 --> 00:50:23,260 E uma vez que eu passo alguma coisa lá, eu nunca precisa olhar para esse elemento novamente. 831 00:50:23,260 --> 00:50:28,600 Porque assim que eu trocar um elemento para o segmento esquerdo da lista, está classificada 832 00:50:28,600 --> 00:50:32,600 porque estamos fazendo tudo em ordem crescente, usando mínimos. 833 00:50:32,600 --> 00:50:38,740 Então nós dissemos, tudo bem, estamos na posição i, e nós precisamos de olhar para todos os elementos 834 00:50:38,740 --> 00:50:42,260 para a direita de i, a fim de encontrar o mínimo. 835 00:50:42,260 --> 00:50:46,150 Assim, isto significa que quer olhar de i + 1 para o fim da lista. 836 00:50:46,150 --> 00:50:51,610 E agora, se o elemento que nós estamos procurando é a menos do que o nosso mínimo até agora, 837 00:50:51,610 --> 00:50:54,190 que, lembre-se, estamos começando a fora mínimo a ser apenas 838 00:50:54,190 --> 00:50:57,020 qualquer elemento que estamos atualmente, eu vou assumir que é o mínimo. 839 00:50:57,020 --> 00:51:00,270 Se eu encontrar um elemento que é menor do que isso, então eu vou dizer, ok, 840 00:51:00,270 --> 00:51:02,700 bem, eu encontrei um novo mínimo. 841 00:51:02,700 --> 00:51:06,080 Eu vou lembrar de onde esse mínimo era. 842 00:51:06,080 --> 00:51:09,560 >> Então, agora, depois de já ter passado por esse segmento direito indiferenciados, 843 00:51:09,560 --> 00:51:16,690 Eu posso dizer que eu vou trocar o elemento mínimo com o elemento que está na posição i. 844 00:51:16,690 --> 00:51:21,100 Que vai construir a minha lista, minha porção classificada da lista da esquerda para a direita, 845 00:51:21,100 --> 00:51:25,190 e não precisar olhar para um elemento novo, uma vez que é nessa porção. 846 00:51:25,190 --> 00:51:27,930 Uma vez que tenhamos trocado ele. 847 00:51:27,930 --> 00:51:30,260 Então, vamos executar tipo de seleção na lista. 848 00:51:30,260 --> 00:51:38,220 O elemento de azul aqui vai ser a i, e o elemento vermelho vai ser o elemento mínimo. 849 00:51:38,220 --> 00:51:41,570 Então eu começa todo o caminho à esquerda da lista, de modo a 5. 850 00:51:41,570 --> 00:51:44,610 Agora precisamos encontrar o elemento mínimo indiferenciados. 851 00:51:44,610 --> 00:51:49,480 Assim, dizemos 0 <5, então 0 é o meu novo mínimo. 852 00:51:49,480 --> 00:51:53,820 >> Mas eu não posso parar por aí, porque, embora possamos reconhecer que 0 é o menor, 853 00:51:53,820 --> 00:51:59,390 que precisamos para executar através de todos os outros elementos da lista para ter certeza. 854 00:51:59,390 --> 00:52:01,760 Então, um é maior, 6 é maior, 4 é maior. 855 00:52:01,760 --> 00:52:05,850 Isso significa que, depois de olhar para todos esses elementos, eu já determinou 0 é o menor. 856 00:52:05,850 --> 00:52:09,800 Então, eu vou trocar o 5 eo 0. 857 00:52:09,800 --> 00:52:15,480 Uma vez eu trocar isso, eu estou indo para obter uma nova lista, e eu sei que eu nunca precisa olhar para isso 0 novamente 858 00:52:15,480 --> 00:52:19,380 porque uma vez eu troquei, eu classificados por ele e estamos a fazer. 859 00:52:19,380 --> 00:52:22,730 Agora, acontece que o elemento azul é novamente a 5, 860 00:52:22,730 --> 00:52:26,030 e que precisa de olhar para o 1, a 6 e a 4 para determinar que um 861 00:52:26,030 --> 00:52:31,520 é o menor elemento mínimo, então vamos trocar o 1 eo 5. 862 00:52:31,520 --> 00:52:36,890 Mais uma vez, temos de olhar - comparar a 5 para o 6 e 4, 863 00:52:36,890 --> 00:52:39,830 e vamos trocar o 4 eo 5, e, finalmente, comparar 864 00:52:39,830 --> 00:52:45,740 os números 2 e trocá-los até chegar a nossa lista de classificados. 865 00:52:45,740 --> 00:52:49,730 Qualquer dúvida sobre tipo de seleção? 866 00:52:49,730 --> 00:52:56,420 Okay. Vamos passar para o último tópico aqui, e que é a recursividade. 867 00:52:56,420 --> 00:52:59,810 >> Recursão, lembre-se, é essa coisa meta realmente onde uma função 868 00:52:59,810 --> 00:53:02,740 repetidamente chama a si mesmo. 869 00:53:02,740 --> 00:53:05,620 Então, em algum ponto, enquanto a nossa fuction é repetidamente chamando-se, 870 00:53:05,620 --> 00:53:10,100 é preciso haver algum ponto em que paramos de nos chamar. 871 00:53:10,100 --> 00:53:13,670 Porque se nós não fizermos isso, então vamos apenas continuar a fazer isso para sempre 872 00:53:13,670 --> 00:53:16,660 e nosso programa é só não vai terminar. 873 00:53:16,660 --> 00:53:19,200 Chamamos essa condição no caso base. 874 00:53:19,200 --> 00:53:22,570 E o caso base diz, ao invés de chamar uma função de novo, 875 00:53:22,570 --> 00:53:25,330 Eu só vou retornar algum valor. 876 00:53:25,330 --> 00:53:28,080 Portanto, uma vez que já retornou um valor, nós paramos de nos chamar, 877 00:53:28,080 --> 00:53:32,550 eo resto dos convites que fizemos até agora também pode retornar. 878 00:53:32,550 --> 00:53:36,050 O oposto do caso base é o caso recursivo. 879 00:53:36,050 --> 00:53:39,050 E isto é quando queremos fazer uma outra chamada para a função que estamos atualmente dentro 880 00:53:39,050 --> 00:53:44,690 E nós provavelmente, embora nem sempre, quer usar argumentos diferentes. 881 00:53:44,690 --> 00:53:48,940 >> Então, se temos uma função chamada f, ef chamado apenas de tomar um argumento, 882 00:53:48,940 --> 00:53:52,010 e nós continuamos chamando f (1), f (1), f (1), e isso só acontece que 883 00:53:52,010 --> 00:53:56,510 o argumento cai em um caso recursivo, estamos ainda nunca vai parar. 884 00:53:56,510 --> 00:54:01,620 Mesmo se tivermos um caso base, precisamos ter certeza de que, eventualmente, vamos bater esse caso base. 885 00:54:01,620 --> 00:54:04,250 Nós não apenas manter permanecer neste caso recursivo. 886 00:54:04,250 --> 00:54:09,870 Geralmente, quando chamamos a nós mesmos, provavelmente vamos ter um argumento diferente a cada vez. 887 00:54:09,870 --> 00:54:12,700 Aqui é uma função muito simples recursiva. 888 00:54:12,700 --> 00:54:15,090 Então, isso vai calcular o fatorial de um número. 889 00:54:15,090 --> 00:54:17,790 Lá em cima, aqui temos o nosso caso base. 890 00:54:17,790 --> 00:54:22,330 No caso em que n ≤ 1, nós não vamos chamar fatorial novamente. 891 00:54:22,330 --> 00:54:26,490 Nós vamos parar, estamos apenas indo para retornar algum valor. 892 00:54:26,490 --> 00:54:30,170 Se isso não é verdade, então nós estamos indo para acertar nosso caso recursivo. 893 00:54:30,170 --> 00:54:33,550 Note-se aqui que não estamos apenas chamando fatorial (n), porque isso não seria muito útil. 894 00:54:33,550 --> 00:54:36,810 Nós vamos chamar fatorial de outra coisa. 895 00:54:36,810 --> 00:54:40,850 >> E assim você pode ver, eventualmente, se passar um algo fatorial (5) ou, 896 00:54:40,850 --> 00:54:45,900 vamos chamar fatorial (4) e assim por diante, e, eventualmente, vamos bater este cenário de base. 897 00:54:45,900 --> 00:54:51,730 Portanto, este parece ser bom. Vamos ver o que acontece quando nós realmente executar este. 898 00:54:51,730 --> 00:54:57,840 Esta é a pilha, e vamos dizer que principal vai chamar esta função com um argumento (4). 899 00:54:57,840 --> 00:55:02,200 Portanto, uma vez fatorial vê e = 4, fatorial irá se identificar. 900 00:55:02,200 --> 00:55:05,010 Agora, de repente, temos fatorial (3). 901 00:55:05,010 --> 00:55:10,780 Então, essas funções vão continuar crescendo até finalmente chegarmos nosso caso base. 902 00:55:10,780 --> 00:55:17,830 Neste ponto, o valor de retorno é o retorno (nx o valor de retorno deste), 903 00:55:17,830 --> 00:55:21,290 o valor de retorno é nx valor o retorno deste. 904 00:55:21,290 --> 00:55:23,290 Eventualmente precisamos acertar algum número. 905 00:55:23,290 --> 00:55:26,560 No topo aqui, dizemos retorno 1. 906 00:55:26,560 --> 00:55:30,650 Isso significa que uma vez que voltar esse número, podemos pop esta na pilha. 907 00:55:30,650 --> 00:55:36,570 Portanto, este fatorial (1) é feito. 908 00:55:36,570 --> 00:55:41,190 Quando um retorna, esse fatoriais (1) retorna, esse retorno a 1. 909 00:55:41,190 --> 00:55:46,910 O valor de retorno a isso, lembre-se, foi nx o valor de retorno deste. 910 00:55:46,910 --> 00:55:50,720 Então, de repente, esse cara sabe que eu quero voltar 2. 911 00:55:50,720 --> 00:55:55,910 >> Então lembre-se, retornar o valor desta é apenas nx o valor de retorno aqui. 912 00:55:55,910 --> 00:56:01,160 Então agora podemos dizer 3 x 2, e, finalmente, aqui podemos dizer 913 00:56:01,160 --> 00:56:04,010 isso é apenas vai ser 4 x 3 x 2. 914 00:56:04,010 --> 00:56:09,570 E uma vez que ele retorna, nós descer a um único inteiro dentro da principal. 915 00:56:09,570 --> 00:56:15,460 Qualquer dúvida sobre recursão? 916 00:56:15,460 --> 00:56:17,090 Tudo bem. Portanto, não há mais tempo para perguntas, no final, 917 00:56:17,090 --> 00:56:23,360 mas agora Joseph cobrirá os tópicos restantes. 918 00:56:23,360 --> 00:56:25,590 >> [Joseph Ong] Tudo bem. Portanto, agora que nós já conversamos sobre recursões, 919 00:56:25,590 --> 00:56:27,840 vamos falar um pouco sobre o que é merge sort. 920 00:56:27,840 --> 00:56:31,740 Merge sort é basicamente uma outra maneira de ordenar uma lista de números. 921 00:56:31,740 --> 00:56:36,430 E como ele funciona é, com merge sort você tem uma lista, eo que fazemos é 922 00:56:36,430 --> 00:56:39,120 dizemos, vamos dividir isso em duas metades. 923 00:56:39,120 --> 00:56:42,750 Vamos primeiro executar merge sort novamente na metade esquerda, 924 00:56:42,750 --> 00:56:45,040 Então vamos correr merge sort na metade direita, 925 00:56:45,040 --> 00:56:50,240 e que nos dá agora duas metades que são classificados, e agora vamos combinar essas metades juntas. 926 00:56:50,240 --> 00:56:55,010 É um pouco difícil de ver sem um exemplo, por isso vamos percorrer as propostas e ver o que acontece. 927 00:56:55,010 --> 00:56:59,590 Então você começa com esta lista, que dividi-lo em duas metades. 928 00:56:59,590 --> 00:57:02,300 Corremos merge sort na metade esquerda primeiro. 929 00:57:02,300 --> 00:57:06,660 Então essa é a metade esquerda, e agora nós executá-los através desta lista novamente 930 00:57:06,660 --> 00:57:09,800 que é passado para merge sort, e então olhamos, mais uma vez, 931 00:57:09,800 --> 00:57:13,270 no lado esquerdo da lista e corremos merge sort sobre ele. 932 00:57:13,270 --> 00:57:15,880 Agora, temos até uma lista de números 2, 933 00:57:15,880 --> 00:57:19,010 e agora a metade esquerda é apenas um elemento de comprimento, e não podemos 934 00:57:19,010 --> 00:57:23,380 dividir uma lista que é apenas um elemento no meio, de modo que acabamos de dizer, uma vez que temos 50, 935 00:57:23,380 --> 00:57:26,400 que é apenas um elemento, já está classificado. 936 00:57:26,400 --> 00:57:29,860 >> Uma vez que estamos a fazer com que, nós podemos ver que nós podemos 937 00:57:29,860 --> 00:57:32,230 passar para a metade direita da lista, 938 00:57:32,230 --> 00:57:36,480 e 3 também é classificado, e agora que as duas metades desta lista são classificados 939 00:57:36,480 --> 00:57:39,080 podemos juntar esses números juntos novamente. 940 00:57:39,080 --> 00:57:45,320 Assim, analisamos 50 e 3, 3 é menor do que 50, de modo que vai em primeiro lugar e, em seguida, 50 vem dentro 941 00:57:45,320 --> 00:57:49,340 Agora, isso é feito, nós voltar-se a essa lista e tipo é meia direita. 942 00:57:49,340 --> 00:57:52,440 42 é seu número próprio, por isso já está classificada. 943 00:57:52,440 --> 00:57:57,850 Então agora nós comparar estes 2 e 3 é menor do que 42, de modo que é colocado em primeiro lugar, 944 00:57:57,850 --> 00:58:02,340 agora com 42 anos é colocado, e 50 é colocado dentro 945 00:58:02,340 --> 00:58:07,220 Agora, que está classificado, que percorrer todo o caminho de volta ao topo, 1337 e 15. 946 00:58:07,220 --> 00:58:14,560 Bem, nós agora olhar para a metade esquerda da lista; 1337 é, por si só por isso é classificado e mesmo com 15. 947 00:58:14,560 --> 00:58:19,020 Então agora nós combinar esses dois números para ordenar que a lista original, 15 <1,337, 948 00:58:19,020 --> 00:58:23,060 assim vai em primeiro lugar, então 1337 vai dentro 949 00:58:23,060 --> 00:58:26,640 E agora nós classificamos as duas metades da lista original em cima. 950 00:58:26,640 --> 00:58:30,440 E tudo o que temos a fazer é combinar estes. 951 00:58:30,440 --> 00:58:36,890 Nós olhamos para os 2 primeiros números desta lista, 3 <15, então ele vai para a matriz de classificação em primeiro lugar. 952 00:58:36,890 --> 00:58:44,460 15 <42, assim que vai dentro Agora, 42 <1337, que vai dentro 953 00:58:44,460 --> 00:58:51,010 50 <1,337, de modo que vai dentro e perceber que nós só teve dois números fora desta lista. 954 00:58:51,010 --> 00:58:53,640 Portanto, não estamos apenas alternando entre as duas listas. 955 00:58:53,640 --> 00:58:56,050 Estamos apenas olhando para o início, e nós estamos levando o elemento 956 00:58:56,050 --> 00:59:00,270 que é menor e, em seguida, colocá-lo em nossa matriz. 957 00:59:00,270 --> 00:59:04,080 Agora nós mesclou todas as metades e estamos a fazer. 958 00:59:04,080 --> 00:59:07,780 >> Qualquer dúvida sobre merge sort? Sim? 959 00:59:07,780 --> 00:59:14,190 [Estudante] Se for dividir em grupos diferentes, por que eles não apenas dividi-lo uma vez 960 00:59:14,190 --> 00:59:19,970 e você tem 3 e 2 em um grupo? [Resto do ininteligível questão] 961 00:59:19,970 --> 00:59:24,940 A razão - então a questão é, por que não podemos simplesmente juntá-las em que o primeiro passo depois de tê-los? 962 00:59:24,940 --> 00:59:29,530 A razão que nós podemos fazer isso, inicie os elementos mais à esquerda de ambos os lados, 963 00:59:29,530 --> 00:59:33,040 e depois tome a menor e colocá-lo em, é que sabemos que esses 964 00:59:33,040 --> 00:59:35,290 listas individuais estão em ordens classificados. 965 00:59:35,290 --> 00:59:37,290 Então, se eu estou olhando para os elementos mais à esquerda de ambas as metades, 966 00:59:37,290 --> 00:59:40,490 Eu sei que eles vão ser os menores elementos dessas listas. 967 00:59:40,490 --> 00:59:43,930 Para que eu possa colocá-los em pontos menor elemento desta lista grande. 968 00:59:43,930 --> 00:59:47,810 Por outro lado, se eu olhar para as duas listas no segundo nível por lá, 969 00:59:47,810 --> 00:59:51,640 50, 3, 42, 1337 e 15, aqueles que não são classificados. 970 00:59:51,640 --> 00:59:55,770 Então, se eu olhar para 50 e 1337, eu vou colocar 50 em minha primeira lista. 971 00:59:55,770 --> 01:00:00,130 Mas isso não faz muito sentido, porque 3 é o menor elemento de todos aqueles. 972 01:00:00,130 --> 01:00:04,390 Então, a única razão que podemos fazer este passo combinando é porque nossas listas já estão classificados. 973 01:00:04,390 --> 01:00:07,010 É por isso que nós temos que começar todo o caminho até o fundo 974 01:00:07,010 --> 01:00:09,800 porque quando temos apenas um único número, você sabe que um único número 975 01:00:09,800 --> 01:00:14,120 em si já é uma lista ordenada. 976 01:00:14,120 --> 01:00:19,360 >> Alguma pergunta? Não? 977 01:00:19,360 --> 01:00:24,260 Complexidade? Bem, você pode ver que em cada etapa há números finais, 978 01:00:24,260 --> 01:00:27,590 e podemos dividir uma lista em meia log n vezes, 979 01:00:27,590 --> 01:00:31,700 que é onde nós começamos este log n x n complexidade. 980 01:00:31,700 --> 01:00:34,940 E você vai ver o melhor caso para merge sort é n log n, e isso só acontece 981 01:00:34,940 --> 01:00:39,340 que o pior caso, ou o Ω lá, também é n log n. 982 01:00:39,340 --> 01:00:42,480 Algo para se manter em mente. 983 01:00:42,480 --> 01:00:45,750 Seguindo em frente, vamos ir para algum arquivo de super básica I / O. 984 01:00:45,750 --> 01:00:48,830 Se você olhou para Scramble, você vai notar que tivemos algum tipo de sistema 985 01:00:48,830 --> 01:00:51,270 onde você pode gravar em um arquivo de log, se você ler o código. 986 01:00:51,270 --> 01:00:53,730 Vamos ver como você pode fazer isso. 987 01:00:53,730 --> 01:00:57,450 Bem, temos fprintf, que você pode pensar em como apenas printf, 988 01:00:57,450 --> 01:01:01,720 mas apenas a impressão para um arquivo em vez disso, e, portanto, o F no início. 989 01:01:01,720 --> 01:01:07,570 Este tipo de código até aqui, o que ele faz é, como você deve ter visto em Scramble, 990 01:01:07,570 --> 01:01:12,310 ele passa por sua impressão matriz de 2 dimensões fora de linha em linha quais são os números. 991 01:01:12,310 --> 01:01:17,850 Neste caso, printf imprime ao seu terminal ou o que chamamos a saída padrão de seção. 992 01:01:17,850 --> 01:01:22,170 >> E agora, neste caso, tudo o que temos a fazer é substituir printf com fprintf, 993 01:01:22,170 --> 01:01:26,770 dizer o que arquivo que você deseja imprimir, e, neste caso, apenas imprime-lo para o arquivo 994 01:01:26,770 --> 01:01:32,230 em vez de mostrá-lo ao seu terminal. 995 01:01:32,230 --> 01:01:36,500 Bem, então, que levanta a questão: Onde é que vamos conseguir esse tipo de arquivo, certo? 996 01:01:36,500 --> 01:01:39,840 Passamos login nesse fuction fprintf mas não tínhamos idéia de onde ele veio. 997 01:01:39,840 --> 01:01:43,980 Bem, no início do código, o que teve foi este pedaço de código aqui, 998 01:01:43,980 --> 01:01:48,340 que basicamente diz que o arquivo aberto chama log.txt. 999 01:01:48,340 --> 01:01:53,220 O que fazer depois disso é que temos que ter certeza de que o arquivo está realmente aberta com êxito. 1000 01:01:53,220 --> 01:01:57,070 Por isso, pode falhar por várias razões, você não tem espaço suficiente no seu computador, por exemplo. 1001 01:01:57,070 --> 01:01:59,790 Por isso é sempre importante antes de fazer qualquer operação com o arquivo 1002 01:01:59,790 --> 01:02:03,300 que verificar se o arquivo foi aberto com sucesso. 1003 01:02:03,300 --> 01:02:09,330 Então, o que que um, isso é um argumento para fopen, bem, podemos abrir um arquivo de muitas maneiras. 1004 01:02:09,330 --> 01:02:13,510 O que podemos fazer é, podemos passá-lo w, o que significa substituir o arquivo, se ele sair já, 1005 01:02:13,510 --> 01:02:18,070 Podemos passar um a, que acrescente ao final do arquivo, em vez de ignorá-los, 1006 01:02:18,070 --> 01:02:22,730 ou podemos especificar r, o que significa, vamos abrir o arquivo como somente leitura. 1007 01:02:22,730 --> 01:02:24,890 Então, se o programa tenta fazer as alterações para o arquivo, 1008 01:02:24,890 --> 01:02:30,140 gritar com eles e não deixá-los fazer isso. 1009 01:02:30,140 --> 01:02:33,320 Finalmente, uma vez que é feito com o arquivo, feito que faz operações sobre ela, 1010 01:02:33,320 --> 01:02:35,860 precisamos ter certeza de que feche o arquivo. 1011 01:02:35,860 --> 01:02:38,830 E assim, no final de seu programa, que vai passá-los novamente 1012 01:02:38,830 --> 01:02:42,120 este arquivo que você abriu, e apenas o fechar. 1013 01:02:42,120 --> 01:02:44,650 Então isso é algo importante que você tem que ter certeza que você faz. 1014 01:02:44,650 --> 01:02:47,180 Então lembre-se que você pode abrir um arquivo, então você pode escrever para o arquivo, 1015 01:02:47,180 --> 01:02:51,270 fazer operações no arquivo, mas então você tem que fechar o arquivo no final. 1016 01:02:51,270 --> 01:02:53,270 >> Qualquer dúvida sobre arquivo básico I / O? Sim? 1017 01:02:53,270 --> 01:02:58,050 [Pergunta do estudante, ininteligível] 1018 01:02:58,050 --> 01:03:02,480 Aqui. A questão é: onde é que este arquivo log.txt aparecer? 1019 01:03:02,480 --> 01:03:07,890 Bem, se você apenas dar-lhe log.txt, cria-lo no mesmo diretório que o executável. 1020 01:03:07,890 --> 01:03:10,500 Então, se você está - >> [pergunta Estudante, ininteligível] 1021 01:03:10,500 --> 01:03:18,830 Sim. Na mesma pasta, ou no mesmo diretório, como lhe chamam. 1022 01:03:18,830 --> 01:03:21,400 Agora memória, pilha, pilha e. 1023 01:03:21,400 --> 01:03:23,400 Então, como é a memória definidos no computador? 1024 01:03:23,400 --> 01:03:26,270 Bem, você pode imaginar a memória como uma espécie de este bloco aqui. 1025 01:03:26,270 --> 01:03:30,260 E na memória, temos o que é chamado de pilha preso lá, ea pilha que está lá embaixo. 1026 01:03:30,260 --> 01:03:34,480 E a pilha cresce para baixo e a pilha cresce para cima. 1027 01:03:34,480 --> 01:03:38,620 Assim como Tommy mencionado - oh, bem, e nós temos esses outros quatro segmentos que eu vou chegar em um segundo - 1028 01:03:38,620 --> 01:03:42,890 Como Tommy disse anteriormente, você sabe como se chamam as suas funções e chamar uns aos outros? 1029 01:03:42,890 --> 01:03:44,930 Constroem-se este tipo de quadro de pilha. 1030 01:03:44,930 --> 01:03:47,360 Bem, se as chamadas principais foo, foo é colocado na pilha. 1031 01:03:47,360 --> 01:03:52,430 Foo chama bar, bar de conseguir colocar na pilha, e que é colocado na pilha depois. 1032 01:03:52,430 --> 01:03:57,040 E como eles retornam, cada um se retirado da pilha. 1033 01:03:57,040 --> 01:04:00,140 O que cada um desses locais e memória segurar? 1034 01:04:00,140 --> 01:04:03,110 Pois bem, a parte superior, que é o segmento de texto, contém o próprio programa. 1035 01:04:03,110 --> 01:04:06,390 Assim, o código de máquina, que está lá, uma vez que você compilar o seu programa. 1036 01:04:06,390 --> 01:04:08,520 Em seguida, qualquer inicializado variáveis ​​globais. 1037 01:04:08,520 --> 01:04:12,660 >> Então você tem variáveis ​​globais em seu programa, e você diz assim, a = 5, 1038 01:04:12,660 --> 01:04:15,260 que é colocado no segmento, e logo abaixo que, 1039 01:04:15,260 --> 01:04:18,990 você tem quaisquer dados não inicializados global, que é apenas um INT, 1040 01:04:18,990 --> 01:04:20,990 mas você não dizer que é igual a nada. 1041 01:04:20,990 --> 01:04:23,870 Perceber estes são variáveis ​​globais, por isso eles estão fora de principal. 1042 01:04:23,870 --> 01:04:28,560 Então isso significa que todas as variáveis ​​globais que são declarados, mas não são inicializados. 1043 01:04:28,560 --> 01:04:32,310 Então, o que está no monte? Memória alocada usando malloc, que nós vamos chegar a um pouco. 1044 01:04:32,310 --> 01:04:35,990 E, finalmente, com a pilha que você tem todas as variáveis ​​locais 1045 01:04:35,990 --> 01:04:39,950 e todas as funções que se pode chamar de qualquer de seus parâmetros. 1046 01:04:39,950 --> 01:04:43,720 A última coisa, você realmente não tem que saber que as variáveis ​​de ambiente fazer, 1047 01:04:43,720 --> 01:04:46,700 mas sempre que você executar o programa, não é algo associado, como 1048 01:04:46,700 --> 01:04:49,550 este é o nome de usuário da pessoa que executou o programa. 1049 01:04:49,550 --> 01:04:51,550 E isso vai ser uma espécie de na parte inferior. 1050 01:04:51,550 --> 01:04:54,540 Em termos de endereços de memória, que são valores hexadecimais, 1051 01:04:54,540 --> 01:04:58,170 os valores no início topo a 0, e vão até o fim para o fundo. 1052 01:04:58,170 --> 01:05:00,440 Neste caso, se você estiver no sistema de 32 bits, 1053 01:05:00,440 --> 01:05:05,390 o endereço na parte inferior vai ser 0x, seguido por af, porque é 32 bits, 1054 01:05:05,390 --> 01:05:10,890 que é de 8 bytes, e neste caso corresponde a 8 bytes de 8 dígitos hexadecimais. 1055 01:05:10,890 --> 01:05:20,110 Então aqui você vai ter, como, 0xffffff, e até lá você vai ter 0. 1056 01:05:20,110 --> 01:05:23,660 Então, o que são ponteiros? Alguns de vocês podem não ter coberto este na seção anterior. 1057 01:05:23,660 --> 01:05:26,660 mas conseguimos passar por isso na palestra, para um ponteiro é apenas um tipo de dados 1058 01:05:26,660 --> 01:05:34,030 quais as lojas, em vez de algum tipo de valor como 50, ele armazena o endereço de algum local na memória. 1059 01:05:34,030 --> 01:05:36,020 Como que a memória [ininteligível]. 1060 01:05:36,020 --> 01:05:41,120 Portanto, neste caso, o que temos é, temos um ponteiro para um inteiro ou um int *, 1061 01:05:41,120 --> 01:05:46,210 e que contém este endereço hexadecimal de 0xDEADBEEF. 1062 01:05:46,210 --> 01:05:50,880 >> Então o que temos é, agora, este ponteiro aponta em algum local na memória, 1063 01:05:50,880 --> 01:05:56,020 e isso é só um, o valor de 50 é neste local de memória. 1064 01:05:56,020 --> 01:06:01,810 Em alguns sistemas de 32 bits, em todos os sistemas de 32 bits, os ponteiros levar até 32 pedaços ou 4 bytes. 1065 01:06:01,810 --> 01:06:06,020 Mas, por exemplo, em um sistema de 64 bits, os ponteiros são 64 bits. 1066 01:06:06,020 --> 01:06:08,040 Então, isso é algo que você vai querer manter em mente. 1067 01:06:08,040 --> 01:06:12,310 Então, em um sistema de ponta-bit, um ponteiro é bits de longo prazo. 1068 01:06:12,310 --> 01:06:17,320 Os ponteiros são uma coisa difícil de digerir sem coisas extras, 1069 01:06:17,320 --> 01:06:20,300 então vamos passar um exemplo de alocação dinâmica de memória. 1070 01:06:20,300 --> 01:06:25,130 O alocação dinâmica de memória faz por você, ou o que chamamos de malloc, 1071 01:06:25,130 --> 01:06:29,280 ele permite que você alocar algum tipo de dados fora do set. 1072 01:06:29,280 --> 01:06:31,830 Portanto, este tipo de dados é mais permanente para a duração do programa. 1073 01:06:31,830 --> 01:06:36,430 Porque, como você sabe, se você declarar x dentro de uma função, e que retorna de função, 1074 01:06:36,430 --> 01:06:40,910 você já não tem acesso aos dados que foram armazenados em x. 1075 01:06:40,910 --> 01:06:44,420 O que vamos fazer ponteiros é que vamos armazenar valores de memória ou loja 1076 01:06:44,420 --> 01:06:46,840 em um segmento diferente de memória, ou seja, a pilha. 1077 01:06:46,840 --> 01:06:49,340 Agora, depois voltamos para fora da função, desde que temos um ponteiro 1078 01:06:49,340 --> 01:06:54,960 para esse local na memória, então o que podemos fazer é que podemos apenas olhar para os valores lá. 1079 01:06:54,960 --> 01:06:58,020 Vejamos um exemplo: Este é o nosso layout de memória novamente. 1080 01:06:58,020 --> 01:07:00,050 E nós temos essa função, principal. 1081 01:07:00,050 --> 01:07:06,870 O que ele faz é - bem, tão simples, certo -? Int x = 5, que é apenas uma variável na pilha na principal. 1082 01:07:06,870 --> 01:07:12,450 >> Por outro lado, agora vamos declarar um ponteiro que chama os giveMeThreeInts função. 1083 01:07:12,450 --> 01:07:16,800 E agora vamos para essa função e criar um novo quadro de pilha para ele. 1084 01:07:16,800 --> 01:07:20,440 No entanto, neste quadro de pilha, nós declaramos temp * int, 1085 01:07:20,440 --> 01:07:23,210 que em mallocs três inteiros para nós. 1086 01:07:23,210 --> 01:07:25,880 Assim o tamanho de int nos dará quantos bytes int este é, 1087 01:07:25,880 --> 01:07:29,620 malloc e dá-nos que muitos bytes de espaço na pilha. 1088 01:07:29,620 --> 01:07:32,890 Portanto, neste caso, criamos espaço suficiente para três números inteiros, 1089 01:07:32,890 --> 01:07:36,830 ea pilha é lá em cima, que é por isso que eu o tirei mais acima. 1090 01:07:36,830 --> 01:07:42,900 Assim que estiver pronto, nós voltamos aqui, você só precisa de 3 ints voltou, 1091 01:07:42,900 --> 01:07:47,000 e retorna o endereço, no caso em que mais de que a memória é. 1092 01:07:47,000 --> 01:07:51,250 E nós definir ponteiro = interruptor, e até lá temos apenas um ponteiro outro. 1093 01:07:51,250 --> 01:07:54,550 Mas o que os retornos de função é empilhado aqui, e desaparece. 1094 01:07:54,550 --> 01:07:59,250 Então temporário desaparece, mas ainda manter o endereço de onde 1095 01:07:59,250 --> 01:08:01,850 esses três inteiros estão dentro da rede. 1096 01:08:01,850 --> 01:08:06,180 Portanto, neste conjunto, os ponteiros são escopo localmente para o quadro empilhados, 1097 01:08:06,180 --> 01:08:09,860 mas a memória a que se referem é no heap. 1098 01:08:09,860 --> 01:08:12,190 >> Isso faz sentido? 1099 01:08:12,190 --> 01:08:14,960 [Estudante] Pode repetir? >> [Joseph] Sim. 1100 01:08:14,960 --> 01:08:20,270 Então, se eu voltar um pouco, você vê que temporário alocado 1101 01:08:20,270 --> 01:08:23,500 alguma memória na pilha lá em cima. 1102 01:08:23,500 --> 01:08:28,680 Então, quando essa função, retorna giveMeThreeInts, esta pilha aqui vai desaparecer. 1103 01:08:28,680 --> 01:08:35,819 E com ele qualquer das variáveis, neste caso, este ponteiro que foi alocado no quadro empilhado. 1104 01:08:35,819 --> 01:08:39,649 Isso vai desaparecer, mas desde que voltou de temperatura 1105 01:08:39,649 --> 01:08:46,330 e partimos ponteiro = temp, o ponteiro agora vai apontar a mesma memória de localização como temperatura foi. 1106 01:08:46,330 --> 01:08:50,370 Então, agora, apesar de perder temp, esse ponteiro local, 1107 01:08:50,370 --> 01:08:59,109 nós ainda manter o endereço de memória do que estava apontando para dentro do que o ponteiro variável. 1108 01:08:59,109 --> 01:09:03,740 Perguntas? Isso pode ser uma espécie de tema confuso se você não ter ido mais em seção. 1109 01:09:03,740 --> 01:09:09,240 Podemos, seu TF vai certamente passar por isso e é claro que podemos responder a perguntas 1110 01:09:09,240 --> 01:09:11,500 no final da sessão de revisão para este. 1111 01:09:11,500 --> 01:09:14,220 Mas esta é uma espécie de um tema complexo, e eu tenho mais exemplos que vão aparecer 1112 01:09:14,220 --> 01:09:18,790 que vai ajudar a esclarecer o que realmente são os ponteiros. 1113 01:09:18,790 --> 01:09:22,500 >> Neste caso, os ponteiros são equivalentes às matrizes, 1114 01:09:22,500 --> 01:09:25,229 então eu só posso usar esse ponteiro como a mesma coisa que uma matriz int. 1115 01:09:25,229 --> 01:09:29,840 Então, eu estou indexação em 0, e mudando o primeiro número inteiro a 1, 1116 01:09:29,840 --> 01:09:39,689 alterar o segundo inteiro de 2, e o número inteiro 3 a 3. 1117 01:09:39,689 --> 01:09:44,210 Então, mais em ponteiros. Bem, lembro Binky. 1118 01:09:44,210 --> 01:09:48,319 Neste caso temos atribuído um ponteiro, ou declaramos um ponteiro, 1119 01:09:48,319 --> 01:09:52,760 mas, inicialmente, quando eu acabara de declarar um ponteiro, ele não está apontando para qualquer lugar na memória. 1120 01:09:52,760 --> 01:09:54,930 É apenas valores de lixo no interior da mesma. 1121 01:09:54,930 --> 01:09:56,470 Então eu não tenho idéia de onde este ponteiro está apontando. 1122 01:09:56,470 --> 01:10:01,630 Ele tem um endereço que é apenas preenchido com 0 e 1, onde ele foi inicialmente declarado. 1123 01:10:01,630 --> 01:10:04,810 Eu não posso fazer nada com isso até eu chamar malloc sobre ele 1124 01:10:04,810 --> 01:10:08,390 e então ele me dá um pouco de espaço na pilha onde eu possa colocar valores dentro. 1125 01:10:08,390 --> 01:10:11,980 Então, novamente, eu não sei o que está dentro dessa memória. 1126 01:10:11,980 --> 01:10:16,780 Então a primeira coisa que tenho a fazer é verificar se o sistema tinha memória suficiente 1127 01:10:16,780 --> 01:10:20,850 para me dar de volta um número inteiro em primeiro lugar, que é por isso que eu estou fazendo essa verificação. 1128 01:10:20,850 --> 01:10:25,020 Se o ponteiro é nulo, o que significa que não têm espaço suficiente ou algum outro erro ocorreu, 1129 01:10:25,020 --> 01:10:26,320 assim que eu deveria sair do meu programa. 1130 01:10:26,320 --> 01:10:29,400  Mas se ele fez sucesso, agora eu posso usar esse ponteiro 1131 01:10:29,400 --> 01:10:35,020 eo que faz é ponteiro * segue-se que o endereço é 1132 01:10:35,020 --> 01:10:38,480 para onde esse valor é, e define-a igual a 1. 1133 01:10:38,480 --> 01:10:41,850 Então, aqui, estamos verificando se a memória existia. 1134 01:10:41,850 --> 01:10:45,380 >> Uma vez que você sabe que ela existe, você pode colocar nele 1135 01:10:45,380 --> 01:10:50,460 qual o valor que você quer colocar nele, neste caso 1. 1136 01:10:50,460 --> 01:10:53,060 Uma vez que estamos a fazer com ele, você precisa de libertar esse ponteiro 1137 01:10:53,060 --> 01:10:57,160 porque nós precisamos voltar ao sistema que a memória que você pediu, em primeiro lugar. 1138 01:10:57,160 --> 01:10:59,690 Como o computador não sabe quando estamos a fazer com ele. 1139 01:10:59,690 --> 01:11:02,510 Neste caso, estamos explicitamente dizendo que, ok, estamos a fazer com que a memória. 1140 01:11:02,510 --> 01:11:10,780 Se algum outro processo precisa dele, algum outro programa precisa dele, sinta-se livre para ir em frente e levá-la. 1141 01:11:10,780 --> 01:11:15,110 O que também pode fazer é que podemos obter apenas o endereço de variáveis ​​locais no conjunto. 1142 01:11:15,110 --> 01:11:19,080 Então x int é dentro do quadro de empilhados principal. 1143 01:11:19,080 --> 01:11:23,060 E quando usamos este comercial, este e operador, o que faz é 1144 01:11:23,060 --> 01:11:27,310 leva x, e x é apenas alguns dados na memória, mas não tem um endereço. 1145 01:11:27,310 --> 01:11:33,790 Ele está situado em algum lugar. Então, chamando & x, o que isto significa é que nos dá o endereço de x. 1146 01:11:33,790 --> 01:11:38,430 Ao fazer isso, estamos fazendo ponto ponteiro para onde x é na memória. 1147 01:11:38,430 --> 01:11:41,710 Agora só faço algo como * x, vamos obter 5 de volta. 1148 01:11:41,710 --> 01:11:43,820 A estrela é chamada dereferencing-lo. 1149 01:11:43,820 --> 01:11:46,640 Você segue o endereço e você terá o valor dele lá armazenados. 1150 01:11:51,000 --> 01:11:53,310 >> Alguma pergunta? Sim? 1151 01:11:53,310 --> 01:11:56,500 [Estudante] Se você não fizer a coisa três pontas, ela ainda compilar? 1152 01:11:56,500 --> 01:11:59,490 Sim. Se você não fizer a coisa de 3 pontos, ele ainda vai compilar, 1153 01:11:59,490 --> 01:12:02,720 mas eu vou mostrar o que acontece em um segundo, e sem fazer isso, 1154 01:12:02,720 --> 01:12:04,860 isso é o que chamamos de vazamento de memória. Você não está dando ao sistema 1155 01:12:04,860 --> 01:12:07,850 apoiar sua memória, por isso depois de um tempo o programa vai acumular 1156 01:12:07,850 --> 01:12:10,940 memória que ele não está usando, e nada mais pode usá-lo. 1157 01:12:10,940 --> 01:12:15,750 Se você já viu o Firefox com 1,5 milhão de kilobytes em seu computador, 1158 01:12:15,750 --> 01:12:17,840 no gerenciador de tarefas, é o que está acontecendo. 1159 01:12:17,840 --> 01:12:20,760 Você tem um vazamento de memória no programa que não está segurando. 1160 01:12:23,080 --> 01:12:26,240 Assim como o ponteiro trabalho aritmética? 1161 01:12:26,240 --> 01:12:29,480 Bem, a aritmética de ponteiro é uma espécie de indexação como em uma matriz. 1162 01:12:29,480 --> 01:12:36,370 Neste caso, eu tenho um ponteiro, eo que eu faço é fazer ponto ponteiro para o primeiro elemento 1163 01:12:36,370 --> 01:12:42,100 Esta série de três números inteiros que eu alocados. 1164 01:12:42,100 --> 01:12:46,670 Então agora o que eu faço, o ponteiro estrela só muda o primeiro elemento da lista. 1165 01:12:46,670 --> 01:12:49,140 Estrela ponteiro 1 pontos aqui. 1166 01:12:49,140 --> 01:12:53,140 Então ponteiro está aqui, é um ponteiro aqui, ponteiro 2 é aqui. 1167 01:12:53,140 --> 01:12:56,610 >> Então, basta adicionar 1 é a mesma coisa que se mover ao longo desta matriz. 1168 01:12:56,610 --> 01:12:59,880 O que fazemos é, quando fazemos um ponteiro de obter o endereço aqui, 1169 01:12:59,880 --> 01:13:04,180 e, a fim de obter o valor aqui, você coloca uma estrela no de toda a expressão 1170 01:13:04,180 --> 01:13:05,990 para cancelar a referência dela. 1171 01:13:05,990 --> 01:13:09,940 Assim, neste caso, eu estou definindo a primeira posição nesta matriz a 1, 1172 01:13:09,940 --> 01:13:13,970 segundo local a 2, e a terceira posição 3. 1173 01:13:13,970 --> 01:13:18,180 Então o que eu estou fazendo aqui é que eu estou imprimindo nosso ponteiro 1, 1174 01:13:18,180 --> 01:13:19,970 que só me dá 2. 1175 01:13:19,970 --> 01:13:23,650 Agora estou incrementando ponteiro, para que o ponteiro é igual a um ponteiro, 1176 01:13:23,650 --> 01:13:26,780 que se move para a frente. 1177 01:13:26,780 --> 01:13:30,810 E agora, se eu imprimir um ponteiro, ponteiro 1 é agora 3, 1178 01:13:30,810 --> 01:13:33,990 que neste caso é impressa 3. 1179 01:13:33,990 --> 01:13:36,560 E a fim de algo livre, o ponteiro que eu dou 1180 01:13:36,560 --> 01:13:40,540 deve estar apontando para o início da matriz, que eu voltei do malloc. 1181 01:13:40,540 --> 01:13:43,430 Assim, neste caso, se eu fosse chamar três aqui, isso não seria certo, 1182 01:13:43,430 --> 01:13:45,070 porque é no meio da matriz. 1183 01:13:45,070 --> 01:13:48,820 Eu tenho que subtrair para chegar ao local original 1184 01:13:48,820 --> 01:13:50,420 o ponto inicial antes que eu possa libertá-lo. 1185 01:13:56,300 --> 01:13:58,450 Então, aqui está um exemplo mais complicado. 1186 01:13:58,450 --> 01:14:03,360 Neste caso, estamos alocando sete caracteres em uma matriz de caracteres. 1187 01:14:03,360 --> 01:14:06,480 >> E, neste caso, o que estamos fazendo é que estamos looping sobre o 6 primeiro deles, 1188 01:14:06,480 --> 01:14:09,900 e estamos colocando-a Z. 1189 01:14:09,900 --> 01:14:13,350 Assim, para i = 0, i> 6, i + +, 1190 01:14:13,350 --> 01:14:16,220 Assim, o ponteiro + i vai apenas dar-nos, neste caso, 1191 01:14:16,220 --> 01:14:20,860 ponteiro, ponteiro 1, 2 ponteiro, ponteiro 3, e assim por diante e assim por diante no circuito. 1192 01:14:20,860 --> 01:14:24,040 O que ele vai fazer é que fica esse endereço, dereferences-lo para obter o valor, 1193 01:14:24,040 --> 01:14:27,440 e muda o valor que para um Z. 1194 01:14:27,440 --> 01:14:30,350 Então, no final lembrar que isto é uma string, certo? 1195 01:14:30,350 --> 01:14:33,560 Todas as cordas têm de terminar com o caractere nulo de terminação. 1196 01:14:33,560 --> 01:14:38,620 Então, o que eu faço é no ponteiro 6 eu coloquei o caráter terminador nulo dentro 1197 01:14:38,620 --> 01:14:43,980 E agora o que estou fazendo aqui, basicamente, está a implementar printf para uma string, certo? 1198 01:14:43,980 --> 01:14:46,190 >> Então, quando é que printf agora, quando ela atingir o final de uma string? 1199 01:14:46,190 --> 01:14:48,230 Quando ela atinge o caractere nulo de terminação. 1200 01:14:48,230 --> 01:14:52,030 Assim, neste caso, os meus ponteiro pontos originais para o início desta matriz. 1201 01:14:52,030 --> 01:14:56,410 Eu imprimir o primeiro caractere fora. Eu movê-lo sobre uma. 1202 01:14:56,410 --> 01:14:58,420 Eu imprimir esse personagem para fora. Eu movê-lo mais. 1203 01:14:58,420 --> 01:15:02,180 E eu continuo fazendo isso até eu chegar ao fim. 1204 01:15:02,180 --> 01:15:07,750 E agora o ponteiro * final será dereference isso e obter o caractere nulo de terminação de volta. 1205 01:15:07,750 --> 01:15:11,780 E por isso o meu loop while é executado somente quando esse valor não é o caractere nulo de terminação. 1206 01:15:11,780 --> 01:15:13,770 Então, agora eu sair fora deste circuito. 1207 01:15:18,780 --> 01:15:21,180 E assim se eu subtrair 6 deste ponteiro, 1208 01:15:21,180 --> 01:15:22,860 Eu voltar todo o caminho até o início. 1209 01:15:22,860 --> 01:15:27,880 Lembre-se, eu estou fazendo isso porque eu tenho que ir para o início, a fim de libertá-la. 1210 01:15:27,880 --> 01:15:30,270 >> Então, eu sei que foi muito. Alguma pergunta? 1211 01:15:30,270 --> 01:15:31,870 Por favor, sim? 1212 01:15:31,870 --> 01:15:36,610 [Ininteligível questão Estudante] 1213 01:15:36,610 --> 01:15:38,190 Você pode dizer que mais alto? Desculpe. 1214 01:15:38,190 --> 01:15:44,140 [Estudante] No último slide direito antes de você libertou o ponteiro, 1215 01:15:44,140 --> 01:15:47,300 onde você estava realmente alterando o valor do ponteiro? 1216 01:15:47,300 --> 01:15:50,370 [Joseph] Então, aqui. >> [Estudante] Ah, ok. 1217 01:15:50,370 --> 01:15:51,890 [Joseph] Então, eu tenho um ponteiro menos menos, direito, 1218 01:15:51,890 --> 01:15:54,140 o que move a coisa de volta um, e então eu libertá-lo, 1219 01:15:54,140 --> 01:15:57,000 porque este ponteiro tem de ser apontado para o início da matriz. 1220 01:15:57,000 --> 01:16:00,420 [Estudante] Mas isso não seria necessário se tivesse parado após essa linha. 1221 01:16:00,420 --> 01:16:03,130 [Joseph] Então, se eu tinha parado depois disso, isso seria considerado um vazamento de memória, 1222 01:16:03,130 --> 01:16:04,810 porque eu não executar o livre. 1223 01:16:04,810 --> 01:16:11,290 [Estudante] I [ininteligível] após as três primeiras linhas em que você tinha um ponteiro [ininteligível]. 1224 01:16:11,290 --> 01:16:13,140 [Joseph] Uh-huh. Então, qual é a pergunta lá? 1225 01:16:13,140 --> 01:16:14,780 Desculpe. Não, não. Vai, vai, por favor. 1226 01:16:14,780 --> 01:16:16,870 [Estudante] Então, você não está alterando o valor de ponteiros. 1227 01:16:16,870 --> 01:16:19,130 Você não teria que fazer ponteiro menos de menos. 1228 01:16:19,130 --> 01:16:19,730 [Joseph] Sim, exatamente. 1229 01:16:19,730 --> 01:16:21,890 Então, quando eu faço um ponteiro e ponteiro 2, 1230 01:16:21,890 --> 01:16:24,410 Eu não estou fazendo um ponteiro igual ponteiro. 1231 01:16:24,410 --> 01:16:27,260 Assim, o ponteiro apenas permanece apontando para o início da matriz. 1232 01:16:27,260 --> 01:16:31,460 É só quando eu faço mais, mais que define o valor de volta para dentro do ponteiro, 1233 01:16:31,460 --> 01:16:33,550 que realmente move este junto. 1234 01:16:36,860 --> 01:16:37,780 Tudo bem. 1235 01:16:40,550 --> 01:16:42,030 Mais perguntas? 1236 01:16:44,680 --> 01:16:47,790 >> Mais uma vez, se este for do tipo esmagador, este será coberto na sessão. 1237 01:16:47,790 --> 01:16:50,710 Pergunte ao seu companheiro de ensino sobre isso, e podemos responder a perguntas no final. 1238 01:16:53,510 --> 01:16:56,600 E, geralmente, não gostam de fazer essa coisa de menos. 1239 01:16:56,600 --> 01:16:59,760 Isso tem que exigir-me manter a par de quanto eu deslocamento na matriz. 1240 01:16:59,760 --> 01:17:04,520 Portanto, em geral, este é apenas para explicar como funciona a aritmética de ponteiro. 1241 01:17:04,520 --> 01:17:07,970 Mas o que nós normalmente gosto de fazer é que nós gostamos de criar uma cópia do ponteiro, 1242 01:17:07,970 --> 01:17:11,640 e depois nós vamos utilizar essa cópia, quando estamos nos movendo em torno do fio. 1243 01:17:11,640 --> 01:17:14,660 Então, nestes caso, você usar a cópia para imprimir toda a cadeia, 1244 01:17:14,660 --> 01:17:19,040 mas não temos que fazer como ponteiro menos 6 ou manter o controle de quanto nos mudamos isso, 1245 01:17:19,040 --> 01:17:22,700 apenas porque sabemos que o nosso ponto original ainda apontou para o início da lista 1246 01:17:22,700 --> 01:17:25,340 e tudo o que foi alterado esta cópia. 1247 01:17:25,340 --> 01:17:28,250 Portanto, em geral, alterar cópias do ponteiro original. 1248 01:17:28,250 --> 01:17:32,350 Não tente a sorte de como - não alterar cópias originais. 1249 01:17:32,350 --> 01:17:35,290 Tentando alterar apenas cópias de seu original. 1250 01:17:41,540 --> 01:17:44,870 Então, você percebe quando passamos a string em printf 1251 01:17:44,870 --> 01:17:48,990 você não tem que colocar uma estrela na frente dele, como fizemos com todos os dereferences outros, certo? 1252 01:17:48,990 --> 01:17:54,180 Então, se você imprimir o s% toda cadeia de espera é um endereço, 1253 01:17:54,180 --> 01:17:57,610 e, neste caso, um ponteiro ou, neste caso, como um conjunto de caracteres. 1254 01:17:57,610 --> 01:18:00,330 >> Caracteres, char * s, e matrizes são a mesma coisa. 1255 01:18:00,330 --> 01:18:03,690 Ponteiro é para personagens, e matrizes de caráter são a mesma coisa. 1256 01:18:03,690 --> 01:18:05,720 E assim, tudo o que temos que fazer é passar em ponteiro. 1257 01:18:05,720 --> 01:18:08,150 Não temos de passar em como ponteiro * ou qualquer coisa assim. 1258 01:18:13,110 --> 01:18:14,930 Então, matrizes e ponteiros são a mesma coisa. 1259 01:18:14,930 --> 01:18:19,160 Quando você está fazendo algo como x [y] aqui por uma matriz, 1260 01:18:19,160 --> 01:18:21,960 o que está fazendo sob o capô é que está dizendo, tudo bem, é uma matriz de caracteres, 1261 01:18:21,960 --> 01:18:23,690 por isso é um ponteiro. 1262 01:18:23,690 --> 01:18:26,510 E assim x são a mesma coisa, 1263 01:18:26,510 --> 01:18:28,650 e assim o que ele faz é acrescenta y para x, 1264 01:18:28,650 --> 01:18:31,820 que é a mesma coisa que avançar na memória muito. 1265 01:18:31,820 --> 01:18:34,930 E agora x + y nos dá algum tipo de endereço, 1266 01:18:34,930 --> 01:18:37,570 e cancelar o endereço ou siga a seta 1267 01:18:37,570 --> 01:18:41,640 a onde que a localização na memória é e obtemos o valor de que a localização na memória. 1268 01:18:41,640 --> 01:18:43,720 Então, assim que estes dois são exatamente a mesma coisa. 1269 01:18:43,720 --> 01:18:45,840 É apenas um açúcar sintático. 1270 01:18:45,840 --> 01:18:48,090 Eles fazem a mesma coisa. Eles são apenas sintática diferentes para cada outro. 1271 01:18:51,500 --> 01:18:57,590 >> Então, o que pode dar errado com ponteiros? Como, muito. Okay. Então, as coisas ruins. 1272 01:18:57,590 --> 01:19:02,410 Algumas coisas ruins que você pode fazer não está verificando se a sua chamada malloc retorna nulo, certo? 1273 01:19:02,410 --> 01:19:06,560 Neste caso, eu estou pedindo o sistema para me dar - o que é esse número? 1274 01:19:06,560 --> 01:19:11,200 Como 2 bilhões de vezes 4, porque o tamanho de um inteiro é 4 bytes. 1275 01:19:11,200 --> 01:19:13,810 Estou perguntando isso para como 8 mil milhões de bytes. 1276 01:19:13,810 --> 01:19:17,270 É claro que meu computador não vai ser capaz de me dar isso de volta muita memória. 1277 01:19:17,270 --> 01:19:20,960 E nós não verificar se este é nulo, por isso, quando tentamos excluir a referência que lá - 1278 01:19:20,960 --> 01:19:24,270 siga a seta para onde ele vai - não temos essa memória. 1279 01:19:24,270 --> 01:19:27,150 Isto é o que chamamos de dereferencing um ponteiro nulo. 1280 01:19:27,150 --> 01:19:29,710 E isso essencialmente faz com que você segfault. 1281 01:19:29,710 --> 01:19:31,790 Esta é uma das maneiras que você pode segfault. 1282 01:19:34,090 --> 01:19:38,090 Outras coisas ruins que você pode fazer - oh bem. 1283 01:19:38,090 --> 01:19:40,650 Que foi dereferencing um ponteiro nulo. Okay. 1284 01:19:40,650 --> 01:19:45,160 Outras coisas ruins - bem, para fixar que você acabou de colocar um cheque lá 1285 01:19:45,160 --> 01:19:46,980 que verifica se o ponteiro é nulo 1286 01:19:46,980 --> 01:19:51,000 e sair do programa, se acontece que malloc retorna um ponteiro nulo. 1287 01:19:55,110 --> 01:19:59,850 Esse é o cômico xkcd. As pessoas entendem agora. Mais ou menos. 1288 01:20:06,120 --> 01:20:09,350 >> Assim, memória. E eu fui por isso. 1289 01:20:09,350 --> 01:20:12,000 Nós estamos chamando malloc em um loop, mas cada vez que chamar malloc 1290 01:20:12,000 --> 01:20:14,370 estamos perdendo a noção de onde este ponteiro está apontando, 1291 01:20:14,370 --> 01:20:15,750 porque estamos a sobrepor-lo. 1292 01:20:15,750 --> 01:20:18,410 Assim, a chamada inicial para malloc me dá memória aqui. 1293 01:20:18,410 --> 01:20:19,990 Meus ponteiros ponteiro para este. 1294 01:20:19,990 --> 01:20:23,020 Agora, eu não liberá-lo, então agora eu chamar malloc novamente. 1295 01:20:23,020 --> 01:20:26,070 Agora ele aponta aqui. Agora, a minha memória está apontando aqui. 1296 01:20:26,070 --> 01:20:27,640 Apontando aqui. Apontando aqui. 1297 01:20:27,640 --> 01:20:31,820 Mas eu perdi o controle dos endereços de toda a memória aqui que eu alocado. 1298 01:20:31,820 --> 01:20:35,100 E agora eu não tenho qualquer referência a eles mais. 1299 01:20:35,100 --> 01:20:37,230 Então, eu não posso libertá-los fora deste circuito. 1300 01:20:37,230 --> 01:20:39,390 E assim, a fim de corrigir algo como isso, 1301 01:20:39,390 --> 01:20:42,250 se você esquecer de memória livre e você receber esse vazamento de memória, 1302 01:20:42,250 --> 01:20:45,810 Você tem que liberar a memória dentro deste ciclo, uma vez que você fez com ele. 1303 01:20:45,810 --> 01:20:51,400 Bem, isso é o que acontece. Eu sei que muitos de vocês odeiam isso. 1304 01:20:51,400 --> 01:20:55,270 Mas agora - yay! Você começa como 44.000 kilobytes. 1305 01:20:55,270 --> 01:20:57,110 Assim, é libertar-lo no final do ciclo, 1306 01:20:57,110 --> 01:20:59,770 e que vai apenas liberar a memória de cada vez. 1307 01:20:59,770 --> 01:21:03,620 Essencialmente, o programa não tem um vazamento de memória mais. 1308 01:21:03,620 --> 01:21:08,150 >> E agora outra coisa que você pode fazer é liberar memória que você pediu duas vezes. 1309 01:21:08,150 --> 01:21:11,060 Neste caso, algo malloc, você muda o seu valor. 1310 01:21:11,060 --> 01:21:13,140 Você libertá-lo uma vez, porque você disse que estava feito com ele. 1311 01:21:13,140 --> 01:21:14,940 Mas, então, libertou-lo novamente. 1312 01:21:14,940 --> 01:21:16,730 Isso é algo que é muito ruim. 1313 01:21:16,730 --> 01:21:18,820 Ele não vai inicialmente segfault, 1314 01:21:18,820 --> 01:21:23,350 mas depois de um tempo o que isso faz é dupla liberação corrompe a sua estrutura de pilha, 1315 01:21:23,350 --> 01:21:27,200 e você vai aprender um pouco mais sobre isso, se você optar por ter uma aula de como CS61. 1316 01:21:27,200 --> 01:21:30,000 Mas, essencialmente, depois de um tempo o computador vai ficar confuso 1317 01:21:30,000 --> 01:21:33,010 sobre o que posições de memória onde e onde é armazenado - 1318 01:21:33,010 --> 01:21:34,800 onde os dados são armazenados na memória. 1319 01:21:34,800 --> 01:21:38,080 E assim liberar um ponteiro duas vezes é uma coisa ruim que você não quer fazer. 1320 01:21:38,080 --> 01:21:41,600 >> Outras coisas que podem dar errado não está usando sizeof. 1321 01:21:41,600 --> 01:21:44,460 Então, neste caso, você malloc 8 bytes, 1322 01:21:44,460 --> 01:21:46,700 e isso é a mesma coisa que dois inteiros, certo? 1323 01:21:46,700 --> 01:21:49,580 Então, isso é perfeitamente seguro, mas é ele? 1324 01:21:49,580 --> 01:21:52,160 Bem, como Lucas falou em diferentes arquiteturas, 1325 01:21:52,160 --> 01:21:54,220 inteiros são de comprimentos diferentes. 1326 01:21:54,220 --> 01:21:57,970 Então, o aparelho que você está usando, inteiros são cerca de 4 bytes, 1327 01:21:57,970 --> 01:22:02,370 mas em algum outro sistema que pode ser de 8 bytes ou eles podem ser de 16 bytes. 1328 01:22:02,370 --> 01:22:05,680 Então, se eu usar esse número aqui, 1329 01:22:05,680 --> 01:22:07,310 este programa pode funcionar no aparelho, 1330 01:22:07,310 --> 01:22:10,360 mas não vai alocar memória suficiente em algum outro sistema. 1331 01:22:10,360 --> 01:22:14,020 Neste caso, é isso que o operador sizeof é usado para. 1332 01:22:14,020 --> 01:22:16,880 Quando chamamos sizeof (int), o que isso faz é 1333 01:22:16,880 --> 01:22:21,910  nos dá o tamanho de um inteiro no sistema que o programa está em execução. 1334 01:22:21,910 --> 01:22:25,490 Assim, neste caso, sizeof (int) retornará 4 sobre algo como o aparelho, 1335 01:22:25,490 --> 01:22:29,980 e agora essa vontade 4 * 2, que é de 8, 1336 01:22:29,980 --> 01:22:32,330 que é apenas a quantidade de espaço necessário para dois inteiros. 1337 01:22:32,330 --> 01:22:36,710 Em um sistema diferente, se um int é como 16 bytes ou 8 bytes, 1338 01:22:36,710 --> 01:22:39,380 ele só vai retornar bytes suficientes para armazenar essa quantidade. 1339 01:22:41,830 --> 01:22:45,310 >> E, finalmente, estruturas. 1340 01:22:45,310 --> 01:22:48,340 Então, se você quiser armazenar uma placa de sudoku na memória, como podemos fazer isso? 1341 01:22:48,340 --> 01:22:51,570 Você pode pensar como uma variável para a primeira coisa, 1342 01:22:51,570 --> 01:22:53,820 uma variável para a segunda coisa, uma variável para a terceira coisa, 1343 01:22:53,820 --> 01:22:56,420 uma variável para a quarta coisa - ruim, certo? 1344 01:22:56,420 --> 01:23:00,750 Então, uma melhoria que você pode fazer em cima deste é fazer um 9 x 9 matriz. 1345 01:23:00,750 --> 01:23:04,480 Isso é bom, mas o que se quis associar outras coisas com a placa de sudoku 1346 01:23:04,480 --> 01:23:06,490 gosto do que a dificuldade do conselho é, 1347 01:23:06,490 --> 01:23:11,740 ou, por exemplo, o que é a sua pontuação, ou quanto tempo ele é levado para resolver este fórum? 1348 01:23:11,740 --> 01:23:14,970 Bem, o que você pode fazer é que você pode criar uma estrutura. 1349 01:23:14,970 --> 01:23:18,910 O que eu estou dizendo basicamente é que eu estou definindo essa estrutura aqui, 1350 01:23:18,910 --> 01:23:23,230 e estou definindo um bordo sudoku que consiste de uma placa que é de 9 x 9. 1351 01:23:23,230 --> 01:23:26,650 >> E o que tem isso tem ponteiros para o nome do nível. 1352 01:23:26,650 --> 01:23:30,730 Ele também tem X e Y, que são as coordenadas de onde estou agora. 1353 01:23:30,730 --> 01:23:35,980 Ele também tem o tempo gasto [ininteligível], e tem o número total de jogadas que eu introduzidos até ao momento. 1354 01:23:35,980 --> 01:23:40,010 E por isso, neste caso, eu posso agrupar um monte de dados em apenas uma estrutura 1355 01:23:40,010 --> 01:23:42,790 em vez de tê-lo como voar em torno de como as diferentes variáveis 1356 01:23:42,790 --> 01:23:44,540 que eu realmente não posso acompanhar. 1357 01:23:44,540 --> 01:23:49,720 E isto nos permite ter apenas uma sintaxe agradável para tipo de referenciar coisas diferentes dentro desta estrutura. 1358 01:23:49,720 --> 01:23:53,430 Eu só posso fazer board.board, e tenho a placa sudoku volta. 1359 01:23:53,430 --> 01:23:56,320 Board.level, eu recebo como é duro. 1360 01:23:56,320 --> 01:24:00,540 Board.x e board.y me dar as coordenadas de onde eu poderia estar na placa. 1361 01:24:00,540 --> 01:24:04,730 E assim eu estou acessando o que chamamos de campos na estrutura. 1362 01:24:04,730 --> 01:24:08,840 Isto define sudokuBoard, que é um tipo que eu tenho. 1363 01:24:08,840 --> 01:24:14,800 E agora estamos aqui. Eu tenho uma variável chamada "placa" de sudokuBoard tipo. 1364 01:24:14,800 --> 01:24:18,820 E agora eu posso acessar todos os campos que compõem esta estrutura aqui. 1365 01:24:20,830 --> 01:24:22,450 >> Qualquer dúvida sobre estruturas? Sim? 1366 01:24:22,450 --> 01:24:25,890 [Estudante] Para int x, y, você declarou tanto em uma linha? >> [Joseph] Uh-huh. 1367 01:24:25,890 --> 01:24:27,400 [Estudante] Então, você poderia apenas fazer isso com todos eles? 1368 01:24:27,400 --> 01:24:31,200 Gosta em x, y vezes vírgula que o total? 1369 01:24:31,200 --> 01:24:34,460 [Joseph] Sim, você definitivamente poderia fazer isso, mas a razão de eu colocar x e y na mesma linha - 1370 01:24:34,460 --> 01:24:36,330 ea questão é por isso que podemos simplesmente fazer isso na mesma linha? 1371 01:24:36,330 --> 01:24:38,600 Por que não vamos apenas colocar todos estes na mesma linha é 1372 01:24:38,600 --> 01:24:42,090 x e y são relacionados uns com os outros, 1373 01:24:42,090 --> 01:24:44,780 e este é apenas estilisticamente mais correto, em certo sentido, 1374 01:24:44,780 --> 01:24:46,600 porque é o agrupamento de duas coisas na mesma linha 1375 01:24:46,600 --> 01:24:49,340 esse tipo de como se relacionam com o mesmo. 1376 01:24:49,340 --> 01:24:51,440 E eu só dividir estes separados. É só uma coisa de estilo. 1377 01:24:51,440 --> 01:24:53,720 Funcionalmente, não faz diferença alguma. 1378 01:24:58,150 --> 01:24:59,270 Quaisquer outras perguntas sobre estruturas? 1379 01:25:03,030 --> 01:25:06,620 Você pode definir uma Pokédex com uma estrutura. 1380 01:25:06,620 --> 01:25:11,720 Um Pokémon tem um número e tem uma letra, um proprietário, um tipo. 1381 01:25:11,720 --> 01:25:16,990 E então, se você tem uma série de Pokémon, você pode fazer uma Pokédex, certo? 1382 01:25:16,990 --> 01:25:20,810 Ok, legal. Assim, questões sobre estruturas. Essas são relacionadas às structs. 1383 01:25:20,810 --> 01:25:25,270 >> Finalmente, GDB. O que o GDB deixar você fazer? Ele permite que você depurar o programa. 1384 01:25:25,270 --> 01:25:27,650 E se você não tiver usado o GDB, eu seria recomendado assistir o curta 1385 01:25:27,650 --> 01:25:31,250 e só vai sobre o GDB é, como você trabalha com ele, como você pode usá-lo, 1386 01:25:31,250 --> 01:25:32,900 e testá-lo em um programa. 1387 01:25:32,900 --> 01:25:37,400 E assim o GDB permite fazer é que permite pausar a [ininteligível] se o seu programa 1388 01:25:37,400 --> 01:25:38,920 e uma linha de prática. 1389 01:25:38,920 --> 01:25:42,600 Por exemplo, eu quero fazer uma pausa durante a execução como a linha 3 do meu programa, 1390 01:25:42,600 --> 01:25:46,010 E enquanto eu estou na linha 3 eu possa imprimir todos os valores que estão lá. 1391 01:25:46,010 --> 01:25:49,710 E então o que nós chamamos como pausar em uma linha 1392 01:25:49,710 --> 01:25:52,350 é nós chamamos isso de colocar um ponto de interrupção na linha que 1393 01:25:52,350 --> 01:25:55,920 e então nós podemos imprimir as variáveis ​​no estado do programa na época. 1394 01:25:55,920 --> 01:25:58,990 >> Podemos, então, a partir daí percorrer o programa de linha-a-linha. 1395 01:25:58,990 --> 01:26:03,200 E então podemos olhar para o estado da pilha no momento. 1396 01:26:03,200 --> 01:26:08,600 E assim, a fim de usar o GDB, o que fazemos é que chamamos de bumbum no arquivo C, 1397 01:26:08,600 --> 01:26:11,290 mas temos que passar a bandeira ggdb. 1398 01:26:11,290 --> 01:26:15,850 E uma vez que estamos a fazer com que apenas executar o gdb no arquivo de saída resultante. 1399 01:26:15,850 --> 01:26:18,810 E para que você obtenha uma massa como de texto como este, 1400 01:26:18,810 --> 01:26:21,990 mas realmente tudo que você precisa fazer é digitar comandos no início. 1401 01:26:21,990 --> 01:26:24,250 Quebrar principal coloca um ponto de interrupção na principal. 1402 01:26:24,250 --> 01:26:28,470 Lista de 400 lista as linhas de código em torno da linha 400. 1403 01:26:28,470 --> 01:26:31,410 E assim, neste caso, você pode apenas olhar ao redor e dizer, oh, 1404 01:26:31,410 --> 01:26:34,360 Quero definir um ponto de interrupção na linha 397, que é esta linha, 1405 01:26:34,360 --> 01:26:37,170 e, em seguida, o programa é executado em que passo e que vai quebrar. 1406 01:26:37,170 --> 01:26:41,120 Vai parar lá, e você pode imprimir, por exemplo, o valor de baixa ou alta. 1407 01:26:41,120 --> 01:26:46,410 E assim há um monte de comandos que você precisa saber, 1408 01:26:46,410 --> 01:26:48,660 e este slideshow vai subir no site, 1409 01:26:48,660 --> 01:26:54,000 por isso, se você quiser apenas fazer referência a estes ou como colocá-los em suas cábulas, sinta-se livre. 1410 01:26:54,000 --> 01:27:00,650 >> Cool. Isso foi Quiz Revisão 0, e vamos ficar por aqui, se você tiver alguma dúvida. 1411 01:27:00,650 --> 01:27:03,850 Tudo bem. 1412 01:27:03,850 --> 01:27:09,030 >>  [Aplausos] 1413 01:27:09,030 --> 01:27:13,000 >> [CS50.TV]