1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Semana 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 [Esta é CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> Todo ben, iso é CS50, e este é o comezo da semana 4, 5 00:00:12,000 --> 00:00:16,000 e este é un dos algoritmos de clasificación máis lenta posible. 6 00:00:16,000 --> 00:00:19,000 Cal era que só asistiu alí? 7 00:00:19,000 --> 00:00:24,000 Que era unha especie de burbulla, en orde grande (n ^ 2) + suma, 8 00:00:24,000 --> 00:00:28,000 e en realidade non son os únicos no mundo parecen saber 9 00:00:28,000 --> 00:00:30,000 que tipo de burbulla é ou seu tempo de execución. 10 00:00:30,000 --> 00:00:33,000 En realidade, esta foi unha entrevista con Eric Schmidt de Google 11 00:00:33,000 --> 00:00:45,000 eo ex senador Barack Obama só uns anos. 12 00:00:45,000 --> 00:00:48,000 >> Agora, o senador, que está aquí en Google, 13 00:00:48,000 --> 00:00:54,000 e eu gusto de pensar a presidencia como unha entrevista de emprego. 14 00:00:54,000 --> 00:00:58,000 Agora, é difícil conseguir un traballo como presidente, e está pasando os rigores agora. 15 00:00:58,000 --> 00:01:00,000 Tamén é difícil conseguir un emprego en Google. 16 00:01:00,000 --> 00:01:05,000 Temos preguntas, e facemos preguntas nosos candidatos, 17 00:01:05,000 --> 00:01:10,000 e este é de Larry David Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Vostedes pensan que eu estou a xogar? É aquí mesmo. 19 00:01:14,000 --> 00:01:18,000 O que é o xeito máis eficaz para clasificar un millón de enteiros de 32 bits? 20 00:01:18,000 --> 00:01:21,000 [Risas] 21 00:01:21,000 --> 00:01:24,000 Ben- 22 00:01:24,000 --> 00:01:26,000 Sinto moito. >> Non, non, non, non. 23 00:01:26,000 --> 00:01:34,000 Eu creo que o bubble sort sería o camiño mal para ir. 24 00:01:34,000 --> 00:01:39,000 >> Imos, que lle dixo iso? 25 00:01:39,000 --> 00:01:43,000 A semana pasada, lembro que tivo un salto de código, polo menos por un día, 26 00:01:43,000 --> 00:01:46,000 e pasaron a concentrarse en algunhas ideas de nivel superior e de resolución de problemas de forma máis xeral 27 00:01:46,000 --> 00:01:49,000 no contexto de investigación e clasificación, 28 00:01:49,000 --> 00:01:53,000 e introduciu algo que non cubrir este nome a semana pasada, 29 00:01:53,000 --> 00:01:56,000 pero a notación asintótica, o Big O, o Omega Grande, 30 00:01:56,000 --> 00:02:00,000 e ás veces a notación Big Theta, e estes eran simplemente formas 31 00:02:00,000 --> 00:02:02,000 de describir o tempo de execución de algoritmos, 32 00:02:02,000 --> 00:02:05,000 canto tempo leva para un algoritmo para ser executado. 33 00:02:05,000 --> 00:02:08,000 >> E ten que se lembrar que falou sobre o tempo de execución en termos de tamaño 34 00:02:08,000 --> 00:02:11,000 da entrada, que xeralmente chamamos n, calquera que sexa o problema pode ser, 35 00:02:11,000 --> 00:02:13,000 onde n é o número de persoas na sala, 36 00:02:13,000 --> 00:02:17,000 o número de páxinas dun libro de teléfono, e comezamos a escribir as cousas 37 00:02:17,000 --> 00:02:21,000 como O (n ^ 2) ou O (n) ou O (n log n), 38 00:02:21,000 --> 00:02:24,000 e mesmo cando as matemáticas non deu moi correcto tan perfectamente 39 00:02:24,000 --> 00:02:28,000 e foi n ² - n / 2, ou algo así 40 00:02:28,000 --> 00:02:31,000 Nós, pola contra, só tirar algúns dos termos de orde máis baixa, 41 00:02:31,000 --> 00:02:34,000 ea motivación alí é que realmente queremos unha 42 00:02:34,000 --> 00:02:37,000 tipo de forma obxectiva avaliar 43 00:02:37,000 --> 00:02:39,000 o desempeño de programas ou o desempeño de algoritmos 44 00:02:39,000 --> 00:02:42,000 que, ao final do día, non ten nada que ver, por exemplo, 45 00:02:42,000 --> 00:02:45,000 coa velocidade do seu ordenador hoxe. 46 00:02:45,000 --> 00:02:47,000 >> Por exemplo, se aplicar bubble sort 47 00:02:47,000 --> 00:02:50,000 ou aplicar merge sort tipo ou selección no ordenador de hoxe, 48 00:02:50,000 --> 00:02:53,000 un ordenador 2 GHz, e executa-lo, 49 00:02:53,000 --> 00:02:56,000 e iso leva algún número de segundos o próximo ano, hai un 3 GHz 50 00:02:56,000 --> 00:02:59,000 ou un ordenador 4 GHz, e podería, entón, afirmar que "Guau, o meu algoritmo 51 00:02:59,000 --> 00:03:03,000 é agora dúas veces máis rápido ", cando en realidade que obviamente non é o caso. 52 00:03:03,000 --> 00:03:06,000 É só o hardware quedou máis rápido, pero o seu ordenador 53 00:03:06,000 --> 00:03:10,000 non, e así nós realmente queremos tirar cousas como 54 00:03:10,000 --> 00:03:13,000 múltiplos de 2 ou múltiplos de 3, cando se trata de describir 55 00:03:13,000 --> 00:03:17,000 quão rápido ou lento como un algoritmo é realmente e concentrarse só 56 00:03:17,000 --> 00:03:20,000 en n ou algún factor º, 57 00:03:20,000 --> 00:03:24,000 algún poder do mesmo, como no caso dos tipos de na última semana. 58 00:03:24,000 --> 00:03:27,000 E lembrar que, coa axuda de merge sort 59 00:03:27,000 --> 00:03:31,000 fomos capaces de facer moito mellor do que o bubble sort e tipo de selección 60 00:03:31,000 --> 00:03:33,000 e tipo de inserción mesmo. 61 00:03:33,000 --> 00:03:36,000 >> Temos ata n log n, e, de novo, 62 00:03:36,000 --> 00:03:39,000 Recordamos que log n xeralmente se refire a algo que crece 63 00:03:39,000 --> 00:03:43,000 máis lentamente entón n, entón n log n, ata agora, era bo 64 00:03:43,000 --> 00:03:45,000 porque era menos ² n. 65 00:03:45,000 --> 00:03:47,000 Pero para acadar n log n con merge sort 66 00:03:47,000 --> 00:03:51,000 cal foi o xerme dunha idea básica que tivemos para alavancar 67 00:03:51,000 --> 00:03:54,000 que tamén alavancou de volta a semana 0? 68 00:03:54,000 --> 00:03:58,000 Coma nós afrontar o problema de ordenación intelixente co merge sort? 69 00:03:58,000 --> 00:04:04,000 Cal foi a clave da comprensión, quizais? 70 00:04:04,000 --> 00:04:07,000 Ninguén. 71 00:04:07,000 --> 00:04:09,000 Ok, imos dar un paso atrás. 72 00:04:09,000 --> 00:04:11,000 Describe merge sort nas súas propias palabras. 73 00:04:11,000 --> 00:04:15,000 Como funciona isto? 74 00:04:15,000 --> 00:04:17,000 Ok, imos remar de volta para 0 semanas. 75 00:04:17,000 --> 00:04:19,000 Ok, si. 76 00:04:19,000 --> 00:04:22,000 [Inaudível-alumno] 77 00:04:22,000 --> 00:04:26,000 Ok, bo, entón dividimos o conxunto de números en dous anacos. 78 00:04:26,000 --> 00:04:29,000 Nós clasificada cada unha destas pezas, e entón fundiuse os, 79 00:04:29,000 --> 00:04:33,000 e vimos esa idea antes de tomar un problema que é tan grande 80 00:04:33,000 --> 00:04:36,000 e cortar-lo nun problema que é tan grande ou tan grande. 81 00:04:36,000 --> 00:04:38,000 >> Teña en conta que do exemplo do libro de teléfono. 82 00:04:38,000 --> 00:04:42,000 Teña en conta que o algoritmo de auto-contador de semanas atrás, 83 00:04:42,000 --> 00:04:45,000 tipo así fundir foi resumida por este pseudocódigo aquí. 84 00:04:45,000 --> 00:04:48,000 Cando está determinado n elementos, primeiro era comprobar a sanidade. 85 00:04:48,000 --> 00:04:51,000 Se n <2, entón non facer nada 86 00:04:51,000 --> 00:04:55,000 porque se n <2, entón n é 0 ou 1, obviamente, 87 00:04:55,000 --> 00:04:57,000 e así se é 0 ou 1 que non hai nada para resolver. 88 00:04:57,000 --> 00:04:59,000 Está feito. 89 00:04:59,000 --> 00:05:01,000 A súa lista xa está trivialmente clasificados. 90 00:05:01,000 --> 00:05:04,000 Pero se non, se ten dous ou máis elementos de ir adiante e división los 91 00:05:04,000 --> 00:05:06,000 en dúas metades, dereita e esquerda. 92 00:05:06,000 --> 00:05:09,000 Ordenar cada unha desas metades, e en seguida, mesturar as metades clasificados. 93 00:05:09,000 --> 00:05:13,000 Pero o problema aquí é que, a primeira vista isto parece que estamos punting. 94 00:05:13,000 --> 00:05:17,000 Esta é unha definición circular na que se eu lle pedín para clasificar estes elementos n 95 00:05:17,000 --> 00:05:22,000 e está me dicindo "Todo ben, todo ben, imos clasificar os elementos n / 2 e n / 2", 96 00:05:22,000 --> 00:05:27,000 entón a miña seguinte pregunta vai ser "Todo ben, como clasificar a n / 2 elementos?" 97 00:05:27,000 --> 00:05:30,000 >> Pero, debido á estrutura do presente programa, 98 00:05:30,000 --> 00:05:33,000 porque non é este o caso base, por así dicir, 99 00:05:33,000 --> 00:05:39,000 Neste caso particular, que di que, se n é 00:05:42,000 Non responder a esta mesma resposta circular. 101 00:05:42,000 --> 00:05:46,000 Este proceso, este ciclicidade acabará. 102 00:05:46,000 --> 00:05:50,000 Se eu lle preguntar "Ordenar estes elementos n", e di: "Moi ben, clasificar estes n / 2", 103 00:05:50,000 --> 00:05:53,000 entón vostede di, "tipo, Fine estes N / 4, n / 8, n/16" 104 00:05:53,000 --> 00:05:56,000 finalmente, vai dividir por un número o suficientemente 105 00:05:56,000 --> 00:05:59,000 que vai ter só un elemento de esquerda, en que punto pode dicir: 106 00:05:59,000 --> 00:06:02,000 "Aquí, aquí é un elemento clasificado único". 107 00:06:02,000 --> 00:06:06,000 A continuación, o brillo deste algoritmo aquí é derivarse do feito de 108 00:06:06,000 --> 00:06:09,000 que unha vez que ten todas estas listas individualmente clasificados, 109 00:06:09,000 --> 00:06:12,000 todos os cales son de tamaño 1, o que parece ser inútil, 110 00:06:12,000 --> 00:06:15,000 unha vez que comezar a fundín-las e mestura-los 111 00:06:15,000 --> 00:06:19,000 construír, finalmente, como Rob fixo no vídeo, finalmente, unha lista ordenada. 112 00:06:19,000 --> 00:06:22,000 >> Pero esa idea vai moito máis alá de clasificación. 113 00:06:22,000 --> 00:06:26,000 Esta é a idea incorporado neste programa coñecido como recursão, 114 00:06:26,000 --> 00:06:29,000 a idea que vostede é un programa, 115 00:06:29,000 --> 00:06:32,000 e para resolver un problema que chama a si mesmo, 116 00:06:32,000 --> 00:06:36,000 ou poñer no contexto de linguaxes de programación é unha función, 117 00:06:36,000 --> 00:06:39,000 e, a fin de resolver un problema, a función de chamar a si mesmo 118 00:06:39,000 --> 00:06:42,000 de novo e de novo e de novo, pero a función 119 00:06:42,000 --> 00:06:44,000 non pode chamar-se infinitas veces. 120 00:06:44,000 --> 00:06:47,000 Finalmente, ten para abaixo para fóra, por así dicir, 121 00:06:47,000 --> 00:06:49,000 e ter algunha condición de base embutida que di 122 00:06:49,000 --> 00:06:53,000 Actualmente deixar de chamar a si mesmo de xeito que todo o proceso 123 00:06:53,000 --> 00:06:56,000 finalmente, de feito parar. 124 00:06:56,000 --> 00:06:58,000 O que isto realmente significa para recurse? 125 00:06:58,000 --> 00:07:01,000 >> Imos ver, si é que podemos facer un exemplo simple, trivial con, digamos, 126 00:07:01,000 --> 00:07:03,000 3 persoas comigo aquí enriba no escenario, se alguén é cómodo. 127 00:07:03,000 --> 00:07:06,000 Un, imos cara arriba, 2 e 3. 128 00:07:06,000 --> 00:07:09,000 Se 3 quere vir ata aquí. 129 00:07:09,000 --> 00:07:12,000 Se queres estar ao meu lado aquí nunha liña, imos supor que o problema na man 130 00:07:12,000 --> 00:07:15,000 é moi trivialmente contar o número de persoas que están aquí. 131 00:07:15,000 --> 00:07:18,000 Pero, francamente, estou canso de todos estes exemplos de conta. 132 00:07:18,000 --> 00:07:21,000 Isto vai levar moito tempo, 1, 2, e punto, punto, punto. 133 00:07:21,000 --> 00:07:23,000 Vai levar unha eternidade. 134 00:07:23,000 --> 00:07:25,000 Eu prefiro só punto este problema completamente coa axuda de-Cal é o seu nome? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, todo ben. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly e? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly e Willy. 138 00:07:31,000 --> 00:07:34,000 Agora eu teño a pregunta por alguén 139 00:07:34,000 --> 00:07:37,000 cantas persoas están a este escenario, e eu non teño idea. 140 00:07:37,000 --> 00:07:40,000 Esta é unha lista moi longa, e así en vez diso eu vou facer este truco. 141 00:07:40,000 --> 00:07:43,000 Vou pedir para a persoa ao meu lado para facer a maior parte do traballo, 142 00:07:43,000 --> 00:07:46,000 e unha vez que ela está feita facendo a maioría do traballo 143 00:07:46,000 --> 00:07:49,000 Vou facer o mínimo de traballo posible e só engadir unha 144 00:07:49,000 --> 00:07:51,000 para o que a súa resposta é, entón aquí imos nós. 145 00:07:51,000 --> 00:07:54,000 Xa me preguntaron cantas persoas están no escenario. 146 00:07:54,000 --> 00:07:57,000 Cantas persoas están no escenario á esquerda de ti? 147 00:07:57,000 --> 00:08:00,000 A esquerda de min? >> Ok, pero non enganar. 148 00:08:00,000 --> 00:08:04,000 Isto é bo, iso é correcto, pero si queremos seguir esta lóxica 149 00:08:04,000 --> 00:08:08,000 imos supor que quere igualmente punto este problema á esquerda de ti, 150 00:08:08,000 --> 00:08:11,000 entón en vez de responder directamente ir adiante e pasar a bola. 151 00:08:11,000 --> 00:08:14,000 Ah, cantas persoas están á esquerda de min? 152 00:08:14,000 --> 00:08:16,000 Cantas persoas están á esquerda? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Risas] 155 00:08:27,000 --> 00:08:30,000 Ok, entón 0, entón o que agora Willy fixo 156 00:08:30,000 --> 00:08:33,000 é vostede volveu a súa resposta neste sentido dicindo 0. 157 00:08:33,000 --> 00:08:36,000 Agora, o que ten que facer? >> 1. 158 00:08:36,000 --> 00:08:39,000 Ok, entón vostede é o 1, entón di: "Todo ben, eu estou indo para engadir un 159 00:08:39,000 --> 00:08:41,000 para calquera conta de Willy era "a 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Vostede está agora 1 para a súa resposta á dereita agora 161 00:08:43,000 --> 00:08:45,000 1. >> E a miña sería 2. 162 00:08:45,000 --> 00:08:48,000 Bo, entón está tomando a resposta anterior 1, 163 00:08:48,000 --> 00:08:51,000 engadindo a cantidade mínima de traballo que quere facer, o que é un. 164 00:08:51,000 --> 00:08:55,000 Vostede agora ten dous, e despois entrega-me que o valor? 165 00:08:55,000 --> 00:08:57,000 3, quero dicir, desculpe, 2. 166 00:08:57,000 --> 00:08:59,000 Bo 167 00:08:59,000 --> 00:09:02,000 >> Ben, tivemos 0 á esquerda. 168 00:09:02,000 --> 00:09:05,000 Entón tivemos un, e entón engadir 2, 169 00:09:05,000 --> 00:09:07,000 e agora está me dando o número 2, 170 00:09:07,000 --> 00:09:10,000 e así que eu estou dicindo, todo ben, unha, 3. 171 00:09:10,000 --> 00:09:13,000 Hai de feito tres persoas que estaban ao meu lado nesta fase, 172 00:09:13,000 --> 00:09:16,000 para que pudéssemos ter feito isto, obviamente, moi lineal, 173 00:09:16,000 --> 00:09:19,000 moi de moda obvio, pero o que realmente facer? 174 00:09:19,000 --> 00:09:21,000 Pegamos un problema de tamaño 3 inicialmente. 175 00:09:21,000 --> 00:09:24,000 A continuación, partiu-se en un problema de tamaño 2, 176 00:09:24,000 --> 00:09:27,000 entón un problema de tamaño 1, e despois, finalmente, se a base 177 00:09:27,000 --> 00:09:29,000 Foi moi, oh, non hai ninguén alí, 178 00:09:29,000 --> 00:09:33,000 momento no que Willy volveu efectivamente unha resposta codificado un par de veces, 179 00:09:33,000 --> 00:09:36,000 ea segunda foi entón borbulhava, borbulhava, borbulhava, 180 00:09:36,000 --> 00:09:39,000 e, a continuación, engadindo a este un un adicional 181 00:09:39,000 --> 00:09:41,000 temos implementado esa idea básica de recursão. 182 00:09:41,000 --> 00:09:44,000 >> Agora, neste caso, realmente non resolver un problema 183 00:09:44,000 --> 00:09:46,000 máis eficazmente, a continuación vimos ata agora. 184 00:09:46,000 --> 00:09:48,000 Pero pense sobre os algoritmos que fixemos no escenario ata o momento. 185 00:09:48,000 --> 00:09:51,000 Tivemos oito anacos de papel no cadro-negro, 186 00:09:51,000 --> 00:09:55,000 en vídeo cando Sean estaba ollando para o número 7, eo que realmente fai? 187 00:09:55,000 --> 00:09:58,000 Ben, el non fixo ningún tipo de dividir e conquistar. 188 00:09:58,000 --> 00:10:01,000 El non fixo ningún tipo de recursão. 189 00:10:01,000 --> 00:10:03,000 Ao contrario, el só fixo este algoritmo lineal. 190 00:10:03,000 --> 00:10:07,000 Pero, cando introduciu a idea de números clasificados no escenario en directo a semana pasada 191 00:10:07,000 --> 00:10:09,000 despois tivemos ese instinto de ir para o medio, 192 00:10:09,000 --> 00:10:13,000 en que punto tivemos unha pequena lista de tamaño 4 ou outra lista de tamaño 4, 193 00:10:13,000 --> 00:10:17,000 e despois tivemos o mesmo problema, por iso, repite, repite, repite. 194 00:10:17,000 --> 00:10:19,000 Noutras palabras, nós recursed. 195 00:10:19,000 --> 00:10:24,000 Moitas grazas aos nosos tres voluntarios aquí para demostrar recursão connosco. 196 00:10:24,000 --> 00:10:28,000 >> Imos ver se non podemos facelo agora un pouco máis concreto, 197 00:10:28,000 --> 00:10:30,000 resolver un problema que de novo podemos facer moi facilmente, 198 00:10:30,000 --> 00:10:34,000 pero imos usalo como un trampolín para a aplicación desta idea básica. 199 00:10:34,000 --> 00:10:37,000 Se eu queira calcular a suma de unha morea de números, 200 00:10:37,000 --> 00:10:39,000 por exemplo, se pasar o número 3, 201 00:10:39,000 --> 00:10:42,000 Eu quero darlle o valor de 3 sigma, 202 00:10:42,000 --> 00:10:46,000 entón a suma de 3 + 2 + 1 + 0. 203 00:10:46,000 --> 00:10:48,000 Eu quero volver a resposta 6, 204 00:10:48,000 --> 00:10:51,000 entón imos implementar esta función sigma, esta función suma 205 00:10:51,000 --> 00:10:54,000 que, unha vez máis, leva a entrada e, a continuación, retorna a suma 206 00:10:54,000 --> 00:10:57,000 dese número ata o final a 0. 207 00:10:57,000 --> 00:10:59,000 Nós poderiamos facelo moi sinxelo, non? 208 00:10:59,000 --> 00:11:01,000 Nós poderiamos facelo con algún tipo de estrutura de loop, 209 00:11:01,000 --> 00:11:04,000 entón deixe-me ir adiante e comezar con iso. 210 00:11:04,000 --> 00:11:07,000 >> Engadir stdio.h. 211 00:11:07,000 --> 00:11:09,000 Deixe-me me meter principal para traballar aquí. 212 00:11:09,000 --> 00:11:12,000 Imos gardalo como sigma.c. 213 00:11:12,000 --> 00:11:14,000 Entón eu vou entrar aquí, e eu vou declarar un int n, 214 00:11:14,000 --> 00:11:18,000 e eu vou facer o seguinte, mentres que o usuario non cooperar. 215 00:11:18,000 --> 00:11:22,000 Mentres o usuario non teña me deu un número positivo 216 00:11:22,000 --> 00:11:26,000 deixe-me ir adiante e levalos para n = GetInt, 217 00:11:26,000 --> 00:11:28,000 e deixe-me dar-lles algunhas instrucións sobre o que facer, 218 00:11:28,000 --> 00:11:33,000 así printf ("enteiro positivo, por favor"). 219 00:11:33,000 --> 00:11:39,000 Só algo relativamente simple como este para que no momento en que alcanzou a liña 14 220 00:11:39,000 --> 00:11:42,000 agora temos un número enteiro positivo, presuntamente, no n. 221 00:11:42,000 --> 00:11:44,000 >> Agora imos facer algo con el. 222 00:11:44,000 --> 00:11:50,000 Deixe-me ir adiante e calcular a suma, entón int suma = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma é só suma, entón eu só estou escribindo a na forma máis extravagante. 224 00:11:54,000 --> 00:11:56,000 Imos chamar-lle só sigma alí. 225 00:11:56,000 --> 00:11:58,000 Esa é a suma, e agora eu vou imprimir o resultado, 226 00:11:58,000 --> 00:12:08,000 printf ("A suma é% d \ n" suma). 227 00:12:08,000 --> 00:12:11,000 E entón eu vou volver 0 para unha boa medida. 228 00:12:11,000 --> 00:12:15,000 Fixemos todo o que este programa require, excepto a parte interesante, 229 00:12:15,000 --> 00:12:18,000 que é para realmente implementar a función sigma. 230 00:12:18,000 --> 00:12:22,000 >> Deixe-me ir ata aquí para a parte inferior, e deixe-me declarar función sigma. 231 00:12:22,000 --> 00:12:26,000 Ten que ter unha variable que é do tipo enteiro, 232 00:12:26,000 --> 00:12:30,000 e que tipo de datos que eu quero volver presuntamente de sigma? 233 00:12:30,000 --> 00:12:34,000 Int, porque quero que corresponden as miñas expectativas en liña 15. 234 00:12:34,000 --> 00:12:37,000 Desde aquí, deixe-me ir adiante e aplicar esta 235 00:12:37,000 --> 00:12:41,000 dunha forma bastante simple. 236 00:12:41,000 --> 00:12:45,000 >> Imos adiante e dicir suma int = 0, 237 00:12:45,000 --> 00:12:47,000 e agora eu vou ter un pouco de loop aquí 238 00:12:47,000 --> 00:12:50,000 que vai dicir algo como isto, 239 00:12:50,000 --> 00:13:01,000 é (int i = 0; I <= número; i + +) suma + = i. 240 00:13:01,000 --> 00:13:05,000 E entón eu vou volver suma. 241 00:13:05,000 --> 00:13:07,000 Eu podería ter aplicado este en calquera número de formas. 242 00:13:07,000 --> 00:13:09,000 Eu podería usar un loop while. 243 00:13:09,000 --> 00:13:11,000 Eu podería ter pulado usando a variable de suma, se realmente quería, 244 00:13:11,000 --> 00:13:15,000 pero en definitiva, só temos unha función que se eu non goof declara suma é 0. 245 00:13:15,000 --> 00:13:18,000 A continuación, el itera de 0 encima a través do número, 246 00:13:18,000 --> 00:13:23,000 e en cada iteração engade que o valor actual de suma e retorna suma. 247 00:13:23,000 --> 00:13:25,000 >> Agora, hai unha optimización de leve aquí. 248 00:13:25,000 --> 00:13:29,000 Este é probablemente un paso desperdiçado, pero que así sexa. Isto é bo para agora. 249 00:13:29,000 --> 00:13:32,000 Estamos, polo menos vai ser completa e 0 todo o camiño enriba. 250 00:13:32,000 --> 00:13:34,000 Non é moi difícil e moi sinxelo, 251 00:13:34,000 --> 00:13:37,000 pero acontece que, coa función de sigma temos a mesma oportunidade 252 00:13:37,000 --> 00:13:39,000 como fixemos aquí no escenario. 253 00:13:39,000 --> 00:13:42,000 No escenario nós só contou cantas persoas estaban ó meu lado, 254 00:13:42,000 --> 00:13:47,000 pero en vez diso se queremos contar o número 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 en ata 0 poderiamos igualmente punto para unha función 256 00:13:51,000 --> 00:13:55,000 que eu vou describir en vez de ser recursiva. 257 00:13:55,000 --> 00:13:57,000 Aquí imos facer un rápido check sanidade e que seguro que eu non fixen broma. 258 00:13:57,000 --> 00:14:00,000 >> Sei que hai polo menos unha cousa neste programa que eu fixen de malo. 259 00:14:00,000 --> 00:14:04,000 Cando eu bati entrar eu estou indo para obter calquera tipo de berrar comigo? 260 00:14:04,000 --> 00:14:06,000 O que é que eu vou ser chamado sobre? 261 00:14:06,000 --> 00:14:11,000 Si, eu esquezo o prototipo, entón eu estou usando unha función chamada sigma na liña 15, 262 00:14:11,000 --> 00:14:16,000 pero non é declarada ata a liña 22, entón eu mellor forma Proativo subir aquí 263 00:14:16,000 --> 00:14:22,000 e declarar un prototipo, e eu vou dicir int sigma (número enteiro), e é iso. 264 00:14:22,000 --> 00:14:24,000 É aplicada na parte inferior. 265 00:14:24,000 --> 00:14:27,000 >> Ou doutro xeito que eu podería resolver iso, 266 00:14:27,000 --> 00:14:30,000 Eu podería mover a función alí enriba, o que non é malo, 267 00:14:30,000 --> 00:14:32,000 pero polo menos cando os seus programas comezan a estar longo, francamente, 268 00:14:32,000 --> 00:14:35,000 Eu creo que hai algún valor en ter sempre principal na parte superior 269 00:14:35,000 --> 00:14:38,000 para que en que o lector pode abrir o ficheiro e inmediatamente ver 270 00:14:38,000 --> 00:14:40,000 o que o programa está facendo sen ter que buscar por el 271 00:14:40,000 --> 00:14:42,000 buscar que a principal función. 272 00:14:42,000 --> 00:14:49,000 Imos ata a miña ventá de terminal aquí, probe facer sigma facer sigma, 273 00:14:49,000 --> 00:14:51,000 e eu estraguei todo aquí tamén. 274 00:14:51,000 --> 00:14:55,000 Declaración implícita de GetInt función significa que eu esquezo de facer o que máis? 275 00:14:55,000 --> 00:14:57,000 [Inaudível-alumno] 276 00:14:57,000 --> 00:15:00,000 Bo, entón, ao parecer, un erro común, entón imos poñer isto aquí, 277 00:15:00,000 --> 00:15:04,000 cs50.h, e agora imos voltar para a miña xanela de terminal. 278 00:15:04,000 --> 00:15:08,000 >> Vou borrar a pantalla, e eu vou facer reprise sigma. 279 00:15:08,000 --> 00:15:11,000 Parece feita. Déixame correr sigma. 280 00:15:11,000 --> 00:15:15,000 Vou escribir o número 3, e eu tiven 6, de modo que non comprobar un rigoroso 281 00:15:15,000 --> 00:15:18,000 pero polo menos parece estar funcionando, a primeira vista, pero agora imos destruír-la, 282 00:15:18,000 --> 00:15:21,000 e imos realmente aproveitar a idea do recurso, de novo, 283 00:15:21,000 --> 00:15:24,000 nun contexto moi sinxelo, para que, no tempo de algunhas semanas 284 00:15:24,000 --> 00:15:27,000 cando comezar a explorar estruturas máis elegantes de datos de matrices 285 00:15:27,000 --> 00:15:30,000 temos outra ferramenta no conxunto de ferramentas coas que a 286 00:15:30,000 --> 00:15:33,000 manipular estas estruturas de datos, como veremos. 287 00:15:33,000 --> 00:15:36,000 Esta é a visión iterativa, a visión baseada en loop. 288 00:15:36,000 --> 00:15:39,000 >> Deixe-me en vez agora facelo. 289 00:15:39,000 --> 00:15:44,000 Deixe-me dicir que, en vez da suma do número 290 00:15:44,000 --> 00:15:48,000 en ata 0 é realmente o mesmo que 291 00:15:48,000 --> 00:15:53,000 + Número sigma (número - 1). 292 00:15:53,000 --> 00:15:57,000 Noutras palabras, así como no escenario eu punted cada unha das persoas próximas a min, 293 00:15:57,000 --> 00:16:00,000 e eles, á súa vez, mantivo punting ata que finalmente o fondo do pozo en Willy, 294 00:16:00,000 --> 00:16:03,000 que tivo que regresar unha resposta codificada como 0. 295 00:16:03,000 --> 00:16:07,000 Aquí, agora, estamos tamén punting para sigma 296 00:16:07,000 --> 00:16:10,000 a mesma función que orixinalmente foi chamado, pero o insight clave aquí 297 00:16:10,000 --> 00:16:12,000 é que nós non estamos chamando sigma idéntica. 298 00:16:12,000 --> 00:16:14,000 Nós non estamos pasando no n. 299 00:16:14,000 --> 00:16:17,000 Estamos claramente pasando en número - 1, 300 00:16:17,000 --> 00:16:20,000 así un problema un pouco menor, problema un pouco menor. 301 00:16:20,000 --> 00:16:23,000 >> Desafortunadamente, esta non é unha solución bastante aínda, e antes de corrixir 302 00:16:23,000 --> 00:16:26,000 o que pode ser tan obvia ir menos algúns de vostedes 303 00:16:26,000 --> 00:16:28,000 deixe-me ir adiante e facer executar de novo. 304 00:16:28,000 --> 00:16:30,000 Parece compilar todo ben. 305 00:16:30,000 --> 00:16:32,000 Deixe-me reprise sigma con 6. 306 00:16:32,000 --> 00:16:37,000 Oops, deixe-me reprise sigma con 6. 307 00:16:37,000 --> 00:16:42,000 Nós xa vimos isto antes, aínda que o tempo accidentalmente pasado tamén. 308 00:16:42,000 --> 00:16:48,000 Por que eu recibín esa fallo de segmento enigmática? Si 309 00:16:48,000 --> 00:16:50,000 [Inaudível-alumno] 310 00:16:50,000 --> 00:16:53,000 Non hai ningún caso base, e máis especificamente, o que probablemente pasou? 311 00:16:53,000 --> 00:16:58,000 Este é un síntoma de que o comportamento? 312 00:16:58,000 --> 00:17:00,000 Din que un pouco máis alto. 313 00:17:00,000 --> 00:17:02,000 [Inaudível-alumno] 314 00:17:02,000 --> 00:17:05,000 É un ciclo infinito de forma eficaz, e que o problema con loops infinitos 315 00:17:05,000 --> 00:17:08,000 cando envolven recursão neste caso, unha función de chamada en si, 316 00:17:08,000 --> 00:17:10,000 o que pasa cada vez que chamar a unha función? 317 00:17:10,000 --> 00:17:13,000 Ben, creo que volver a ser como que estableceu a memoria dun ordenador. 318 00:17:13,000 --> 00:17:16,000 Nós dixemos que non hai este anaco de memoria chamado pila que está no fondo, 319 00:17:16,000 --> 00:17:19,000 e cada vez que chamar a unha función de memoria un pouco máis e colocar 320 00:17:19,000 --> 00:17:24,000 sobre esta pila chamada conteñen variábeis locais que función ou parámetros, 321 00:17:24,000 --> 00:17:27,000 por iso, se sigma Chamadas sigma sigma chama sigma 322 00:17:27,000 --> 00:17:29,000  chama sigma de onde vén esa historia remata? 323 00:17:29,000 --> 00:17:31,000 >> Ben, el acabou derrapagens o importe total 324 00:17:31,000 --> 00:17:33,000 de memoria que ten dispoñible para o seu ordenador. 325 00:17:33,000 --> 00:17:37,000 Vostede excedeu o segmento que debería estar dentro, 326 00:17:37,000 --> 00:17:40,000 e ten esa fallo de segmento, o núcleo despexado, 327 00:17:40,000 --> 00:17:43,000 e que o núcleo despexado significa que agora eu teño un arquivo chamado núcleo 328 00:17:43,000 --> 00:17:46,000 que é un arquivo que contén ceros e uns 329 00:17:46,000 --> 00:17:49,000 que, en realidade, no futuro, será útil para diagnóstico. 330 00:17:49,000 --> 00:17:52,000 Se non é obvio para ti, onde o erro é 331 00:17:52,000 --> 00:17:54,000 realmente pode facer un pouco de análise forense, por así dicir, 332 00:17:54,000 --> 00:17:58,000 neste ficheiro dump de memoria, que, de novo, é só unha morea de ceros e uns 333 00:17:58,000 --> 00:18:02,000 que, esencialmente, representa o estado do seu programa na memoria 334 00:18:02,000 --> 00:18:05,000 no momento en que deixou de funcionar deste xeito. 335 00:18:05,000 --> 00:18:11,000 >> A corrección aquí é que non podemos simplemente volver cegamente sigma, 336 00:18:11,000 --> 00:18:14,000 o número + sigma dun problema un pouco menor. 337 00:18:14,000 --> 00:18:16,000 Necesitamos ter algún tipo de caso base aquí, 338 00:18:16,000 --> 00:18:19,000 e cal debe ser o caso base, probablemente, ser? 339 00:18:19,000 --> 00:18:22,000 [Inaudível-alumno] 340 00:18:22,000 --> 00:18:25,000 Ok, se o número é positivo que debe realmente volver iso, 341 00:18:25,000 --> 00:18:29,000 ou dito doutra forma, se o número é, digamos, <= 0 342 00:18:29,000 --> 00:18:32,000 vostede sabe, eu vou adiante e volver 0, 343 00:18:32,000 --> 00:18:36,000 así como Willy fixo, e máis, eu estou indo para adiante 344 00:18:36,000 --> 00:18:41,000 e devolver o presente, por iso non é moito menor do que 345 00:18:41,000 --> 00:18:44,000 que a versión iterativa que instigou o primeiro en utilizar un loop for, 346 00:18:44,000 --> 00:18:48,000 de notar que hai este tipo de elegancia a el. 347 00:18:48,000 --> 00:18:51,000 En vez de regresar algún número e realizando toda a matemática esta 348 00:18:51,000 --> 00:18:54,000 e engadindo as cousas coas variables locais 349 00:18:54,000 --> 00:18:57,000 está no canto dicindo: "Ok, este é un problema super doado, 350 00:18:57,000 --> 00:19:01,000 como o número é <0, deixe-me inmediatamente volver 0. " 351 00:19:01,000 --> 00:19:03,000 >> Non imos molestar de apoio números negativos, 352 00:19:03,000 --> 00:19:05,000 entón eu vou código ríxido o valor 0. 353 00:19:05,000 --> 00:19:08,000 Pero se non, para aplicar esta idea de sumar 354 00:19:08,000 --> 00:19:11,000 todos estes números xuntos, pode efectivamente dar unha pequena mordida 355 00:19:11,000 --> 00:19:14,000 fóra do problema, así como fixemos aquí no escenario, 356 00:19:14,000 --> 00:19:18,000 entón punto o resto do problema para a seguinte persoa, 357 00:19:18,000 --> 00:19:20,000 pero neste caso a persoa próxima é a si mesmo. 358 00:19:20,000 --> 00:19:22,000 É unha función de nome idéntico. 359 00:19:22,000 --> 00:19:25,000 Só pasar un problema cada vez menor e menor de cada vez, 360 00:19:25,000 --> 00:19:28,000 e aínda que non temos cousas moi formalizados en código aquí 361 00:19:28,000 --> 00:19:33,000 iso é o que estaba a suceder na semana 0 co libro de teléfono. 362 00:19:33,000 --> 00:19:36,000 Este é o que estaba acontecendo nas últimas semanas, con Sean 363 00:19:36,000 --> 00:19:39,000 e as súas demostracións de busca de números. 364 00:19:39,000 --> 00:19:42,000 É tomar un problema e división lo novo e de novo. 365 00:19:42,000 --> 00:19:44,000 >> Noutras palabras, hai un xeito de traducir agora 366 00:19:44,000 --> 00:19:47,000 esta construción mundo real, esta construción nivel superior 367 00:19:47,000 --> 00:19:51,000 de dividir e conquistar e facer algo de novo e de novo 368 00:19:51,000 --> 00:19:56,000 no código, entón iso é algo que imos ver de novo ao longo do tempo. 369 00:19:56,000 --> 00:20:00,000 Agora, como un aparte, se vostede é novo para a recursividade ten que polo menos entender agora 370 00:20:00,000 --> 00:20:02,000 por que iso é divertido. 371 00:20:02,000 --> 00:20:05,000 Eu estou indo a ir a google.com, 372 00:20:05,000 --> 00:20:17,000 e eu vou buscar algúns consellos e trucos sobre recursão, entrar. 373 00:20:17,000 --> 00:20:21,000 Diga a persoa ao seu lado, no caso de que non estaban rindo agora. 374 00:20:21,000 --> 00:20:23,000 Quixo dicir recursão? 375 00:20:23,000 --> 00:20:25,000 Quería dicir ah, alí imos nós. 376 00:20:25,000 --> 00:20:28,000 Ok, agora que está o resto de todos. 377 00:20:28,000 --> 00:20:30,000 Un ovo de Pascua pequeno embutido en algún lugar alí en Google. 378 00:20:30,000 --> 00:20:33,000 Como un aparte, un dos enlaces que poñemos na web do curso 379 00:20:33,000 --> 00:20:36,000 por hoxe é só esa reixa de varios algoritmos de ordenación, 380 00:20:36,000 --> 00:20:39,000 algúns dos cales nós miramos a semana pasada, pero o que é agradable sobre esta visualización 381 00:20:39,000 --> 00:20:43,000 como tenta involucrar súa mente en torno a varias cousas relacionadas con algoritmos 382 00:20:43,000 --> 00:20:46,000 saber que pode moi facilmente agora comezar con diferentes tipos de insumos. 383 00:20:46,000 --> 00:20:50,000 As entradas de todos invertidos, as entradas ordenadas na maior parte, as entradas aleatoria e así por diante. 384 00:20:50,000 --> 00:20:53,000 Como tenta, unha vez máis, distinguir estas cousas na súa mente 385 00:20:53,000 --> 00:20:57,000 entender que esa URL na páxina web do curso na páxina de conferencias 386 00:20:57,000 --> 00:21:00,000 pode axudar a razón por medio dalgún destes. 387 00:21:00,000 --> 00:21:05,000 >> Hoxe por fin comezar a solucionar este problema de un tempo atrás, 388 00:21:05,000 --> 00:21:08,000 o que foi que esta función de intercambio simplemente non funciona, 389 00:21:08,000 --> 00:21:12,000 e cal foi o problema fundamental con esta cambio de función, 390 00:21:12,000 --> 00:21:15,000 cuxo obxectivo foi, de novo, para intercambiar un valor aquí e aquí 391 00:21:15,000 --> 00:21:17,000 de tal forma que isto ocorre? 392 00:21:17,000 --> 00:21:20,000 Isto realmente non funciona. Por que? 393 00:21:20,000 --> 00:21:22,000 Si 394 00:21:22,000 --> 00:21:28,000 [Inaudível-alumno] 395 00:21:28,000 --> 00:21:31,000 Exactamente, a explicación a este notan 396 00:21:31,000 --> 00:21:34,000 simplemente foi porque cando chamar funcións en C 397 00:21:34,000 --> 00:21:38,000 e esas funcións reciben argumentos, como a e b aquí, 398 00:21:38,000 --> 00:21:42,000 está pasando en copias de calquera valor que está dando a esta función. 399 00:21:42,000 --> 00:21:46,000 Non está introducindo os valores orixinais propios, 400 00:21:46,000 --> 00:21:49,000 entón vimos isto no contexto buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, que parecía un pouco algo como isto. 402 00:21:52,000 --> 00:21:57,000 >> Recórdese que tiñamos x e y inicializar con 1 e 2, respectivamente. 403 00:21:57,000 --> 00:21:59,000 A continuación, imprimiu o que eran. 404 00:21:59,000 --> 00:22:03,000 Eu, entón, dixo que eu estaba cambiando-os chamando intercambio de x, y. 405 00:22:03,000 --> 00:22:06,000 Pero o problema era que o intercambio funcionou, 406 00:22:06,000 --> 00:22:10,000 pero só no ámbito da programación propia función. 407 00:22:10,000 --> 00:22:13,000 Así que bateu liña 40 eses valores trocados 408 00:22:13,000 --> 00:22:16,000 foron xogados fóra, e así nada 409 00:22:16,000 --> 00:22:21,000 na función de inicio orixinal foi realmente cambiou en todo, 410 00:22:21,000 --> 00:22:26,000 por iso, se pensas que volta a continuación, como o que iso parece en termos da nosa memoria 411 00:22:26,000 --> 00:22:29,000 este lado esquerdo do consello representa- 412 00:22:29,000 --> 00:22:33,000 e eu vou facer o meu mellor para todo o mundo ver esta-se ese lado esquerdo do consello 413 00:22:33,000 --> 00:22:37,000 representa, por exemplo, a súa memoria RAM, ea pila vai medrar por riba desa forma, 414 00:22:37,000 --> 00:22:43,000 e chamamos unha función como principal, e principal ten dúas variables locais, X e Y, 415 00:22:43,000 --> 00:22:48,000 imos describir aqueles que x aquí, e imos describir estes como y aquí, 416 00:22:48,000 --> 00:22:55,000 e imos poñer en valor 1 e 2, de xeito que este aquí é principal, 417 00:22:55,000 --> 00:22:58,000 e cando chama a principal función de intercambio do sistema operativo 418 00:22:58,000 --> 00:23:02,000 dá a función de intercambio súa faixa propia de memoria na pila, 419 00:23:02,000 --> 00:23:04,000 seu propio cadro na pila, por así dicir. 420 00:23:04,000 --> 00:23:08,000 Tamén aloca 32 bits para estes ints. 421 00:23:08,000 --> 00:23:11,000 Pasa a chamalos a e b, pero iso é totalmente arbitrario. 422 00:23:11,000 --> 00:23:13,000 Podería chamar o que quere, pero o que ocorre cando principal 423 00:23:13,000 --> 00:23:19,000 cambio de nome que leva este 1, coloca unha copia alí, coloca unha copia alí. 424 00:23:19,000 --> 00:23:23,000 >> Hai outra variábel local en cambio, porén, o que chamou? Tmp. >> 425 00:23:23,000 --> 00:23:27,000 Tmp, entón deixe-me dar-me máis 32 bits aquí, 426 00:23:27,000 --> 00:23:29,000 eo que foi que eu fixen nesta función? 427 00:23:29,000 --> 00:23:34,000 Eu dixen tmp int recibe un, entón un ten un, entón eu fixen iso cando xogou por última vez con este exemplo. 428 00:23:34,000 --> 00:23:39,000 Entón un queda b, entón B é 2, e agora iso se fai 2, 429 00:23:39,000 --> 00:23:42,000 e agora b recibe tempo, de xeito temporal é 1, 430 00:23:42,000 --> 00:23:44,000 agora se fai presente b. 431 00:23:44,000 --> 00:23:46,000 Isto é óptimo. Funcionou. 432 00:23:46,000 --> 00:23:49,000 Pero entón, logo que o retorno da función 433 00:23:49,000 --> 00:23:52,000 memoria de intercambio en efecto desaparece de xeito que pode ser reutilizado 434 00:23:52,000 --> 00:23:58,000 por algunha outra función no futuro, e principal é obviamente completamente inalterada. 435 00:23:58,000 --> 00:24:00,000 Necesitamos un xeito de solucionar este problema, fundamentalmente, 436 00:24:00,000 --> 00:24:03,000 e hoxe imos finalmente ter unha forma de facelo a través do cal 437 00:24:03,000 --> 00:24:06,000 podemos introducir algo chamado un punteiro. 438 00:24:06,000 --> 00:24:09,000 Acontece que podemos solucionar este problema 439 00:24:09,000 --> 00:24:12,000 non pasando copias de x e y 440 00:24:12,000 --> 00:24:18,000 pero en vez pasando o que pensas que para a función de cambio? 441 00:24:18,000 --> 00:24:20,000 Si, o que o enderezo? 442 00:24:20,000 --> 00:24:22,000 Nós realmente non temos falado sobre enderezos en moitos detalles, 443 00:24:22,000 --> 00:24:25,000 pero se este cadro representa a memoria do meu ordenador 444 00:24:25,000 --> 00:24:28,000 seguramente poderiamos comezar a numeración dos bytes na miña memoria RAM 445 00:24:28,000 --> 00:24:31,000 e dicir que iso é byte # 1, que é byte # 2, byte # 3, 446 00:24:31,000 --> 00:24:35,000 byte # 4, # byte ... 2000000000 se eu tivera 2 gigabytes de memoria RAM, 447 00:24:35,000 --> 00:24:38,000 para que pudéssemos certamente chegar a algún esquema de numeración arbitraria 448 00:24:38,000 --> 00:24:41,000 para todos os bytes individuais na memoria do meu ordenador. 449 00:24:41,000 --> 00:24:43,000 >> E se en vez cando eu chamo de intercambio 450 00:24:43,000 --> 00:24:47,000 en vez de pasar unha copia de X e Y 451 00:24:47,000 --> 00:24:51,000 por que non me vez pasar o enderezo de x aquí, 452 00:24:51,000 --> 00:24:55,000 o enderezo de y aquí, esencialmente, o enderezo postal 453 00:24:55,000 --> 00:24:59,000 X e Y, porque entón cambiar, se está informado 454 00:24:59,000 --> 00:25:01,000 enderezo na memoria de x e y, 455 00:25:01,000 --> 00:25:04,000 a continuación, cambiar, se adestrou un pouco, 456 00:25:04,000 --> 00:25:07,000 podería potencialmente levar a este enderezo, por así dicir, 457 00:25:07,000 --> 00:25:11,000 x, e cambiar o número alí, entón dirixirse ao enderezo de y, 458 00:25:11,000 --> 00:25:16,000 cambiar o número de alí, mesmo se non está realmente a recibir copias de si mesmo eses valores, 459 00:25:16,000 --> 00:25:19,000 por iso mesmo que nós conversas sobre iso como memoria principal 460 00:25:19,000 --> 00:25:23,000 e memoria este troco como de poderosos e parte perigosa da C 461 00:25:23,000 --> 00:25:28,000 é que calquera función pode tocar en calquera parte da memoria do ordenador, 462 00:25:28,000 --> 00:25:32,000 e este é poderoso que pode facer cousas moi extravagantes con programas de ordenador en C. 463 00:25:32,000 --> 00:25:36,000 Isto é perigoso, porque tamén se pode romper moi facilmente. 464 00:25:36,000 --> 00:25:39,000 En realidade, unha das formas máis comúns para os programas estes días a ser explotado 465 00:25:39,000 --> 00:25:42,000 Non é para un programador para realizar 466 00:25:42,000 --> 00:25:45,000 que el ou ela está permitindo que un conxunto de datos 467 00:25:45,000 --> 00:25:49,000 a ser escrito en un lugar na memoria que non se destinaba. 468 00:25:49,000 --> 00:25:51,000 >> Por exemplo, el ou ela declárase unha matriz de tamaño 10 469 00:25:51,000 --> 00:25:56,000 pero entón accidentalmente intenta poñer 11 bytes en que a matriz de memoria, 470 00:25:56,000 --> 00:25:59,000 e comezar a tocar partes da memoria que non son máis válidos. 471 00:25:59,000 --> 00:26:02,000 Só para contextual iso, algúns de vostedes poden saber que 472 00:26:02,000 --> 00:26:06,000 software moitas veces pídelle a números de serie ou claves de rexistro, 473 00:26:06,000 --> 00:26:08,000 Photoshop Word e e programas como este. 474 00:26:08,000 --> 00:26:12,000 Existen rachaduras, como algúns de vostedes saben, en liña onde podes xirar un pequeno programa, 475 00:26:12,000 --> 00:26:14,000 e listo, máis unha proposta de número de serie. 476 00:26:14,000 --> 00:26:16,000 Como é que funciona? 477 00:26:16,000 --> 00:26:21,000 En moitos casos, estas cousas son simplemente atopar nos ordenadores 478 00:26:21,000 --> 00:26:24,000 segmentos de texto ceros reais do ordenador e entes 479 00:26:24,000 --> 00:26:28,000 onde é que a función onde o número de serie é solicitado, 480 00:26:28,000 --> 00:26:31,000 e substituír ese espazo, ou mentres o programa está a ser executado 481 00:26:31,000 --> 00:26:33,000 pode descubrir onde a clave é almacenado 482 00:26:33,000 --> 00:26:37,000 usar algo chamado un depurador, e pode romper forma de software que. 483 00:26:37,000 --> 00:26:40,000 Isto non quere dicir que este é o noso obxectivo para o próximo par de días, 484 00:26:40,000 --> 00:26:42,000 pero ten moito do mundo real ramificacións. 485 00:26:42,000 --> 00:26:45,000 Isto acontece para involucrar un roubo de software, 486 00:26:45,000 --> 00:26:47,000 pero hai tamén compromiso de máquinas completas. 487 00:26:47,000 --> 00:26:50,000 >> En realidade, cando sitios estes días son explotadas 488 00:26:50,000 --> 00:26:53,000 e comprometida e os datos son filtrada e contrasinal son roubados 489 00:26:53,000 --> 00:26:58,000 que moitas veces se refire á mala xestión da súa memoria, 490 00:26:58,000 --> 00:27:01,000 ou, no caso dos bancos de datos, a incapacidade de prever 491 00:27:01,000 --> 00:27:03,000 entrada de contraditorio, de xeito máis sobre iso nas próximas semanas, 492 00:27:03,000 --> 00:27:07,000 pero por agora só unha previa do sneak de tipo de dano que pode facer 493 00:27:07,000 --> 00:27:11,000 por non entender moi ben como funcionan as cousas debaixo do capó. 494 00:27:11,000 --> 00:27:14,000 Imos sobre a comprensión de por que isto está roto 495 00:27:14,000 --> 00:27:17,000 cunha ferramenta que pode facer-se cada vez máis útil 496 00:27:17,000 --> 00:27:19,000 como os nosos programas se fan máis complexas. 497 00:27:19,000 --> 00:27:21,000 Ata agora, cando tivo un erro no seu programa 498 00:27:21,000 --> 00:27:23,000 como foi preto de depurá-lo? 499 00:27:23,000 --> 00:27:25,000 O que as súas técnicas foi, ata agora, se ensina pola súa TF 500 00:27:25,000 --> 00:27:27,000 ou só autodidacta? 501 00:27:27,000 --> 00:27:29,000 [Estudante] printf. 502 00:27:29,000 --> 00:27:31,000 Printf, así printf probablemente foi o seu amigo en que, se quere ver 503 00:27:31,000 --> 00:27:33,000 o que está a suceder dentro do seu programa 504 00:27:33,000 --> 00:27:36,000 acaba de poñer printf aquí, printf aquí, printf aquí. 505 00:27:36,000 --> 00:27:38,000 Entón executalo, e terá unha morea de cousas na pantalla 506 00:27:38,000 --> 00:27:43,000 que pode usar para, entón, deducir o que realmente está a suceder de malo no seu programa. 507 00:27:43,000 --> 00:27:45,000 >> Printf tende a ser unha cousa moi poderosa, 508 00:27:45,000 --> 00:27:47,000 pero é un proceso moi manual. 509 00:27:47,000 --> 00:27:49,000 Ten que poñer un printf aquí, un printf aquí, 510 00:27:49,000 --> 00:27:51,000 e se colocar-lo dentro dun loop que pode obter de 100 liñas 511 00:27:51,000 --> 00:27:53,000 de saída que entón ten que peneirar. 512 00:27:53,000 --> 00:27:58,000 Non é un mecanismo moi user-friendly ou interactivo para programas de depuración, 513 00:27:58,000 --> 00:28:00,000 pero felices hai alternativas. 514 00:28:00,000 --> 00:28:03,000 Hai un programa, por exemplo, chamada GDB, GNU Debugger, 515 00:28:03,000 --> 00:28:06,000 que é un arcano pouco como usalo. 516 00:28:06,000 --> 00:28:08,000 É un pouco complexo, pero, francamente, 517 00:28:08,000 --> 00:28:11,000 Esta é unha desas cousas que, se pór esta semana e na próxima 518 00:28:11,000 --> 00:28:14,000 a hora extra para entender algo como GDB 519 00:28:14,000 --> 00:28:18,000 vai aforrar probablemente decenas de horas, a longo prazo, 520 00:28:18,000 --> 00:28:21,000 Entón, con iso, deixe-me dar-lle un teaser de como esa cousa funciona. 521 00:28:21,000 --> 00:28:23,000 >> Eu estou na miña xanela de terminal. 522 00:28:23,000 --> 00:28:26,000 Deixe-me ir adiante e compilar este programa, buggy3. 523 00:28:26,000 --> 00:28:28,000 Xa é ata a data. 524 00:28:28,000 --> 00:28:31,000 Deixe-me executa-lo así como fixemos un tempo atrás, e de feito, está roto. 525 00:28:31,000 --> 00:28:34,000 Pero por que isto? Poida que eu estraguei a función de intercambio. 526 00:28:34,000 --> 00:28:37,000 Quizais sexa a e b. Eu non estou moi movendo-os correctamente. 527 00:28:37,000 --> 00:28:39,000 Deixe-me ir adiante e facelo. 528 00:28:39,000 --> 00:28:43,000 En vez de só executar buggy3 déixeme en vez de executar este programa GDB, 529 00:28:43,000 --> 00:28:48,000 e eu vou dicir a el para realizar buggy3, 530 00:28:48,000 --> 00:28:52,000 e eu vou incluír un argumento de liña de comandos,-Tui, 531 00:28:52,000 --> 00:28:55,000 e imos poñer isto en problemas futuros en especificación para lembrar. 532 00:28:55,000 --> 00:28:57,000 E agora esta interface branco e negro apareceu que, de novo, 533 00:28:57,000 --> 00:28:59,000 é un pouco esmagadora no primeiro, porque non é todo isto 534 00:28:59,000 --> 00:29:02,000 información sobre a garantía aquí, pero polo menos hai algo familiar. 535 00:29:02,000 --> 00:29:04,000 Na parte superior da xanela é o código real, 536 00:29:04,000 --> 00:29:08,000 e se eu rolar por aquí, deixe-me ir para arriba do meu arquivo, 537 00:29:08,000 --> 00:29:11,000 e, de feito, hai buggy3.c e observe na parte inferior da ventá 538 00:29:11,000 --> 00:29:13,000 Eu teño ese aviso GDB. 539 00:29:13,000 --> 00:29:16,000 >> Este non é o mesmo que o meu normal, John Harvard ventá. 540 00:29:16,000 --> 00:29:19,000 Este é un aviso de que me vai permitir controlar GDB. 541 00:29:19,000 --> 00:29:21,000 GDB é un depurador. 542 00:29:21,000 --> 00:29:24,000 Un depurador é un programa que lle permite percorrer 543 00:29:24,000 --> 00:29:27,000 execución do seu programa liña a liña por liña, 544 00:29:27,000 --> 00:29:30,000 ao longo do camiño facendo o que quere co programa, 545 00:29:30,000 --> 00:29:33,000 mesmo chamar funcións, ou á procura, máis importante, 546 00:29:33,000 --> 00:29:35,000 en valores de variables varios. 547 00:29:35,000 --> 00:29:37,000 Imos adiante e facelo. 548 00:29:37,000 --> 00:29:40,000 Eu estou indo a ir adiante e escribir run no prompt do GDB, 549 00:29:40,000 --> 00:29:43,000 Entón, observe na parte inferior esquerda da pantalla eu escriba correr, 550 00:29:43,000 --> 00:29:45,000 e eu presione enter, e que o que facer? 551 00:29:45,000 --> 00:29:50,000 É, literalmente, correu meu programa, pero eu realmente non vexo moi continuar aquí 552 00:29:50,000 --> 00:29:55,000 porque eu realmente non teño dixo o depurador 553 00:29:55,000 --> 00:29:57,000 para facer unha pausa nun determinado momento no tempo. 554 00:29:57,000 --> 00:29:59,000 Só escribindo run executa o programa. 555 00:29:59,000 --> 00:30:01,000 Eu realmente non vexo nada. Eu non podo manipulala lo. 556 00:30:01,000 --> 00:30:03,000 >> En vez diso, deixe-me facelo. 557 00:30:03,000 --> 00:30:08,000 Neste ventá GDB déixeme en vez tipo de quebra, entrar. 558 00:30:08,000 --> 00:30:10,000 Isto non é o que eu quería escribir. 559 00:30:10,000 --> 00:30:13,000 Imos ao contrario tipo de quebra de inicio. 560 00:30:13,000 --> 00:30:15,000 Noutras palabras, quero establecer algo chamado un punto de interrupción, 561 00:30:15,000 --> 00:30:18,000 que é apropiadamente chamado porque vai romper ou pausar 562 00:30:18,000 --> 00:30:21,000 execución do seu programa naquel determinado lugar. 563 00:30:21,000 --> 00:30:23,000 Principal é o nome da miña función. 564 00:30:23,000 --> 00:30:25,000 Teña en conta que o GDB é moi intelixente. 565 00:30:25,000 --> 00:30:28,000 El descubriu que acontece principal para comezar a aproximadamente na liña 18 566 00:30:28,000 --> 00:30:32,000 de buggy3.c, e despois observar aquí na esquina superior esquerda 567 00:30:32,000 --> 00:30:34,000 b + é ben próximo á liña 18. 568 00:30:34,000 --> 00:30:38,000 Iso está me lembrar que eu definir un punto de interrupción na liña 18. 569 00:30:38,000 --> 00:30:42,000 Esta vez, cando eu tecleo carreira, eu vou facer o meu programa 570 00:30:42,000 --> 00:30:45,000 ata que chega o punto de interrupción, 571 00:30:45,000 --> 00:30:48,000 para que o programa fará unha pausa para min na liña 18. 572 00:30:48,000 --> 00:30:50,000 Aquí imos nós, executar. 573 00:30:50,000 --> 00:30:53,000 Nada parece acontecer, pero aviso na parte inferior esquerda 574 00:30:53,000 --> 00:30:58,000 programa de partida, buggy3, punto de interrupción nun inicio no buggy3.c liña 18. 575 00:30:58,000 --> 00:31:00,000 ¿Que podo facer agora? 576 00:31:00,000 --> 00:31:03,000 >> Repare que eu poida comezar a escribir cousas como impresión, 577 00:31:03,000 --> 00:31:08,000 Non printf, print x, e agora que é estraño. 578 00:31:08,000 --> 00:31:11,000 Os US $ 1 é só unha curiosidade, como veremos 579 00:31:11,000 --> 00:31:14,000 cada vez que imprimir algo que comeza un novo valor R $. 580 00:31:14,000 --> 00:31:18,000 Isto é para que poida referirse a valores anteriores para o caso, 581 00:31:18,000 --> 00:31:21,000 pero por agora o que está me dicindo impresión é que o valor de x, neste punto da historia 582 00:31:21,000 --> 00:31:26,000 é aparentemente 134514032. 583 00:31:26,000 --> 00:31:29,000 O que? Onde foi que mesmo vén? 584 00:31:29,000 --> 00:31:31,000 [Inaudível-alumno] 585 00:31:31,000 --> 00:31:34,000 En realidade, iso é o que imos chamar un valor de lixo, e non falamos sobre iso aínda, 586 00:31:34,000 --> 00:31:37,000 pero a razón que arrincar variables 587 00:31:37,000 --> 00:31:40,000 é, obviamente, para que eles teñan un valor que quere que eles teñan. 588 00:31:40,000 --> 00:31:44,000 Pero o problema é lembrar que pode declarar variables 589 00:31:44,000 --> 00:31:46,000 como eu fixen hai pouco no meu exemplo sigma 590 00:31:46,000 --> 00:31:48,000 sen realmente dándolles un valor. 591 00:31:48,000 --> 00:31:50,000 Teña en conta que o que eu fixen aquí no sigma. 592 00:31:50,000 --> 00:31:52,000 Eu declarei n, pero o valor eu dar? 593 00:31:52,000 --> 00:31:56,000 Ningún, porque eu sabía que nas próximas liñas 594 00:31:56,000 --> 00:31:59,000 GetInt ía coidar do problema de poñer un valor dentro de n. 595 00:31:59,000 --> 00:32:02,000 >> Pero, neste punto da historia da liña 11 596 00:32:02,000 --> 00:32:05,000 e 12 de liña e liña 13 e liña 14 597 00:32:05,000 --> 00:32:08,000 ao longo destas liñas de varias cal é o valor de n? 598 00:32:08,000 --> 00:32:10,000 C simplemente non sabe. 599 00:32:10,000 --> 00:32:14,000 É xeralmente un valor lixo, un número completamente aleatorio 600 00:32:14,000 --> 00:32:17,000 que sobrou esencialmente dalgunha función anterior 601 00:32:17,000 --> 00:32:21,000 sendo executado, así como o seu programa é executado 602 00:32:21,000 --> 00:32:24,000 lembrar que a función recibe, función, función. 603 00:32:24,000 --> 00:32:27,000 Todos estes cadros colocar en memoria, e despois os retorno funcións, 604 00:32:27,000 --> 00:32:31,000 e, así como eu suxerín a goma a súa memoria, finalmente, é reutilizada. 605 00:32:31,000 --> 00:32:37,000 Ben, acontece que esta variable x neste programa 606 00:32:37,000 --> 00:32:41,000 parece contido algún valor lixo como 134514032 607 00:32:41,000 --> 00:32:44,000 dalgunha función anterior, non un que eu escribín. 608 00:32:44,000 --> 00:32:47,000 Podería ser algo que vén de forma eficaz co sistema operativo, 609 00:32:47,000 --> 00:32:49,000 algunha función debaixo do capó. 610 00:32:49,000 --> 00:32:52,000 >> Ok, todo ben, pero imos agora avanzar na seguinte liña. 611 00:32:52,000 --> 00:32:55,000 Se eu escribir "next" no meu GDB pronta e eu bati entrar, 612 00:32:55,000 --> 00:32:58,000 notar que o realce move cara abaixo a liña 19, 613 00:32:58,000 --> 00:33:01,000 pero a implicación lóxica é que a liña 18 614 00:33:01,000 --> 00:33:06,000 xa rematou de executar, entón eu escribir de novo "print x" 615 00:33:06,000 --> 00:33:10,000 I que ver agora un, e de feito, eu fago. 616 00:33:10,000 --> 00:33:14,000 Unha vez máis, as cousas $ é unha forma de lembra-lo GDB 617 00:33:14,000 --> 00:33:17,000 o que a historia de impresións son de que vostede fixo. 618 00:33:17,000 --> 00:33:21,000 Agora déixeme ir adiante e imprimir y, e, de feito, y é un valor tolo, así como, 619 00:33:21,000 --> 00:33:24,000 pero non é gran cousa, porque na liña 19 que estamos a piques de atribuílo lo 620 00:33:24,000 --> 00:33:27,000 o valor 2, entón deixe-me escribir "próximo" de novo. 621 00:33:27,000 --> 00:33:29,000 E agora estamos na liña printf. 622 00:33:29,000 --> 00:33:31,000 Deixe-me facer x impresión. 623 00:33:31,000 --> 00:33:34,000 Deixe-me facer y impresión. Francamente, estou quedando un pouco canso de imprimir este. 624 00:33:34,000 --> 00:33:38,000 Deixe-me no canto tipo "display x" e "y exhibición" 625 00:33:38,000 --> 00:33:41,000 e agora cada vez que eu escribir un comando no futuro 626 00:33:41,000 --> 00:33:45,000 Vou lembrar que é x e y, o que é X e Y, que é x e y. 627 00:33:45,000 --> 00:33:48,000 >> Eu tamén poden, como un aparte, escriba "veciños de información." 628 00:33:48,000 --> 00:33:50,000 Info é un comando especial. 629 00:33:50,000 --> 00:33:52,000 Veciños significa que me amosa as variables locais. 630 00:33:52,000 --> 00:33:55,000 Só no caso de eu esquezo ou esta é unha función, tolo complicado 631 00:33:55,000 --> 00:33:57,000 que eu ou alguén escribiu veciños información vai dicir 632 00:33:57,000 --> 00:34:00,000 que son todas as variables locais dentro desta función local 633 00:34:00,000 --> 00:34:03,000 que pode preocupar se quere bisbilhotar. 634 00:34:03,000 --> 00:34:07,000 Agora, printf está a piques de executar, entón deixe-me ir adiante e só un tipo "próximo". 635 00:34:07,000 --> 00:34:10,000 Porque somos neste ambiente non estamos realmente vendo iso 636 00:34:10,000 --> 00:34:14,000 executar aquí, pero entende que está quedando un pouco mutilado aquí. 637 00:34:14,000 --> 00:34:17,000 Pero teña en conta que está substituíndo a pantalla de alí, 638 00:34:17,000 --> 00:34:21,000 polo tanto, non é un programa perfecto aquí, pero todo ben, porque eu sempre pode fuçar 639 00:34:21,000 --> 00:34:23,000 usando de impresión, se eu queira. 640 00:34:23,000 --> 00:34:26,000 >> Deixe-me preto tipo de novo, e agora aquí é a parte interesante. 641 00:34:26,000 --> 00:34:29,000 Neste punto da historia y é 2, e x 1, 642 00:34:29,000 --> 00:34:32,000 como aquí suxerido, e de novo, 643 00:34:32,000 --> 00:34:35,000 A razón é automaticamente amosar agora é porque eu usei o comando 644 00:34:35,000 --> 00:34:40,000 Mostrar X e Y de exhibición, entón o momento próximo tecleo 645 00:34:40,000 --> 00:34:43,000 na teoría X e Y deben ser trocados. 646 00:34:43,000 --> 00:34:45,000 Agora xa sabemos que non vai ser o caso, 647 00:34:45,000 --> 00:34:49,000 pero imos ver en un momento como podemos mergullar máis fondo para descubrir por que isto é verdade. 648 00:34:49,000 --> 00:34:54,000 A continuación, e, por desgraza, aínda é y 2 e x aínda é un, e podo confirmar tanto. 649 00:34:54,000 --> 00:34:56,000 Imprimir x, y de impresión. 650 00:34:56,000 --> 00:34:59,000 En realidade, ningunha cambio que realmente aconteceu, entón imos comezar de novo isto. 651 00:34:59,000 --> 00:35:01,000 Claramente intercambio é roto. 652 00:35:01,000 --> 00:35:04,000 Imos en vez escriba "Executar" de novo. 653 00:35:04,000 --> 00:35:07,000 Deixe-me dicir que si, que quero para reinicia-lo desde o inicio, entrar. 654 00:35:07,000 --> 00:35:09,000 >> Agora estou de volta para a liña 18. 655 00:35:09,000 --> 00:35:11,000 Agora notar x e y son os valores de lixo novo. 656 00:35:11,000 --> 00:35:15,000 Next, Next, Next, Next. 657 00:35:15,000 --> 00:35:17,000 Se eu estar aburrido eu tamén pode simplemente escribir n para a próxima. 658 00:35:17,000 --> 00:35:21,000 Pode abreviar-lo para o máis curto posible secuencia de caracteres. 659 00:35:21,000 --> 00:35:23,000 Intercambio agora roto. 660 00:35:23,000 --> 00:35:25,000 Imos mergullo, entón en vez de escribir seguinte 661 00:35:25,000 --> 00:35:30,000 agora eu vou escribir paso para que eu estou pisando dentro desta función 662 00:35:30,000 --> 00:35:33,000 para que eu poida atravesalo-la, entón eu acertar paso e despois entrar. 663 00:35:33,000 --> 00:35:37,000 Repare que os saltos destacando máis abaixo no meu programa para a liña 36. 664 00:35:37,000 --> 00:35:39,000 Agora, cales son as variables locais? 665 00:35:39,000 --> 00:35:41,000 Información local. 666 00:35:41,000 --> 00:35:43,000 Nada só porque aínda non chegaran a esta liña, 667 00:35:43,000 --> 00:35:47,000 entón imos adiante e dicir "próximo". 668 00:35:47,000 --> 00:35:50,000 Agora parece que temos tmp tmp impresión. 669 00:35:50,000 --> 00:35:52,000 Valor de lixo, non? Creo que si. 670 00:35:52,000 --> 00:35:55,000 Que tal imprimir unha, imprimir B, 1 e 2? 671 00:35:55,000 --> 00:35:58,000 Nun momento, así como eu escriba seguinte novo 672 00:35:58,000 --> 00:36:02,000 tmp vai asumir un valor de 1, espera-se, 673 00:36:02,000 --> 00:36:05,000 tmp que vai ser asignado o valor dun. 674 00:36:05,000 --> 00:36:08,000 >> Agora imos facer imprimir a, b de impresión, 675 00:36:08,000 --> 00:36:11,000 pero agora imprimir tmp, e é de feito un. 676 00:36:11,000 --> 00:36:14,000 Deixe-me facer a continuación. Deixe-me facer a continuación. 677 00:36:14,000 --> 00:36:16,000 Eu rematar a función de intercambio. 678 00:36:16,000 --> 00:36:19,000 Eu aínda estou dentro dela na liña 40, entón deixe-me imprimir un, 679 00:36:19,000 --> 00:36:22,000 b impresión, e eu non me importa o tmp é. 680 00:36:22,000 --> 00:36:27,000 Parece que intercambio é correcto cando se trata de cambiar a e b. 681 00:36:27,000 --> 00:36:31,000 Pero se eu agora escribir seguinte, eu saltar de volta para a liña 25, 682 00:36:31,000 --> 00:36:34,000 e, por suposto, se eu escribir X e Y de impresión 683 00:36:34,000 --> 00:36:38,000 eles aínda están inalterados, por iso non corrixido o problema. 684 00:36:38,000 --> 00:36:41,000 Pero agora pode diagnóstico con este programa GDB 685 00:36:41,000 --> 00:36:44,000 temos, polo menos, quedou un paso máis preto de comprender 686 00:36:44,000 --> 00:36:47,000 o que está a suceder de malo sen ter que lixo noso código, colocando un printf aquí, 687 00:36:47,000 --> 00:36:50,000 printf aquí, printf aquí e despois executa-lo novo e de novo 688 00:36:50,000 --> 00:36:52,000 tentando descubrir o que está a suceder de malo. 689 00:36:52,000 --> 00:36:55,000 >> Eu estou indo a ir adiante e saír fóra deste conxunto con saia. 690 00:36:55,000 --> 00:36:57,000 Vai entón dicir: "Saír de todos os xeitos?" Si 691 00:36:57,000 --> 00:37:00,000 Agora estou de volta ao meu poder normal, e eu estou feito empregando GDB. 692 00:37:00,000 --> 00:37:03,000 Como un aparte, non utilizar este Tui-bandeira. 693 00:37:03,000 --> 00:37:07,000 En realidade, se omiti-lo ten, esencialmente, a metade inferior da pantalla. 694 00:37:07,000 --> 00:37:11,000 Se eu escriba intervalo principal e executa 695 00:37:11,000 --> 00:37:15,000 Aínda podo correr o meu programa, pero o que vai facer é textualmente 696 00:37:15,000 --> 00:37:18,000 só mostrar-me a unha corrente de liña de cada vez. 697 00:37:18,000 --> 00:37:21,000 O Tui-, interface de usuario textual, 698 00:37:21,000 --> 00:37:25,000 só mostra máis do programa dunha soa vez, o que pode ser un pouco conceptualmente máis fácil. 699 00:37:25,000 --> 00:37:27,000 Pero, en realidade, eu só podo facer a continuación, avanzar, avanzar, 700 00:37:27,000 --> 00:37:30,000 e eu vou ver unha liña de cada vez, e eu realmente quero ver o que está a suceder 701 00:37:30,000 --> 00:37:35,000 Podo tipo de lista para ver unha morea de liñas veciñas. 702 00:37:35,000 --> 00:37:39,000 >> Hai un vídeo que pedimos que ve ao problema define tres 703 00:37:39,000 --> 00:37:43,000 en que Nate abrangue algúns dos meandros do GDB, 704 00:37:43,000 --> 00:37:46,000 e esta é unha desas cousas que, sinceramente, onde algúns dos non-trivial de ti 705 00:37:46,000 --> 00:37:49,000 nunca vai tocar GDB, e que vai ser unha cousa mala 706 00:37:49,000 --> 00:37:53,000 porque literalmente vai acabar gastan máis tempo aínda este semestre 707 00:37:53,000 --> 00:37:56,000 perseguir erros entón tería se pór en que media hora / hora 708 00:37:56,000 --> 00:38:00,000 esta semana e aprendizaxe seguinte para sentirse cómodo co GDB. 709 00:38:00,000 --> 00:38:02,000 Printf era o seu amigo. 710 00:38:02,000 --> 00:38:05,000 GDB debe agora ser o seu amigo. 711 00:38:05,000 --> 00:38:08,000 >> Calquera dúbida sobre o GDB? 712 00:38:08,000 --> 00:38:12,000 E aquí está unha breve lista de algúns dos comandos máis poderosas e útiles. 713 00:38:12,000 --> 00:38:15,000 Si >> É posible imprimir unha cadea? 714 00:38:15,000 --> 00:38:17,000 É posible imprimir unha cadea? Absolutamente. 715 00:38:17,000 --> 00:38:19,000 Non ten que ser só números enteiros. 716 00:38:19,000 --> 00:38:22,000 Unha variable s é unha secuencia de só un tipo de s de impresión. 717 00:38:22,000 --> 00:38:24,000 Ela vai amosar o que é variable de cadea. 718 00:38:24,000 --> 00:38:26,000 [Inaudível-alumno] 719 00:38:26,000 --> 00:38:28,000 El vai che dar o enderezo eo cadea. 720 00:38:28,000 --> 00:38:32,000 Ela vai amosar tanto. 721 00:38:32,000 --> 00:38:34,000 E unha última cousa, só porque estes son bo saber tamén. 722 00:38:34,000 --> 00:38:37,000 Backtrace e armazón, deixe-me mergullo nunha última vez, 723 00:38:37,000 --> 00:38:39,000 programa exactamente o mesmo co GDB. 724 00:38:39,000 --> 00:38:44,000 Deixe-me ir adiante e executar a versión da interface de usuario textual, 725 00:38:44,000 --> 00:38:46,000 romper principal. 726 00:38:46,000 --> 00:38:49,000 Deixe-me ir adiante e executar de novo. Aquí estou. 727 00:38:49,000 --> 00:38:55,000 Agora déixeme ir a continuación, next, next, next, next, paso, entrar. 728 00:38:55,000 --> 00:39:00,000 >> E agora creo que eu son agora, a cambio de propósito, pero eu son así "Porra, cal foi o valor de x?" 729 00:39:00,000 --> 00:39:02,000 Eu non podo facer máis x. 730 00:39:02,000 --> 00:39:05,000 Eu non podo facer y porque eles non están no ámbito. 731 00:39:05,000 --> 00:39:07,000 Eles non están no contexto, pero non hai problema. 732 00:39:07,000 --> 00:39:09,000 Podo escribir backtrace. 733 00:39:09,000 --> 00:39:13,000 Que me mostra todas as funcións que teñan firmado ata este momento. 734 00:39:13,000 --> 00:39:16,000 Teña en conta que o un na parte inferior, de inicio, aliñan con principal 735 00:39:16,000 --> 00:39:18,000 estar no fondo da nosa imaxe aquí. 736 00:39:18,000 --> 00:39:22,000 O feito de que por riba de intercambio é que sexa aliñado con intercambio estar por riba del na memoria aquí, 737 00:39:22,000 --> 00:39:26,000 e se eu queira volver ao inicio temporalmente podo dicir "marco". 738 00:39:26,000 --> 00:39:30,000 Cal é o número? Principal é o marco # 1. 739 00:39:30,000 --> 00:39:32,000 Eu estou indo a ir adiante e dicir "1 cadro". 740 00:39:32,000 --> 00:39:36,000 >> Agora estou de volta na principal, e podo imprimir x, e podo imprimir y, 741 00:39:36,000 --> 00:39:40,000 pero eu non podo imprimir a ou b. 742 00:39:40,000 --> 00:39:43,000 Pero eu podo, se eu digo: "Ok, agarde un minuto. Onde estaba o intercambio?" 743 00:39:43,000 --> 00:39:46,000 Deixe-me ir adiante e dicir "0 cadro." 744 00:39:46,000 --> 00:39:48,000 Agora estou de volta onde eu quero ser, e como un aparte, 745 00:39:48,000 --> 00:39:52,000 hai tamén outros comandos, como se está realmente quedando aburrido dixitación next, next, next, next, 746 00:39:52,000 --> 00:39:56,000 xeralmente pode dicir cousas como "10 next", e que pode percorrer os próximos 10 liñas. 747 00:39:56,000 --> 00:39:59,000 Tamén pode escribir "seguir" cando realmente funciona coa depuración a través dela. 748 00:39:59,000 --> 00:40:05,000 Continuar ha executar o programa sen interrupción ata alcanzar outro punto de interrupción, 749 00:40:05,000 --> 00:40:07,000 en un loop ou máis abaixo no seu programa. 750 00:40:07,000 --> 00:40:11,000 >> Neste caso, continuou ata o final, eo programa saíu normalmente. 751 00:40:11,000 --> 00:40:13,000 Esta é unha maneira extravagante, proceso inferior. 752 00:40:13,000 --> 00:40:16,000 Só o seu programa saíu normalmente. 753 00:40:16,000 --> 00:40:24,000 Máis sobre iso no vídeo e en sesións de depuración para vir. 754 00:40:24,000 --> 00:40:26,000 Isto foi moito. 755 00:40:26,000 --> 00:40:35,000 Imos dar o noso intervalo de 5 minutos aquí, e nós imos volver con structs e arquivos. 756 00:40:35,000 --> 00:40:38,000 >> Se mergullou pset desta semana xa 757 00:40:38,000 --> 00:40:41,000 vostede sabe que usamos no código de distribución, 758 00:40:41,000 --> 00:40:45,000 o código fonte que ofrece a vostede como un punto de partida, algunhas técnicas novas. 759 00:40:45,000 --> 00:40:50,000 En particular, introduciu esta nova contrasinal chamada struct, a estrutura, 760 00:40:50,000 --> 00:40:53,000 para que poidamos crear variables personalizadas de sortes. 761 00:40:53,000 --> 00:40:57,000 Tamén introduciu a noción de ficheiro de entrada de arquivo I / O, e de saída, 762 00:40:57,000 --> 00:41:00,000 e isto é para que poidamos gardar o estado 763 00:41:00,000 --> 00:41:03,000 da súa tarxeta Scramble para un ficheiro en disco 764 00:41:03,000 --> 00:41:06,000 para que os compañeiros de ensino e podo entender 765 00:41:06,000 --> 00:41:09,000 o que está a suceder dentro do seu programa sen ter que manualmente xogar 766 00:41:09,000 --> 00:41:11,000 decenas de xogos de carreira. 767 00:41:11,000 --> 00:41:13,000 Podemos facelo máis automatedly. 768 00:41:13,000 --> 00:41:18,000 >> Esa idea dunha estrutura resolve un problema moi convincente. 769 00:41:18,000 --> 00:41:21,000 Supoña que queremos aplicar algún programa 770 00:41:21,000 --> 00:41:25,000 que dalgunha forma mantén o control da información sobre os alumnos, 771 00:41:25,000 --> 00:41:28,000 e os alumnos poden ter, por exemplo, un número de identificación, o nome 772 00:41:28,000 --> 00:41:31,000 e unha casa nun lugar como Harvard, así que estes son tres pezas de información 773 00:41:31,000 --> 00:41:34,000 queremos manter ao redor, entón deixe-me ir adiante e comezar a escribir un pequeno programa aquí, 774 00:41:34,000 --> 00:41:38,000 incluír stdio.h. 775 00:41:38,000 --> 00:41:42,000 Deixe-me facer inclúen cs50.h. 776 00:41:42,000 --> 00:41:44,000 E entón comezar a miña función principal. 777 00:41:44,000 --> 00:41:46,000 Eu non vou preocupar con calquera argumentos de liña de comandos, 778 00:41:46,000 --> 00:41:49,000 e aquí quero ter un estudante, entón eu vou dicir 779 00:41:49,000 --> 00:41:54,000 un alumno ten un nome, entón eu vou dicir "nome de cadea." 780 00:41:54,000 --> 00:41:59,000 Entón eu vou dicir unha estudante tamén ten un ID, ID para int, 781 00:41:59,000 --> 00:42:03,000 e un alumno ten unha casa, entón eu tamén vou dicir "casa corda". 782 00:42:03,000 --> 00:42:06,000 Entón eu vou pedir un pouco eses máis limpa coma este. 783 00:42:06,000 --> 00:42:11,000 Ok, agora eu teño tres variables que representan un estudante, polo tanto, "un estudante." 784 00:42:11,000 --> 00:42:15,000 >> E agora quero para cubrir eses valores, entón deixe-me ir adiante e dicir algo así como 785 00:42:15,000 --> 00:42:18,000 "ID = 123". 786 00:42:18,000 --> 00:42:21,000 Nome vai quedar David. 787 00:42:21,000 --> 00:42:24,000 Digamos casa vai estar Mather, 788 00:42:24,000 --> 00:42:31,000 e entón eu vou facer algo arbitrariamente como printf ("% s, 789 00:42:31,000 --> 00:42:37,000 cuxa identificación é% d, vive en% s. 790 00:42:37,000 --> 00:42:41,000 E agora, o que quero conectar aquí, un despois do outro? 791 00:42:41,000 --> 00:42:47,000 Nome, ID de casa,; retorno 0. 792 00:42:47,000 --> 00:42:50,000 Ok, a menos que eu estraguei todo en algún lugar aquí 793 00:42:50,000 --> 00:42:54,000 Eu creo que temos un programa moi bo, que almacena un estudante. 794 00:42:54,000 --> 00:42:57,000 Está claro que iso non é todo o que interesante. E se eu queira ter dous alumnos? 795 00:42:57,000 --> 00:42:59,000 Isto non é gran cousa. Eu podo soportar 2 persoas. 796 00:42:59,000 --> 00:43:03,000 Deixe-me ir adiante e destacar iso e ir ata aquí, 797 00:43:03,000 --> 00:43:09,000 e podo dicir "id = 456" para alguén como Rob que vive en Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Ok, agarde, pero non podo chamalos a mesma cousa, 799 00:43:12,000 --> 00:43:15,000 e parece que vou ter que copiar iso, 800 00:43:15,000 --> 00:43:19,000 entón deixe-me dicir que estas serán as variables de David, 801 00:43:19,000 --> 00:43:23,000 e deixe-me algunhas copias destes para o Rob. 802 00:43:23,000 --> 00:43:27,000 Imos chamar estas Rob, pero iso non vai funcionar agora 803 00:43:27,000 --> 00:43:33,000 porque eu, agarde, imos cambiar-me para id1, name1 e house1. 804 00:43:33,000 --> 00:43:35,000 Rob será de 2, 2. 805 00:43:35,000 --> 00:43:42,000 Eu teño que cambiar isto aquí, aquí, aquí, aquí, aquí, aquí. 806 00:43:42,000 --> 00:43:45,000 Espere, o que pasa con Tommy? Imos facer iso de novo. 807 00:43:45,000 --> 00:43:49,000 Obviamente, se aínda pensa que isto é unha boa forma de facer isto, non é, 808 00:43:49,000 --> 00:43:52,000 para copiar / pegar malo. 809 00:43:52,000 --> 00:43:55,000 Pero nós resolvemos isto hai unha semana. 810 00:43:55,000 --> 00:43:59,000 >> Cal foi a nosa solución, cando quería ter varias instancias do mesmo tipo de datos? 811 00:43:59,000 --> 00:44:01,000 [Os alumnos] Unha matriz. 812 00:44:01,000 --> 00:44:03,000 Unha matriz, entón deixe-me tentar limpar isto. 813 00:44:03,000 --> 00:44:07,000 Deixe-me facer algunhas para min mesmo no cumio, e deixe-me en vez facelo aquí. 814 00:44:07,000 --> 00:44:12,000 Imos chamar esta xente, e ao contrario diso eu vou dicir "IDs int", 815 00:44:12,000 --> 00:44:14,000 e eu estou indo a soportar 3 de nós agora. 816 00:44:14,000 --> 00:44:18,000 Eu vou dicir "nomes de cadea", e eu vou apoia-3 de nós, 817 00:44:18,000 --> 00:44:22,000 e entón eu vou dicir "casas secuencia," e eu vou apoiar a 3. 818 00:44:22,000 --> 00:44:26,000 Agora aquí en lugar de David recibindo as súas propias variables locais 819 00:44:26,000 --> 00:44:28,000 podemos librar deles. 820 00:44:28,000 --> 00:44:30,000 Isto é bo que estamos limpar isto. 821 00:44:30,000 --> 00:44:35,000 Podo, entón, dicir que David vai ser [0] e nomes [0] 822 00:44:35,000 --> 00:44:38,000 e casas [0]. 823 00:44:38,000 --> 00:44:41,000 E, a continuación, Rob podemos igualmente aforrar no presente. 824 00:44:41,000 --> 00:44:46,000 Imos poñer iso aquí, entón vai ser arbitrariamente IDs [1]. 825 00:44:46,000 --> 00:44:50,000 El vai ser nomes, [1] 826 00:44:50,000 --> 00:44:53,000 e, a continuación, finalmente, casas [1]. 827 00:44:53,000 --> 00:44:57,000 >> Aínda un pouco entediante, e agora eu teño que descubrir iso, 828 00:44:57,000 --> 00:45:03,000 entón imos dicir "nomes [0], id [0], casas [0] 829 00:45:03,000 --> 00:45:06,000 e imos pluralizar iso. 830 00:45:06,000 --> 00:45:09,000 IDs, IDs, IDs. 831 00:45:09,000 --> 00:45:12,000 E de novo, eu estou facendo iso, por iso de novo, eu xa estou recorrendo para copiar / pegar de novo, 832 00:45:12,000 --> 00:45:14,000 así as probabilidades son de que hai outra solución aquí. 833 00:45:14,000 --> 00:45:18,000 Eu probablemente pode borrar isto aínda máis con un lazo ou algo así, 834 00:45:18,000 --> 00:45:21,000 Entón, en suma, é un pouco mellor, pero aínda se sente como 835 00:45:21,000 --> 00:45:24,000 Estou recorrendo para copiar / pegar, pero iso, eu afirmo, 836 00:45:24,000 --> 00:45:27,000 non é realmente a solución correcta fundamentalmente porque 837 00:45:27,000 --> 00:45:29,000 E se algún día decidimos que vostede sabe o que? 838 00:45:29,000 --> 00:45:32,000 Realmente debe ser almacenar enderezos de correo-e para David e Rob 839 00:45:32,000 --> 00:45:34,000 e todos os outros neste programa. 840 00:45:34,000 --> 00:45:36,000 Debemos tamén almacenar números de teléfono. 841 00:45:36,000 --> 00:45:39,000 Debemos tamén almacenar números de contacto de urxencia. 842 00:45:39,000 --> 00:45:41,000 Temos todas estas pezas de datos que desexa almacenar, 843 00:45:41,000 --> 00:45:43,000 entón como vai facer sobre iso? 844 00:45:43,000 --> 00:45:46,000 >> Vostede declara outra matriz, na parte superior, e entón engadir manualmente 845 00:45:46,000 --> 00:45:49,000 un enderezo de correo electrónico [0] enderezo, correo electrónico [1] 846 00:45:49,000 --> 00:45:51,000 para David e Rob e así por diante. 847 00:45:51,000 --> 00:45:56,000 Pero hai realmente só unha suposición subxacente a este proxecto 848 00:45:56,000 --> 00:45:59,000 que eu estou a usar o sistema de honra saber que 849 00:45:59,000 --> 00:46:03,000 [I] en cada un dos distintos arrays 850 00:46:03,000 --> 00:46:06,000 Acontece para referirse á mesma persoa, 851 00:46:06,000 --> 00:46:10,000 así [0] no IDs é o número 123, 852 00:46:10,000 --> 00:46:13,000 e eu vou asumir que os nomes [0] 853 00:46:13,000 --> 00:46:16,000 é o nome da mesma persoa e casas [0] 854 00:46:16,000 --> 00:46:21,000 é casa da mesma persoa e así por diante para todas as matrices diferentes que creo. 855 00:46:21,000 --> 00:46:24,000 Pero teña en conta que non hai ningunha conexión fundamentais 856 00:46:24,000 --> 00:46:27,000 entre esas tres pezas de información, identificación, nome e casa, 857 00:46:27,000 --> 00:46:32,000 aínda que a entidade que estamos intentando modelo neste programa non é matrices. 858 00:46:32,000 --> 00:46:35,000 Matrices son exactamente desa forma programática para facelo. 859 00:46:35,000 --> 00:46:38,000 O que realmente queremos para modelar o noso programa é unha persoa 860 00:46:38,000 --> 00:46:41,000 como David, unha persoa como Rob dentro do cal 861 00:46:41,000 --> 00:46:46,000 ou encapsulamento é un nome e número de identificación e unha casa. 862 00:46:46,000 --> 00:46:49,000 >> Será que podemos expresar esa idea de encapsulamento 863 00:46:49,000 --> 00:46:52,000 polo cal unha persoa ten un ID, un nome e unha casa 864 00:46:52,000 --> 00:46:55,000 e non recorrer a este truco realmente que nós só 865 00:46:55,000 --> 00:46:58,000 confiar que algo soporte 866 00:46:58,000 --> 00:47:02,000 refírese a unha mesma persoa humana en cada unha desas matrices diferentes? 867 00:47:02,000 --> 00:47:04,000 Podemos realmente facer iso. 868 00:47:04,000 --> 00:47:08,000 Deixe-me ir enriba principal para agora, e deixe-me crear o meu propio tipo de datos 869 00:47:08,000 --> 00:47:10,000 para realmente por primeira vez. 870 00:47:10,000 --> 00:47:14,000 Usan esta técnica en Scramble, 871 00:47:14,000 --> 00:47:17,000 pero aquí eu estou indo a ir adiante e crear un tipo de datos, 872 00:47:17,000 --> 00:47:19,000 e vostede sabe, eu vou chamalo de estudante ou persoa, 873 00:47:19,000 --> 00:47:23,000 e eu vou usar typedef para definir un tipo. 874 00:47:23,000 --> 00:47:25,000 Eu vou dicir que esta é unha estrutura, 875 00:47:25,000 --> 00:47:29,000 e entón esta estrutura vai ser de estudante tipo, imos dicir, 876 00:47:29,000 --> 00:47:31,000 aínda que sexa un pouco datado agora para min. 877 00:47:31,000 --> 00:47:33,000 Nós imos dicir "int id". 878 00:47:33,000 --> 00:47:35,000 Nós imos dicir "nome de cadea." 879 00:47:35,000 --> 00:47:37,000 Entón, imos dicir "casa corda", 880 00:47:37,000 --> 00:47:40,000 agora ata o final de estas poucas liñas de código 881 00:47:40,000 --> 00:47:45,000 Acabo ensinou bumbum que non existe 882 00:47:45,000 --> 00:47:49,000 un tipo de datos ademais de ints, ademais de cordas, ademais de dúos, ademais de coches alegóricos. 883 00:47:49,000 --> 00:47:54,000 >> A partir deste momento, en vez da liña 11, existe agora un novo tipo de datos chamado estudantes, 884 00:47:54,000 --> 00:47:58,000 e agora podo declarar unha variable alumno en calquera lugar que quero, 885 00:47:58,000 --> 00:48:01,000 entón deixe-me ir ata aquí para a xente. 886 00:48:01,000 --> 00:48:05,000 Agora podo me librar diso, e podo ir de volta para David aquí, 887 00:48:05,000 --> 00:48:10,000 e David podo realmente dicir que David, 888 00:48:10,000 --> 00:48:13,000 podemos literalmente nomear a variable despois de min, 889 00:48:13,000 --> 00:48:16,000 vai ser de estudante tipo. 890 00:48:16,000 --> 00:48:18,000 Isto pode parecer un pouco raro, pero isto non é así tan diferente 891 00:48:18,000 --> 00:48:22,000 de declarar algo como un int ou unha cadea ou unha boia. 892 00:48:22,000 --> 00:48:24,000 Isto só pasa a ser chamado de estudante, 893 00:48:24,000 --> 00:48:28,000 e se eu queira poñer algo dentro desta estrutura 894 00:48:28,000 --> 00:48:31,000 Eu agora teño que usar unha nova peza de sintaxe, pero é moi sinxelo, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" na capital D, 896 00:48:39,000 --> 00:48:42,000 e david.house = "Mather," 897 00:48:42,000 --> 00:48:46,000 e agora podo me librar destas cousas aquí. 898 00:48:46,000 --> 00:48:51,000 Repare que temos agora redeseñado noso programa en realidade unha forma moito mellor 899 00:48:51,000 --> 00:48:54,000 en que agora o noso programa reflicte o mundo real. 900 00:48:54,000 --> 00:48:57,000 >> Hai unha noción do mundo real dunha persoa ou dun estudante. 901 00:48:57,000 --> 00:49:02,000 Aquí temos agora unha versión C dunha persoa ou, máis especificamente, un estudante. 902 00:49:02,000 --> 00:49:05,000 Dentro desa persoa son esas características relevantes, 903 00:49:05,000 --> 00:49:10,000 ID, nome e casa, por iso Rob torna-se esencialmente a mesma cousa aquí, 904 00:49:10,000 --> 00:49:14,000 entón estudante Rob, e agora rob.id = 456, 905 00:49:14,000 --> 00:49:17,000 rob.name = "Rob". 906 00:49:17,000 --> 00:49:20,000 O feito de que a variable é chamado Rob é unha especie de sentido. 907 00:49:20,000 --> 00:49:22,000 Poderiamos chamar x ou y ou z. 908 00:49:22,000 --> 00:49:25,000 Nós só nomeou Rob para semanticamente consistente, 909 00:49:25,000 --> 00:49:28,000 pero realmente o nome está dentro do propio campo, 910 00:49:28,000 --> 00:49:30,000 entón agora eu teño iso. 911 00:49:30,000 --> 00:49:33,000 Isto tamén non se sente como o mellor proxecto en que eu codificado David. 912 00:49:33,000 --> 00:49:35,000 Eu codificado Rob. 913 00:49:35,000 --> 00:49:39,000 E eu aínda teño que recorrer a algún copiar e pegar cada vez que quero novas variables. 914 00:49:39,000 --> 00:49:43,000 Ademais, eu teño que dar, ao parecer, cada unha desas variables dun nome, 915 00:49:43,000 --> 00:49:46,000 aínda que eu prefiro describir estas variables 916 00:49:46,000 --> 00:49:48,000  alumnos máis xenericamente como. 917 00:49:48,000 --> 00:49:52,000 >> Agora podemos mesturar as ideas que teñen benvida a traballar ben para nós 918 00:49:52,000 --> 00:49:56,000 e, en vez dicir: "Vostede sabe o que, dáme un estudantes variable chamada, 919 00:49:56,000 --> 00:50:01,000 e imos ter que ser de tamaño 3 ", entón agora podo refinar este aínda máis, 920 00:50:01,000 --> 00:50:04,000 librar-se do David manualmente declarou, 921 00:50:04,000 --> 00:50:08,000 e podo dicir algo en vez como estudantes [0] aquí. 922 00:50:08,000 --> 00:50:11,000 Podo, entón, dicir que os alumnos [0] aquí, 923 00:50:11,000 --> 00:50:14,000 alumnos [0] aquí, e así por diante, e podo saír por aí 924 00:50:14,000 --> 00:50:16,000 e limpar isto para Rob. 925 00:50:16,000 --> 00:50:19,000 Eu tamén podería ir sobre agora quizais engadindo un loop 926 00:50:19,000 --> 00:50:23,000 e usando GetString e GetInt para realmente obter estes valores do usuario. 927 00:50:23,000 --> 00:50:27,000 Eu podería ir sobre como engadir unha constante, porque esta é xeralmente mala práctica 928 00:50:27,000 --> 00:50:29,000 duro código algún número arbitrario como 3 aquí 929 00:50:29,000 --> 00:50:33,000 e lembre que ten que poñer máis de 3 alumnos na mesma. 930 00:50:33,000 --> 00:50:36,000 Probablemente sería mellor usar # define no principio do meu arquivo 931 00:50:36,000 --> 00:50:40,000 e factor que fóra, así, de feito, deixe-me ir adiante e xeneralizar iso. 932 00:50:40,000 --> 00:50:43,000 >> Deixe-me abrir un exemplo que está entre os de hoxe 933 00:50:43,000 --> 00:50:46,000 exemplos de antelación, structs1. 934 00:50:46,000 --> 00:50:49,000 Este é un programa máis completo que utiliza # defínese aquí 935 00:50:49,000 --> 00:50:51,000 e di que imos ter 3 alumnos por defecto. 936 00:50:51,000 --> 00:50:54,000 Aquí estou declarando un valor clase de estudantes, 937 00:50:54,000 --> 00:50:57,000 para unha aula de alumnos, e agora está a usar un loop 938 00:50:57,000 --> 00:51:00,000 só para facer o código un pouco máis elegante, encher a clase 939 00:51:00,000 --> 00:51:05,000 coa entrada do usuario, de xeito iterar a partir de i = 0 encima para os alumnos, que é 3. 940 00:51:05,000 --> 00:51:07,000 E entón eu pedir que o usuario nesta versión 941 00:51:07,000 --> 00:51:10,000  o que é o ID do alumno, e eu fico con GetInt. 942 00:51:10,000 --> 00:51:13,000 Cal é o nome do alumno, e entón eu comezo coa GetString. 943 00:51:13,000 --> 00:51:15,000 O que é a casa do alumno? Recibe o con GetString. 944 00:51:15,000 --> 00:51:19,000 E entón no fondo aquí, eu simplemente decidir cambiar 945 00:51:19,000 --> 00:51:22,000 como eu estou imprimindo estes para fóra, e realmente usar un loop, 946 00:51:22,000 --> 00:51:24,000 E quen son eu imprimir? 947 00:51:24,000 --> 00:51:27,000 De acordo co comentario que eu estou imprimindo calquera en Mather, 948 00:51:27,000 --> 00:51:30,000 e iso para Rob e Tommy e así por diante, en realidade Tommy en Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy e David sería impreso no caso, pero como é que isto funciona? 950 00:51:34,000 --> 00:51:40,000 Nós non vimos esa función antes, pero dar un palpite sobre o que iso fai. 951 00:51:40,000 --> 00:51:42,000 Compara cadeas. 952 00:51:42,000 --> 00:51:45,000 >> É un pouco non obvio como se compara cordas pois verifica-se 953 00:51:45,000 --> 00:51:49,000 se volve 0 que significa que as cordas son iguais. 954 00:51:49,000 --> 00:51:53,000 Se volve a -1 que significa un vén antes do outro en orde alfabética, 955 00:51:53,000 --> 00:51:57,000 e se volve un que significa a palabra outro vén en orde alfabética 956 00:51:57,000 --> 00:52:00,000 antes do outro, e pode buscar en liña ou na páxina do home 957 00:52:00,000 --> 00:52:04,000 para ver exactamente cal é cal, pero todo iso está facendo agora é que está dicindo 958 00:52:04,000 --> 00:52:09,000 o [i]. casa é igual a "Mather" 959 00:52:09,000 --> 00:52:13,000 entón vai adiante e imprimir así e así é en Mather. 960 00:52:13,000 --> 00:52:16,000 Pero aquí está algo que non teña visto antes, e nós imos voltar a este. 961 00:52:16,000 --> 00:52:21,000 Non me lembro de algunha vez ter que facelo en calquera un dos meus programas. 962 00:52:21,000 --> 00:52:24,000 Libre aparentemente referíndose a memoria, liberando memoria, 963 00:52:24,000 --> 00:52:31,000 pero o que a memoria aparentemente estou liberando neste loop na parte inferior do programa? 964 00:52:31,000 --> 00:52:34,000 Parece que eu estou liberando nome dunha persoa 965 00:52:34,000 --> 00:52:37,000 e da casa dunha persoa, pero por que isto? 966 00:52:37,000 --> 00:52:41,000 >> Acontece que todas estas semanas que está a usar GetString 967 00:52:41,000 --> 00:52:45,000 temos está a introducir tipo de un erro en cada un dos seus programas. 968 00:52:45,000 --> 00:52:51,000 GetString pola memoria aloca proxecto para que poida voltar a vostede unha cadea, 969 00:52:51,000 --> 00:52:55,000 como David, ou Rob, e entón pode facer o que quere 970 00:52:55,000 --> 00:52:59,000 con esa secuencia no seu programa porque temos a memoria reservada para ti. 971 00:52:59,000 --> 00:53:02,000 O problema é todo ese tempo cada vez que chamar GetString 972 00:53:02,000 --> 00:53:05,000 nós, os autores de GetString, teñen que chegou a pedir o sistema operativo 973 00:53:05,000 --> 00:53:07,000 para dar un pouco de memoria RAM para esta cadea. 974 00:53:07,000 --> 00:53:09,000 Deixa-nos un pouco de memoria RAM para esta próxima corda. 975 00:53:09,000 --> 00:53:11,000 Deixa-nos un pouco máis de memoria RAM para esta secuencia seguinte. 976 00:53:11,000 --> 00:53:13,000 O que, programador, nunca foron facendo 977 00:53:13,000 --> 00:53:15,000 está nos dando de volta a memoria, 978 00:53:15,000 --> 00:53:17,000 así a estas semanas todos os programas que escribiu 979 00:53:17,000 --> 00:53:20,000 ter o que se chama un salto de memoria en que eles seguen a usar 980 00:53:20,000 --> 00:53:24,000 máis memoria e máis cada vez que chamar GetString, e iso é bo. 981 00:53:24,000 --> 00:53:27,000 Nós deliberadamente facelo nas primeiras semanas, porque non é tan interesante 982 00:53:27,000 --> 00:53:29,000 ter que se preocupar con onde a corda está a benvida. 983 00:53:29,000 --> 00:53:34,000 Todo o que quere é a palabra Rob para volver cando o usuario escribe-lo dentro 984 00:53:34,000 --> 00:53:38,000 >> Pero avanzar agora temos que comezar a estar máis sofisticada sobre iso. 985 00:53:38,000 --> 00:53:42,000 A calquera momento que reservar memoria é mellor, eventualmente, entrega-lo de volta. 986 00:53:42,000 --> 00:53:45,000 En caso contrario, no mundo real no seu Mac ou PC, pode ter ocasionalmente experimentado 987 00:53:45,000 --> 00:53:50,000 síntomas onde o ordenador está a piques de paralizar eventualmente 988 00:53:50,000 --> 00:53:54,000 ou o balón de praia parvo fiación só ocupando o ordenador 989 00:53:54,000 --> 00:53:56,000 toda a atención e non pode facer as cousas. 990 00:53:56,000 --> 00:54:00,000 Isto pode ser explicado por unha serie de erros, pero entre os posibles erros 991 00:54:00,000 --> 00:54:03,000 son cousas chamadas derrames de memoria en que alguén que escribiu ese anaco de software 992 00:54:03,000 --> 00:54:07,000 que está a usar non se lembrar de memoria libre 993 00:54:07,000 --> 00:54:10,000 que el ou ela preguntou o sistema operativo para, 994 00:54:10,000 --> 00:54:14,000 non usar GetString, porque iso é unha cousa CS50, pero usando funcións similares 995 00:54:14,000 --> 00:54:16,000 que piden o sistema operativo para a memoria. 996 00:54:16,000 --> 00:54:19,000 Se vostede ou romper e nunca realmente volver que a memoria 997 00:54:19,000 --> 00:54:24,000 un síntoma de que pode ser un programa que retarda e reduce e retarda 998 00:54:24,000 --> 00:54:26,000 a menos que se lembrar de chamar libre. 999 00:54:26,000 --> 00:54:28,000 >> Nós imos voltar a cando e por que chamaría de libre, 1000 00:54:28,000 --> 00:54:32,000 pero imos adiante só para unha boa medida e intente realizar este programa en particular. 1001 00:54:32,000 --> 00:54:35,000 Isto foi chamado structs1, entrar. 1002 00:54:35,000 --> 00:54:40,000 Deixe-me ir adiante e executar structs1, 123, David Mather, 1003 00:54:40,000 --> 00:54:47,000 456, Rob Kirkland, 789, 1004 00:54:47,000 --> 00:54:50,000 Tommy Mather, e vemos David en Mather, Tommy en Mather. 1005 00:54:50,000 --> 00:54:53,000 Este é só unha proba de sanidade de que o programa está funcionando. 1006 00:54:53,000 --> 00:54:56,000 Agora, desgraciadamente, este programa é un pouco frustrante, en que 1007 00:54:56,000 --> 00:55:00,000 Eu fixen todo este traballo, eu escriba en nove distintos secuencias, prema Intro, 1008 00:55:00,000 --> 00:55:04,000 se dixo que estaba en Mather, pero, obviamente, eu sabía que estaba en Mather, porque eu xa escribiu. 1009 00:55:04,000 --> 00:55:07,000 Sería bo que, polo menos, este programa é máis como unha base de datos 1010 00:55:07,000 --> 00:55:10,000 e realmente se lembra do que eu escriba 1011 00:55:10,000 --> 00:55:12,000 entón eu nunca máis ter que introducir estes rexistros dos alumnos. 1012 00:55:12,000 --> 00:55:15,000 Quizais sexa como un sistema registrarial. 1013 00:55:15,000 --> 00:55:21,000 >> Podemos facelo empregando esta técnica coñecida como ficheiro de entrada de arquivo I / O, e de saída, 1014 00:55:21,000 --> 00:55:24,000 unha forma moi xenérica de dicir calquera momento que quere ler arquivos ou escribir arquivos 1015 00:55:24,000 --> 00:55:26,000 pode facelo cun determinado conxunto de funcións. 1016 00:55:26,000 --> 00:55:29,000 Deixe-me ir adiante e abrir este structs2.c exemplo, 1017 00:55:29,000 --> 00:55:33,000 que é case idéntico, pero imos ver o que fai agora. 1018 00:55:33,000 --> 00:55:36,000 No cumio do arquivo eu declaro unha clase de alumnos. 1019 00:55:36,000 --> 00:55:38,000 Eu, entón, encher a clase coa entrada do usuario, 1020 00:55:38,000 --> 00:55:41,000 para as liñas de código son exactamente como antes. 1021 00:55:41,000 --> 00:55:45,000 Entón, se eu rolar aquí eu imprimir os que están en Mather arbitrariamente como antes, 1022 00:55:45,000 --> 00:55:47,000 pero esta é unha novidade interesante. 1023 00:55:47,000 --> 00:55:51,000 Estas liñas de código son novos, e introdúcense algo aquí, 1024 00:55:51,000 --> 00:55:55,000 Arquivo, todas as tapas, e * aquí tamén. 1025 00:55:55,000 --> 00:55:58,000 Deixe-me pasar iso aquí, a * por aquí tamén. 1026 00:55:58,000 --> 00:56:00,000 >> Esta función non vimos antes, fopen, 1027 00:56:00,000 --> 00:56:03,000 pero significa ficheiro aberto, entón imos percorrer estes, 1028 00:56:03,000 --> 00:56:05,000 e iso é algo que nós imos voltar a serie de exercicios no futuro, 1029 00:56:05,000 --> 00:56:10,000 pero esta liña aquí, esencialmente, abre un arquivo chamado base de datos, 1030 00:56:10,000 --> 00:56:13,000 e específicamente ábrese a de tal forma que el pode facer o que con el? 1031 00:56:13,000 --> 00:56:15,000 [Inaudível-alumno] 1032 00:56:15,000 --> 00:56:19,000 Certo, entón "w" significa só que está dicindo o sistema operativo 1033 00:56:19,000 --> 00:56:21,000 abrir este ficheiro de tal forma que eu poida escribir para el. 1034 00:56:21,000 --> 00:56:23,000 Eu non quero le-lo. Eu non quero só ollar para el. 1035 00:56:23,000 --> 00:56:26,000 Eu quero cambiar isto e engadir cousas potencialmente a el, 1036 00:56:26,000 --> 00:56:28,000 eo arquivo vai ser chamado de base de datos. 1037 00:56:28,000 --> 00:56:30,000 Isto podería ser chamado nada. 1038 00:56:30,000 --> 00:56:32,000 Isto podería ser database.txt. Isto podería ser. DB. 1039 00:56:32,000 --> 00:56:37,000 Esta podería ser unha palabra como tal, pero eu arbitrariamente escolleu o nome da base de datos de arquivo. 1040 00:56:37,000 --> 00:56:42,000 Este é un exame de sanidade de que imos volver en gran detalle ao longo do tempo, 1041 00:56:42,000 --> 00:56:47,000 se fp, para punteiro do ficheiro, non NULL igual significa que todo está ben. 1042 00:56:47,000 --> 00:56:51,000 >> Longa historia curta, funcións como fopen ás veces fallan. 1043 00:56:51,000 --> 00:56:53,000 Quizais o ficheiro non existe. Quizais estea fóra do espazo de disco. 1044 00:56:53,000 --> 00:56:55,000 Quizais non ten permiso para esa carpeta, 1045 00:56:55,000 --> 00:56:58,000 por iso, se fopen retorna algo nulo de malo aconteceu. 1046 00:56:58,000 --> 00:57:02,000 Por outra banda, se fopen non volver nulo todo está ben 1047 00:57:02,000 --> 00:57:04,000 e podo comezar a escribir para este ficheiro. 1048 00:57:04,000 --> 00:57:06,000 Aquí está o truco novo. 1049 00:57:06,000 --> 00:57:08,000 Este é un loop que está interactuando sobre cada un dos meus alumnos, 1050 00:57:08,000 --> 00:57:10,000 e iso parece tan semellante ao que fixemos antes, 1051 00:57:10,000 --> 00:57:15,000 pero esta función é un primo do printf chamado fprintf para arquivo printf, 1052 00:57:15,000 --> 00:57:18,000 e entender que é diferente en só dous camiños. 1053 00:57:18,000 --> 00:57:20,000 Un deles, que comeza con f en vez de p, 1054 00:57:20,000 --> 00:57:23,000 pero entón o seu primeiro argumento é aparentemente o que? 1055 00:57:23,000 --> 00:57:25,000 [Os alumnos] do arquivo. >> É un arquivo. 1056 00:57:25,000 --> 00:57:30,000 Esa cousa chamada FP, que vai finalmente destrinçar o que é un punteiro do ficheiro, 1057 00:57:30,000 --> 00:57:35,000 pero por agora FP simplemente representa o arquivo que eu abri, 1058 00:57:35,000 --> 00:57:41,000 fprintf así aquí está dicindo imprimir ID de usuario para o ficheiro, non para a pantalla. 1059 00:57:41,000 --> 00:57:44,000 Imprimir o nome de usuario para o ficheiro, e non para a pantalla, 1060 00:57:44,000 --> 00:57:47,000 a casa para o arquivo, e non para a pantalla, e despois para abaixo aquí, obviamente, 1061 00:57:47,000 --> 00:57:50,000 Pecha o ficheiro, e despois para abaixo aquí libre da memoria. 1062 00:57:50,000 --> 00:57:53,000 >> A única diferenza entre esta versión ea versión 2 1 1063 00:57:53,000 --> 00:57:58,000 é a introdución de fopen e este arquivo con * 1064 00:57:58,000 --> 00:58:01,000 e esa noción de fprintf, entón imos ver o que o resultado final é. 1065 00:58:01,000 --> 00:58:03,000 Deixe-me ir para a miña xanela de terminal. 1066 00:58:03,000 --> 00:58:06,000 Déixame correr structs2, entrar. 1067 00:58:06,000 --> 00:58:09,000 Parece que todo está ben. Imos facer novo structs2. 1068 00:58:09,000 --> 00:58:15,000 123, David Mather, 456, Rob Kirkland, 1069 00:58:15,000 --> 00:58:19,000 789, Tommy Mather, entrar. 1070 00:58:19,000 --> 00:58:23,000 Parece que se comportou o mesmo, pero eu fago agora ls 1071 00:58:23,000 --> 00:58:28,000 entender o que está no arquivo aquí entre todo o meu código, base de datos, 1072 00:58:28,000 --> 00:58:32,000 entón imos abrir ese, ollar gedit de base de datos, e para iso. 1073 00:58:32,000 --> 00:58:34,000 Non é o máis sexy de formatos de ficheiro. 1074 00:58:34,000 --> 00:58:38,000 É realmente unha peza de liña de datos por liña por liña, 1075 00:58:38,000 --> 00:58:42,000 pero aqueles de vostedes que usan arquivos de Excel ou CSV, valores separados por comas, 1076 00:58:42,000 --> 00:58:47,000 Eu certamente podería usar fprintf ao contrario quizais facer algo así 1077 00:58:47,000 --> 00:58:50,000 para que eu puidese realmente crear o equivalente a un arquivo de Excel 1078 00:58:50,000 --> 00:58:53,000 separando as cousas con comas, e non só as novas liñas. 1079 00:58:53,000 --> 00:58:56,000 >> Neste caso, se eu tivese usado en vez comas en vez de novas liñas 1080 00:58:56,000 --> 00:59:01,000 Eu podería literalmente abrir este ficheiro de base de datos en Excel, se eu, no canto fixo parecer así. 1081 00:59:01,000 --> 00:59:03,000 En suma, agora que temos o poder de gardar arquivos 1082 00:59:03,000 --> 00:59:07,000 agora podemos comezar a persistencia de datos, mantendo-a en torno de disco 1083 00:59:07,000 --> 00:59:10,000 para que poidamos manter a información de novo e de novo. 1084 00:59:10,000 --> 00:59:14,000 Teña en conta un par de outras cousas que son agora un pouco máis familiar. 1085 00:59:14,000 --> 00:59:16,000 No cume deste arquivo C Temos un typedef 1086 00:59:16,000 --> 00:59:21,000 porque queriamos crear un tipo de datos que representa unha palabra, 1087 00:59:21,000 --> 00:59:25,000 de xeito que este tipo é chamado de palabra, e dentro desta estrutura 1088 00:59:25,000 --> 00:59:27,000 é un pouco afeccionado agora. 1089 00:59:27,000 --> 00:59:30,000 Porque é unha palabra composta de, ao parecer, unha matriz? 1090 00:59:30,000 --> 00:59:33,000 ¿Que é unha palabra só de forma intuitiva? 1091 00:59:33,000 --> 00:59:35,000 >> É unha matriz de caracteres. 1092 00:59:35,000 --> 00:59:37,000 É unha secuencia de caracteres de costas cara atrás. 1093 00:59:37,000 --> 00:59:41,000 Letras en todas as tapas pasa de ser nós arbitrariamente dicir o lonxitude máxima 1094 00:59:41,000 --> 00:59:44,000 de calquera palabra no dicionario que estamos usando para Scramble. 1095 00:59:44,000 --> 00:59:46,000 Por que eu teño un 1? 1096 00:59:46,000 --> 00:59:48,000 O personaxe nulo. 1097 00:59:48,000 --> 00:59:51,000 Lembre-se de cando fixemos o exemplo Bananagrams necesitabamos dun valor especial 1098 00:59:51,000 --> 00:59:55,000 no fin da palabra, a fin de manter a par 1099 00:59:55,000 --> 00:59:59,000 onde as palabras realmente acabou, e como a especificación do conxunto de problemas di 1100 00:59:59,000 --> 01:00:03,000 aquí estamos asociando con unha determinada palabra un valor booleano, 1101 01:00:03,000 --> 01:00:05,000 unha bandeira, por así dicir, verdadeira ou falsa. 1102 01:00:05,000 --> 01:00:09,000 Xa atopou esta palabra xa, porque entendemos 1103 01:00:09,000 --> 01:00:13,000 Nós realmente necesitamos un xeito de lembrar non só o que a palabra está no Scramble 1104 01:00:13,000 --> 01:00:15,000 pero se está ou non, o ser humano, teñen atopado 1105 01:00:15,000 --> 01:00:20,000 de xeito que se non atopa a palabra "o" non pode simplemente escribir o, entra a, entre a, insira 1106 01:00:20,000 --> 01:00:23,000 e obter 3 puntos, 3 puntos, 3 puntos, 3 puntos. 1107 01:00:23,000 --> 01:00:26,000 Queremos ser capaces de untar esa palabra definindo un bool 1108 01:00:26,000 --> 01:00:29,000 a verdade se xa atopou, e é por iso que nós 1109 01:00:29,000 --> 01:00:31,000 encapsulado na súa estrutura. 1110 01:00:31,000 --> 01:00:35,000 >> Agora, aquí no Scramble hai esa outra struct chamado dicionario. 1111 01:00:35,000 --> 01:00:39,000 Ausente aquí é a palabra typedef porque neste caso 1112 01:00:39,000 --> 01:00:43,000 necesitabamos para encapsular a idea dun dicionario, 1113 01:00:43,000 --> 01:00:46,000 e un dicionario contén unha morea de palabras, 1114 01:00:46,000 --> 01:00:49,000 como implicado por esta matriz, e cantas desas palabras están alí? 1115 01:00:49,000 --> 01:00:51,000 Ben, calquera que sexa deste tamaño variable chamada di. 1116 01:00:51,000 --> 01:00:53,000 Pero só necesitamos un dicionario. 1117 01:00:53,000 --> 01:00:55,000 Nós non precisamos dun tipo de datos chamado dicionario. 1118 01:00:55,000 --> 01:00:58,000 Nós só necesitamos un deles, por iso acaba en C 1119 01:00:58,000 --> 01:01:03,000 que, se non se typedef, acaba de dicir struct, a continuación, dentro das claves 1120 01:01:03,000 --> 01:01:05,000 poñer as súas variables, entón poñer o nome. 1121 01:01:05,000 --> 01:01:09,000 Este é declarar unha variable chamada dicionario 1122 01:01:09,000 --> 01:01:11,000 que se parece con isto. 1123 01:01:11,000 --> 01:01:16,000 Por outra banda, estas liñas son a creación dunha estrutura de datos reutilizable chamado palabra 1124 01:01:16,000 --> 01:01:19,000 que pode crear varias copias, así como creamos 1125 01:01:19,000 --> 01:01:22,000 varias copias de alumnos. 1126 01:01:22,000 --> 01:01:24,000 >> O que isto finalmente permitir que fagamos? 1127 01:01:24,000 --> 01:01:30,000 Deixe-me volver a, digamos, un exemplo máis simple a partir de tempos máis simple, 1128 01:01:30,000 --> 01:01:34,000 e deixe-me abrir-se, por exemplo, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 O problema aquí en mans é realmente casca de volta 1130 01:01:38,000 --> 01:01:41,000 a capa dunha corda e comezar a sacar esas Rodas pequenas 1131 01:01:41,000 --> 01:01:44,000 pois verifícase que unha secuencia de todo este tempo 1132 01:01:44,000 --> 01:01:47,000 é como prometemos a semana 1 só un apelido, 1133 01:01:47,000 --> 01:01:51,000 un sinónimo da biblioteca CS50 por algo que parece un pouco máis crítico, 1134 01:01:51,000 --> 01:01:53,000 char *, e vimos esa estrela antes. 1135 01:01:53,000 --> 01:01:55,000 Vímolo no contexto de arquivos. 1136 01:01:55,000 --> 01:01:59,000 >> Imos ver agora porque estamos escondendo ese detalle xa hai algún tempo. 1137 01:01:59,000 --> 01:02:02,000 Aquí está un arquivo chamado compare1.c, 1138 01:02:02,000 --> 01:02:07,000 e, ao parecer, pide ao usuario para dúas cordas, S e T, 1139 01:02:07,000 --> 01:02:11,000 e entón intenta comparar esas cordas de igualdade na liña 26, 1140 01:02:11,000 --> 01:02:14,000 e se son iguais el di: "Inseriu o mesmo", 1141 01:02:14,000 --> 01:02:17,000 e se eles non son iguais el di: "Inseriu cousas distintas." 1142 01:02:17,000 --> 01:02:19,000 Deixe-me ir adiante e executar este programa. 1143 01:02:19,000 --> 01:02:23,000 Deixe-me ir para o meu directorio de orixe, facer unha compare1. El compilou todo ben. 1144 01:02:23,000 --> 01:02:25,000 Déixame correr compare1. 1145 01:02:25,000 --> 01:02:27,000 Vou aumentar o zoom, entrar. 1146 01:02:27,000 --> 01:02:29,000 Diga algo. OLA. 1147 01:02:29,000 --> 01:02:32,000 Eu vou dicir algo novo. OLA. 1148 01:02:32,000 --> 01:02:34,000 Eu definitivamente non escriba cousas distintas. 1149 01:02:34,000 --> 01:02:37,000 >> Deixe-me tentar de novo. Bye Bye. 1150 01:02:37,000 --> 01:02:40,000 En definitiva non é diferente, por iso o que está a suceder aquí? 1151 01:02:40,000 --> 01:02:44,000 Ben, o que realmente está a ser comparado en liña 26? 1152 01:02:44,000 --> 01:02:46,000 [Inaudível-alumno] 1153 01:02:46,000 --> 01:02:49,000 Si, entón dedúcese que unha cadea, tipo de datos, é un tipo de mentira. 1154 01:02:49,000 --> 01:02:53,000 Unha cadea é un char *, pero o que é un char *? 1155 01:02:53,000 --> 01:02:56,000 A * char, como eles din, é un punteiro, 1156 01:02:56,000 --> 01:03:00,000 e un punteiro é efectivamente un enderezo, 1157 01:03:00,000 --> 01:03:05,000 suma un lugar na memoria, e se ocorrer de que vostede escriba unha palabra como OLA, 1158 01:03:05,000 --> 01:03:08,000 Recordo de discusións pasadas de cordas 1159 01:03:08,000 --> 01:03:16,000 Isto é como a palabra OLA. 1160 01:03:16,000 --> 01:03:19,000 Lembre que unha palabra como OLA pode ser representado 1161 01:03:19,000 --> 01:03:22,000 como unha matriz de caracteres como esta 1162 01:03:22,000 --> 01:03:25,000 e despois con un carácter especial ao final chamou o carácter nulo, 1163 01:03:25,000 --> 01:03:27,000 como o denota \. 1164 01:03:27,000 --> 01:03:29,000 O que é realmente unha cadea? 1165 01:03:29,000 --> 01:03:32,000 Nótese que isto é varios anacos de memoria, 1166 01:03:32,000 --> 01:03:36,000 e, de feito, o fin do que é coñecido só cando ollar a través de toda a cadea 1167 01:03:36,000 --> 01:03:38,000 ollando para o carácter nulo especial. 1168 01:03:38,000 --> 01:03:41,000 Pero este é un anaco da memoria a memoria do meu ordenador, 1169 01:03:41,000 --> 01:03:44,000 imos arbitrariamente dicir que esa secuencia de só tivo sorte, 1170 01:03:44,000 --> 01:03:47,000 e foi colocado no inicio de RAM do meu ordenador. 1171 01:03:47,000 --> 01:03:54,000 Este é o byte 0, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> Cando digo algo así como GetString e eu cadea s = GetString 1173 01:04:02,000 --> 01:04:04,000 o que realmente está a ser devolto? 1174 01:04:04,000 --> 01:04:08,000 Para estas últimas semanas, o que realmente está a ser almacenado en s 1175 01:04:08,000 --> 01:04:13,000 non é esa secuencia de per se, pero neste caso o que está a ser almacenado é 1176 01:04:13,000 --> 01:04:18,000 o número 0, porque o que realmente fai GetString 1177 01:04:18,000 --> 01:04:20,000 é que fisicamente non voltar a cadea. 1178 01:04:20,000 --> 01:04:22,000 Que nin sequera realmente ten sentido conceptual. 1179 01:04:22,000 --> 01:04:24,000 O que fai de retorno é un número. 1180 01:04:24,000 --> 01:04:28,000 Ese número é o enderezo OLA na memoria, 1181 01:04:28,000 --> 01:04:32,000 e cadea s, a continuación, se pelar esta capa, cadea non existe realmente. 1182 01:04:32,000 --> 01:04:35,000 É só unha simplificación na biblioteca CS50. 1183 01:04:35,000 --> 01:04:38,000 >> Isto realmente é algo chamado char *. 1184 01:04:38,000 --> 01:04:41,000 Char ten sentido, porque o que é unha palabra, como OLA? 1185 01:04:41,000 --> 01:04:44,000 Ben, é unha serie de caracteres, unha serie de personaxes. 1186 01:04:44,000 --> 01:04:47,000 Char * significa que o enderezo dun personaxe, 1187 01:04:47,000 --> 01:04:50,000 Entón, o que iso supón para voltar a cadea? 1188 01:04:50,000 --> 01:04:53,000 Unha forma agradable, sinxelo de retornar unha cadea 1189 01:04:53,000 --> 01:04:57,000 é mellor que tentar descubrir como eu volver a 5 ou 6 bytes diferentes 1190 01:04:57,000 --> 01:05:01,000 deixe-me volver ao enderezo que byte? 1191 01:05:01,000 --> 01:05:03,000 O primeiro. 1192 01:05:03,000 --> 01:05:06,000 Noutras palabras, deixe-me dar-lle a dirección dun personaxe na memoria. 1193 01:05:06,000 --> 01:05:10,000 Isto é o que representa char *, unha dirección dun único carácter na memoria. 1194 01:05:10,000 --> 01:05:12,000 Chama iso é variable. 1195 01:05:12,000 --> 01:05:15,000 Tenda en s que determinado enderezo, o que eu dixen é arbitrariamente 0, 1196 01:05:15,000 --> 01:05:19,000 só para manter as cousas simples, pero en realidade el é xeralmente un número maior. 1197 01:05:19,000 --> 01:05:21,000 >> Espere un minuto. 1198 01:05:21,000 --> 01:05:23,000 Se só está me dando o enderezo do primeiro carácter, como sei que o enderezo é 1199 01:05:23,000 --> 01:05:25,000 do segundo personaxe, o terceiro, o cuarto eo quinto? 1200 01:05:25,000 --> 01:05:27,000 [Inaudível-alumno] 1201 01:05:27,000 --> 01:05:31,000 Só sabe que o fin da secuencia é por medio deste truco práctico, 1202 01:05:31,000 --> 01:05:35,000 Entón, cando usa algo así como printf, o que printf literalmente toma como argumento, 1203 01:05:35,000 --> 01:05:39,000 Recordamos que usan este espazo reservado% s, e entón pasa 1204 01:05:39,000 --> 01:05:41,000 a variable que está almacenando unha cadea. 1205 01:05:41,000 --> 01:05:47,000 O que realmente está pasando é o enderezo do primeiro carácter desa secuencia. 1206 01:05:47,000 --> 01:05:50,000 Printf entón usa un lazo ou bucle while, ao recibir este enderezo, 1207 01:05:50,000 --> 01:05:53,000 por exemplo, 0, entón deixe-me facelo agora, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n" s); 1209 01:06:02,000 --> 01:06:07,000 Cando eu chamo printf ("% s \ n" s), o que realmente estou dando printf con 1210 01:06:07,000 --> 01:06:13,000 é o enderezo do primeiro caracter en s, o cal, neste caso, é arbitraria H. 1211 01:06:13,000 --> 01:06:16,000 >> Como se sabe exactamente o que printf para amosar na pantalla? 1212 01:06:16,000 --> 01:06:19,000 A persoa que aplicou printf aplicou un loop while ou un loop 1213 01:06:19,000 --> 01:06:23,000 que di que este personaxe igualar o carácter nulo especial? 1214 01:06:23,000 --> 01:06:25,000 Se non, imprimir lo. Que tal un regalo? 1215 01:06:25,000 --> 01:06:28,000 Se non imprimir lo, imprimir lo, imprimir lo, imprimir lo. 1216 01:06:28,000 --> 01:06:32,000 Oh, este é especial. Interromper a impresión e voltar para o usuario. 1217 01:06:32,000 --> 01:06:35,000 E iso é, literalmente, todo o que está a suceder debaixo do capó, 1218 01:06:35,000 --> 01:06:38,000 e iso é moita cousa para dixerir, o primeiro día dunha clase, 1219 01:06:38,000 --> 01:06:43,000 pero por agora é realmente o alicerce de todo comprensión 1220 01:06:43,000 --> 01:06:46,000 que está a suceder dentro da memoria do noso ordenador, 1221 01:06:46,000 --> 01:06:49,000 e, finalmente, imos provocar este apart cunha pequena axuda 1222 01:06:49,000 --> 01:06:51,000 dun dos nosos amigos en Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> Profesor Nick parlante en Stanford fixo esta secuencia marabilloso vídeo 1224 01:06:56,000 --> 01:06:58,000 de todo tipo de linguas diferentes que introduciron 1225 01:06:58,000 --> 01:07:00,000 Binky este pequeno personaxe Claymation. 1226 01:07:00,000 --> 01:07:03,000 A voz que está a piques de escoitar en apenas uns previa segunda 1227 01:07:03,000 --> 01:07:05,000 é a dun profesor de Stanford, e está quedando 1228 01:07:05,000 --> 01:07:07,000 só 5 ou 6 segundos de que agora, 1229 01:07:07,000 --> 01:07:09,000 pero esta é a nota que imos terminar hoxe 1230 01:07:09,000 --> 01:07:11,000 e comezar o mércores. 1231 01:07:11,000 --> 01:07:15,000 Eu darlle Fun Pointer con Binky, a visualización. 1232 01:07:15,000 --> 01:07:18,000 [♪ ♪ Música] [Profesor parlante] Ei, Binky. 1233 01:07:18,000 --> 01:07:21,000 Espertar. É hora de diversión punteiro. 1234 01:07:21,000 --> 01:07:24,000 [Binky] O que é isto? Máis información sobre punteiros? 1235 01:07:24,000 --> 01:07:26,000 Ah, bo! 1236 01:07:26,000 --> 01:07:29,000 >> Imos velo o mércores. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]