1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [Sección 5: menos cómodo] 2 00:00:02,730 --> 00:00:05,180 [Nate Hardison, Harvard University] 3 00:00:05,180 --> 00:00:08,260 [Esta é CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Entón Benvido de volta, rapaces. 5 00:00:11,690 --> 00:00:16,320 Benvido á sección 5. 6 00:00:16,320 --> 00:00:20,220 Neste punto, completando cuestionario 0 e vendo como fixo, 7 00:00:20,220 --> 00:00:25,770 espero que se sentir realmente ben, porque eu estaba moi impresionado coa puntuación nesta sección. 8 00:00:25,770 --> 00:00:28,050 Para os nosos espectadores en liña, tivemos un par de preguntas 9 00:00:28,050 --> 00:00:33,680 sobre os dous últimos problemas no conxunto de problemas - ou no cuestionario, en vez. 10 00:00:33,680 --> 00:00:39,690 Entón, nós estamos indo ir sobre os moi rapidamente, de xeito que todo o mundo ve o que pasou 11 00:00:39,690 --> 00:00:45,060 e como ir a través da solución real e non só ver a solución en si. 12 00:00:45,060 --> 00:00:50,330 Nós imos pasar por riba o último par de problemas moi rapidamente, 32 e 33. 13 00:00:50,330 --> 00:00:53,240 Así, unha vez máis, para que os espectadores en liña pode ver iso. 14 00:00:53,240 --> 00:00:59,080 >> Se conectar ao seu problema 32, que está na páxina 13, 15 00:00:59,080 --> 00:01:02,730 13 de 16, problema 32 é todo sobre swaps. 16 00:01:02,730 --> 00:01:05,010 Era todo sobre o intercambio de dous enteiros. 17 00:01:05,010 --> 00:01:08,740 É o problema que fora durante un par de veces en charla. 18 00:01:08,740 --> 00:01:13,590 E aquí, o que estabamos pedindo para facer é un trazo de memoria rápida. 19 00:01:13,590 --> 00:01:17,000 Para cubrir os valores das variables que están na pila 20 00:01:17,000 --> 00:01:20,250 como o código pasa por esta función de intercambio. 21 00:01:20,250 --> 00:01:24,500 En particular, o que nós estamos mirando - eu vou poñer este iPad cara abaixo - 22 00:01:24,500 --> 00:01:29,650 en particular, o que estamos vendo é esta liña numerada 6 aquí. 23 00:01:29,650 --> 00:01:36,740 E é numerada 6 por só contiguidade co problema anterior. 24 00:01:36,740 --> 00:01:41,720 O que queremos facer é amosar ou etiquetar o estado da memoria 25 00:01:41,720 --> 00:01:46,090 como é na altura en que se executa este número da liña 6, 26 00:01:46,090 --> 00:01:52,540 que é efectivamente un retorno da nosa función de intercambio aquí. 27 00:01:52,540 --> 00:01:59,450 Se rolar aquí, vimos que os enderezos de todo na memoria foi subministrado por nós. 28 00:01:59,450 --> 00:02:02,540 Iso é moi fundamental, nós imos volver a el en só un momento. 29 00:02:02,540 --> 00:02:09,240 E entón, aquí abaixo, na parte inferior, tivemos un diagrama de pouca memoria que imos referir. 30 00:02:09,240 --> 00:02:12,490 Eu realmente fixen iso no meu iPad. 31 00:02:12,490 --> 00:02:20,720 Entón, eu estou indo a cambiar rapidamente entre o iPad e este código só para referencia. 32 00:02:20,720 --> 00:02:26,540 >> Imos comezar. En primeiro lugar, imos nos centrarse no primeiro par de liñas de inicio aquí. 33 00:02:26,540 --> 00:02:30,220 Para comezar, imos iniciar x e y a 1 a 2. 34 00:02:30,220 --> 00:02:33,040 Polo tanto, temos dúas variables enteiras, ambos están indo para ser colocado na pila. 35 00:02:33,040 --> 00:02:36,050 Nós imos poñer un 1 e un 2 neles. 36 00:02:36,050 --> 00:02:43,150 Entón, se eu virar para o meu iPad, esperamos, imos ver - 37 00:02:43,150 --> 00:02:48,660 Apple espelhamento de TV, e alí imos nós. Okay. 38 00:02:48,660 --> 00:02:51,670 Entón, se eu virar para o meu iPad, 39 00:02:51,670 --> 00:02:56,220 Eu quero iniciar x e y a 1 a 2. 40 00:02:56,220 --> 00:03:00,580 Facemos isto simplemente escribindo un 1 no cadro marcada x 41 00:03:00,580 --> 00:03:07,730 e un 2 na caixa marcada y. Moi sinxelo. 42 00:03:07,730 --> 00:03:11,620 Entón agora imos volver para o portátil, ver o que acontece. 43 00:03:11,620 --> 00:03:15,810 Entón esta liña seguinte é onde as cousas están complicadas. 44 00:03:15,810 --> 00:03:28,110 Nós pasar o enderezo de x e y o enderezo de como os parámetros a e b para a función de cambio. 45 00:03:28,110 --> 00:03:32,380 O enderezo de x é o enderezo de y son cousas que non podemos calcular 46 00:03:32,380 --> 00:03:36,360 sen referirse a estes bala apunta cara á dereita aquí. 47 00:03:36,360 --> 00:03:39,750 E, por sorte, os dous primeiros puntos de bala nos dicir exactamente cales son as respostas. 48 00:03:39,750 --> 00:03:44,740 O enderezo de memoria x 10, e o seu enderezo na memoria y é 14. 49 00:03:44,740 --> 00:03:51,870 Entón eses son os valores que son pasados ​​como a e b enriba da nosa función de intercambio. 50 00:03:51,870 --> 00:04:00,760 Entón, de novo, voltar para o noso diagrama, podo escribir un 10 nun 51 00:04:00,760 --> 00:04:07,400 e 14 un en b. 52 00:04:07,400 --> 00:04:11,610 Agora, este punto é onde nós continuar co cambio. 53 00:04:11,610 --> 00:04:14,520 Entón, lanzando ao seu portátil de novo, 54 00:04:14,520 --> 00:04:21,079 vemos que a forma na que o intercambio funciona é que dereference primeiro unha tenda e o resultado en tmp. 55 00:04:21,079 --> 00:04:27,650 Así, o operador dereference di, "Hey. Tratar o contido dunha variable como un enderezo. 56 00:04:27,650 --> 00:04:33,830 Ir para o que está almacenado naquel enderezo, e cargalo. " 57 00:04:33,830 --> 00:04:41,720 O que leva a fóra da variable que vai ser almacenado na nosa variable tmp. 58 00:04:41,720 --> 00:04:45,150 Lanzando ao seu iPad. 59 00:04:45,150 --> 00:04:51,690 Ou tamén para tratar 10, sabemos que é o enderezo de 10 x varible 60 00:04:51,690 --> 00:04:55,480 porque foi dito polo noso punto de bala que o enderezo de x en memoria é 10. 61 00:04:55,480 --> 00:05:00,180 Entón, podemos ir alí, incorporarse o valor do mesmo, o que é un, como podemos ver no noso iPad, 62 00:05:00,180 --> 00:05:06,300 e cargar isto tmp. 63 00:05:06,300 --> 00:05:08,250 De novo, isto non é o contido final. 64 00:05:08,250 --> 00:05:14,350 Nós imos camiñar e nós imos chegar ao noso estado final do programa no final. 65 00:05:14,350 --> 00:05:17,210 Pero agora temos o valor almacenado nun tmp. 66 00:05:17,210 --> 00:05:19,210 >> E hai unha pregunta rápida aquí. 67 00:05:19,210 --> 00:05:23,980 [Alexander] é o operador dereference - que é só o dereito de estrela na fronte da variable? 68 00:05:23,980 --> 00:05:27,600 Si >>. Así, o operador dereference, como virar de volta para o noso portátil, unha vez máis, 69 00:05:27,600 --> 00:05:33,780 é esta estrela fronte. 70 00:05:33,780 --> 00:05:37,460 Nese sentido, é - vostede comparalos-lo co seu fornecedor de multiplicación 71 00:05:37,460 --> 00:05:42,400 que require dúas cousas: o operador dereference é un operador unário. 72 00:05:42,400 --> 00:05:46,130 Só aplicada a un valor, por oposición a un operador binario, 73 00:05:46,130 --> 00:05:48,810 onde aplica a dous valores distintos. 74 00:05:48,810 --> 00:05:52,080 Entón, iso é o que pasa nesta liña. 75 00:05:52,080 --> 00:05:58,390 Nós cargados o valor 1 e é almacenado no noso variable temporal enteiro. 76 00:05:58,390 --> 00:06:05,800 A seguinte liña, gardados o contido b - 77 00:06:05,800 --> 00:06:12,630 ou, en vez diso, almacenar o contido que B está a apuntar cara o lugar onde un está a apuntar. 78 00:06:12,630 --> 00:06:17,690 Se analizamos este da dereita para a esquerda, imos b dereference, 79 00:06:17,690 --> 00:06:23,580 imos abordar 14, imos pegar o número enteiro que está aí, 80 00:06:23,580 --> 00:06:26,900 e entón nós estamos indo para ir ao enderezo 10, 81 00:06:26,900 --> 00:06:34,240 e imos xogar o resultado da nosa dereference de b en que o espazo. 82 00:06:34,240 --> 00:06:40,080 Lanzando de volta ao noso iPad, onde podemos facelo un pouco máis concreto, 83 00:06:40,080 --> 00:06:44,070 que podería axudar se eu escribir números en todos os enderezos aquí. 84 00:06:44,070 --> 00:06:53,820 Entón, nós sabemos que, y, estamos no enderezo 14, x está no enderezo 10. 85 00:06:53,820 --> 00:07:00,180 Cando comezamos a B, B dereference, imos pegar o valor 2. 86 00:07:00,180 --> 00:07:08,320 Nós imos ir ese valor porque ese é o valor que vive no enderezo 14. 87 00:07:08,320 --> 00:07:15,700 E nós imos poñelas na variable que vive no enderezo 10, 88 00:07:15,700 --> 00:07:19,160 que está alí, correspondente á nosa variable x. 89 00:07:19,160 --> 00:07:21,810 Así, podemos facer un pouco de sobreescribir aquí 90 00:07:21,810 --> 00:07:35,380 onde imos nos librar do noso 1 e en vez diso, escriba unha 2. 91 00:07:35,380 --> 00:07:39,560 Entón está todo ben e bo no mundo, aínda que teñamos x sobres agora. 92 00:07:39,560 --> 00:07:44,890 Temos almacenados valor antigo de x na nosa variable tmp. 93 00:07:44,890 --> 00:07:50,210 Así, podemos completar a cambio a liña seguinte. 94 00:07:50,210 --> 00:07:53,030 Lanzando de novo o noso portátil. 95 00:07:53,030 --> 00:07:58,150 Agora todo o que queda é levar o contido da nosa variable temporal enteiro 96 00:07:58,150 --> 00:08:05,630 e almacena-los na variable que vive no enderezo que B está seguro. 97 00:08:05,630 --> 00:08:10,230 Entón, nós imos efectivamente b dereference para obter acceso á variable 98 00:08:10,230 --> 00:08:14,340 é dicir, no enderezo que b ten nel, 99 00:08:14,340 --> 00:08:19,190 e nós imos encher o valor que tmp está seguro para el. 100 00:08:19,190 --> 00:08:23,280 Lanzando ao seu iPad unha vez. 101 00:08:23,280 --> 00:08:31,290 Eu podo borrar este valor aquí, 2, 102 00:08:31,290 --> 00:08:41,010 e en vez diso imos copiar o dereito un para el. 103 00:08:41,010 --> 00:08:43,059 A continuación, a seguinte liña que executa, por suposto - 104 00:08:43,059 --> 00:08:47,150 se jogarmos ao seu portátil - é este o punto 6, 105 00:08:47,150 --> 00:08:52,500 que é o momento en que nós queriamos ter o noso diagrama completo cuberto. 106 00:08:52,500 --> 00:08:58,940 Entón, lanzando ao seu iPad, unha vez máis, só así pode ver o diagrama completo, 107 00:08:58,940 --> 00:09:06,610 podes ver que temos un 10 nun 14 en un B, a 1 tmp, un 2 en x, e un 1 en y. 108 00:09:06,610 --> 00:09:11,000 Hai algunha dúbida sobre iso? 109 00:09:11,000 --> 00:09:14,640 Será que isto fai máis sentido, tendo orientado por ela? 110 00:09:14,640 --> 00:09:24,850 Facer menos sentido? Esperemos que non. Okay. 111 00:09:24,850 --> 00:09:28,230 >> Os punteiros son un tema moi complicado. 112 00:09:28,230 --> 00:09:33,420 Un dos caras que traballan con ten un dito moi común: 113 00:09:33,420 --> 00:09:36,590 "Para entender os punteiros, ten que primeiro entender os punteiros". 114 00:09:36,590 --> 00:09:40,530 Que eu creo que é moi certo. Fai levar un pouco para acostumar con iso. 115 00:09:40,530 --> 00:09:45,360 Sorteo de fotos, sorteo de diagramas de memoria como esta son moi útil, 116 00:09:45,360 --> 00:09:49,480 e despois de andar por exemplo tras exemplo tras exemplo, 117 00:09:49,480 --> 00:09:54,450 vai comezar a ter sentido un pouco máis e sentido un pouco máis e un pouco máis de sentido. 118 00:09:54,450 --> 00:10:01,560 Finalmente, un día, vai ter todo completamente dominado. 119 00:10:01,560 --> 00:10:13,800 Calquera dúbida, antes de pasar ao seguinte problema? Todo ben. 120 00:10:13,800 --> 00:10:18,840 Entón Xire cara atrás para o portátil. 121 00:10:18,840 --> 00:10:23,300 O seguinte problema que temos é o problema número 33 na lista de I / O. 122 00:10:23,300 --> 00:10:26,350 Zoom sobre iso un pouco. 123 00:10:26,350 --> 00:10:28,710 Problema 33 - Si? 124 00:10:28,710 --> 00:10:32,110 >> [Daniel] Eu só tiña unha pregunta rápida. Esta estrela, ou o asterisco, 125 00:10:32,110 --> 00:10:35,590 é chamado dereferencing cando usa un asterisco antes. 126 00:10:35,590 --> 00:10:38,820 Como se chama cando usa o comercial antes? 127 00:10:38,820 --> 00:10:43,140 >> O comercial antes é o enderezo do operador. 128 00:10:43,140 --> 00:10:45,880 Entón, imos rodar de volta. 129 00:10:45,880 --> 00:10:49,310 Oops. Eu estou no modo de zoom, non podo realmente desprazamento. 130 00:10:49,310 --> 00:10:52,780 Se olharmos para este código realmente rápido aquí, 131 00:10:52,780 --> 00:10:54,980 de novo, a mesma cousa suceder. 132 00:10:54,980 --> 00:10:59,180 Se olharmos para este código aquí, nesta liña onde facemos unha chamada para intercambiar, 133 00:10:59,180 --> 00:11:10,460 o comercial é só dicir "obter o enderezo no que vive a variable x." 134 00:11:10,460 --> 00:11:14,460 Cando o compilador compilar código, 135 00:11:14,460 --> 00:11:20,590 ten que fisicamente marcar un lugar na memoria de todos os seus variables para vivir. 136 00:11:20,590 --> 00:11:24,910 E así que o compilador pode entón facer unha vez que está feita de todo, 137 00:11:24,910 --> 00:11:31,110 el sabe, "Oh, eu coloque no enderezo x 10. coloque y no enderezo 14." 138 00:11:31,110 --> 00:11:34,640 Pode, entón, encher estes valores para ti. 139 00:11:34,640 --> 00:11:44,740 Así, pode entón - pode pasar este e pase & y no ben. 140 00:11:44,740 --> 00:11:50,730 Eses faces obter o enderezo, pero tamén, cando paso-los para a función de intercambio, 141 00:11:50,730 --> 00:11:55,690 este tipo de información, este int * aquí, di o compilador, 142 00:11:55,690 --> 00:12:01,350 "Ok, imos estar interpretando este enderezo como un enderezo dunha variable enteira." 143 00:12:01,350 --> 00:12:05,900 Como un enderezo de un número enteiro, que é distinto do enderezo de unha variable de caracteres 144 00:12:05,900 --> 00:12:09,930 porque un int toma-se en unha máquina de 32 bits, ocupa 4 bytes de espazo, 145 00:12:09,930 --> 00:12:13,310 mentres que un único personaxe ocupa 1 byte de espazo. 146 00:12:13,310 --> 00:12:17,310 Por iso, é importante saber tamén o que é - o que vive, o tipo de valor 147 00:12:17,310 --> 00:12:20,340 está a vivir no enderezo que foi pasado dentro 148 00:12:20,340 --> 00:12:22,020 Ou o que está lidando. 149 00:12:22,020 --> 00:12:29,020 Desta forma, vostede sabe cantos bytes de información para realmente levar a súa memoria RAM. 150 00:12:29,020 --> 00:12:31,780 E entón, si, este operador dereference, como se está preguntando: 151 00:12:31,780 --> 00:12:37,200 vai e accede a información nun enderezo particular. 152 00:12:37,200 --> 00:12:42,820 Por iso, di, con esta variable dun aquí, tratar o contido dun como enderezo, 153 00:12:42,820 --> 00:12:47,880 ir a este enderezo, e tirar, preme no procesador, a carga nun rexistrador 154 00:12:47,880 --> 00:12:56,340 os valores reais ou os contidos que viven aquel enderezo. 155 00:12:56,340 --> 00:12:59,620 Algunha pregunta? Estas son boas preguntas. 156 00:12:59,620 --> 00:13:01,650 É un monte de nova terminoloxía tamén. 157 00:13:01,650 --> 00:13:09,800 É tamén unha especie de funk, vendo & * e en diferentes lugares. 158 00:13:09,800 --> 00:13:13,180 >> Todo ben. 159 00:13:13,180 --> 00:13:18,530 Entón, de volta para o problema de 33, arquivo I / O. 160 00:13:18,530 --> 00:13:22,540 Este foi un dos problemas que eu creo que un par de cousas aconteceu. 161 00:13:22,540 --> 00:13:25,400 Un, é un tema relativamente novo. 162 00:13:25,400 --> 00:13:30,590 El foi presentado pouco antes da proba, 163 00:13:30,590 --> 00:13:33,400 e entón eu creo que foi máis ou menos como un dos problemas de palabras en matemáticas 164 00:13:33,400 --> 00:13:39,720 onde eles dan-lle unha morea de información, pero realmente non acabar tendo que usar unha tonelada do mesmo. 165 00:13:39,720 --> 00:13:44,060 A primeira parte deste problema está describindo o que é un ficheiro CSV. 166 00:13:44,060 --> 00:13:50,620 Agora, un arquivo CSV, de acordo coa descrición, é un arquivo separado por comas valores. 167 00:13:50,620 --> 00:13:55,300 A razón, son en todo interesante, ea razón pola que nunca usalos, 168 00:13:55,300 --> 00:14:00,800 é, pois, como moitos de vostedes xa usou o material como o Excel? 169 00:14:00,800 --> 00:14:03,240 Imaxe maioría de vostedes probablemente, ou vai utilizar nalgún momento da súa vida. 170 00:14:03,240 --> 00:14:06,430 Vai usar algo como o Excel. 171 00:14:06,430 --> 00:14:10,940 Co fin de obter os datos dunha folla de cálculo de Excel ou facer calquera tipo de tratamento con el, 172 00:14:10,940 --> 00:14:17,240 se quería escribir un programa en C ou Python programa, o programa Java, 173 00:14:17,240 --> 00:14:20,070 para xestionar os datos almacenados alí, 174 00:14:20,070 --> 00:14:23,170 unha das formas máis comúns para tiralo está nun ficheiro CSV. 175 00:14:23,170 --> 00:14:26,850 E pode abrir o Excel e cando vai cara á 'Gardar como' o diálogo, 176 00:14:26,850 --> 00:14:32,840 pode saír un arquivo CSV real. 177 00:14:32,840 --> 00:14:35,890 >> Útil para saber como tratar con isto. 178 00:14:35,890 --> 00:14:42,010 O modo como funciona é que é semellante a - Quero dicir, é esencialmente imitando unha folla, 179 00:14:42,010 --> 00:14:47,590 onde, como vemos aquí, na peza máis á esquerda, 180 00:14:47,590 --> 00:14:49,910 temos todos os últimos nomes. 181 00:14:49,910 --> 00:14:54,670 Así, temos Malan, entón Hardison, e, a continuación, Bowden, MacWilliam, e, a continuación, Chan. 182 00:14:54,670 --> 00:14:59,470 Todos os sobrenomes. E entón unha coma separa os apelidos dos primeiros nomes. 183 00:14:59,470 --> 00:15:02,970 David, Nate, Rob, Tommy, e Zamyla. 184 00:15:02,970 --> 00:15:06,850 Eu sempre mesturar Robby e Tom 185 00:15:06,850 --> 00:15:10,940 E, a continuación, finalmente, a terceira columna é o enderezo de e-mail. 186 00:15:10,940 --> 00:15:18,500 Despois de entender iso, o resto do programa é moi sinxelo de implementar. 187 00:15:18,500 --> 00:15:23,850 O que temos feito, a fin de imitar esa mesma estrutura no noso programa C 188 00:15:23,850 --> 00:15:27,510 é que usei unha estrutura. 189 00:15:27,510 --> 00:15:30,520 Imos comezar a xogar con estes un pouco tamén. 190 00:15:30,520 --> 00:15:35,790 Vimo-los para o primeiro bit pouco no conxunto de problemas 3, cando estabamos lidando con os dicionarios. 191 00:15:35,790 --> 00:15:40,290 Pero esa estrutura persoal almacena un último nome, un nome e un correo-e. 192 00:15:40,290 --> 00:15:44,500 Así como o noso arquivo CSV foi gardar. 193 00:15:44,500 --> 00:15:47,950 Polo tanto, esta é só a conversión dun formato a outro. 194 00:15:47,950 --> 00:15:54,630 Temos que converter, neste caso, unha estrutura persoal para unha liña, 195 00:15:54,630 --> 00:15:59,060 unha liña separada por comas, só como aquel. 196 00:15:59,060 --> 00:16:01,500 Isto ten sentido? Vostedes teñen todos levados ao cuestionario, 197 00:16:01,500 --> 00:16:07,680 entón eu imaxino que teña polo menos tivo moito tempo para pensar sobre iso. 198 00:16:07,680 --> 00:16:16,410 >> Na función de aluguer, o problema nos pide para tomar - zoom we'll sobre iso un pouco - 199 00:16:16,410 --> 00:16:22,480 tomar nunha estrutura de persoal, unha estrutura de persoal, co nome de s, 200 00:16:22,480 --> 00:16:30,900 e achegar o seu contido para o noso arquivo staff.csv. 201 00:16:30,900 --> 00:16:34,230 Acontece que iso é moi sinxelo de usar. 202 00:16:34,230 --> 00:16:37,430 Imos tipo de xogar con esas funcións hoxe un pouco máis. 203 00:16:37,430 --> 00:16:44,510 Pero, neste caso, a función fprintf é realmente a clave. 204 00:16:44,510 --> 00:16:51,960 Así, con fprintf, podemos imprimir, así como vostedes teñen benvida a utilizar este termo printf todo. 205 00:16:51,960 --> 00:16:55,050 Pode printf unha liña dun arquivo. 206 00:16:55,050 --> 00:16:59,030 Entón, en vez de só facer unha chamada de costume printf onde lle dá a el a cadea de formato 207 00:16:59,030 --> 00:17:05,380 e despois de substituír todas as variables cos seguintes argumentos, 208 00:17:05,380 --> 00:17:11,290 con fprintf, o seu argumento é moi primeira vez o ficheiro que quere gravar. 209 00:17:11,290 --> 00:17:21,170 Se estivésemos a mirar para iso no aparello, por exemplo, o home fprintf, 210 00:17:21,170 --> 00:17:25,980 podemos ver a diferenza entre o printf e fprintf. 211 00:17:25,980 --> 00:17:28,960 Vou ampliar un pouco aquí. 212 00:17:28,960 --> 00:17:33,140 Así, con printf, dar-lle unha secuencia de formato, e logo os argumentos seguintes 213 00:17:33,140 --> 00:17:37,580 son todas as variables para reposición ou substitución na nosa cadea de formato. 214 00:17:37,580 --> 00:17:47,310 Considerando que, con fprintf, o primeiro argumento é de feito ese * ficheiro chamado un córrego. 215 00:17:47,310 --> 00:17:51,800 >> Voltar aquí para a nosa contratación, 216 00:17:51,800 --> 00:17:54,550 nós xa temos o noso fluxo * ficheiro aberto para nós. 217 00:17:54,550 --> 00:17:57,810 Isto é o que fai esta primeira liña, que abre o ficheiro staff.csv, 218 00:17:57,810 --> 00:18:01,690 abre en modo incremental, e todo o que queda para nós é 219 00:18:01,690 --> 00:18:08,640 escribir a estrutura de persoal para o arquivo. 220 00:18:08,640 --> 00:18:10,870 E, imos ver, eu quero usar o iPad? 221 00:18:10,870 --> 00:18:17,900 Vou usar o iPad. Temos baleiro - imos poñer isto na mesa para que eu poida escribir un pouco mellor - 222 00:18:17,900 --> 00:18:33,680 anular a contratación e que leva, un argumento, unha estrutura de equipo chamado s. 223 00:18:33,680 --> 00:18:44,120 Temos os nosos aparellos, temos a nosa * ficheiro chamado ficheiro, 224 00:18:44,120 --> 00:18:48,380 Nós temos a nosa liña fopen dada a nós, 225 00:18:48,380 --> 00:18:51,890 e eu vou gravala-lo como puntos, unha vez que xa está no pedía. 226 00:18:51,890 --> 00:19:00,530 E entón, na nosa liña seguinte, imos facer unha chamada fprintf 227 00:19:00,530 --> 00:19:03,700 e imos pasar o arquivo que desexa imprimir, 228 00:19:03,700 --> 00:19:10,290 e entón a nosa cadea de formato, que - 229 00:19:10,290 --> 00:19:14,300 Eu vou deixar vostedes me dicir o que parece. 230 00:19:14,300 --> 00:19:20,500 E, Stella? Vostede sabe o que a primeira parte da cadea de formato parece? 231 00:19:20,500 --> 00:19:24,270 [Stella] Eu non estou seguro. Sinto-se a liberdade de >> pedir Jimmy. 232 00:19:24,270 --> 00:19:27,690 Sábese, Jimmy? 233 00:19:27,690 --> 00:19:31,000 [Jimmy] Sería só ser o último? Eu non sei. Eu non estou totalmente seguro. 234 00:19:31,000 --> 00:19:39,020 Ok >>. Que tal, será que alguén recibir este correcta no exame? 235 00:19:39,020 --> 00:19:41,770 Non Todo ben. 236 00:19:41,770 --> 00:19:47,920 Acontece que aquí todo o que temos que facer é que queremos cada parte do noso cadro de persoal 237 00:19:47,920 --> 00:19:53,290 para ser impreso como unha cadea na nosa arquivo. 238 00:19:53,290 --> 00:19:59,900 Nós só usar o personaxe substitución corda tres veces distintas, porque temos un apelido 239 00:19:59,900 --> 00:20:07,160 seguido por coma, un nome seguido dunha coma, 240 00:20:07,160 --> 00:20:12,430 e, finalmente, o seu enderezo de correo-e que é seguido - que non é 241 00:20:12,430 --> 00:20:15,140 encaixando na miña pantalla - pero é seguido por un carácter de nova liña. 242 00:20:15,140 --> 00:20:20,060 Entón eu vou escribir isto só alí en baixo. 243 00:20:20,060 --> 00:20:23,560 E entón, despois da nosa secuencia de formato, 244 00:20:23,560 --> 00:20:27,880 só temos as substitucións, que temos acceso mediante a notación de punto 245 00:20:27,880 --> 00:20:31,370 que vimos no conxunto de problemas 3. 246 00:20:31,370 --> 00:20:48,820 Podemos usar s.last, s.first e s.email 247 00:20:48,820 --> 00:20:58,990 para substituír os tres valores na nosa cadea de formato. 248 00:20:58,990 --> 00:21:06,190 Entón, como foi iso? Ten sentido? 249 00:21:06,190 --> 00:21:09,700 Si? Non? Posiblemente? Okay. 250 00:21:09,700 --> 00:21:14,180 >> A última cousa que facemos despois de que nós impreso e despois abrimos o noso arquivo: 251 00:21:14,180 --> 00:21:17,370 sempre que abriu un arquivo, temos sempre que lembrar pechalo. 252 00:21:17,370 --> 00:21:19,430 Porque, do contrario imos acabar vazando a memoria, 253 00:21:19,430 --> 00:21:22,500 utilizando-se descritores de ficheiros. 254 00:21:22,500 --> 00:21:25,950 Entón, para pecha-lo, que a función que imos usar? Daniel? 255 00:21:25,950 --> 00:21:30,120 [Daniel] fclose? >> Fclose, exactamente. 256 00:21:30,120 --> 00:21:37,520 Así, a última parte deste problema era pechar correctamente o ficheiro usando a función fclose, 257 00:21:37,520 --> 00:21:40,370 que só se parece con isto. 258 00:21:40,370 --> 00:21:43,880 Non é moi tolo. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Entón, iso é problema de 33 no cuestionario. 261 00:21:49,520 --> 00:21:52,480 Nós imos ter que arquivo definitivamente máis I / O chegando. 262 00:21:52,480 --> 00:21:55,130 Imos facer un pouco máis en charla hoxe, ou na sección de hoxe, 263 00:21:55,130 --> 00:22:01,710 porque é iso que vai formar a maior parte deste pset próximo. 264 00:22:01,710 --> 00:22:05,020 Imos seguir adiante dende o cuestionario neste momento. Si? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] Por que fclose (arquivo) no canto de fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 Ah >>. Porque sucede que - para a cuestión, que é un gran, 267 00:22:19,100 --> 00:22:27,800 É por iso que, cando escribimos fclose, estamos escribindo fclose estrela variable (arquivo) 268 00:22:27,800 --> 00:22:33,680 en oposición ao nome do ficheiro, staff.csv? Isto é correcta? Si 269 00:22:33,680 --> 00:22:39,570 Entón, imos dar un ollo. Se eu atrás para o meu portátil, 270 00:22:39,570 --> 00:22:45,040 e imos ollar para a función fclose. 271 00:22:45,040 --> 00:22:51,460 Así, a función fclose pecha un córrego e leva no punteiro para o fluxo de que desexa pechar 272 00:22:51,460 --> 00:22:57,010 en oposición ao nome real do ficheiro que desexa pechar. 273 00:22:57,010 --> 00:23:01,620 E isto porque, nos bastidores, cando fai unha chamada para fopen, 274 00:23:01,620 --> 00:23:12,020 cando abrir un ficheiro, está, de feito, a distribución de memoria para almacenar informacións sobre o arquivo. 275 00:23:12,020 --> 00:23:16,380 Entón tes un punteiro do ficheiro que contén información sobre o arquivo, 276 00:23:16,380 --> 00:23:23,080 como é aberto, o seu tamaño, onde está actualmente no arquivo, 277 00:23:23,080 --> 00:23:29,100 de modo que pode facer chamadas de lectura e escritura para aquel lugar especial dentro do arquivo. 278 00:23:29,100 --> 00:23:38,060 Vostede acaba de pechar o punteiro no canto de pechar o nome do ficheiro. 279 00:23:38,060 --> 00:23:48,990 >> Si? [Daniel] Polo tanto, a fin de utilizar de aluguer, diría que - como obter a entrada do usuario? 280 00:23:48,990 --> 00:23:53,830 O fprintf actuar como GetString no sentido de que el só vai esperar a entrada do usuario 281 00:23:53,830 --> 00:23:57,180 e pedir-lle para escribir isto - ou esperar para escribir estas tres cousas? 282 00:23:57,180 --> 00:24:00,480 Ou precisa de usar algo para aplicar aluguer? 283 00:24:00,480 --> 00:24:04,100 Si >>. Entón, nós non somos - a cuestión foi, como é que imos chegar a entrada do usuario 284 00:24:04,100 --> 00:24:09,220 a fin de implementar aluguer? E o que temos aquí é o chamador de aluguer, 285 00:24:09,220 --> 00:24:17,690 pasaron neste struct persoal con todos os datos almacenados na estrutura xa. 286 00:24:17,690 --> 00:24:22,990 Entón fprintf é capaz de escribir só que os datos directamente para o arquivo. 287 00:24:22,990 --> 00:24:25,690 Non hai espera para a entrada do usuario. 288 00:24:25,690 --> 00:24:32,110 O usuario xa está dada a entrada correctamente por poñelas nesa estrutura de persoal. 289 00:24:32,110 --> 00:24:36,510 E as cousas, por suposto, vai romper algún destes punteiros foron nulos, 290 00:24:36,510 --> 00:24:40,370 para que rolar para atrás ata aquí e miramos para a nosa estrutura. 291 00:24:40,370 --> 00:24:43,640 Temos cadea cadea ultimo primeiro, e-mail cadea. 292 00:24:43,640 --> 00:24:48,530 Agora sabemos que todos aqueles realmente, baixo o capo, son variables char *. 293 00:24:48,530 --> 00:24:53,470 Isto pode ou non pode estar apuntando para nulo. 294 00:24:53,470 --> 00:24:55,800 Poden estar apuntando para a memoria na pila, 295 00:24:55,800 --> 00:24:59,650 quizais memoria na pila. 296 00:24:59,650 --> 00:25:04,580 Nós realmente non sei, pero se calquera destes punteiros son nulos ou inválidos, 297 00:25:04,580 --> 00:25:08,120 que iso sempre vai fallar a nosa función de aluguer. 298 00:25:08,120 --> 00:25:11,050 Iso era algo que estaba medio fóra do alcance do exame. 299 00:25:11,050 --> 00:25:16,440 Non está preocupando con iso. 300 00:25:16,440 --> 00:25:22,170 Grande. Okay. Entón pasar do quiz. 301 00:25:22,170 --> 00:25:25,760 >> Imos pechar este cara, e nós estamos indo ollar pset 4. 302 00:25:25,760 --> 00:25:34,700 Entón, se vostedes ollar para a especificación pset, xa que pode acceder a ela, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 imos pasar por algúns dos problemas de hoxe da sección. 304 00:25:42,730 --> 00:25:52,240 Estou desprazamento cara abaixo - sección de preguntas comeza na terceira páxina da especificación pset. 305 00:25:52,240 --> 00:25:57,800 E a primeira parte pídelle para ir e ver o curta en redirixido e canos. 306 00:25:57,800 --> 00:26:02,820 Que era unha especie de curto legal, mostra-lle algúns trucos novos, frescos mando de liña que pode usar. 307 00:26:02,820 --> 00:26:06,050 E entón temos algunhas preguntas para ti tamén. 308 00:26:06,050 --> 00:26:10,860 Esta primeira pregunta sobre fluxos, para que printf escribe por defecto, 309 00:26:10,860 --> 00:26:15,920 que tipo de tocada en só un pouco de un momento atrás. 310 00:26:15,920 --> 00:26:22,380 Este fprintf que nós estabamos discutindo leva un fluxo de ficheiro * como o seu argumento. 311 00:26:22,380 --> 00:26:26,580 fclose leva un fluxo de ficheiro *, así como, 312 00:26:26,580 --> 00:26:32,660 eo valor de retorno de fopen lle dá un fluxo de ficheiro * tamén. 313 00:26:32,660 --> 00:26:36,060 A razón que nós non vimos antes, cando os que lidou con printf 314 00:26:36,060 --> 00:26:39,450 é porque printf ten un fluxo de patrón. 315 00:26:39,450 --> 00:26:41,810 E o fluxo estándar para o que el escribe 316 00:26:41,810 --> 00:26:45,190 vai descubrir máis sobre a curta. 317 00:26:45,190 --> 00:26:50,080 Entón, en definitiva, dar un ollo. 318 00:26:50,080 --> 00:26:53,010 >> Na sección de hoxe, imos falar un pouco sobre o GDB, 319 00:26:53,010 --> 00:26:57,720 pois canto máis lle está familiarizado con el, máis práctica comeza con el, 320 00:26:57,720 --> 00:27:01,390 o máis capaz será realmente descubrir os erros no seu propio código. 321 00:27:01,390 --> 00:27:05,540 Isto acelera o proceso de depuración se tremendamente. 322 00:27:05,540 --> 00:27:09,230 Entón, usando printf, cada vez que fai que ten que recompilar o código, 323 00:27:09,230 --> 00:27:13,000 ten que executa-lo de novo, ás veces ten que mover a chamada printf redor, 324 00:27:13,000 --> 00:27:17,100 Comentar o código, el só leva un tempo. 325 00:27:17,100 --> 00:27:20,850 O noso obxectivo é intentar convencelo de que, co GDB, pode esencialmente 326 00:27:20,850 --> 00:27:26,810 nada printf en calquera punto do seu código e nunca ten que recopila-lo. 327 00:27:26,810 --> 00:27:35,120 Vostede non ten que iniciar e manter adiviñar onde printf seguinte. 328 00:27:35,120 --> 00:27:40,910 A primeira cousa que facer é copiar esa liña e obter o código da sección fóra da rede. 329 00:27:40,910 --> 00:27:47,530 Estou copiando esta liña de código que di: "http://cdn.cs50.net wget". 330 00:27:47,530 --> 00:27:49,510 Eu estou indo a copia-lo. 331 00:27:49,510 --> 00:27:55,950 Eu estou indo a ir para o meu aparello, zoom out para que poida ver o que eu estou facendo, 332 00:27:55,950 --> 00:28:01,890 cola-lo alí, e cando presione Enter, este comando wget é literalmente unha tea obter. 333 00:28:01,890 --> 00:28:06,210 Vai tirar para abaixo este ficheiro fóra de Internet, 334 00:28:06,210 --> 00:28:11,790 e vai garda-lo para o directorio actual. 335 00:28:11,790 --> 00:28:21,630 Agora, se eu incluír o meu directorio actual, podes ver que eu teño ese arquivo section5.zip ben alí. 336 00:28:21,630 --> 00:28:25,260 O xeito de xestionar este cara é descompactá-lo, 337 00:28:25,260 --> 00:28:27,650 que pode facer na liña de comandos, así como este. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Isto vai descompactá-lo, crear o cartafol para min, 340 00:28:36,980 --> 00:28:40,410 inflar todo o contido, poñer-los alí dentro. 341 00:28:40,410 --> 00:28:47,410 Entón agora podo ir ao meu directorio sección 5 usando o comando cd. 342 00:28:47,410 --> 00:28:58,310 Limpar a pantalla usando claro. Entón, limpar a pantalla. 343 00:28:58,310 --> 00:29:02,280 Agora eu teño un terminal limpo agradable de manexar. 344 00:29:02,280 --> 00:29:06,200 >> Agora, se eu incluír todos os ficheiros que eu vexo neste directorio, 345 00:29:06,200 --> 00:29:12,270 vostede ve que eu teño catro arquivos: buggy1, buggy2, buggy3 e buggy4. 346 00:29:12,270 --> 00:29:16,180 Eu tamén teño os arquivos correspondentes. C. 347 00:29:16,180 --> 00:29:20,400 Non imos ollar para os arquivos. C por agora. 348 00:29:20,400 --> 00:29:24,140 En vez diso, imos usalos cando abrimos GDB. 349 00:29:24,140 --> 00:29:28,220 Mantivemos-los en torno de xeito que temos acceso ao código fonte real cando estamos usando GDB, 350 00:29:28,220 --> 00:29:32,740 pero o obxectivo desta parte da sección é de xogar volta co GDB 351 00:29:32,740 --> 00:29:40,370 e ver como podemos usalo para descubrir o que está a suceder de malo con cada un dos catro programas de buggy. 352 00:29:40,370 --> 00:29:43,380 Entón, estamos só indo ao redor da sala moi rapidamente, 353 00:29:43,380 --> 00:29:47,000 e eu vou pedir a alguén para realizar un dos programas de buggy, 354 00:29:47,000 --> 00:29:54,730 e despois imos en grupo mediante GDB, e imos ver o que podemos facer para corrixir estes programas, 355 00:29:54,730 --> 00:29:58,460 ou, polo menos, identificar o que está a suceder de malo en cada un deles. 356 00:29:58,460 --> 00:30:04,760 Imos comezar con Daniel. Vai executar buggy1? Imos ver o que acontece. 357 00:30:04,760 --> 00:30:09,470 [Daniel] El di que hai un fallo de aplicación. Si >>. Exactamente. 358 00:30:09,470 --> 00:30:12,460 Entón, se eu executar buggy1, eu recibín un fallo de seg. 359 00:30:12,460 --> 00:30:16,210 Neste punto, eu podería ir e abrir buggy1.c, 360 00:30:16,210 --> 00:30:19,450 tentar descubrir o que está a suceder de malo, 361 00:30:19,450 --> 00:30:22,000 pero unha das cousas máis irritantes sobre este erro de falla de seg 362 00:30:22,000 --> 00:30:27,610 é que non di en que liña das cousas programa realmente deu mal e rompe. 363 00:30:27,610 --> 00:30:29,880 Vostede medio que ten que ollar para o código 364 00:30:29,880 --> 00:30:33,990 e descubrir usando palpite e marque ou printf para ver o que está a suceder de malo. 365 00:30:33,990 --> 00:30:37,840 Unha das cousas máis legais sobre o GDB é que é moi, moi fácil 366 00:30:37,840 --> 00:30:42,170 para descubrir a liña na que traba o programa. 367 00:30:42,170 --> 00:30:46,160 É totalmente paga a pena usalo, aínda que só por iso. 368 00:30:46,160 --> 00:30:56,190 Entón, para arrincar GDB, eu tecleo GDB, e entón eu dar-lle o camiño para o executable que quero correr. 369 00:30:56,190 --> 00:31:01,960 Aquí eu estou escribindo gdb ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Prema Intro. Me dá toda a información dos dereitos de autor, 371 00:31:06,600 --> 00:31:13,000 e aquí podes ver esta liña que di: "a lectura de símbolos / home / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1 ". 373 00:31:17,680 --> 00:31:22,060 E, se todo funcionar ben, vai ver que imprimir unha mensaxe parecida con esta. 374 00:31:22,060 --> 00:31:25,500 El vai ler símbolos, que vai dicir: "Eu estou lendo símbolos do seu arquivo executábel", 375 00:31:25,500 --> 00:31:29,900 e entón el vai ter ese "feito" mensaxe aquí. 376 00:31:29,900 --> 00:31:35,410 Se ves algunha outra variación deste, ou ver que non conseguía atopar os símbolos 377 00:31:35,410 --> 00:31:41,460 ou algo así, o que significa é que simplemente non compilado o executable correctamente. 378 00:31:41,460 --> 00:31:49,980 Cando compilar programas para o seu uso co GDB, temos que usar a bandeira especial-g, 379 00:31:49,980 --> 00:31:54,540 e iso está feito por defecto, se compilar os seus programas, só escribindo facer 380 00:31:54,540 --> 00:31:59,320 ou facer buggy ou facer recuperar, calquera destes. 381 00:31:59,320 --> 00:32:07,800 Pero se está compilando manualmente con Clang, entón vai ter que ir e que inclúen flag-g. 382 00:32:07,800 --> 00:32:10,310 >> Neste punto, agora que temos o noso GDB ventá, 383 00:32:10,310 --> 00:32:12,310 é moi sinxelo de executar o programa. 384 00:32:12,310 --> 00:32:19,740 Nós pode escribir run, ou podemos simplemente escriba r. 385 00:32:19,740 --> 00:32:22,820 A maioría dos comandos de GDB pode ser abreviado. 386 00:32:22,820 --> 00:32:25,940 Normalmente, a só un ou dous cartas, o que é moi agradable. 387 00:32:25,940 --> 00:32:30,980 Entón Saad, se escribir r e prema Intro, o que ocorre? 388 00:32:30,980 --> 00:32:39,390 [Saad] Eu teño SIGSEGV, fallo de segmento, e entón todo este argot. 389 00:32:39,390 --> 00:32:43,650 Si >>. 390 00:32:43,650 --> 00:32:47,990 Como estamos vendo na pantalla, agora, e como Saad dixo, 391 00:32:47,990 --> 00:32:53,430 cando digitamos carreira ou R e presione Enter, aínda recibimos o fallo seg mesmo. 392 00:32:53,430 --> 00:32:55,830 Entón, usando o GDB non resolve o noso problema. 393 00:32:55,830 --> 00:32:59,120 Pero dános algúns gobbledygook, e verifícase que este gobbledygook 394 00:32:59,120 --> 00:33:03,080 De feito, dinos onde está a suceder. 395 00:33:03,080 --> 00:33:10,680 Para analizar iso un pouco, este primeiro bit é a función en que todo está a suceder de malo. 396 00:33:10,680 --> 00:33:20,270 Hai esa __ strcmp_sse4_2, e dinos que está a suceder neste ficheiro 397 00:33:20,270 --> 00:33:29,450 chamado sysdeps/i386, todo iso, de novo, unha especie de confusión - pero a liña 254. 398 00:33:29,450 --> 00:33:31,670 Isto é medio difícil de analizar. Normalmente, cando ve as cousas como esta, 399 00:33:31,670 --> 00:33:38,770 o que significa que está seg falla dunha das bibliotecas de sistema. 400 00:33:38,770 --> 00:33:43,220 Entón, algo que ver con strcmp. Vostedes viron strcmp antes. 401 00:33:43,220 --> 00:33:52,730 Non é moi tolo, pero iso significa que strcmp está roto ou que hai un problema co strcmp? 402 00:33:52,730 --> 00:33:57,110 ¿Que pensas, Alexandre? 403 00:33:57,110 --> 00:34:04,890 [Alexander] É que - é de 254 a liña? E o - non binario, pero non é o seu falsos, 404 00:34:04,890 --> 00:34:10,590 e despois hai outra lingua para cada función. É que 254 en que a función ou -? 405 00:34:10,590 --> 00:34:21,460 É >> liña 254. Parece que neste ficheiro s., Por iso, probablemente código de montaxe. 406 00:34:21,460 --> 00:34:25,949 >> Pero, eu creo que a cousa máis urxente é porque temos tido unha falla de seg, 407 00:34:25,949 --> 00:34:29,960 e parece que está a benvida a función strcmp, 408 00:34:29,960 --> 00:34:38,030 iso implica, entón, que strcmp está roto? 409 00:34:38,030 --> 00:34:42,290 Non debería, espero. Entón, só porque ten un fallo de segmento 410 00:34:42,290 --> 00:34:49,480 nunha das funcións do sistema, normalmente significa que simplemente non telo chamado correctamente. 411 00:34:49,480 --> 00:34:52,440 O máis rápido que hai que facer para descubrir o que está realmente a suceder 412 00:34:52,440 --> 00:34:55,500 cando ve algo tolo como este, sempre que ve unha falla seg, 413 00:34:55,500 --> 00:34:59,800 especialmente se ten un programa que está a usar máis que de inicio, 414 00:34:59,800 --> 00:35:03,570 é a utilización dun rexistro de chamadas. 415 00:35:03,570 --> 00:35:13,080 I abreviar backtrace escribindo BT, en oposición á palabra backtrace completo. 416 00:35:13,080 --> 00:35:16,510 Pero Charlotte, o que ocorre cando escribe BT e prema Intro? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] El me amosa dúas liñas, a liña 0 e liña 1. 418 00:35:23,200 --> 00:35:26,150 Si >>. Así liña 0 e liña 1. 419 00:35:26,150 --> 00:35:34,560 Estes son os cadros de pila reais que estaban actualmente no xogo cando o programa deixou de funcionar. 420 00:35:34,560 --> 00:35:42,230 A partir do cadro superior, cadro 0, e indo ao fondo máis, que é unha armazón. 421 00:35:42,230 --> 00:35:45,140 O noso cadro de nivel superior é o cadro strcmp. 422 00:35:45,140 --> 00:35:50,080 Podes pensar niso como semellante ao problema que só estaban facendo no cuestionario cos punteiros, 423 00:35:50,080 --> 00:35:54,890 onde tiñamos intercambiar cadro de pila enriba cadro de pila principal, 424 00:35:54,890 --> 00:35:59,700 e tivemos as variables que cambio estaba usando encima das variables que principal estaba usando. 425 00:35:59,700 --> 00:36:08,440 Aquí a nosa caída produciuse na nosa función strcmp, que foi chamado pola nosa función principal, 426 00:36:08,440 --> 00:36:14,370 backtrace e está nos dando non só as funcións en que as cousas fallaron, 427 00:36:14,370 --> 00:36:16,440 pero tamén está nos dicindo que todo foi chamado. 428 00:36:16,440 --> 00:36:18,830 Entón, se eu rolar un pouco máis á dereita, 429 00:36:18,830 --> 00:36:26,110 podemos ver que, si, que estaban na liña 254 do ficheiro strcmp-sse4.s. 430 00:36:26,110 --> 00:36:32,540 Pero a chamada foi feita en buggy1.c, liña 6. 431 00:36:32,540 --> 00:36:35,960 Entón isto significa que podemos facer - é que podemos só ir comprobar e ver o que estaba acontecendo 432 00:36:35,960 --> 00:36:39,930 en buggy1.c, liña 6. 433 00:36:39,930 --> 00:36:43,780 De novo, hai algunhas formas de facelo. Un deles é para saír do GDB 434 00:36:43,780 --> 00:36:49,460 ou ter o seu código aberto noutra xanela e referencia cruzada. 435 00:36:49,460 --> 00:36:54,740 Iso, por si só, é moi útil, porque agora se está en horario de oficina 436 00:36:54,740 --> 00:36:57,220 e ten un fallo seg eo seu TF está a se pregunta onde todo estaba batendo, 437 00:36:57,220 --> 00:36:59,710 pode só dicir: "Oh, liña 6. que eu non sei o que está a suceder, 438 00:36:59,710 --> 00:37:03,670 pero algo sobre a liña 6 está causando o meu programa para romper ". 439 00:37:03,670 --> 00:37:10,430 A outra forma de facer isto é que pode usar este comando chamada lista en GDB. 440 00:37:10,430 --> 00:37:13,650 Tamén pode abreviar con l. 441 00:37:13,650 --> 00:37:18,910 Entón, se se loita l, o que temos aquí? 442 00:37:18,910 --> 00:37:21,160 Temos unha morea de cousas estrañas. 443 00:37:21,160 --> 00:37:26,030 Este é o código de montaxe real 444 00:37:26,030 --> 00:37:29,860 que está en strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Isto parece tipo de funky, 446 00:37:32,440 --> 00:37:36,520 ea razón que estamos recibindo é porque agora, 447 00:37:36,520 --> 00:37:40,160 GDB nos ten en cadro 0. 448 00:37:40,160 --> 00:37:43,070 >> Entón, cando nós miramos para as variables, cada vez que ollar para o código fonte, 449 00:37:43,070 --> 00:37:50,530 nós estamos mirando para o código fonte que pertence ao cadro de pila que estamos actualmente dentro 450 00:37:50,530 --> 00:37:53,200 Polo tanto, a fin de obter algo significativo, temos que 451 00:37:53,200 --> 00:37:57,070 moverse para un cadro de pila que fai máis sentido. 452 00:37:57,070 --> 00:38:00,180 Neste caso, o cadro de pila principal tería sentido un pouco máis, 453 00:38:00,180 --> 00:38:02,680 porque ese era realmente o código que escribiu. 454 00:38:02,680 --> 00:38:05,330 Non o código strcmp. 455 00:38:05,330 --> 00:38:08,650 A forma como pode mover-se entre os cadros, neste caso, porque temos dous, 456 00:38:08,650 --> 00:38:10,430 temos 0 e 1, 457 00:38:10,430 --> 00:38:13,650 fai iso con cara arriba e para abaixo comandos. 458 00:38:13,650 --> 00:38:18,480 Se eu subir un cadro, 459 00:38:18,480 --> 00:38:21,770 agora eu estou no cadro de pila principal. 460 00:38:21,770 --> 00:38:24,330 Eu podo mover para abaixo para volver a onde eu estaba, 461 00:38:24,330 --> 00:38:32,830 ir para arriba de novo, ir para abaixo de novo, e ir para arriba de novo. 462 00:38:32,830 --> 00:38:39,750 Se sempre fai o programa no GDB, ten unha caída, comeza a backtrace, 463 00:38:39,750 --> 00:38:42,380 e ve que está en algún arquivo que non sabe o que está a suceder. 464 00:38:42,380 --> 00:38:45,460 Intenta lista, o código non parece familiar para vostede, 465 00:38:45,460 --> 00:38:48,150 dar un ollo nos seus cadros e descubrir onde está. 466 00:38:48,150 --> 00:38:51,010 Probablemente está no cadro de pila incorrecta. 467 00:38:51,010 --> 00:38:58,760 Ou, polo menos está en un cadro de pila que non é o que realmente pode depurar. 468 00:38:58,760 --> 00:39:03,110 Agora que estamos no cadro de pila axeitada, estamos en principal, 469 00:39:03,110 --> 00:39:08,100 agora podemos utilizar o comando lista para descubrir o que a liña estaba. 470 00:39:08,100 --> 00:39:13,590 E pode velo, imprimir lo para nós aquí. 471 00:39:13,590 --> 00:39:19,470 Pero podemos acertar incluír todos o mesmo, e lista dános a impresión agradable 472 00:39:19,470 --> 00:39:23,920 do código fonte real que está a suceder aquí. 473 00:39:23,920 --> 00:39:26,420 >> En particular, podemos ollar para a liña 6. 474 00:39:26,420 --> 00:39:29,330 Podemos ver o que está a suceder aquí. 475 00:39:29,330 --> 00:39:31,250 E parece que nós estamos facendo unha comparación de cadea 476 00:39:31,250 --> 00:39:41,050 entre a cadea "CS50 pedras" e argv [1]. 477 00:39:41,050 --> 00:39:45,700 Algo sobre iso foi bater. 478 00:39:45,700 --> 00:39:54,120 Entón Missy, tes algunha opinión sobre o que pode estar a suceder aquí? 479 00:39:54,120 --> 00:39:59,400 [Missy] Eu non sei por que está fallando. >> Vostede non sabe por que está batendo? 480 00:39:59,400 --> 00:40:02,700 Jimmy, todos os pensamentos? 481 00:40:02,700 --> 00:40:06,240 [Jimmy] eu non estou totalmente seguro, pero a última vez que usou cadea de comparar, 482 00:40:06,240 --> 00:40:10,260 ou strcmp, tivemos algo así como tres casos diferentes baixo el. 483 00:40:10,260 --> 00:40:12,800 Nós non temos un ==, eu non creo que, mesmo en que a primeira liña. 484 00:40:12,800 --> 00:40:16,700 En vez diso, foi separada en tres, e unha era == 0, 485 00:40:16,700 --> 00:40:19,910 un foi <0, eu creo, e foi un> 0. 486 00:40:19,910 --> 00:40:22,590 Entón quizais algo así? Si >>. Entón hai esa cuestión 487 00:40:22,590 --> 00:40:27,200 de que estamos facendo a comparación correctamente? 488 00:40:27,200 --> 00:40:31,660 Stella? Todos os pensamentos? 489 00:40:31,660 --> 00:40:38,110 [Stella] Eu non estou seguro. >> Non estou seguro. Daniel? Pensamentos? Okay. 490 00:40:38,110 --> 00:40:44,770 Acontece que o que está a suceder aquí é cando executamos o programa 491 00:40:44,770 --> 00:40:48,370 e temos a culpa seg, cando o programa foi executado por primeira vez, Daniel, 492 00:40:48,370 --> 00:40:50,800 deu a ela os argumentos de liña de comandos? 493 00:40:50,800 --> 00:40:58,420 [Daniel] Non Non >> Neste caso, o que é o valor argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> Non hai ningún valor. >> Dereito. 495 00:41:00,920 --> 00:41:06,120 Ben, non hai valor de secuencia apropiada. 496 00:41:06,120 --> 00:41:10,780 Pero hai algún valor. Cal é o valor que queda almacenado alí? 497 00:41:10,780 --> 00:41:15,130 Un valor >> lixo? >> É tanto un valor de lixo, ou, neste caso, 498 00:41:15,130 --> 00:41:19,930 o final da matriz argv sempre é rematada co null. 499 00:41:19,930 --> 00:41:26,050 Entón, o que realmente foi almacenado alí é nulo. 500 00:41:26,050 --> 00:41:30,810 A outra forma de solucionar isto, en vez de pensar niso, 501 00:41:30,810 --> 00:41:33,420 é intentar mostra-lo. 502 00:41:33,420 --> 00:41:35,880 Este é o lugar onde eu estaba dicindo que o uso de GDB é grande, 503 00:41:35,880 --> 00:41:40,640 porque pode imprimir todas as variables, todos os valores que quere 504 00:41:40,640 --> 00:41:43,230 Usando este práctico-dandy mando p. 505 00:41:43,230 --> 00:41:48,520 Entón, se eu escribir p e escriba o valor dunha variable ou nome dunha variable, 506 00:41:48,520 --> 00:41:55,320 dicir, argc, vexo que argc é 1. 507 00:41:55,320 --> 00:42:01,830 Se eu queira imprimir argv [0], podo facelo así. 508 00:42:01,830 --> 00:42:04,840 E, como vimos, argv [0] é sempre o nome do seu programa, 509 00:42:04,840 --> 00:42:06,910 sempre o nome do executable. 510 00:42:06,910 --> 00:42:09,740 Aquí vese que ten o nome completo do camiño. 511 00:42:09,740 --> 00:42:15,920 Eu tamén pode imprimir argv [1] e ver o que acontece. 512 00:42:15,920 --> 00:42:20,890 >> Aquí temos este tipo de valor místico. 513 00:42:20,890 --> 00:42:23,890 Temos este 0x0. 514 00:42:23,890 --> 00:42:27,850 Teña en conta que, no inicio do mandato, cando falamos de cifras hexadecimais? 515 00:42:27,850 --> 00:42:34,680 Ou que pequena pregunta ao final pset 0 sobre como representar 50 en hexadecimal? 516 00:42:34,680 --> 00:42:39,410 A nosa forma de escribir números hexadecimais no CS, só para non confundir-nos 517 00:42:39,410 --> 00:42:46,080 con números decimais, sempre prefixo-los con 0x. 518 00:42:46,080 --> 00:42:51,420 Polo tanto, este prefixo 0x sempre significa só interpretar o seguinte número como un número hexadecimal, 519 00:42:51,420 --> 00:42:57,400 non como unha cadea, non como un número decimal, non como un número binario. 520 00:42:57,400 --> 00:43:02,820 Unha vez que o número de 5-0 é un número válido en hexadecimal. 521 00:43:02,820 --> 00:43:06,240 E é un número decimal, 50. 522 00:43:06,240 --> 00:43:10,050 Polo tanto, este é só coma nós disambiguate. 523 00:43:10,050 --> 00:43:14,860 Entón 0x0 medios 0 hexadecimal, que tamén é decimal, binario 0 0. 524 00:43:14,860 --> 00:43:17,030 É só o valor 0. 525 00:43:17,030 --> 00:43:22,630 Acontece que iso é o que nulo é, en realidade, na memoria. 526 00:43:22,630 --> 00:43:25,940 Nulo é só 0. 527 00:43:25,940 --> 00:43:37,010 Aquí, o elemento almacenado argv [1] é nulo. 528 00:43:37,010 --> 00:43:45,220 Entón, estamos tentando comparar o noso "CS50 rochas" cadea para unha cadea nula. 529 00:43:45,220 --> 00:43:48,130 Entón dereferencing nulo, intentando acceder cousas ao nulo, 530 00:43:48,130 --> 00:43:55,050 aqueles son normalmente vai causar algún tipo de fallo de segmento ou doutras cousas malas acontezan. 531 00:43:55,050 --> 00:43:59,350 E ocorre que strcmp non comproba 532 00:43:59,350 --> 00:44:04,340 ou non que pasou un valor que é nulo. 533 00:44:04,340 --> 00:44:06,370 En vez diso, el simplemente vai adiante, intenta facer a súa cousa, 534 00:44:06,370 --> 00:44:14,640 e seg defectos, ela seg fallos, e é o seu problema. Ten que ir arranxar. 535 00:44:14,640 --> 00:44:19,730 Moi rapidamente, como podemos solucionar este problema? Charlotte? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Podes comprobar se a usar. 537 00:44:23,540 --> 00:44:32,240 Entón, se argv [1] é nulo, == 0, a continuación, voltar 1, ou algo [inintelixible]. 538 00:44:32,240 --> 00:44:34,590 Si >>. Entón esta é unha boa forma de facelo, como se pode comprobar, 539 00:44:34,590 --> 00:44:39,230 o valor que estamos a piques de pasar ao strcmp, argv [1], non é nulo? 540 00:44:39,230 --> 00:44:45,830 Se é nulo, entón podemos dicir ben, abortar. 541 00:44:45,830 --> 00:44:49,450 >> A forma máis común de facer isto é usar o valor argc. 542 00:44:49,450 --> 00:44:52,040 Podes ver aquí a principios do inicio, 543 00:44:52,040 --> 00:44:58,040 omitimos que primeiro exame que normalmente facemos cando usar argumentos de liña de comandos, 544 00:44:58,040 --> 00:45:05,240 que é para probar se ou non o seu valor argc é o que esperamos. 545 00:45:05,240 --> 00:45:10,290 Neste caso, estamos esperando polo menos dous argumentos, 546 00:45:10,290 --> 00:45:13,660 o nome do programa máis outro. 547 00:45:13,660 --> 00:45:17,140 Porque nós estamos a piques de empregar o segundo argumento aquí. 548 00:45:17,140 --> 00:45:21,350 Entón, ter algún tipo de proba con antelación, antes da nosa chamada strcmp 549 00:45:21,350 --> 00:45:37,390 que as probas ou non argv é polo menos dúas, tamén faría o mesmo tipo de cousas. 550 00:45:37,390 --> 00:45:40,620 Podemos ver se isto funciona, executando o programa de novo. 551 00:45:40,620 --> 00:45:45,610 Sempre pode reiniciar o programa dentro do GDB, que é moi bo. 552 00:45:45,610 --> 00:45:49,310 Pode correr, e cando pasar argumentos para o seu programa, 553 00:45:49,310 --> 00:45:53,060 pasa-los cando chamar executar, non cando arrincar GDB. 554 00:45:53,060 --> 00:45:57,120 Desta forma, pode manter invocando o seu programa con argumentos diferentes cada vez. 555 00:45:57,120 --> 00:46:08,080 Entón execute, ou aínda, podo escribir r, e imos ver o que pasa se escribir "Ola". 556 00:46:08,080 --> 00:46:11,140 Será sempre preguntar se quere inicia-lo desde o inicio de novo. 557 00:46:11,140 --> 00:46:17,490 Normalmente, quere comezar desde o inicio de novo. 558 00:46:17,490 --> 00:46:25,010 E, neste punto, el reinicia-lo novo, el imprime 559 00:46:25,010 --> 00:46:28,920 o programa que estamos correndo, buggy1, co argumento Ola, 560 00:46:28,920 --> 00:46:32,720 e imprime tanto estándar, el di, "Ten un D," fronte triste. 561 00:46:32,720 --> 00:46:37,610 Pero nós non seg culpa. El dixo que o proceso saíu normalmente. 562 00:46:37,610 --> 00:46:39,900 De xeito que parece moi bo. 563 00:46:39,900 --> 00:46:43,050 Ningunha falla máis seg, podemos pasado, 564 00:46:43,050 --> 00:46:48,190 entón parece que ese era realmente o erro culpa seg que estabamos recibindo. 565 00:46:48,190 --> 00:46:51,540 Desafortunadamente, el nos di que estamos comezando un D. 566 00:46:51,540 --> 00:46:54,090 >> Podemos ir cara atrás e ollar para o código e ver o que estaba acontecendo alí 567 00:46:54,090 --> 00:46:57,980 para descubrir o que era - por iso que estaba nos dicindo que temos un D. 568 00:46:57,980 --> 00:47:03,690 Imos ver, aquí foi este printf dicindo que ten un D. 569 00:47:03,690 --> 00:47:08,540 Se tipo de lista, como manter a lista de escribir, el mantén a iteração a través do seu programa, 570 00:47:08,540 --> 00:47:10,940 por iso vai amosar-lle as primeiras liñas do seu programa. 571 00:47:10,940 --> 00:47:15,450 A continuación, vai amosar-lle as próximas liñas, eo anaco seguinte eo seguinte peza. 572 00:47:15,450 --> 00:47:18,240 E vai continuar intentando ir para abaixo. 573 00:47:18,240 --> 00:47:21,180 E agora imos comezar a "liña de número 16 está fóra de alcance." 574 00:47:21,180 --> 00:47:23,940 Porque só ten 15 liñas. 575 00:47:23,940 --> 00:47:30,310 Se chegar a este punto ea súa pregunta: "O que fago?" pode usar o comando de axuda. 576 00:47:30,310 --> 00:47:34,340 Use a axuda e, a continuación, dar-lle o nome dun comando. 577 00:47:34,340 --> 00:47:36,460 E ve o GDB dános todo este tipo de cousas. 578 00:47:36,460 --> 00:47:43,870 Ela di: "Sen argumento, lista dez liñas máis logo ou en torno á listaxe anterior. 579 00:47:43,870 --> 00:47:47,920 Lista - lista as 10 liñas antes - " 580 00:47:47,920 --> 00:47:52,960 Entón, imos tentar usar menos lista. 581 00:47:52,960 --> 00:47:57,000 E que lista as 10 liñas anterior, pode xogar con unha lista pouco. 582 00:47:57,000 --> 00:48:02,330 Podes facer a lista, lista -, pode ata dar incluír un número, como a lista de 8, 583 00:48:02,330 --> 00:48:07,500 e vai incluír as 10 liñas en torno á liña 8. 584 00:48:07,500 --> 00:48:10,290 E podes ver o que está a suceder aquí é que ten un simple, se outra cousa. 585 00:48:10,290 --> 00:48:13,980 Se insire CS50 rochas, ela mostra "Ten un A." 586 00:48:13,980 --> 00:48:16,530 Se non, el imprime "Ten un D." 587 00:48:16,530 --> 00:48:23,770 Cidade chatice. Todo ben. Si? 588 00:48:23,770 --> 00:48:26,730 >> [Daniel] Entón, cando intento facer CS50 rochas sen as comiñas, 589 00:48:26,730 --> 00:48:29,290 el di "Ten un D." 590 00:48:29,290 --> 00:48:32,560 Eu precisaba das aspas para facelo funcionar, por que isto? 591 00:48:32,560 --> 00:48:38,490 Si >>. Acontece que cando - este é outro petisco pouco de diversión - 592 00:48:38,490 --> 00:48:47,900 cando executar o programa, se executa-lo e escribir CS50 rochas, 593 00:48:47,900 --> 00:48:50,800 só como Daniel estaba dicindo que el fixo, e presione Enter, 594 00:48:50,800 --> 00:48:52,870 aínda di que obter un D. 595 00:48:52,870 --> 00:48:55,580 E a pregunta é, por que é isto? 596 00:48:55,580 --> 00:49:02,120 E verifícase que o terminal noso e GDB analizar estes como dous argumentos distintos. 597 00:49:02,120 --> 00:49:04,800 Porque cando hai un espazo que está implícito como 598 00:49:04,800 --> 00:49:08,730 o primeiro argumento rematou, o seguinte argumento está a piques de comezar. 599 00:49:08,730 --> 00:49:13,260 O xeito de combinar os en dous, ou moito, nun argumento, 600 00:49:13,260 --> 00:49:18,510 é utilizar as comiñas. 601 00:49:18,510 --> 00:49:29,560 Entón, agora, se poñelas entre comiñas e executa-lo de novo, temos un A. 602 00:49:29,560 --> 00:49:38,780 Entón, só para recapitular, sen comiñas, CS50 e rochas son analizados como dous argumentos distintos. 603 00:49:38,780 --> 00:49:45,320 Con aspas, é analizado como un argumento completamente. 604 00:49:45,320 --> 00:49:53,070 >> Podemos ver isto con un punto de interrupción. 605 00:49:53,070 --> 00:49:54,920 Ata agora temos sido executado o noso programa, e está sendo executado 606 00:49:54,920 --> 00:49:58,230 ata que seg fallos ou acertos dun erro 607 00:49:58,230 --> 00:50:05,930 ou ata que saíu e todo foi totalmente ben. 608 00:50:05,930 --> 00:50:08,360 Iso non é necesariamente o máis útil, porque ás veces 609 00:50:08,360 --> 00:50:11,840 ten un erro no seu programa, pero el non está causando un fallo de segmento. 610 00:50:11,840 --> 00:50:16,950 Non está causando o seu programa para deixar ou algo así. 611 00:50:16,950 --> 00:50:20,730 O camiño para chegar GDB para pausar o seu programa nun punto 612 00:50:20,730 --> 00:50:23,260 é establecer un punto de interrupción. 613 00:50:23,260 --> 00:50:26,520 Podes facelo a través da creación dun punto de interrupción nun nome de función 614 00:50:26,520 --> 00:50:30,770 ou pode definir un punto de interrupción nunha determinada liña de código. 615 00:50:30,770 --> 00:50:34,450 Eu gusto de definir puntos de interrupción en nomes de función, porque - fácil de lembrar, 616 00:50:34,450 --> 00:50:37,700 e se realmente entrar e cambiar o seu código fonte un pouco, 617 00:50:37,700 --> 00:50:42,020 entón o seu punto de interrupción vai realmente estar no mesmo lugar dentro do seu código. 618 00:50:42,020 --> 00:50:44,760 Considerando que se está a usar números de liña, e os números de liña cambiar 619 00:50:44,760 --> 00:50:51,740 porque engadir ou eliminar algún código, a continuación, os puntos de interrupción están totalmente asneira. 620 00:50:51,740 --> 00:50:58,590 Unha das cousas máis comúns que facer é establecer un punto de interrupción na función principal. 621 00:50:58,590 --> 00:51:05,300 Moitas veces, eu vou arrincar o GDB, eu vou escribir b principal, prema Intro, e que vai establecer un punto de interrupción 622 00:51:05,300 --> 00:51:10,630 sobre a función principal, que só di: "Pause o programa así que comezar a correr", 623 00:51:10,630 --> 00:51:17,960 e de que xeito, cando executar o meu programa con, digamos, CS50 rochas como dous argumentos 624 00:51:17,960 --> 00:51:24,830 e prema Intro, el está coa función principal e para na primeira liña, 625 00:51:24,830 --> 00:51:30,620 dereita antes que avalía a función strcmp. 626 00:51:30,620 --> 00:51:34,940 >> Dende que eu estou unha pausa, agora podo comezar a perder tempo e ver o que está a suceder 627 00:51:34,940 --> 00:51:40,250 con todas as diferentes variables que son pasados ​​para o meu programa. 628 00:51:40,250 --> 00:51:43,670 Aquí podo imprimir argc e ver o que está a suceder. 629 00:51:43,670 --> 00:51:50,030 Mira que argc e 3, porque ten tres valores diferentes nela. 630 00:51:50,030 --> 00:51:54,060 Ten o nome do programa, que ten o primeiro argumento eo segundo argumento. 631 00:51:54,060 --> 00:52:09,330 Podemos imprimir os para fóra, mirando para argv [0], argv [1], e argv [2]. 632 00:52:09,330 --> 00:52:12,030 Entón, agora tamén se pode ver por esta chamada strcmp vai fallar, 633 00:52:12,030 --> 00:52:21,650 porque ve que o fixo dividir o CS50 e as rochas en dous argumentos distintos. 634 00:52:21,650 --> 00:52:27,250 Neste punto, unha vez que alcance un punto de interrupción, pode continuar a percorrer o seu programa 635 00:52:27,250 --> 00:52:32,920 liña por liña, en vez de comezar o programa de novo. 636 00:52:32,920 --> 00:52:35,520 Entón, se non quere comezar o seu programa de novo e só continuar a partir de aquí, 637 00:52:35,520 --> 00:52:41,970 pode usar o comando siga e seguir o programa será executado ata o final. 638 00:52:41,970 --> 00:52:45,010 Así como el fixo aquí. 639 00:52:45,010 --> 00:52:54,880 Con todo, se eu reiniciar o programa, CS50 rochas, que bate no meu punto de interrupción de novo, 640 00:52:54,880 --> 00:52:59,670 e esta vez, si eu non quero só ir ata o final o resto do programa, 641 00:52:59,670 --> 00:53:08,040 Podo utilizar o comando seguinte, o que tamén abreviar con n. 642 00:53:08,040 --> 00:53:12,960 E iso vai percorrer o programa liña a liña. 643 00:53:12,960 --> 00:53:17,530 Así, pode ver como as cousas executar, como cambio de variables, como as cousas se actualizado. 644 00:53:17,530 --> 00:53:21,550 O que é moi bo. 645 00:53:21,550 --> 00:53:26,570 A outra cousa legal é, en vez de repetir o mesmo comando máis e máis e máis unha vez, 646 00:53:26,570 --> 00:53:30,670 se só prema Intro - por iso aquí ve que eu non ingresaran nada - 647 00:53:30,670 --> 00:53:33,780 se eu só presione Enter, que vai repetir o mando anterior, 648 00:53:33,780 --> 00:53:36,900 ou o comando GDB anterior que eu só poñer dentro 649 00:53:36,900 --> 00:53:56,000 Podo seguir batendo Intro e vai manter percorrendo o meu código liña por liña. 650 00:53:56,000 --> 00:53:59,310 Quere fomentar vostedes para ir comprobar os programas de buggy outros tamén. 651 00:53:59,310 --> 00:54:01,330 Non temos tempo para pasar por todos eles hoxe en sección. 652 00:54:01,330 --> 00:54:05,890 O código fonte está alí, entón podes tipo de ver o que está a suceder 653 00:54:05,890 --> 00:54:07,730 nos bastidores se queda moi preso, 654 00:54:07,730 --> 00:54:11,940 pero, como mínimo, só a práctica de arrincar GDB, 655 00:54:11,940 --> 00:54:13,940 a execución do programa ata que se rompe en ti, 656 00:54:13,940 --> 00:54:18,260 recibindo o backtrace, descubrir cal a función do accidente estaba, 657 00:54:18,260 --> 00:54:24,450 que liña era en, imprimindo uns valores variables, 658 00:54:24,450 --> 00:54:30,140 só para que vostede unha idea para el, porque iso vai realmente axudar aquí para fronte. 659 00:54:30,140 --> 00:54:36,340 Neste punto, nós estamos indo a saír fóra do GDB, que deixar de usar ou só q. 660 00:54:36,340 --> 00:54:40,460 Se o seu programa está no medio da execución, aínda así, non foi pechado, 661 00:54:40,460 --> 00:54:43,510 sempre preguntar: "Vostede está seguro de que realmente quere saír?" 662 00:54:43,510 --> 00:54:48,770 Pode só bater si. 663 00:54:48,770 --> 00:54:55,250 >> Agora imos ollar para o seguinte problema que temos, que é o programa de gato. 664 00:54:55,250 --> 00:54:59,880 Se asistir a curta en redirixido e tubos, vai ver que Tommy usa este programa 665 00:54:59,880 --> 00:55:07,540 que, basicamente, imprime toda a saída dun arquivo para a pantalla. 666 00:55:07,540 --> 00:55:12,660 Entón, se eu executar gato, este é realmente un programa embutido no aparello, 667 00:55:12,660 --> 00:55:16,860 e se ten Macs pode facelo no seu Mac tamén, se abrir o terminal. 668 00:55:16,860 --> 00:55:25,630 E nós - gato, imos dicir, cp.c, e prema Intro. 669 00:55:25,630 --> 00:55:29,640 O que este fixo, se rolar un pouco e ver onde nós corremos a liña, 670 00:55:29,640 --> 00:55:40,440 ou en que executou a orde gato, literalmente impresa o contido do cp.c a nosa pantalla. 671 00:55:40,440 --> 00:55:44,140 Podemos executar de novo e pode pór en varios arquivos xuntos. 672 00:55:44,140 --> 00:55:49,880 Así pode facer cp.c gato, e entón tamén podemos concatenar o arquivo cat.c, 673 00:55:49,880 --> 00:55:53,250 Que é o programa que estamos a piques de escribir, 674 00:55:53,250 --> 00:55:58,140 e vai imprimir ambos os arquivos de volta para facer a nosa pantalla. 675 00:55:58,140 --> 00:56:05,490 Entón, se rolar un pouco, vemos que, cando rodamos este cp.c gato, cat.c, 676 00:56:05,490 --> 00:56:17,110 primeiro-lo impreso o arquivo CP, e despois a continuación, el imprimiu o arquivo cat.c ben aquí. 677 00:56:17,110 --> 00:56:19,650 Nós imos usar isto para só peirao os pés. 678 00:56:19,650 --> 00:56:25,930 Brinque con impresión sinxela á terminal, ver como é que funciona. 679 00:56:25,930 --> 00:56:39,170 Se vostedes se abre con gedit cat.c, prema Intro, 680 00:56:39,170 --> 00:56:43,760 podes ver o programa que estamos a piques de escribir. 681 00:56:43,760 --> 00:56:48,980 Nós temos esta tarxeta de caldeira nice, polo tanto, non ten que gastar tempo escribindo todo isto. 682 00:56:48,980 --> 00:56:52,310 Tamén comprobar o número de argumentos pasado dentro 683 00:56:52,310 --> 00:56:56,910 Nós imprimir unha mensaxe de uso agradable. 684 00:56:56,910 --> 00:57:00,950 >> Este é o tipo de cousas que, unha vez máis, como vimos falando, 685 00:57:00,950 --> 00:57:04,490 é case como se a memoria muscular. 686 00:57:04,490 --> 00:57:07,190 Só lembre de seguir facendo o mesmo tipo de material 687 00:57:07,190 --> 00:57:11,310 e sempre imprimir algún tipo de mensaxe útil 688 00:57:11,310 --> 00:57:17,670 para que as persoas saiban como realizar o seu programa. 689 00:57:17,670 --> 00:57:21,630 Co gato, é moi sinxelo, só imos pasar por todos os diferentes argumentos 690 00:57:21,630 --> 00:57:24,300 que foron pasadas para o noso programa, e nós estamos indo para imprimir 691 00:57:24,300 --> 00:57:29,950 o seu contido para fóra da pantalla de un de cada vez. 692 00:57:29,950 --> 00:57:35,670 Para imprimir arquivos para a pantalla, imos facer algo moi semellante 693 00:57:35,670 --> 00:57:38,120 ao que fixemos a finais do cuestionario. 694 00:57:38,120 --> 00:57:45,350 Ao final do cuestionario, que contraten programa, tivemos que abrir un arquivo, 695 00:57:45,350 --> 00:57:48,490 e despois tivemos de imprimir nela. 696 00:57:48,490 --> 00:57:54,660 Neste caso, imos abrir un arquivo, e imos le-lo no seu lugar. 697 00:57:54,660 --> 00:58:00,630 Entón nós imos para imprimir, en vez de un arquivo, imos imprimir na pantalla. 698 00:58:00,630 --> 00:58:05,830 Así, a impresión para a pantalla que todos fixemos antes con printf. 699 00:58:05,830 --> 00:58:08,290 Entón, iso non é moi tolo. 700 00:58:08,290 --> 00:58:12,190 Pero a lectura dun arquivo é medio raro. 701 00:58:12,190 --> 00:58:17,300 Nós imos pasar por iso un pouco de cada vez. 702 00:58:17,300 --> 00:58:20,560 Se vostedes volver a ese último problema no seu cuestionario, problema 33, 703 00:58:20,560 --> 00:58:27,280 a primeira liña que nós imos facer aquí, abrir o ficheiro, é moi semellante ao que fixemos alí. 704 00:58:27,280 --> 00:58:36,370 Entón, Stella, o que fai aquel ollar liña como, cando abrir un arquivo? 705 00:58:36,370 --> 00:58:47,510 [Stella] FILE * Capital, arquivo - >> Okay. >> - É igual a fopen. >> Yup. 706 00:58:47,510 --> 00:58:55,980 Que neste caso é? É no comentario. 707 00:58:55,980 --> 00:59:06,930 >> É o comentario? argv [i] e R? 708 00:59:06,930 --> 00:59:11,300 >> Exactamente. Certo. Entón, Stella é totalmente certo. 709 00:59:11,300 --> 00:59:13,720 Isto é o que a liña parece. 710 00:59:13,720 --> 00:59:19,670 Estamos indo para obter unha variable fluxo de ficheiro, almacena-lo nun FILE *, entón todas as tapas, 711 00:59:19,670 --> 00:59:25,720 File, *, eo nome desta variable será de arquivo. 712 00:59:25,720 --> 00:59:32,250 Poderiamos chamalo de todo o que lle gusta. Nós poderiamos chamar iso first_file ou file_i, todo o que quere. 713 00:59:32,250 --> 00:59:37,590 E entón o nome do ficheiro foi pasado na liña de comandos para este programa. 714 00:59:37,590 --> 00:59:44,450 Entón, é almacenado en argv [i] e, a continuación, imos abrir este ficheiro en modo lectura. 715 00:59:44,450 --> 00:59:48,100 Agora que abriu o ficheiro, o que é a cousa que sempre temos que lembrar de facer 716 00:59:48,100 --> 00:59:52,230 sempre que abriu un arquivo? Pecha-lo. 717 00:59:52,230 --> 00:59:57,220 Entón Missy, como é que imos pechar un arquivo? 718 00:59:57,220 --> 01:00:01,020 [Missy] fclose (arquivo) >> fclose (arquivo). Exactamente. 719 01:00:01,020 --> 01:00:05,340 Grande. Okay. Se olharmos para este facer comentario aquí, 720 01:00:05,340 --> 01:00:11,940 el di, "Open argv [i] e imprimir o seu contido á saída." 721 01:00:11,940 --> 01:00:15,460 >> Stdout é un nome estraño. Saída estándar é só unha forma de dicir 722 01:00:15,460 --> 01:00:22,880 queremos imprimir á terminal, queremos imprimir lo para o fluxo de saída estándar. 723 01:00:22,880 --> 01:00:26,450 Podemos realmente se librar deste comentario aquí. 724 01:00:26,450 --> 01:00:36,480 Eu estou indo a copia-lo enteira e pegala, xa que é o que nós fixemos. 725 01:00:36,480 --> 01:00:41,290 Neste punto, agora temos que ler o ficheiro de pouco a pouco. 726 01:00:41,290 --> 01:00:46,300 Nós discutir algunhas formas de lectura de arquivos. 727 01:00:46,300 --> 01:00:51,830 Cales son os seus favoritos ata agora? 728 01:00:51,830 --> 01:00:57,960 Que forma xa viu ou non se lembra, para ler ficheiros? 729 01:00:57,960 --> 01:01:04,870 [Daniel] fread? Fread >>? Entón fread é un deles. Jimmy, coñece algún outro? 730 01:01:04,870 --> 01:01:12,150 [Jimmy] Non >> Okay. Nope. Charlotte? Alexander? Outros? Okay. 731 01:01:12,150 --> 01:01:20,740 Así, os outros son fgetc, é que nós imos usar moito. 732 01:01:20,740 --> 01:01:26,410 Hai tamén fscanf; vostedes ver un estándar aquí? 733 01:01:26,410 --> 01:01:29,170 Todos eles comezan con f. Nada que ver con un arquivo. 734 01:01:29,170 --> 01:01:35,260 Hai fread, fgetc, fscanf. Estas son todas as funcións de lectura. 735 01:01:35,260 --> 01:01:49,120 Para escribir temos fwrite, temos fputc vez de fgetc. 736 01:01:49,120 --> 01:01:58,250 Temos tamén fprintf como vimos no cuestionario. 737 01:01:58,250 --> 01:02:01,680 Unha vez que este é un problema que implica a lectura de un ficheiro, 738 01:02:01,680 --> 01:02:04,940 imos usar unha desas tres funcións. 739 01:02:04,940 --> 01:02:10,890 Nós non estamos indo a usar estas funcións aquí. 740 01:02:10,890 --> 01:02:14,880 Estas funcións son encontradas na biblioteca de E / S por defecto. 741 01:02:14,880 --> 01:02:17,510 Entón, se ollar para arriba do programa, 742 01:02:17,510 --> 01:02:24,110 podes ver que xa incluído o ficheiro de cabeceira para a biblioteca de E / S por defecto. 743 01:02:24,110 --> 01:02:27,120 Se queremos descubrir cal queremos usar, 744 01:02:27,120 --> 01:02:29,690 podemos sempre abrir as páxinas man. 745 01:02:29,690 --> 01:02:34,350 Así, podemos escribir stdio home 746 01:02:34,350 --> 01:02:43,180 e ler todo sobre a entrada stdio e funcións de saída en C. 747 01:02:43,180 --> 01:02:49,870 E xa podemos ver oh, mira. É mencionar fgetc, é mencionar fputc. 748 01:02:49,870 --> 01:02:57,220 Así, pode afondar un pouco e ollar para, digamos, fgetc 749 01:02:57,220 --> 01:03:00,060 e ollar para a súa páxina do home. 750 01:03:00,060 --> 01:03:03,430 Podes ver que vai xunto con unha morea de outras funcións: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, queda, ungetc, ea súa entrada de caracteres e cadeas. 752 01:03:12,640 --> 01:03:19,180 Polo tanto, esta é a forma como lemos en carácteres e cadeas de ficheiros de entrada estándar, 753 01:03:19,180 --> 01:03:21,990 que é, esencialmente, a partir do usuario. 754 01:03:21,990 --> 01:03:24,780 E é así que facemos en C. real 755 01:03:24,780 --> 01:03:30,850 Polo tanto, este non está a usar o GetString e funcións getchar 756 01:03:30,850 --> 01:03:36,840 que foi utilizada dende a biblioteca de CS50. 757 01:03:36,840 --> 01:03:39,710 Nós imos facer este problema nun par de formas 758 01:03:39,710 --> 01:03:43,430 de xeito que se pode ver dúas formas diferentes de facelo. 759 01:03:43,430 --> 01:03:48,490 Tanto a función fread que Daniel mencionado e fgetc son boas maneiras de facelo. 760 01:03:48,490 --> 01:03:53,790 Eu creo que fgetc é un pouco máis fácil, porque só ten, como se ve, 761 01:03:53,790 --> 01:03:59,660 un argumento, o FILE * que estamos intentando ler o personaxe, 762 01:03:59,660 --> 01:04:02,740 eo seu valor de retorno é un int. 763 01:04:02,740 --> 01:04:05,610 E iso é un pouco confuso, non? 764 01:04:05,610 --> 01:04:11,450 >> Porque nós estamos comezando un personaxe, entón por que non o fai un retorno char? 765 01:04:11,450 --> 01:04:18,700 Vostedes teñen algunha idea sobre por que isto non pode voltar un char? 766 01:04:18,700 --> 01:04:25,510 [Respostas Missy, inintelixible] >> si. Entón, Missy é totalmente certo. 767 01:04:25,510 --> 01:04:31,570 Se é ASCII, entón este enteiro podería ser mapeado a un carácter real. 768 01:04:31,570 --> 01:04:33,520 Podería ser un carácter ASCII, e iso é certo. 769 01:04:33,520 --> 01:04:36,220 Isto é exactamente o que está a suceder. 770 01:04:36,220 --> 01:04:39,190 Estamos a usar un int simplemente porque ten máis bits. 771 01:04:39,190 --> 01:04:44,750 É máis grande que un char, o noso carbón só 8 bits, 1 byte que nas nosas máquinas de 32 bits. 772 01:04:44,750 --> 01:04:48,520 E un int ten valor todos os 4 bytes "do espazo. 773 01:04:48,520 --> 01:04:50,940 E ocorre que a forma fgetc funciona, 774 01:04:50,940 --> 01:04:53,940 desprazarse cara abaixo na nosa sinopse nesta páxina do manual un pouco, 775 01:04:53,940 --> 01:05:05,000 percorrer todo o camiño cara a abaixo. Acontece que usan ese valor especial chamado EOF. 776 01:05:05,000 --> 01:05:09,640 É unha constante especial como o valor de retorno da función fgetc 777 01:05:09,640 --> 01:05:14,570 sempre que alcanzou ao final do ficheiro ou se recibir un erro. 778 01:05:14,570 --> 01:05:18,170 E verifícase que para facer estas comparacións con EOF correctamente, 779 01:05:18,170 --> 01:05:24,060 quere ter esa cantidade extra de información que ten un int 780 01:05:24,060 --> 01:05:28,420 en vez de usar unha variable char. 781 01:05:28,420 --> 01:05:32,130 Aínda que fgetc é efectivamente comezar un personaxe dun ficheiro, 782 01:05:32,130 --> 01:05:38,450 quere lembrar que está retornando algo que é do tipo int para ti. 783 01:05:38,450 --> 01:05:41,360 Dito isto, é moi doado de usar. 784 01:05:41,360 --> 01:05:44,960 Vai dar un carácter, por iso todo o que temos que facer é continuar facendo o ficheiro, 785 01:05:44,960 --> 01:05:48,440 "Deixa-me o seguinte personaxe, dáme o seguinte personaxe, dáme o seguinte personaxe", 786 01:05:48,440 --> 01:05:51,400 ata chegar ao final do arquivo. 787 01:05:51,400 --> 01:05:54,730 E que ha puxar un personaxe nun momento do noso arquivo, 788 01:05:54,730 --> 01:05:56,250 e entón podemos facer o que quere con el. 789 01:05:56,250 --> 01:06:00,160 Podemos almacena-lo, podemos engadir lo a unha corda, que pode imprimir lo. 790 01:06:00,160 --> 01:06:04,630 Facer nada diso. 791 01:06:04,630 --> 01:06:09,600 >> Zoom de volta e volver ao noso programa cat.c, 792 01:06:09,600 --> 01:06:16,170 se imos usar fgetc, 793 01:06:16,170 --> 01:06:21,710 como podemos abordar esta próxima liña de código? 794 01:06:21,710 --> 01:06:26,020 Nós imos empregar - fread vai facer algo un pouco diferente. 795 01:06:26,020 --> 01:06:32,600 E, nesta ocasión, imos só para usar fgetc para obter un personaxe de cada vez. 796 01:06:32,600 --> 01:06:40,910 Para procesar un arquivo enteiro, o que podería temos que facer? 797 01:06:40,910 --> 01:06:44,030 Cantos personaxes están aí nun arquivo? 798 01:06:44,030 --> 01:06:47,390 Hai unha gran cantidade. Entón probablemente quere obter un 799 01:06:47,390 --> 01:06:49,860 e despois coller outro e comezar outro e comezar outro. 800 01:06:49,860 --> 01:06:53,330 Que tipo de algoritmo que pensas que pode ter que usar aquí? 801 01:06:53,330 --> 01:06:55,470 Que tipo de -? [Alexander] Un loop for? >> Exactamente. 802 01:06:55,470 --> 01:06:57,500 Algún tipo de lazo. 803 01:06:57,500 --> 01:07:03,380 Un lazo é realmente grande, neste caso. 804 01:07:03,380 --> 01:07:08,620 E como estaba dicindo, parece que quere un lazo sobre o ficheiro, 805 01:07:08,620 --> 01:07:11,820 obtención dun personaxe de cada vez. 806 01:07:11,820 --> 01:07:13,850 Suxestións sobre o que pode parecer? 807 01:07:13,850 --> 01:07:22,090 [Alexander, inintelixible] 808 01:07:22,090 --> 01:07:30,050 >> Ok, dígame en inglés o que estás a facer? [Alexander, inintelixible] 809 01:07:30,050 --> 01:07:36,270 Polo tanto, neste caso, parece que estamos só tentando varrer o ficheiro. 810 01:07:36,270 --> 01:07:45,330 [Alexander] Entón i > O tamaño -? 811 01:07:45,330 --> 01:07:49,290 Eu creo que o tamaño do arquivo, non? O tamaño - nós só escribir así. 812 01:07:49,290 --> 01:07:57,470 Tamaño do ficheiro para o momento, i + +. 813 01:07:57,470 --> 01:08:04,610 Así, verifícase que a forma de facelo empregando fgetc, e iso é novo, 814 01:08:04,610 --> 01:08:10,460 é que non hai ningunha forma fácil de obter só o tamaño dun ficheiro 815 01:08:10,460 --> 01:08:16,979 con este "sizeof" tipo de construción que xa viu antes. 816 01:08:16,979 --> 01:08:20,910 Cando usamos esa función fgetc, estamos introducindo algún tipo de 817 01:08:20,910 --> 01:08:29,069 sintaxe, novo funky para este loop, onde en vez de usar só un contador básico 818 01:08:29,069 --> 01:08:33,920 ir carácter por carácter, imos tirar un personaxe de cada vez, 819 01:08:33,920 --> 01:08:37,120 un personaxe de cada vez, e de maneira que sabemos que estamos no fin 820 01:08:37,120 --> 01:08:41,290 non é cando temos contado un determinado número de caracteres, 821 01:08:41,290 --> 01:08:49,939 pero cando o personaxe que retire é ese fin específico do ficheiro de caracteres. 822 01:08:49,939 --> 01:08:58,689 Así, podemos facer iso - Eu chamo iso de PC, e nós estamos indo para o arrincar 823 01:08:58,689 --> 01:09:08,050 coa nosa primeira chamada para o primeiro carácter fóra do arquivo. 824 01:09:08,050 --> 01:09:14,979 Entón, esa parte aquí, iso vai obter un personaxe fóra do arquivo 825 01:09:14,979 --> 01:09:20,840 e almacena-lo no ch variable. 826 01:09:20,840 --> 01:09:25,420 Nós imos seguir facendo iso ata chegar ao final do arquivo, 827 01:09:25,420 --> 01:09:41,170 o que facemos por medio de probas para o personaxe non ser igual ao que o personaxe EOF especial. 828 01:09:41,170 --> 01:09:48,750 E, a continuación, en vez de facer o ch + +, o que só aumentar o valor, 829 01:09:48,750 --> 01:09:52,710 por iso, se lemos un fóra a do ficheiro, unha capital dun, digamos, 830 01:09:52,710 --> 01:09:56,810 ch + + nos daría b, e entón teriamos C e D. 831 01:09:56,810 --> 01:09:59,310 Isto claramente non é o que queremos. O que queremos aquí 832 01:09:59,310 --> 01:10:05,830 neste último bit é que queremos obter o próximo personaxe a partir do ficheiro. 833 01:10:05,830 --> 01:10:09,500 >> Entón, como podemos obter o seguinte carácter do ficheiro? 834 01:10:09,500 --> 01:10:13,470 Como podemos obter o primeiro carácter do ficheiro? 835 01:10:13,470 --> 01:10:17,200 [Estudante] fgetfile? Fgetc >> ou, desculpe, estaba totalmente seguro. 836 01:10:17,200 --> 01:10:20,470 Eu grafada aí. Entón, si. 837 01:10:20,470 --> 01:10:26,240 Aquí, en vez de facer ch + +, 838 01:10:26,240 --> 01:10:29,560 Nós só estamos indo a chamar fgetc (arquivo) novo 839 01:10:29,560 --> 01:10:39,180 e almacenar o resultado da nosa variable ch mesmo. 840 01:10:39,180 --> 01:10:43,730 [Pregunta do estudante, inintelixible] 841 01:10:43,730 --> 01:10:52,390 >> Este é o lugar onde estes faces ficheiro * son especiais. 842 01:10:52,390 --> 01:10:59,070 A forma de traballar é que - cando abre por primeira vez - cando facer esa chamada fopen, 843 01:10:59,070 --> 01:11:04,260 o FILE * eficazmente serve como un punteiro para o inicio do proceso. 844 01:11:04,260 --> 01:11:12,830 E entón, cada vez que chamar fgetc, move-se un personaxe a través do arquivo. 845 01:11:12,830 --> 01:11:23,280 Así, sempre que chama iso, está incrementando o punteiro do ficheiro por un carácter. 846 01:11:23,280 --> 01:11:26,210 E cando fgetc novo, está movéndose outro personaxe 847 01:11:26,210 --> 01:11:28,910 e outro personaxe e outro personaxe e outro personaxe. 848 01:11:28,910 --> 01:11:32,030 [Pregunta do estudante, inintelixible] >> E isto - si. 849 01:11:32,030 --> 01:11:34,810 É unha especie de esta maxia debaixo do capó. 850 01:11:34,810 --> 01:11:37,930 Simplemente continúa incrementando a través. 851 01:11:37,930 --> 01:11:46,510 Neste punto, vostede é capaz de realmente traballar cun personaxe. 852 01:11:46,510 --> 01:11:52,150 Entón, como podemos imprimir iso para a pantalla, agora? 853 01:11:52,150 --> 01:11:58,340 Podemos usar a mesma cousa printf que usan antes. 854 01:11:58,340 --> 01:12:00,330 Que temos benvida a empregar todo o semestre. 855 01:12:00,330 --> 01:12:05,450 Podemos chamar printf, 856 01:12:05,450 --> 01:12:21,300 e podemos pasar o personaxe así. 857 01:12:21,300 --> 01:12:27,430 Outra forma de facelo é en vez de usar printf e ter que facer esa secuencia de formato, 858 01:12:27,430 --> 01:12:29,490 Tamén podemos utilizar unha das outras funcións. 859 01:12:29,490 --> 01:12:40,090 Podemos usar fputc, que imprime un carácter para a pantalla, 860 01:12:40,090 --> 01:12:52,580 excepto se olharmos para fputc - deixe-me afastar un pouco. 861 01:12:52,580 --> 01:12:56,430 Vemos o que é bo é que leva no carácter que lemos, utilizando fgetc, 862 01:12:56,430 --> 01:13:05,100 pero entón temos que darlle un fluxo para imprimir. 863 01:13:05,100 --> 01:13:11,850 Podemos tamén usar a función putchar, que pode pór directamente saída estándar. 864 01:13:11,850 --> 01:13:16,070 Polo tanto, hai unha morea de opcións diferentes que pode usar para impresión. 865 01:13:16,070 --> 01:13:19,580 Eles están todos na biblioteca de E / S por defecto. 866 01:13:19,580 --> 01:13:25,150 Sempre que quere imprimir - así printf, por defecto, pode imprimir a norma especial saída de fluxo, 867 01:13:25,150 --> 01:13:27,910 que é a saída estándar. 868 01:13:27,910 --> 01:13:41,300 Así, podemos só se refiren a el como unha especie de maxia este valor, saída estándar aquí. 869 01:13:41,300 --> 01:13:48,410 Oops. Pon o punto e coma fóra. 870 01:13:48,410 --> 01:13:52,790 >> Esta é unha gran cantidade de información nova, funk aquí. 871 01:13:52,790 --> 01:13:58,600 Unha gran parte destas é moi idiomática, no sentido de que este é o código 872 01:13:58,600 --> 01:14:05,700 que está escrito desta forma só porque é limpo de ler, fácil de ler. 873 01:14:05,700 --> 01:14:11,520 Hai moitas formas diferentes de facer iso, moitas funcións diferentes que pode usar, 874 01:14:11,520 --> 01:14:14,680 pero nós só tenden a seguir estes mesmos patróns máis e máis. 875 01:14:14,680 --> 01:14:20,180 Polo tanto, non se Sorprende se ves un código coma este está de novo e de novo. 876 01:14:20,180 --> 01:14:25,690 Todo ben. Neste punto, é preciso romper para o día. 877 01:14:25,690 --> 01:14:31,300 Grazas por vir. Grazas por asistir, se está en liña. E nós imos velo na próxima semana. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]