1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [Odjeljak 5 - ugodnije] 2 00:00:02,500 --> 00:00:04,690 [Rob Bowden - Sveučilište Harvard] 3 00:00:04,690 --> 00:00:07,250 [Ovo je CS50. - CS50.TV] 4 00:00:08,990 --> 00:00:14,250 >> Kao što sam rekao u mom e-pošte, postoji mnogo stvari koje možete koristiti 5 00:00:14,250 --> 00:00:17,060 osim aparata da zapravo učiniti problematična seta. 6 00:00:17,060 --> 00:00:19,910 Preporučujemo vam to učiniti u aparatu samo zato onda možemo lakše pomoći 7 00:00:19,910 --> 00:00:22,070 i znamo kako će se sve raditi. 8 00:00:22,070 --> 00:00:26,950 No, kao jedan primjer gdje možete učiniti stvari ako, recimo, nemate pristup 9 00:00:26,950 --> 00:00:31,570 do aparata ili želite raditi u podrumu znanosti Center - 10 00:00:31,570 --> 00:00:33,090 koji zapravo imaju aparat previše - 11 00:00:33,090 --> 00:00:35,150 ako želite raditi bilo gdje. 12 00:00:35,150 --> 00:00:42,370 Jedan primjer je što ste vidjeli / čuli SSH? 13 00:00:44,380 --> 00:00:47,780 SSH je u osnovi samo kao povezivanje s nečim. 14 00:00:47,780 --> 00:00:51,340 Zapravo, upravo sada sam SSHed u aparat. 15 00:00:51,340 --> 00:00:54,290 Ja nikada ne rade izravno u aparat. 16 00:00:55,930 --> 00:01:01,060 Ovdje je aparat, a ako pogledate dolje vidite ovu IP adresu. 17 00:01:01,060 --> 00:01:03,650 Ja nikada ne rade u aparatu same; 18 00:01:03,650 --> 00:01:08,840 Uvijek sam došao preko na iTerm2 prozora / terminalu prozora. 19 00:01:08,840 --> 00:01:15,910 Možete SSH na tu IP adresu, ssh jharvard@192.168.129.128. 20 00:01:15,910 --> 00:01:20,390 Sjećam se da je broj vrlo lako jer je tako lijepo uzorak. 21 00:01:20,390 --> 00:01:24,920 Ali da će me pitati za moj lozinka, a sada sam u aparatu. 22 00:01:24,920 --> 00:01:33,060 Uglavnom, u ovom trenutku, ako je otvorio terminal unutar aparata, 23 00:01:33,060 --> 00:01:36,350 ovo sučelje, no što bi ga koristiti, je točno isti 24 00:01:36,350 --> 00:01:40,010 kao sučelje Ja sam koristeći ovamo, ali sada ste SSHed. 25 00:01:42,240 --> 00:01:44,920 Vi ne morate SSH na uređaj. 26 00:01:44,920 --> 00:01:52,360 Jedan od primjera drugom mjestu ste mogli SSH na je prilično sam siguran da imaju po defaultu - 27 00:01:52,360 --> 00:01:55,020 Oh. Veći. 28 00:01:55,020 --> 00:02:01,130 Svi vi bi trebali imati po defaultu FAS računa o FAS poslužiteljima. 29 00:02:01,130 --> 00:02:06,840 Za mene, ja bih SSH na rbowden@nice.fas.harvard.edu. 30 00:02:06,840 --> 00:02:11,610 To će vas zatražiti da prvi put, a vi kažete da. 31 00:02:11,610 --> 00:02:15,840 Moj lozinka samo će biti moj FAS lozinkom. 32 00:02:15,840 --> 00:02:22,650 I tako sada, ja sam SSHed na lijepim poslužiteljima, a ja mogu učiniti ništa želim ovdje. 33 00:02:22,650 --> 00:02:28,560 Puno klasa koje možete poduzeti, kao 124, će imati što upload stvari koje se ovdje 34 00:02:28,560 --> 00:02:30,950 zapravo pošaljete svoje skupove problema. 35 00:02:30,950 --> 00:02:34,100 Ali kažu da nemaju pristup vašem uređaju. 36 00:02:34,100 --> 00:02:37,910 Zatim možete napraviti stvari, kao što je ovdje, to će reći - 37 00:02:37,910 --> 00:02:42,160 Ovo je samo naš dio pitanja. 38 00:02:42,160 --> 00:02:45,070 To će vas pitati da to učinite u aparatu. 39 00:02:45,070 --> 00:02:47,790 Umjesto toga, ja ću samo to učiniti na poslužitelju. 40 00:02:47,790 --> 00:02:50,560 Idem unzip to. 41 00:02:50,560 --> 00:02:55,670 Problem će biti da ste navikli koristiti nešto poput gedit 42 00:02:55,670 --> 00:02:58,160 ili bilo unutar uređaja. 43 00:02:58,160 --> 00:03:01,830 Nećeš imati to na FAS poslužitelju. 44 00:03:01,830 --> 00:03:04,110 To je sve samo će biti ovo tekstualno sučelje. 45 00:03:04,110 --> 00:03:09,180 Tako da bi bilo jedan, pokušati naučiti tekst editor da oni imaju. 46 00:03:09,180 --> 00:03:12,130 Oni imaju Nano. 47 00:03:12,130 --> 00:03:14,990 Nano je obično prilično jednostavan za korištenje. 48 00:03:14,990 --> 00:03:19,470 Možete koristiti svoje strijele i upišite obično. 49 00:03:19,470 --> 00:03:21,250 Dakle, to nije teško. 50 00:03:21,250 --> 00:03:24,720 Ako želite dobiti vrlo nestvarno možete koristiti Emacs, 51 00:03:24,720 --> 00:03:29,850 koji se vjerojatno ne bi otvorio jer ja ne znam ni kako se zatvoriti Emacs. 52 00:03:29,850 --> 00:03:32,760 Kontrola X, Kontrola C? Da. 53 00:03:32,760 --> 00:03:35,310 Ili možete koristiti VIM, što je ono što sam koristiti. 54 00:03:35,310 --> 00:03:37,800 I tako oni su vaše mogućnosti. 55 00:03:37,800 --> 00:03:43,830 Ako ne želite da to učinite, možete također, ako pogledate manual.cs50.net-- 56 00:03:43,830 --> 00:03:45,410 Oh. 57 00:03:45,410 --> 00:03:49,920 Na računalu, možete SSH pomoću Putty, 58 00:03:49,920 --> 00:03:51,940 koje ćete morati preuzeti zasebno. 59 00:03:51,940 --> 00:03:55,460 Na Mac, možete jednostavno po defaultu korištenja terminala ili možete preuzeti iTerm2, 60 00:03:55,460 --> 00:03:58,490 koji je kao lijepo, fancy Terminal. 61 00:03:58,490 --> 00:04:03,780 Ako idete na manual.cs50.net vidjet ćete link na Notepad + +, 62 00:04:03,780 --> 00:04:07,120 što je ono što se može koristiti na računalu. 63 00:04:07,120 --> 00:04:13,340 To vam omogućuje da SFTP iz Notepad + +, koji je u osnovi SSH. 64 00:04:13,340 --> 00:04:17,750 Što će to neka ti je urediti svoje datoteke na lokalnoj razini, 65 00:04:17,750 --> 00:04:20,670 i onda kad god želite da ih spasi, ona će vas spasiti da nice.fas, 66 00:04:20,670 --> 00:04:23,670 gdje onda možete ih izvoditi. 67 00:04:23,670 --> 00:04:26,880 A ekvivalent na Mac će biti TextWrangler. 68 00:04:26,880 --> 00:04:28,760 Dakle, to vam omogućuje da učinite istu stvar. 69 00:04:28,760 --> 00:04:32,800 To vam omogućuje uređivanje datoteke na lokalnoj razini, te ih spremiti na nice.fas, 70 00:04:32,800 --> 00:04:35,730 gdje onda možete ih izvoditi. 71 00:04:35,730 --> 00:04:40,400 Dakle, ako ste ikada zapeli bez aparata, imate ove opcije 72 00:04:40,400 --> 00:04:44,230 na dalje raditi svoje skupove problema. 73 00:04:44,230 --> 00:04:48,250 Jedan problem će biti da nećeš imati CS50 knjižnicu 74 00:04:48,250 --> 00:04:51,580 jer nice.fas ne po defaultu imaju to. 75 00:04:51,580 --> 00:04:55,970 Možete preuzeti CS50 knjižnicu - 76 00:04:55,970 --> 00:04:58,470 Ja ne mislim da je potrebno da u ovom trenutku. 77 00:04:58,470 --> 00:05:03,270 Možete preuzeti CS50 knjižnicu i kopirati ga preko nice.fas, 78 00:05:03,270 --> 00:05:07,450 ili mislim u ovom trenutku ne koristite ga više svejedno. 79 00:05:07,450 --> 00:05:12,720 Ili, ako ćemo učiniti, možete za sada ga zamijeniti s 80 00:05:12,720 --> 00:05:18,480 je implementacija funkcija u CS50 knjižnici svejedno. 81 00:05:18,480 --> 00:05:21,370 Tako da ne bi trebalo biti da je mnogo ograničenja. 82 00:05:21,370 --> 00:05:23,710 I to je to. 83 00:05:26,460 --> 00:05:29,820 >> Ja ću se vratiti na aparatu sada, a mi ćemo učiniti sve što je u aparatu. 84 00:05:29,820 --> 00:05:37,510 Gledajući na našem dijelu pitanja, na početku, kao što sam rekao u mom e-pošte, 85 00:05:37,510 --> 00:05:43,620 moramo razgovarati o jednom kratkom li su se trebali gledati. 86 00:05:43,620 --> 00:05:51,980 Imamo preusmjeravanje & cijevi i ova tri pitanja. 87 00:05:51,980 --> 00:05:56,070 >> Za koji potok ne funkcionira kao printf pisati po defaultu? 88 00:05:56,070 --> 00:05:59,130 Dakle potok. Što je struja? 89 00:06:06,520 --> 00:06:15,100 Stream je u osnovi kao da je to samo neke od njih - 90 00:06:15,100 --> 00:06:21,450 To nije ni izvor 1s i 0s. 91 00:06:21,450 --> 00:06:24,920 Struja to je molba za ovdje je standardni van. 92 00:06:24,920 --> 00:06:27,250 I tako standardni izlaz je potok da kada pišete na njega, 93 00:06:27,250 --> 00:06:30,940 se pojavljuje na zaslonu. 94 00:06:30,940 --> 00:06:36,860 Standardni van, tako potoka, to znači da samo napisati 1s i 0s na njega, 95 00:06:36,860 --> 00:06:40,220 a drugi kraj standardni izlaz samo čita iz tog potoka. 96 00:06:40,220 --> 00:06:43,540 To je samo niz 1s i 0s. 97 00:06:43,540 --> 00:06:45,570 Možete pisati potoka ili možete pročitati iz potoka 98 00:06:45,570 --> 00:06:47,950 ovisno o tome što je zapravo potok. 99 00:06:47,950 --> 00:06:52,800 Druge dvije zadane struje su standardni u i standardnom pogreškom. 100 00:06:52,800 --> 00:06:57,540 Standard u je kad god ne GetString, to je za vas čeka na ulaz stvari. 101 00:06:57,540 --> 00:07:01,570 Tako je za vas čeka, to je zapravo čeka na standard u, 102 00:07:01,570 --> 00:07:04,880 što je zapravo ono što ste dobili kad upišete na tipkovnici. 103 00:07:04,880 --> 00:07:07,530 Vi pišete u standardu u. 104 00:07:07,530 --> 00:07:10,050 Standardna pogreška je u osnovi jednak standardnom van, 105 00:07:10,050 --> 00:07:13,280 ali to je specijalizirana za koje prilikom ispisa na standardne pogreške, 106 00:07:13,280 --> 00:07:16,770 ti si trebao samo ispisati poruku o pogrešci na to 107 00:07:16,770 --> 00:07:20,200 tako da možete razlikovati redovitim porukama ispisanim na zaslonu 108 00:07:20,200 --> 00:07:24,560 u odnosu na pogreškama, ovisno o tome da li su otišli na standardni izlaz ili standardne pogreške. 109 00:07:24,560 --> 00:07:28,660 Datoteke previše. 110 00:07:28,660 --> 00:07:32,440 Standardni van, standard u, a standardna pogreška su samo posebni potoci, 111 00:07:32,440 --> 00:07:36,810 ali stvarno bilo koju datoteku, kada otvorite datoteku, ona postaje tok bajtova 112 00:07:36,810 --> 00:07:40,740 gdje možete samo pročitati iz tog potoka. 113 00:07:40,740 --> 00:07:47,770 Vi, za najveći dio, mogu samo zamisliti datoteku kao tok bajtova. 114 00:07:47,770 --> 00:07:51,190 Dakle, ono što potoci oni pisati po defaultu? Standardni van. 115 00:07:51,190 --> 00:07:56,980 >> Koja je razlika između> i >>? 116 00:07:58,140 --> 00:08:03,710 Je li itko gledati video unaprijed? Ok. 117 00:08:03,710 --> 00:08:10,960 > Će biti kako se preusmjeriti na datoteke, 118 00:08:10,960 --> 00:08:15,240 i >> također će se preusmjeriti izlaz u datoteke, 119 00:08:15,240 --> 00:08:17,820 ali umjesto toga će se dodati u datoteku. 120 00:08:17,820 --> 00:08:23,430 Na primjer, recimo da sam se dogoditi da imaju DICT ovdje, 121 00:08:23,430 --> 00:08:27,020 i samo stvari unutar DICT je mačka, mačka, pas, riba, pas. 122 00:08:27,020 --> 00:08:31,530 Jedna naredba da imate na naredbenog retka je mačka, 123 00:08:31,530 --> 00:08:34,539 koji je pravedan idući ispisati ono što je u datoteci. 124 00:08:34,539 --> 00:08:40,679 Dakle, kada kažem mačka dict, to će ispisati mačka, mačka, pas, riba, pas. To je sve što mačka radi. 125 00:08:40,679 --> 00:08:46,280 To znači da je tiskana na standard od mačka, mačka, pas, riba, pas. 126 00:08:46,280 --> 00:08:53,240 Ako sam umjesto želite preusmjeriti da u datoteku, mogu koristiti> i to preusmjeriti na ono što je datoteka. 127 00:08:53,240 --> 00:08:56,460 Nazvat ću datoteku datoteka. 128 00:08:56,460 --> 00:09:00,320 Pa sad, ako ja li, vidjet ću imam novu datoteku pod nazivom datoteke. 129 00:09:00,320 --> 00:09:05,700 I ako sam ga otvoriti, to će imati točno ono što mačka staviti na naredbenog retka. 130 00:09:05,700 --> 00:09:11,040 Pa sad, ako sam to učiniti opet, onda će preusmjeriti izlaz u datoteku, 131 00:09:11,040 --> 00:09:13,930 i ja ću imati istu točno stvar. 132 00:09:13,930 --> 00:09:17,910 Dakle, tehnički, to je potpuno overrode ono što smo imali. 133 00:09:17,910 --> 00:09:22,970 A vidjet ćemo, ako sam promijeniti dict, sam izvadio psa. 134 00:09:22,970 --> 00:09:29,980 Sada, ako mi mačka dict u datoteci opet, idemo imate novu verziju s pas uklonjen. 135 00:09:29,980 --> 00:09:32,400 Tako da ga potpuno nadjačava. 136 00:09:32,400 --> 00:09:36,640 Umjesto toga, ako koristite >>, to će dodati datoteke. 137 00:09:36,640 --> 00:09:40,860 Sada, otvaranje datoteka, vidimo imamo samo dva puta istu stvar tiskani 138 00:09:40,860 --> 00:09:44,920 jer je to bio tamo jednom, onda smo u prilogu izvornika. 139 00:09:44,920 --> 00:09:48,130 Dakle, to je ono što> i >> napraviti. 140 00:09:48,130 --> 00:09:50,580 Da li sljedeći pitati - To ne pita o tome. 141 00:09:50,580 --> 00:09:59,050 >> Drugi koji imamo je <, koji, ako> preusmjerava standardni out, 142 00:09:59,050 --> 00:10:01,970 <Će se preusmjeriti standarda u. 143 00:10:01,970 --> 00:10:12,050 Idemo vidjeti ako imamo primjer. 144 00:10:14,750 --> 00:10:16,930 Ja mogu napisati jedan pravi brzo. 145 00:10:17,870 --> 00:10:25,700 Uzmimo bilo koju datoteku, hello.c. 146 00:10:56,060 --> 00:10:59,070 Relativno jednostavan datoteka. 147 00:10:59,070 --> 00:11:03,570 Ja sam samo dobivanje string, a zatim ispis "Hello" bez obzira na niz Upravo sam ušao bio. 148 00:11:03,570 --> 00:11:07,990 Tako bi pozdraviti i onda. / Bok. 149 00:11:07,990 --> 00:11:10,720 Sada me je navelo da unesete nešto, 150 00:11:10,720 --> 00:11:15,070 što znači da je čeka na stvari koje se upisuju u standardu u. 151 00:11:15,070 --> 00:11:20,450 Tako unijeti što god želim u standardu u. Mi samo htio reći Pozdrav, Rob! 152 00:11:20,450 --> 00:11:23,310 Onda to znači tiskanje standardu iz Pozdrav, Rob! 153 00:11:23,310 --> 00:11:28,860 Ako mi je činiti. / Bok, a zatim preusmjeravanje, 154 00:11:30,740 --> 00:11:34,310 za sada se samo može preusmjeriti iz datoteke. 155 00:11:34,310 --> 00:11:41,720 Dakle, ako sam stavio u neki file, txt, a ja sam stavio Rob, 156 00:11:41,720 --> 00:11:52,300 ako sam pokrenuti bok, a zatim preusmjeriti datoteku txt u. / halo, to će reći Pozdrav, Rob! odmah. 157 00:11:52,300 --> 00:11:57,160 Kada je prvi dobiva GetString i to čeka na standardu u, 158 00:11:57,160 --> 00:12:01,730 standard u više ne čeka na tipkovnici podataka da biste ušli. 159 00:12:01,730 --> 00:12:05,980 Umjesto toga, mi smo preusmjereni standard u čitati iz datoteke txt. 160 00:12:05,980 --> 00:12:10,290 I tako to ide čitati iz datoteke txt, što je samo linija Rob, 161 00:12:10,290 --> 00:12:13,380 i onda će se ispisati Hello, Rob! 162 00:12:13,380 --> 00:12:18,180 A ako sam htio, mogao učiniti. / Pozdrav 00:12:21,500 i onda standardno se da je tisak, koji je Hello, Rob!, 164 00:12:21,500 --> 00:12:24,700 Ja mogu preusmjeriti da u vlastitu datoteku. 165 00:12:24,700 --> 00:12:29,790 Samo ću nazvati datoteku halo - ne, neću, jer to je izvršna - txt2. 166 00:12:29,790 --> 00:12:40,150 Sada, txt2 će imati izlaz. / Hello 00:12:43,520 >> Pitanja? 168 00:12:45,900 --> 00:12:49,090 >> Ok. Dakle ovdje imamo plinovoda. 169 00:12:49,090 --> 00:12:53,510 Cijevi su zadnja jedinica preusmjeravanje. 170 00:12:53,510 --> 00:12:58,750 >> Oh. Valjda još jedan jedinica preusmjeravanje je ako umjesto> ti 2>, 171 00:12:58,750 --> 00:13:01,070 da je preusmjeravanje standardnu ​​pogrešku. 172 00:13:01,070 --> 00:13:06,280 Dakle, ako je nešto pošlo za standardne pogreške, da ne bi dobili staviti u txt2. 173 00:13:06,280 --> 00:13:12,480 Ali primijetite da radim 2>, onda je to još uvijek ispisa Pozdrav, Rob! na naredbenog retka 174 00:13:12,480 --> 00:13:18,600 jer ja sam samo preusmjeravanje standardnu ​​pogrešku, nisam preusmjeravanje standarda van. 175 00:13:18,600 --> 00:13:22,210 Standardna pogreška i standardno se razlikuju. 176 00:13:24,210 --> 00:13:27,080 Ako biste željeli zapravo pisati standardne pogreške, 177 00:13:27,080 --> 00:13:35,080 onda bih mogao promijeniti to biti fprintf na stderr. 178 00:13:35,080 --> 00:13:37,850 Dakle printf, po defaultu, ispisuje na standardni izlaz. 179 00:13:37,850 --> 00:13:41,720 Ako želim ispisati na standardne pogreške ručno, onda moram koristiti fprintf 180 00:13:41,720 --> 00:13:45,010 i odrediti ono što želim za ispis. 181 00:13:45,010 --> 00:13:49,720 Ako umjesto toga sam učinio fprintf stdout, onda je to u osnovi ekvivalent printf. 182 00:13:49,720 --> 00:13:55,530 Ali fprintf za standardne pogreške. 183 00:13:57,790 --> 00:14:03,650 Pa sad, ako sam preusmjeriti to u txt2, Pozdrav, Rob! još uvijek uzimajući tiskan na naredbenog retka 184 00:14:03,650 --> 00:14:08,270 jer to je dobivanje tiskan na standardne pogreške, a ja sam samo preusmjeravanje standarda van. 185 00:14:08,270 --> 00:14:16,420 Ako ja sada preusmjeriti standardnu ​​pogrešku, sada se nije tiskan, a txt2 će biti Pozdrav, Rob! 186 00:14:16,420 --> 00:14:21,910 Tako sada, možete ispisati svoje stvarne pogreške na standardnom pogreškom 187 00:14:21,910 --> 00:14:24,720 i ispisati svoje redovite poruke na standardni izlaz. 188 00:14:24,720 --> 00:14:31,420 I tako kada pokrenete program, možete ga pokrenuti kao. / Pozdrav ovu vrstu s 2> 189 00:14:31,420 --> 00:14:33,800 tako da vaš program će se pokrenuti normalno, 190 00:14:33,800 --> 00:14:38,400 ali sve poruke o pogreškama koje ste dobili možete provjeriti kasnije u svom dnevniku pogreške, 191 00:14:38,400 --> 00:14:44,500 tako pogrešaka, a zatim gledati kasnije i vaš pogreške datoteka će imati bilo kakve pogreške koje su se dogodile. 192 00:14:45,200 --> 00:14:47,540 >> Pitanja? 193 00:14:47,540 --> 00:14:58,070 >> Posljednji je cijev koja možete razmišljati kao vodeći standard iz jedne naredbe 194 00:14:58,070 --> 00:15:01,210 a što je standard u za sljedeću naredbu. 195 00:15:01,210 --> 00:15:05,570 Primjer ovdje je odjek je stvar naredbenog retka 196 00:15:05,570 --> 00:15:11,840 samo da se ide na odjek god sam stavio kao argument. Neću staviti citati. 197 00:15:11,840 --> 00:15:16,150 Echo bla, bla, bla, samo će se ispisati bla, bla, bla. 198 00:15:16,150 --> 00:15:20,600 Prije, kad sam rekao da sam ja morao staviti Rob u txt datoteku 199 00:15:20,600 --> 00:15:28,830 jer ja samo mogu preusmjeriti txt datoteke, umjesto toga, / ako sam jeka Rob 200 00:15:28,830 --> 00:15:35,520 i onda ga u cijevi. / halo, koji će također učiniti istu vrstu stvar. 201 00:15:35,520 --> 00:15:39,160 To je uzimanje izlaz ove naredbe, jeka Rob, 202 00:15:39,160 --> 00:15:43,610 i koristiti ga kao ulaz za. / bok. 203 00:15:44,790 --> 00:15:49,560 Možete misliti o njemu kao prvo preusmjeravanje echo Rob u datoteku 204 00:15:49,560 --> 00:15:54,160 i onda ulaz u. / halo tu datoteku koja je upravo outputted. 205 00:15:54,160 --> 00:15:57,850 Ali to traje privremenu datoteku iz slike. 206 00:16:01,890 --> 00:16:04,460 >> Pitanja o tome? 207 00:16:04,460 --> 00:16:07,150 >> Sljedeće pitanje će uključivati ​​ovo. 208 00:16:07,150 --> 00:16:15,310 Što Plinovod bi mogao koristiti kako bi pronašli broj jedinstvenih imena u datoteci pod nazivom names.txt? 209 00:16:15,310 --> 00:16:24,160 Naredbe Mi ćemo želite koristiti ovdje su jedinstveni, tako uniq, a zatim wc. 210 00:16:24,160 --> 00:16:28,840 Možete napraviti čovjek uniq zapravo pogledati što da radi, 211 00:16:28,840 --> 00:16:34,840 i to samo ide za filtriranje susjedne podudaranje linije od ulaza. 212 00:16:34,840 --> 00:16:40,690 I čovjek wc ide za ispis newline, riječi i bajtova za svaku datoteku. 213 00:16:40,690 --> 00:16:43,760 I posljednji idemo želite koristiti je vrsta, 214 00:16:43,760 --> 00:16:47,410 koji će se samo sortiranje linije txt datoteku. 215 00:16:47,410 --> 00:16:58,080 Ako sam napraviti neki txt, names.txt, i to je Rob, Tommy, Josip, Tommy, Josip, RJ, Rob, 216 00:16:58,080 --> 00:17:03,910 ono što želim učiniti ovdje je pronaći broj jedinstvenih imena u ovoj datoteci. 217 00:17:03,910 --> 00:17:08,750 Dakle, ono što bi trebao biti odgovor? >> [Student] 4. >> Da. 218 00:17:08,750 --> 00:17:13,780 To bi trebao biti 4 od Rob, Tommy, Josipa, RJ su jedina jedinstvena imena u ovoj datoteci. 219 00:17:13,780 --> 00:17:20,180 Prvi korak, ako sam to riječ računati na names.txt, 220 00:17:20,180 --> 00:17:24,290 to je zapravo govori mi sve. 221 00:17:24,290 --> 00:17:32,560 To je zapravo tisak - neka se vidi, čovjek wc - nove linije i dr., riječi i bajt count. 222 00:17:32,560 --> 00:17:38,270 Ako sam samo stalo linije, onda ja samo mogu učiniti wc-l names.txt. 223 00:17:41,730 --> 00:17:44,300 Dakle, to je korak jedan. 224 00:17:44,300 --> 00:17:50,510 Ali ja ne želim da wc-l names.txt jer names.txt samo sadrži sva imena, 225 00:17:50,510 --> 00:17:54,170 i želim da filtrira sve ne-jedinstvene one. 226 00:17:54,170 --> 00:18:01,200 Dakle, ako sam to uniq names.txt, da ne sasvim mi dati ono što želim 227 00:18:01,200 --> 00:18:03,760 jer su dvostruki imena su još uvijek tamo. 228 00:18:03,760 --> 00:18:07,690 Zašto je to? Zašto je uniq ne radi ono što želim? 229 00:18:07,690 --> 00:18:10,500 [Student] U duplikati nisu [nečujno] >> Da. 230 00:18:10,500 --> 00:18:16,370 Zapamtite man stranicu za uniq kaže filter susjedna podudarna linije. 231 00:18:16,370 --> 00:18:19,680 Oni nisu u susjedstvu, tako da ih neće filtrirati. 232 00:18:19,680 --> 00:18:31,100 Ako sam ih poredate prvi, vrsta names.txt će staviti sve duple linije zajedno. 233 00:18:31,100 --> 00:18:34,450 Tako sada vrsta names.txt je to. 234 00:18:34,450 --> 00:18:40,550 Idem želite koristiti kao ulaz na uniq, koji je | uniq. 235 00:18:40,550 --> 00:18:43,390 To mi daje Josipu, RJ, Rob, Tommy, 236 00:18:43,390 --> 00:18:49,260 i želim ga koristiti kao ulaz u wc-l, 237 00:18:49,260 --> 00:18:52,740 koji će mi dati četiri. 238 00:18:52,740 --> 00:18:56,930 Kao da kaže ovdje, ono plinovod mogao koristiti? 239 00:18:56,930 --> 00:19:01,390 To možete učiniti mnogo stvari poput korištenja niz naredbi 240 00:19:01,390 --> 00:19:05,130 gdje ćete koristiti izlaz iz jedne naredbe kao ulaz na sljedeću naredbu. 241 00:19:05,130 --> 00:19:08,780 Možete učiniti puno stvari, puno pametnih stvari. 242 00:19:08,780 --> 00:19:11,440 >> Pitanja? 243 00:19:12,910 --> 00:19:14,600 Ok. 244 00:19:14,600 --> 00:19:17,880 To je to za cijevi i preusmjeravanje. 245 00:19:18,370 --> 00:19:24,090 >> Sada ćemo ići na stvarne stvari, kodiranje stvari. 246 00:19:24,090 --> 00:19:29,100 Unutar ovaj PDF, vidjet ćete ovu naredbu, 247 00:19:29,100 --> 00:19:32,950 i da ćete želite pokrenuti ovu naredbu u vašem uređaju. 248 00:19:36,240 --> 00:19:42,250 wget je naredba za samo dobivanje nešto s interneta, u osnovi, 249 00:19:42,250 --> 00:19:45,180 tako wget i ovaj URL. 250 00:19:45,180 --> 00:19:49,110 Ako ode na ovaj URL u pregledniku, to bi preuzeti tu datoteku. 251 00:19:49,110 --> 00:19:52,510 Upravo sam kliknuo na njega, tako da preuzmete datoteku za mene. 252 00:19:52,510 --> 00:19:55,650 Ali pisanje wget te stvari unutar terminala 253 00:19:55,650 --> 00:19:58,620 samo ide ga preuzeti na svoj terminal. 254 00:19:58,620 --> 00:20:02,750 Imam section5.zip, a vi ćete želite unzip section5.zip, 255 00:20:02,750 --> 00:20:06,520 koji će vam dati mapu pod nazivom section5, 256 00:20:06,520 --> 00:20:11,550 koji će imati sve datoteke idemo da se pomoću danas unutar nje. 257 00:20:33,380 --> 00:20:37,710 Kao ovi programi "datoteka imena sugeriraju, oni su malo lud, 258 00:20:37,710 --> 00:20:40,990 tako da vaš zadatak je shvatiti zašto koristite gdb. 259 00:20:40,990 --> 00:20:44,560 Da li svatko ima ih skinuti / znati kako bi ih preuzeli 260 00:20:44,560 --> 00:20:47,480 u svojoj aparat? Ok. 261 00:20:47,480 --> 00:20:56,400 >> Trčanje ./buggy1, to će reći segmentacije grešku (jezgra bačena), 262 00:20:56,400 --> 00:21:00,500 koji svaki put kada se segfault, to je loša stvar. 263 00:21:00,500 --> 00:21:03,810 Pod kojim okolnostima ne dobijete segfault? 264 00:21:03,810 --> 00:21:08,210 [Student] Dereferencing null pokazivač. >> Da. Dakle, to je jedan primjer. 265 00:21:08,210 --> 00:21:11,580 Dereferencing null pokazivač idete da biste dobili segfault. 266 00:21:11,580 --> 00:21:16,720 Što znači segfault je god dira memoriju da ne bi trebali biti dira. 267 00:21:16,720 --> 00:21:21,350 Dakle dereferencing null pokazivač dodiruje adresu 0, 268 00:21:21,350 --> 00:21:28,060 i zapravo, sva računala danas kažu da je adresa 0 je memorija koju ne treba dira. 269 00:21:28,060 --> 00:21:31,920 Dakle, to je razlog zašto dereferencing null pointer rezultate u segfault. 270 00:21:31,920 --> 00:21:37,210 Kada vam se dogoditi da ne inicijalizirati pokazivač, onda to ima smeća vrijednost, 271 00:21:37,210 --> 00:21:41,520 pa kada pokušate dereference to, po svemu sudeći ste dira memoriju 272 00:21:41,520 --> 00:21:43,540 koji je u sredini nigdje. 273 00:21:43,540 --> 00:21:45,650 Ako vam se dogoditi da se posreći i smeća vrijednost 274 00:21:45,650 --> 00:21:48,440 dogodilo ukazati na negdje na stogu ili nešto, 275 00:21:48,440 --> 00:21:50,820 onda kada dereference da pokazivač koji niste inicijaliziran, 276 00:21:50,820 --> 00:21:52,730 ništa neće poći po zlu. 277 00:21:52,730 --> 00:21:55,480 No, ako je pokazujući na, recimo, negdje između dimnjaka i gomile, 278 00:21:55,480 --> 00:21:59,850 ili to pokazuje samo negdje da nije bio korišten od strane svog programa, ali, 279 00:21:59,850 --> 00:22:02,240 onda ste dira memoriju da ne bi trebali biti dodirivanje i segfault. 280 00:22:02,240 --> 00:22:06,370 Kada napisati rekurzivni funkciju i to recurses previše puta 281 00:22:06,370 --> 00:22:08,720 i vaš stog raste prevelika i slagati sudara u stvari 282 00:22:08,720 --> 00:22:12,270 da to ne bi trebao biti sudara s, ti si dira memoriju da ne bi trebali biti dira, 283 00:22:12,270 --> 00:22:14,810 tako da segfault. 284 00:22:14,810 --> 00:22:17,010 To je ono što segfault je. 285 00:22:17,010 --> 00:22:21,810 >> To je također isti razlog da, ako imate niz poput - 286 00:22:21,810 --> 00:22:23,930 Vratimo se na prethodni program. 287 00:22:23,930 --> 00:22:28,530 U hello.c--Ja sam samo će učiniti nešto drugo. 288 00:22:28,530 --> 00:22:33,770 char * s = "Hello World!"; 289 00:22:33,770 --> 00:22:42,310 Ako sam koristiti * s = nešto ili s [0] = 'X'; 290 00:22:42,310 --> 00:22:47,290 tako da bi halo,. / halo, zašto da segfault? 291 00:22:48,410 --> 00:22:51,250 Zašto to segfault? 292 00:22:55,660 --> 00:22:57,890 Što bi vi očekujete da će se dogoditi? 293 00:22:57,890 --> 00:23:06,640 Ako sam printf ("% s \ n", a); što bi vi očekujete da će se ispisati? 294 00:23:06,640 --> 00:23:09,930 [Student] X bok. >> Da. 295 00:23:09,930 --> 00:23:15,140 Problem je u tome da kada se proglasi string ovako, 296 00:23:15,140 --> 00:23:18,190 a je pokazivač koji će ići na stog, 297 00:23:18,190 --> 00:23:25,880 i ono što je ukazuje na to je niz koji je sadržan u samo za čitanje memorije. 298 00:23:25,880 --> 00:23:30,560 Dakle, samo po imenu, samo za čitanje memorije, te bi trebao dobiti ideju 299 00:23:30,560 --> 00:23:33,010 da, ako pokušate promijeniti ono što je samo za čitanje memorije, 300 00:23:33,010 --> 00:23:36,670 radite nešto što ne bi trebao biti događaj s pamćenjem i segfault. 301 00:23:36,670 --> 00:23:45,360 To je zapravo velika razlika između char * s, a char s []. 302 00:23:45,360 --> 00:23:48,790 Dakle char s [], sada ovaj niz će se staviti na stog, 303 00:23:48,790 --> 00:23:53,960 i stog nije samo za čitanje, što znači da bi to trebalo raditi savršeno u redu. 304 00:23:55,500 --> 00:23:57,370 I to radi. 305 00:23:57,370 --> 00:24:06,250 Zapamtite da kada radim char * s = "Hello World!", A sama je na stogu 306 00:24:06,250 --> 00:24:10,390 ali s točke na negdje drugdje, a da negdje drugdje dogodi da se samo za čitanje. 307 00:24:10,390 --> 00:24:15,640 Ali char s [] je samo nešto na stog. 308 00:24:17,560 --> 00:24:21,760 Dakle, to je još jedan primjer segfault događa. 309 00:24:21,760 --> 00:24:27,820 >> Vidjeli smo da je ./buggy1 rezultiralo segfault. 310 00:24:27,820 --> 00:24:31,810 U teoriji, da ne bi trebali gledati na buggy1.c odmah. 311 00:24:31,810 --> 00:24:35,170 Umjesto toga, mi ćemo gledati na to kroz gdb. 312 00:24:35,170 --> 00:24:37,750 Primijetit ćete da kada se segmentacije grešku (jezgra bačena), 313 00:24:37,750 --> 00:24:40,850 ste dobili ovu datoteku ovamo zove jezgre. 314 00:24:40,850 --> 00:24:45,200 Ako smo ls-l, vidjet ćemo da je jezgra je obično prilično velika datoteka. 315 00:24:45,200 --> 00:24:51,580 To je broj bajtova u datoteci, tako da izgleda kao da je 250 i nešto kilobajta. 316 00:24:51,580 --> 00:24:56,120 Razlog za to je da je ono što je srž deponij zapravo je 317 00:24:56,120 --> 00:25:01,410 kada je vaš program ruši, stanje memorije vašeg programa 318 00:25:01,410 --> 00:25:05,230 samo dobiva kopirati i zalijepiti u ovoj datoteci. 319 00:25:05,230 --> 00:25:07,270 Ona dobiva bačena u toj datoteci. 320 00:25:07,270 --> 00:25:13,060 Ovaj program, a to je trčanje, dogodilo da su memorije od oko 250 kilobajta, 321 00:25:13,060 --> 00:25:17,040 pa to je ono što je dobio bačena u ovoj datoteci. 322 00:25:17,040 --> 00:25:23,630 Sada možete gledati na tu datoteku, ako mi GDB buggy1 jezgru. 323 00:25:23,630 --> 00:25:30,130 Mi samo možemo učiniti gdb buggy1, i da će samo pokrenuti gdb redovito, 324 00:25:30,130 --> 00:25:33,800 pomoću buggy1 kao ulazne datoteke. 325 00:25:33,800 --> 00:25:38,260 Ali ako ne GDB buggy1 jezgru, onda je to posebno će se pokrenuti gdb 326 00:25:38,260 --> 00:25:40,330 gledanjem na toj jezgri datoteke. 327 00:25:40,330 --> 00:25:45,560 I rekavši buggy1 znači gdb zna da je jezgra datoteku dolazi iz buggy1 programa. 328 00:25:45,560 --> 00:25:49,580 Dakle gdb buggy1 jezgra će odmah donijeti nam 329 00:25:49,580 --> 00:25:52,060 na kojem je program dogodilo prekinuti. 330 00:25:57,720 --> 00:26:02,340 Ovdje vidimo program prestaje sa signalom 11, Segmentacija kvara. 331 00:26:02,340 --> 00:26:10,110 Mi se dogoditi da vidi liniju skupštine, koja vjerojatno nije vrlo korisno. 332 00:26:10,110 --> 00:26:15,360 Ali ako upišete BT ili Povratno praćenje, koji će biti funkcija 333 00:26:15,360 --> 00:26:19,430 koji nam daje popis naših trenutnih stog okvire. 334 00:26:19,430 --> 00:26:23,150 Dakle povratno praćenje. Izgleda imamo samo dva dimnjaka okvire. 335 00:26:23,150 --> 00:26:26,310 Prvi je naš glavni stog okvir, 336 00:26:26,310 --> 00:26:29,810 a drugi je stog okvir za ovu funkciju da mi se dogoditi da se u, 337 00:26:29,810 --> 00:26:34,440 koji izgleda kao imamo samo sklopa kod za. 338 00:26:34,440 --> 00:26:38,050 Dakle, vratimo se u našem glavnom funkcijom, 339 00:26:38,050 --> 00:26:42,300 i da to možemo učiniti okvir jedne, i mislim da možemo napraviti prema dolje, 340 00:26:42,300 --> 00:26:45,160 ali ja gotovo nikad ne dolje - ili gore. Da. 341 00:26:45,160 --> 00:26:50,710 Gore i dolje. Gore vam donosi jednu stog okvir, dolje vam donosi niz stog okvir. 342 00:26:50,710 --> 00:26:53,240 I imaju tendenciju da nikada koristiti. 343 00:26:53,240 --> 00:26:59,120 Upravo sam konkretno reći okvir 1, koji se ići na okvir s oznakom 1. 344 00:26:59,120 --> 00:27:01,750 Okvir 1 će nas dovesti u glavnom stog okvir, 345 00:27:01,750 --> 00:27:05,570 i to kaže ovdje liniju koda mi se dogoditi da se na. 346 00:27:05,570 --> 00:27:07,950 Ako smo htjeli još par linija koda, možemo reći popis, 347 00:27:07,950 --> 00:27:11,280 i da će nam dati sve linije koda oko nje. 348 00:27:11,280 --> 00:27:13,360 Linija mi segfaulted na bilo 6: 349 00:27:13,360 --> 00:27:17,360 if (strcmp ("CS50 stijene", argv [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 Ako to nije očito još, možete ga dobiti ravno iz ovdje samo razmišljam zašto segfaulted. 351 00:27:24,130 --> 00:27:28,800 No, možemo ga uzeti jedan korak dalje i reći: "Zašto bi argv [1] segfault?" 352 00:27:28,800 --> 00:27:38,830 Idemo ispis argv [1], i to izgleda kao da je 0x0, koji je null pokazivač. 353 00:27:38,830 --> 00:27:44,750 Mi smo strcmping CS50 stijene i Null, i to tako da će segfault. 354 00:27:44,750 --> 00:27:48,280 I zašto je argv [1] null? 355 00:27:48,640 --> 00:27:51,280 [Student] Zato mi nije dao nikakve ga naredbenog retka argumente. 356 00:27:51,280 --> 00:27:53,390 Da. Nismo mu dati nikakve naredbenog retka argumente. 357 00:27:53,390 --> 00:27:58,460 Dakle ./buggy1 samo će imati argv [0] biti ./buggy1. 358 00:27:58,460 --> 00:28:02,100 To neće imati argv [1], tako da će segfault. 359 00:28:02,100 --> 00:28:07,450 Ali ako, umjesto toga, radim samo CS50, to će reći ćete dobiti D 360 00:28:07,450 --> 00:28:09,950 jer to je ono što je trebao učiniti. 361 00:28:09,950 --> 00:28:15,240 Gledajući buggy1.c, to je trebalo ispisati "Ti dvojku" - 362 00:28:15,240 --> 00:28:20,820 Ako argv [1] nije "CS50 stijene", "Ti dvojku", drugi "Možete dobiti!" 363 00:28:20,820 --> 00:28:25,660 Dakle, ako želimo, trebamo to usporediti kao istinito, 364 00:28:25,660 --> 00:28:28,710 što znači da je to uspoređuje s 0. 365 00:28:28,710 --> 00:28:31,100 Dakle, argv [1] treba biti "CS50 stijene". 366 00:28:31,100 --> 00:28:35,660 Ako želite to učiniti na naredbenog retka, morate koristiti \ pobjeći prostor. 367 00:28:35,660 --> 00:28:41,690 Dakle CS50 \ stijene i dobijete A! 368 00:28:41,690 --> 00:28:44,060 Ako to ne učinite crticu, zašto to ne rade? 369 00:28:44,060 --> 00:28:47,190 [Student] To je dvije različite argumente. >> Da. 370 00:28:47,190 --> 00:28:52,540 Argv [1] će biti CS50 i argv [2] koja će se stijene. Ok. 371 00:28:52,540 --> 00:28:56,470 >> Sada ./buggy2 će segfault opet. 372 00:28:56,470 --> 00:29:01,880 Umjesto otvarajući ga sa svojim osnovnim datoteku, samo ćemo otvoriti buggy2 izravno, 373 00:29:01,880 --> 00:29:05,000 tako gdb buggy2. 374 00:29:05,000 --> 00:29:09,590 Sada, ako smo samo pokrenuti naš program, onda će to reći Program dobio signal SIGSEGV, 375 00:29:09,590 --> 00:29:15,530 koji je segfault signal, a to je mjesto gdje se to dogodilo da se dogodi. 376 00:29:15,530 --> 00:29:21,250 Gledajući naše Povratno praćenje, vidimo da smo bili u funkciji oh_no, 377 00:29:21,250 --> 00:29:23,900 koji je pozvao funkciju Dinky, koji je bio pozvan od strane funkcije binky, 378 00:29:23,900 --> 00:29:26,460 koji je pozvao glavni. 379 00:29:26,460 --> 00:29:31,680 Također možemo vidjeti argumente za ove funkcije. 380 00:29:31,680 --> 00:29:34,680 Argument da Dinky i binky bio jedan. 381 00:29:34,680 --> 00:29:44,390 Ako ćemo navesti funkcije oh_no, vidimo da oh_no samo radi char ** S = NULL; 382 00:29:44,390 --> 00:29:47,410 * S = "BOOM"; 383 00:29:47,410 --> 00:29:50,330 Zašto bi to uspjeti? 384 00:29:54,330 --> 00:29:58,380 [Student] Vi ne možete dereference nul pokazivač? >> Da. 385 00:29:58,380 --> 00:30:06,090 To samo govori a je NULL, bez obzira na to, ako se to dogodi biti char **, 386 00:30:06,090 --> 00:30:12,070 koji, ovisno o tome kako ga tumače, to bi mogao biti pokazivač na pokazivač na niz 387 00:30:12,070 --> 00:30:15,550 ili niz žice. 388 00:30:15,550 --> 00:30:21,430 To je i je NULL, pa * s je dereferencing null pokazivač, 389 00:30:21,430 --> 00:30:24,800 i tako to ide na sudar. 390 00:30:24,800 --> 00:30:27,540 To je jedan od najbržih načina možete eventualno segfault. 391 00:30:27,540 --> 00:30:31,300 To je samo proglašenje null pokazivač i odmah segfaulting. 392 00:30:31,300 --> 00:30:34,570 To je ono što oh_no radi. 393 00:30:34,570 --> 00:30:43,400 Ako ćemo ići gore jedan okvir, onda ćemo ući u funkciju koja se zove oh_no. 394 00:30:43,400 --> 00:30:44,830 Moram to učiniti dolje. 395 00:30:44,830 --> 00:30:48,610 Ako ne unesete naredbu, a vi samo pritisnite Enter opet, 396 00:30:48,610 --> 00:30:52,350 samo će ponoviti prethodne naredbe koje ste pokrenuli. 397 00:30:52,350 --> 00:30:56,610 Mi smo u okviru jedne. 398 00:30:56,610 --> 00:31:04,650 Oglas tog okvira, vidimo ovdje je naša funkcija. 399 00:31:04,650 --> 00:31:08,520 Možete pogoditi popis opet, ili možete napraviti popis 20 i on će se popis više. 400 00:31:08,520 --> 00:31:13,640 Funkcija nakićen kaže ako je i jedan, a zatim otići na oh_no funkciji, 401 00:31:13,640 --> 00:31:15,960 drugdje ići na graciozan funkciji. 402 00:31:15,960 --> 00:31:18,700 A znamo i iznosi 1 jer mi se dogoditi da vidim ovdje 403 00:31:18,700 --> 00:31:22,560 da nakićen zvao s argumentom jedan. 404 00:31:22,560 --> 00:31:27,560 Ili možete jednostavno moram ispisati i to će reći da sam je jednom. 405 00:31:27,560 --> 00:31:33,770 Mi smo trenutno u Dinky, a ako odemo još jedan okvir, znamo da ćemo završiti u binky. 406 00:31:33,770 --> 00:31:36,600 Gore. Sada smo u binky. 407 00:31:36,600 --> 00:31:41,340 Oglas ovu funkciju - popis od prije polovine me satre - 408 00:31:41,340 --> 00:31:52,670 ona je započela kao da sam je 0, onda ćemo ga nazvati oh_no, drugačije nazvati nakićen. 409 00:31:52,670 --> 00:31:57,000 Znamo bio sam jednom, tako se zove nakićen. 410 00:31:57,000 --> 00:32:05,030 I sad smo se vratili u glavni, a glavna samo će biti int i = rand ()% 3; 411 00:32:05,030 --> 00:32:08,790 To samo će vam dati slučajni broj koji je bilo 0, 1 ili 2. 412 00:32:08,790 --> 00:32:12,780 To će se zvati binky s tim brojem, a to će se vratiti 0. 413 00:32:12,780 --> 00:32:16,700 Gledajući to, 414 00:32:16,700 --> 00:32:19,880 samo hodanje kroz program ručno bez trčanje odmah, 415 00:32:19,880 --> 00:32:25,400 ti bi postavili break na glavnom, što znači da kada smo pokrenuti program 416 00:32:25,400 --> 00:32:31,020 vaš program radi dok ne udari break. 417 00:32:31,020 --> 00:32:35,450 Dakle pokretanja programa, ona će se izvoditi i onda će pogoditi glavnu funkciju i prestati prikazivati. 418 00:32:35,450 --> 00:32:44,700 Sada smo unutar glavna, i korak ili sljedećeg će nas dovesti do sljedećeg retka koda. 419 00:32:44,700 --> 00:32:47,050 Možete napraviti korak ili sljedeći. 420 00:32:47,050 --> 00:32:51,800 Udaranje sljedeći, sada sam je postavljen na rand ()% 3, tako da možemo ispisati vrijednost i, 421 00:32:51,800 --> 00:32:55,280 a to će reći da sam je jednom. 422 00:32:55,280 --> 00:32:58,110 Sada to ne obzira da li možemo koristiti sljedeći korak ili. 423 00:32:58,110 --> 00:33:01,000 Mislim da je važno u prethodnom jedan, ali mi bi željeli koristiti sljedeći. 424 00:33:01,000 --> 00:33:06,000 Ako ćemo koristiti korak, stupamo u funkciju, što znači pogledati na stvar 425 00:33:06,000 --> 00:33:07,940 što se događa unutar binky. 426 00:33:07,940 --> 00:33:10,510 Ako koristite sljedeći, onda to znači ići preko funkciju 427 00:33:10,510 --> 00:33:14,070 i samo ići na sljedeći redak koda u našem glavnom funkciji. 428 00:33:14,070 --> 00:33:17,900 Upravo ovdje na ovoj liniji, bio sam u kojem je rekao rand ()% 3; 429 00:33:17,900 --> 00:33:21,320 ako sam učinio korak, to će ići u provedbu rand 430 00:33:21,320 --> 00:33:25,110 i pogledati što se događa tamo, a ja sam mogao proći kroz rand funkcije. 431 00:33:25,110 --> 00:33:26,920 Ali ja ne stalo rand funkcije. 432 00:33:26,920 --> 00:33:30,190 Ja samo želim ići na sljedeći redak koda u glavnom, pa sam koristiti sljedeći. 433 00:33:30,190 --> 00:33:35,800 Ali sada imam brigu o binky funkciju, pa želim da korak u tome. 434 00:33:35,800 --> 00:33:37,730 Sada sam u binky. 435 00:33:37,730 --> 00:33:42,040 Prva linija koda će reći ako (i == 0), sam uzeti jedan korak, 436 00:33:42,040 --> 00:33:44,930 vidimo se završiti na Dinky. 437 00:33:44,930 --> 00:33:51,620 Ako smo popis stvari, vidjet ćemo da je to provjerio je i = 0. 438 00:33:51,620 --> 00:33:55,470 i je nije jednaka 0, tako da ode u drugo stanje, 439 00:33:55,470 --> 00:33:59,540 koji će se nazvati Dinky (i). 440 00:33:59,540 --> 00:34:04,030 Možda se zbuniti. 441 00:34:04,030 --> 00:34:07,380 Ako samo pogledate ovih redaka izravno, možda mislite da ako (i == 0), 442 00:34:07,380 --> 00:34:10,800 ok, onda sam uzeo korak i sada sam na Dinky (i), 443 00:34:10,800 --> 00:34:14,120 možda mislite da mora značiti i = 0 ili nešto. 444 00:34:14,120 --> 00:34:18,980 Ne, to samo znači da se zna da može staviti izravno na liniji Dinky (i). 445 00:34:18,980 --> 00:34:23,300 Jer ja ne 0, sljedeći korak ne ide do kraja u drugi. 446 00:34:23,300 --> 00:34:26,239 Inače nije linija će to zaustaviti na. 447 00:34:26,239 --> 00:34:31,570 To je samo ići na sljedeći redak to zapravo može realizirati, što je nakićen (ja). 448 00:34:31,570 --> 00:34:36,090 Ulazeći u Dinky (ja), vidimo ako (i == 1). 449 00:34:36,090 --> 00:34:42,670 Mi ne znamo i = 1, pa kad smo korak, znamo da ćemo završiti u oh_no 450 00:34:42,670 --> 00:34:46,489 jer sam = 1 naziva funkcije oh_no, koju može stati u, 451 00:34:46,489 --> 00:34:52,969 koja će se postaviti char ** s = na NULL i odmah "bum". 452 00:34:54,270 --> 00:34:59,690 I onda zapravo gleda na provedbi buggy2, 453 00:34:59,690 --> 00:35:04,590 to, ja samo dobivanje slučajni broj - 0, 1, ili 2 - poziv binky, 454 00:35:04,590 --> 00:35:10,610 što ako ja je 0 to zove oh_no, inače naziva nakićen, koji dolazi ovdje. 455 00:35:10,610 --> 00:35:18,100 Ako sam je jednom, poziv oh_no, drugačije nazvati graciozan, koji dolaze ovdje, 456 00:35:18,100 --> 00:35:20,460 ako je i 2, nazovite oh_no. 457 00:35:20,460 --> 00:35:24,720 Ja čak ne mislim da postoji način - 458 00:35:24,720 --> 00:35:30,030 Da li itko vidi način izrade ovaj program koji neće segfault? 459 00:35:30,030 --> 00:35:37,530 Jer ako sam nešto nedostaje, ako je i 0, odmah ćete segfault, 460 00:35:37,530 --> 00:35:41,250 drugo idete u funkciji što ako sam je jednom ste segfault, 461 00:35:41,250 --> 00:35:44,540 drugo idete u funkciji gdje ako je i dvije ste segfault. 462 00:35:44,540 --> 00:35:46,810 Dakle, bez obzira što radite, segfault. 463 00:35:46,810 --> 00:35:52,380 >> Valjda jedan način popravljajući to će biti umjesto da radiš char ** S = NULL, 464 00:35:52,380 --> 00:35:55,610 mogli malloc prostor za taj niz. 465 00:35:55,610 --> 00:36:04,230 Mogli smo učiniti malloc (sizeof) - sizeof što? 466 00:36:09,910 --> 00:36:15,190 [Student] (char) * 5? >> Da li to činiti zar ne? 467 00:36:15,190 --> 00:36:21,060 Ja sam uz pretpostavku da će raditi ako sam ga zapravo trčao, ali to nije ono što ja tražim. 468 00:36:24,400 --> 00:36:32,940 Pogledajte vrsti s.. Dodajmo int *, tako int * x. 469 00:36:32,940 --> 00:36:35,600 Ja bih to malloc (sizeof (int)). 470 00:36:35,600 --> 00:36:40,490 Ili, ako sam htio niz 5, ja bih to (sizeof (int) * 5); 471 00:36:40,490 --> 00:36:44,210 Što ako imam int **? 472 00:36:46,260 --> 00:36:49,140 Što bih malloc? 473 00:36:49,140 --> 00:36:53,510 [Student] Veličina pokazivača. >> Da. (Sizeof (int *)); 474 00:36:53,510 --> 00:36:56,960 Ista stvar ovdje dolje. 475 00:36:56,960 --> 00:37:01,280 Želim (sizeof (char *)); 476 00:37:06,170 --> 00:37:12,840 To će se alocirati prostor za pokazivač koji upućuje na "bum". 477 00:37:12,840 --> 00:37:15,330 Ne trebam izdvojiti prostor za "bum" sama 478 00:37:15,330 --> 00:37:17,210 jer je to u osnovi ekvivalent onoga što sam rekao prije 479 00:37:17,210 --> 00:37:20,870 od char * x = "BOOM". 480 00:37:20,870 --> 00:37:27,950 "BOOM" već postoji. To se događa da postoje u read-only regiji memorije. 481 00:37:27,950 --> 00:37:35,200 Ali to već postoji, što znači ovaj redak koda, ukoliko je char **, 482 00:37:35,200 --> 00:37:43,900 onda * s je char * i da postavljate ovu char * ukazati na "bum". 483 00:37:43,900 --> 00:37:50,040 Ako sam htjela kopirati "boom" u s., onda bih morati izdvojiti prostor za s.. 484 00:37:55,170 --> 00:38:03,900 Učinit ću * s = malloc (sizeof (char) * 5); 485 00:38:03,900 --> 00:38:06,210 Zašto pet? 486 00:38:06,210 --> 00:38:10,860 Zašto ne 4? To izgleda kao "boom" 4 znaka. >> [Student] null karakter. 487 00:38:10,860 --> 00:38:14,580 Da. Sve svoje žice će trebati null karakter. 488 00:38:14,580 --> 00:38:23,590 Sada ja mogu učiniti nešto poput strcat - Što je funkcija za kopiranje niz? 489 00:38:23,590 --> 00:38:28,520 [Student] KPJ? >> Strcpy. 490 00:38:28,520 --> 00:38:32,700 Čovjek strcpy. 491 00:38:36,120 --> 00:38:39,590 Dakle strcpy ili strncpy. 492 00:38:39,590 --> 00:38:43,410 strncpy je malo sigurnije jer možete odrediti točno koliko znakova, 493 00:38:43,410 --> 00:38:46,190 ali ovdje to ne smeta, jer mi znamo. 494 00:38:46,190 --> 00:38:50,340 Dakle strcpy i gledati u argumente. 495 00:38:50,340 --> 00:38:53,100 Prvi argument je naše odredište. 496 00:38:53,100 --> 00:38:56,770 Drugi argument je naš izvor. 497 00:38:56,770 --> 00:39:10,310 Mi idemo kopirati u našem mjestu * S pokazivač "bum". 498 00:39:10,310 --> 00:39:19,820 Zašto bi želite učiniti sa strcpy umjesto samo ono što smo imali prije 499 00:39:19,820 --> 00:39:22,800 od * s = "BOOM"? 500 00:39:22,800 --> 00:39:28,630 Tu je razlog možda želite to učiniti, ali što je to razlog? 501 00:39:28,630 --> 00:39:31,940 [Student] Ako želite nešto promijeniti u "boom". >> Da. 502 00:39:31,940 --> 00:39:37,950 Sada mogu učiniti nešto slično s [0] = 'X'; 503 00:39:37,950 --> 00:39:48,190 jer s točke na hrpu i da je prostor na hrpi koja je okrenuta prema 504 00:39:48,190 --> 00:39:52,320 je pokazivač više prostora na hrpu, koja je čuvanje "bum". 505 00:39:52,320 --> 00:39:55,150 Dakle, ovaj primjerak "boom" koji se pohranjuju u gomili. 506 00:39:55,150 --> 00:39:58,780 Postoje tehnički dvije kopije "bum" u našem programu. 507 00:39:58,780 --> 00:40:03,500 Tu je prvi onaj koji je samo dao ovaj "bum" string konstante, 508 00:40:03,500 --> 00:40:09,250 a drugi primjerak "boom", strcpy stvorio primjerak "bum". 509 00:40:09,250 --> 00:40:13,100 Ali primjerak "boom" koji se spremaju na hrpi, i hrpa ste slobodni promijeniti. 510 00:40:13,100 --> 00:40:17,250 Gomila ne samo za čitanje, tako da znači da je [0] 511 00:40:17,250 --> 00:40:20,500 će vam promijeniti vrijednost "bum". 512 00:40:20,500 --> 00:40:23,130 To će vam promijeniti te znakove. 513 00:40:23,130 --> 00:40:26,640 >> Pitanja? 514 00:40:27,740 --> 00:40:29,290 Ok. 515 00:40:29,290 --> 00:40:35,500 >> Premještanje na buggy3, ajmo GDB buggy3. 516 00:40:35,500 --> 00:40:39,840 Mi samo ga pokrenuti, a vidimo što smo dobili segfault. 517 00:40:39,840 --> 00:40:46,550 Ako povratno praćenje, postoje samo dvije funkcije. 518 00:40:46,550 --> 00:40:52,970 Ako idemo u našem glavnom funkcijom, vidjet ćemo da smo segfaulted na toj liniji. 519 00:40:52,970 --> 00:41:00,180 Dakle, samo gleda na toj liniji, za (int redak = 0; fgets ove stvari ne jednak NULL; 520 00:41:00,180 --> 00:41:03,770 linija + +). 521 00:41:03,770 --> 00:41:08,010 Naša prethodna okvir zvao _IO_fgets. 522 00:41:08,010 --> 00:41:10,720 Vidjet ćete da je puno s ugrađenim u C funkcija, 523 00:41:10,720 --> 00:41:15,350 da kad ste dobili segfault, tu će biti jako grobni imena funkcija 524 00:41:15,350 --> 00:41:18,090 kao što je ovaj _IO_fgets. 525 00:41:18,090 --> 00:41:21,770 No, to će se odnositi na ovom fgets poziva. 526 00:41:21,770 --> 00:41:25,850 Negdje u ovdje, mi smo segfaulting. 527 00:41:25,850 --> 00:41:30,340 Ako gledamo argumenata za fgets, možemo ispisati tampon. 528 00:41:30,340 --> 00:41:41,180 Ajmo ispisati - Oh, ne. 529 00:41:48,980 --> 00:41:51,900 Ispis se ne ide na posao točno onako kako želim da. 530 00:41:55,460 --> 00:41:58,000 Pogledajmo stvarni programa. 531 00:42:02,200 --> 00:42:09,640 Pufer je lik polje. To je lik niz od 128 znakova. 532 00:42:09,640 --> 00:42:14,980 Dakle, kada kažem ispis tampon, to će ispisati one 128 znakova, 533 00:42:14,980 --> 00:42:18,300 koja valjda je ono što se očekuje. 534 00:42:18,300 --> 00:42:21,390 Ono što sam bio u potrazi za je ispisati adresu tampon, 535 00:42:21,390 --> 00:42:23,680 ali to zapravo ne da mi puno. 536 00:42:23,680 --> 00:42:30,770 Dakle, kada sam se dogoditi da kažu ovdje x tampon, to mi pokazuje 0xbffff090, 537 00:42:30,770 --> 00:42:38,690 koja, ako se sjećate iz ranije ili nekom trenutku, Oxbffff tendira da bude stog-ish regija. 538 00:42:38,690 --> 00:42:46,020 Stog sklon početi negdje samo pod 0xc000. 539 00:42:46,020 --> 00:42:51,890 Samo gledajući ovu adresu, znam da tampon se događa na stog. 540 00:42:51,890 --> 00:43:04,500 Ponovno moj program, trčanje, gore, tampon smo vidjeli bio ovaj slijed znakova 541 00:43:04,500 --> 00:43:06,530 da su prilično besmisleno. 542 00:43:06,530 --> 00:43:12,270 Zatim ispis datoteke, što znači datoteka izgledati? 543 00:43:15,120 --> 00:43:17,310 [Student] Null. >> Da. 544 00:43:17,310 --> 00:43:22,610 Datoteka je tipa FILE *, tako da je pokazivač, 545 00:43:22,610 --> 00:43:26,610 i vrijednost tog pokazivača null. 546 00:43:26,610 --> 00:43:33,240 Dakle fgets će pokušati pročitati iz tog pokazivač na posredan način, 547 00:43:33,240 --> 00:43:37,320 ali kako pristupiti tom pokazivač, ima da ga dereference. 548 00:43:37,320 --> 00:43:40,550 Ili, kako bi pristupili ono što bi trebao biti ukazujući na, on ga dereferences. 549 00:43:40,550 --> 00:43:43,810 Dakle, to je dereferencing null pokazivač i to segfaults. 550 00:43:46,600 --> 00:43:48,730 Mogao sam ga ponovno tamo. 551 00:43:48,730 --> 00:43:52,170 Ako smo razbiti u našem glavnom točkom i pokrenuti, 552 00:43:52,170 --> 00:43:57,320 Prva linija koda je char * filename = "nonexistent.txt"; 553 00:43:57,320 --> 00:44:00,870 To bi trebalo dati prilično veliku savjet o tome zašto ovaj program ne uspije. 554 00:44:00,870 --> 00:44:06,080 Tipkanje pored me dovodi do sljedećeg retka, gdje sam otvoriti ovu datoteku, 555 00:44:06,080 --> 00:44:11,140 i onda sam odmah ući u našu liniju, gdje je nekada sam pogodio sljedeći, to će segfault. 556 00:44:11,140 --> 00:44:16,880 Se bilo tko želi izbaciti razlog zašto bismo se segfaulting? 557 00:44:16,880 --> 00:44:19,130 [Student] Datoteka ne postoji. >> Da. 558 00:44:19,130 --> 00:44:22,250 To je trebao biti nagovještaj 559 00:44:22,250 --> 00:44:29,570 da kad god otvaranja datoteku trebate provjeriti da datoteka zapravo postoji. 560 00:44:29,570 --> 00:44:31,510 Dakle, ovdje, "nonexistent.txt"; 561 00:44:31,510 --> 00:44:34,700 Kada smo fopen filename za čitanje, onda ćemo morati reći 562 00:44:34,700 --> 00:44:45,870 if (file == NULL) i reći printf ("Datoteka ne postoji!" 563 00:44:45,870 --> 00:44:56,340 ili - još bolje - filename); povratak 1; 564 00:44:56,340 --> 00:45:00,300 Dakle, sada smo provjeriti da li je NULL 565 00:45:00,300 --> 00:45:03,930 prije nego što zapravo nastavlja i težak za čitanje iz te datoteke. 566 00:45:03,930 --> 00:45:08,800 Možemo ga remake samo da vidim da se to radi. 567 00:45:11,020 --> 00:45:14,970 Namjeravao sam uključuju novu liniju. 568 00:45:21,090 --> 00:45:25,290 Tako sada nonexistent.txt ne postoji. 569 00:45:26,890 --> 00:45:30,040 Uvijek treba provjeriti za ovu vrstu stvar. 570 00:45:30,040 --> 00:45:33,870 Uvijek treba provjeriti da li fopen vraća NULL. 571 00:45:33,870 --> 00:45:38,170 Uvijek treba provjeriti kako bi bili sigurni da malloc ne vrati NULL, 572 00:45:38,170 --> 00:45:41,410 inače segfault. 573 00:45:42,200 --> 00:45:45,930 >> Sada buggy4.c. 574 00:45:49,190 --> 00:45:58,440 Trčanje. Pretpostavljam da je ovaj čeka ulaz ili eventualno beskonačne petlje. 575 00:45:58,440 --> 00:46:01,870 Da, to je beskonačna petlje. 576 00:46:01,870 --> 00:46:05,560 Dakle buggy4. Čini se kao da smo beskonačni loop. 577 00:46:05,560 --> 00:46:12,590 Možemo razbiti na glavni, pokrenuti naš program. 578 00:46:12,590 --> 00:46:20,180 U gdb, dok skraćenica koristite je nedvosmislen 579 00:46:20,180 --> 00:46:23,420 ili posebne skraćenice koje oni pružaju za vas, 580 00:46:23,420 --> 00:46:29,020 onda možete koristiti n koristiti sljedeći, umjesto da se tip iz sljedećoj skroz. 581 00:46:29,020 --> 00:46:33,730 I sad da sam pogodio n jednom, ja mogu samo pritisnite Enter zadržati ide pored 582 00:46:33,730 --> 00:46:36,640 umjesto da se pogodio n Enter, n Enter, n Enter. 583 00:46:36,640 --> 00:46:44,630 Čini se kao da sam u nekoj vrsti za petlje da se postavljaju niz [i] na 0. 584 00:46:44,630 --> 00:46:50,510 Čini se kao da sam nikada nije sam nego iz ove for petlje. 585 00:46:50,510 --> 00:46:54,780 Ako sam ja ispisali, pa sam je 2, onda ću ići sljedeći. 586 00:46:54,780 --> 00:46:59,250 Ja ću ispisati, ja je tri, onda ću ići sljedeći. 587 00:46:59,250 --> 00:47:05,360 Ja ću ispisati i ja je tri. Dalje, ja ispisati, ja je 4. 588 00:47:05,360 --> 00:47:14,520 Zapravo, print sizeof (niz), tako da veličina polja je 20. 589 00:47:16,310 --> 00:47:32,870 No, to izgleda kao da je neki poseban gdb naredba za odlazak dok se nešto dogodi. 590 00:47:32,870 --> 00:47:37,620 To je kao postavljanje stanje na vrijednosti varijable. Ali ne sjećam se što je to. 591 00:47:37,620 --> 00:47:44,100 Dakle, ako smo zadržati ide - 592 00:47:44,100 --> 00:47:47,120 Što su vam rekli? Što ste dovesti do? 593 00:47:47,120 --> 00:47:50,500 [Student] Da li se prikazati i dodati - >> Da. Dakle prikazati ja mogu pomoći. 594 00:47:50,500 --> 00:47:54,530 Ako mi samo mogu prikazati, ona će staviti ovdje ono što vrijednost i je 595 00:47:54,530 --> 00:47:56,470 tako da ne moram to ispisati svaki put. 596 00:47:56,470 --> 00:48:02,930 Ako smo samo zadržati ide dalje, vidimo 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5. 597 00:48:02,930 --> 00:48:08,530 Nešto se događa užasno krivo, a ja se vratiti na 0. 598 00:48:13,330 --> 00:48:22,220 Gledajući buggy4.c, vidimo sve što se događa je int niz [5]; 599 00:48:22,220 --> 00:48:26,200 za (i = 0; i <= sizeof (polje); i + +) 600 00:48:26,200 --> 00:48:28,550 Niz [i] = 0; 601 00:48:28,550 --> 00:48:31,390 Što ćemo vidjeti da je krivo ovdje? 602 00:48:31,390 --> 00:48:39,480 Kao savjet, kad sam bio događaj gdb buggy4 - ajmo razbiti glavna, mali - 603 00:48:39,480 --> 00:48:45,980 Ja nisam ispis sizeof (array) samo da se vidi što je uvjet gdje sam napokon trebala izbiti. 604 00:48:47,690 --> 00:48:51,100 Gdje sam? Jesam li pokrenuti? 605 00:48:51,100 --> 00:48:54,280 Nisam proglasiti još. 606 00:48:54,280 --> 00:48:58,680 Dakle ispisati sizeof (array), a to je 20, 607 00:48:58,680 --> 00:49:06,690 koja se očekuje od moje polje je veličine pet i to je od pet brojeva, 608 00:49:06,690 --> 00:49:12,410 tako da cijela stvar bi trebala biti 5 * sizeof (int) bajtova, gdje sizeof (int) teži da bude 4. 609 00:49:12,410 --> 00:49:14,780 Dakle, sizeof (array) je 20. 610 00:49:14,780 --> 00:49:17,420 Što bi to moglo biti? 611 00:49:17,420 --> 00:49:21,720 [Student] Podijeljen sizeof (int). >> Da, / sizeof (int). 612 00:49:21,720 --> 00:49:30,630 To izgleda kao da je još uvijek problem ovdje. Mislim da je to samo treba biti < 613 00:49:30,630 --> 00:49:36,960 jer to je prilično puno uvijek 00:49:44,860 Sada ćemo razmišljati o tome zašto je to zapravo bio slomljen. 615 00:49:44,860 --> 00:49:53,370 Se bilo tko imati nagađanja zašto je ja vratiti na 0 kroz svaku iteraciju petlje? 616 00:50:01,300 --> 00:50:09,350 Jedina stvar unutar ovog što se događa je da niz [i] se postavlja na 0.. 617 00:50:09,350 --> 00:50:15,350 Tako nekako, ova linija koda uzrokuje našu int ja biti postavljen na 0. 618 00:50:16,730 --> 00:50:23,130 [Student] Može li to biti, jer to je najvažniji sjećanje na ovom dijelu ja 619 00:50:23,130 --> 00:50:27,970 kad misli da je sljedeći element niza? >> [Bowden] Da. 620 00:50:27,970 --> 00:50:33,880 Kad idemo van kraju našeg polja, 621 00:50:33,880 --> 00:50:39,870 nekako taj prostor da smo prevladavajućeg je prevladavajućeg vrijednost i.. 622 00:50:39,870 --> 00:50:48,030 I tako, ako gledamo u buggy4, razbiti glavni, trčanje, 623 00:50:48,030 --> 00:50:53,120 ajmo ispisati adresu ja. 624 00:50:53,120 --> 00:50:57,280 To izgleda kao da je bffff124. 625 00:50:57,280 --> 00:51:03,930 Sada ćemo ispisati adresu niz [0]. 110. 626 00:51:03,930 --> 00:51:06,290 Što o [1]? 114. 627 00:51:06,290 --> 00:51:07,920 [2], 118. 628 00:51:07,920 --> 00:51:14,530 11c, 120. array [5] bfff124. 629 00:51:14,530 --> 00:51:26,990 Dakle, niz [5] ima istu adresu kao što sam, što znači da je niz [5] ja. 630 00:51:26,990 --> 00:51:30,720 Ako imaju istu adresu, oni su ista stvar. 631 00:51:30,720 --> 00:51:38,410 Dakle, kada smo postavili niz [5] na 0, mi smo ja postavljanja na 0. 632 00:51:38,410 --> 00:51:46,070 A ako mislite o tome u smislu stog, 633 00:51:46,070 --> 00:51:55,590 int i je proglašen prvi, što znači da sam dobiva neke prostor na stog. 634 00:51:55,590 --> 00:52:04,730 Tada niz [5] raspoređuje, pa onda 20 bytes se dodjeljuju na stog. 635 00:52:04,730 --> 00:52:08,400 Dakle, ja dobiva dodijeljen prvi, onda ti 20 bajtova dobiti raspoređuje. 636 00:52:08,400 --> 00:52:11,400 Dakle, ja se događa neposredno prije polju, 637 00:52:11,400 --> 00:52:19,230 i zbog načina na koji, kao što sam rekao prošli tjedan, u kojoj je tehnički stog raste prema dolje, 638 00:52:19,230 --> 00:52:28,520 kada indeks u polju, mi smo jamči da je 0. položaj u polju 639 00:52:28,520 --> 00:52:31,970 uvijek događa prije na prvoj poziciji u polju. 640 00:52:31,970 --> 00:52:35,900 To je vrsta kako sam ga izvukao prošli tjedan. 641 00:52:35,900 --> 00:52:42,210 Primijetit ćete da na dnu imamo adresu 0 a na vrhu imamo adresu Max. 642 00:52:42,210 --> 00:52:44,880 Stog uvijek raste prema dolje. 643 00:52:48,100 --> 00:52:53,500 Ajmo reći da smo ja dodijeliti. 644 00:52:53,500 --> 00:52:59,680 Mi izdvojiti cijeli ja, što znači da recimo samo da se ovdje cijeli ja dobiva dodijeljen. 645 00:52:59,680 --> 00:53:06,420 Onda smo izdvojiti naš niz od 5 brojeva, što znači da se ispod koje, 646 00:53:06,420 --> 00:53:11,230 budući da je stog raste prema dolje, te pet integeri se dodjeljuje. 647 00:53:11,230 --> 00:53:15,900 Ali, jer kako polja rade, mi smo zajamčeno da prvu poziciju u polju 648 00:53:15,900 --> 00:53:22,260 uvijek ima Adresa manje od drugog stvar u polju. 649 00:53:22,260 --> 00:53:28,270 Dakle, niz položaj 0 uvijek mora dogoditi prvi u memoriju, 650 00:53:28,270 --> 00:53:30,700 dok je niz poziciju 1 ima dogoditi nakon toga 651 00:53:30,700 --> 00:53:33,310 i niz pozicija 2 mora se dogoditi nakon toga, 652 00:53:33,310 --> 00:53:37,900 što znači da je 0 polje položaj će se dogoditi negdje ovdje dolje, 653 00:53:37,900 --> 00:53:40,690 Niz poziciju jednog će se dogoditi iznad toga 654 00:53:40,690 --> 00:53:45,530 jer se kreće prema gore znači veće adrese od maksimalno adresa je ovdje. 655 00:53:45,530 --> 00:53:50,490 Dakle, niz [0] ovdje dolje, niz [1] ovdje, niz [2] ovdje, polje [3] ovdje. 656 00:53:50,490 --> 00:53:55,620 Obavijest o tome kako smo prije izdvojila cijeli sam sve do ovdje, 657 00:53:55,620 --> 00:54:01,040 kako idemo dalje i dalje u našem polju, mi smo sve bliže i bliže našem cijeli i.. 658 00:54:01,040 --> 00:54:07,640 To samo tako dogodi da array [5], koji je jedno mjesto izvan naše polje, 659 00:54:07,640 --> 00:54:13,010 je točno gdje cijeli sam se dogodilo da se dodjeljuju. 660 00:54:13,010 --> 00:54:16,920 Dakle, to je točka gdje smo se dogoditi da se udaranje prostora na stogu 661 00:54:16,920 --> 00:54:21,680 koja je namijenjena za cijeli ja, a mi smo postavljanje da na 0. 662 00:54:21,680 --> 00:54:26,160 >> To je kako da radi. Pitanja? Da. 663 00:54:26,160 --> 00:54:30,710 [Student] Nikad pamet. Ok. 664 00:54:30,710 --> 00:54:33,090 [Student] Kako ste izbjegli ove vrste pogreške? 665 00:54:33,090 --> 00:54:41,190 Ovo vrsta pogrešaka? Nemojte koristiti C kao programskom jeziku. 666 00:54:41,190 --> 00:54:45,840 Koristite jezik koji ima niz granice provjere. 667 00:54:45,840 --> 00:54:55,900 Dokle god ste oprezni, trebate samo kako bi se izbjeglo ide prošlosti granica svoje polje. 668 00:54:55,900 --> 00:54:58,300 [Student] Pa evo kad smo išli prošlosti granica svoje polje - 669 00:54:58,300 --> 00:55:01,840 [Bowden] To je mjesto gdje se stvari početi idući krivu. >> [Student] Oh, u redu. 670 00:55:01,840 --> 00:55:05,730 Dokle god vam ostati u sjećanju dodijeljenog za svoj niz, ti si u redu. 671 00:55:05,730 --> 00:55:12,400 Ali C ne čini provjera. Ako mi je činiti niz [1000], on će rado samo mijenjati ono što se događa - 672 00:55:12,400 --> 00:55:16,500 To ide na početku niza, onda to ide 1.000 pozicije nakon te ga postavlja na 0.. 673 00:55:16,500 --> 00:55:20,000 To ne činiti bilo provjere da oh, to zapravo ne imati 1000 stvari u njemu. 674 00:55:20,000 --> 00:55:22,750 1000 je način izvan onoga što sam trebala mijenjati, 675 00:55:22,750 --> 00:55:26,940 dok Java ili nešto što ćete dobiti niz od graničnih indeksa 676 00:55:26,940 --> 00:55:29,820 ili indeks izvan granica iznimke. 677 00:55:29,820 --> 00:55:33,950 To je razlog zašto puno višoj razini jezika imaju ove stvari 678 00:55:33,950 --> 00:55:37,340 gdje ako idete izvan granica polja, možete uspjeti 679 00:55:37,340 --> 00:55:40,070 tako da se ne mogu promijeniti stvari od ispod vas 680 00:55:40,070 --> 00:55:42,590 i tada su se stvari ići puno gore nego samo dobivanje iznimku 681 00:55:42,590 --> 00:55:44,940 govoreći da ode izvan kraja niza. 682 00:55:44,940 --> 00:55:50,970 [Student] I tako bi mi samo promijenili <= samo > [Bowden] Aha. 683 00:55:50,970 --> 00:55:54,800 To bi trebao biti 00:55:59,560 jer sizeof (array) je 20, ali mi samo želimo pet. >> [Student] Točno. 685 00:55:59,560 --> 00:56:04,060 Više pitanja? Ok. 686 00:56:04,060 --> 00:56:07,380 >> [Student] imam pitanje. >> Da. 687 00:56:07,380 --> 00:56:16,440 [Student] Što je stvarna varijabla? 688 00:56:16,440 --> 00:56:20,000 [Bowden] Kao što je niz? 689 00:56:20,000 --> 00:56:24,930 Array sama po sebi je simbol. 690 00:56:24,930 --> 00:56:31,490 To je samo adresa početka 20 bajtova da smo referenciranje. 691 00:56:31,490 --> 00:56:38,070 Možete misliti o njemu kao pokazivač, ali to je konstantna pokazivač. 692 00:56:38,070 --> 00:56:44,140 Čim se stvari sastavio, varijabla polje više ne postoji. 693 00:56:44,140 --> 00:56:48,210 [Student] Pa kako to pronaći veličinu niza? 694 00:56:48,210 --> 00:56:54,130 Veličina polja odnosi se na veličinu tog bloka koji se odnosi na simbol. 695 00:56:54,130 --> 00:57:01,240 Kad sam napraviti nešto poput printf ("% p \ n", niz); 696 00:57:01,240 --> 00:57:05,140 ajmo ga pokrenuti. 697 00:57:12,960 --> 00:57:15,530 Što sam samo krivo? 698 00:57:15,530 --> 00:57:19,220 Array 'polje' proglašen ovdje. 699 00:57:20,820 --> 00:57:23,200 Oh, ovdje. 700 00:57:23,200 --> 00:57:31,250 Jeka je pametan, a to se događa da se primjetiti da sam proglašen niz kao pet elemenata 701 00:57:31,250 --> 00:57:34,540 ali ja sam indeksiranje u poziciju 1000. 702 00:57:34,540 --> 00:57:38,450 To se može učiniti, jer to su samo konstante. 703 00:57:38,450 --> 00:57:43,370 To samo može ići tako daleko u primjećujući da idem van granica niza. 704 00:57:43,370 --> 00:57:46,880 Ali primijetite prije, kada smo imali ja biti kriv, 705 00:57:46,880 --> 00:57:51,040 to nikako ne može utvrditi koliko je vrijednosti i može se na, 706 00:57:51,040 --> 00:57:55,540 tako da se ne može utvrditi da sam bio idući iza kraja niza. 707 00:57:55,540 --> 00:57:59,430 To je samo jeka bude pametan. 708 00:57:59,430 --> 00:58:03,340 >> Ali sada bi buggy4. Pa što drugo radim krivo? 709 00:58:03,340 --> 00:58:05,970 Implicitno proglašenja knjižnica funkcija 'printf'. 710 00:58:05,970 --> 00:58:14,960 Idem želite # include . 711 00:58:14,960 --> 00:58:18,710 Ok. Sada radi buggy4. 712 00:58:18,710 --> 00:58:24,840 Ispis vrijednost polja kao što sam učinio ovdje, to tisak kao pokazivač 713 00:58:24,840 --> 00:58:30,060 ispisuje nešto što izgleda ovako - bfb8805c - što je neke adresa 714 00:58:30,060 --> 00:58:33,450 da je u stog-ish regiji. 715 00:58:33,450 --> 00:58:41,820 Array sama je kao pokazivač, ali to nije stvarni pokazivač, 716 00:58:41,820 --> 00:58:45,410 od obične pokazivač možemo promijeniti. 717 00:58:45,410 --> 00:58:54,700 Array je samo neka konstanta. 20 blokova memorije početi na adresi 0xbfb8805c. 718 00:58:54,700 --> 00:59:09,020 Dakle bfb8805c kroz ovu adresu +20--ili valjda -20 - 719 00:59:09,020 --> 00:59:17,400 je sve memorije dodijeljenog za ovaj niz. 720 00:59:17,400 --> 00:59:20,350 Array, varijabla sama nije pohranjena bilo gdje. 721 00:59:20,350 --> 00:59:27,660 Kada ste sastavljanje, prevodilac - ruka val na njega - 722 00:59:27,660 --> 00:59:33,060 ali prevodilac će samo koristiti gdje zna polje biti. 723 00:59:33,060 --> 00:59:36,090 To zna gdje da niz počinje, 724 00:59:36,090 --> 00:59:40,910 i tako se uvijek može učiniti samo stvari u smislu offseta od tog početka. 725 00:59:40,910 --> 00:59:43,960 To ne treba varijablu sama za zastupanje niz. 726 00:59:43,960 --> 00:59:53,730 Ali kad sam učiniti nešto poput int * p = array; sada je p pokazivač koji pokazuje na tom polju, 727 00:59:53,730 --> 00:59:57,830 a sada p zapravo ne postoji na stog. 728 00:59:57,830 --> 01:00:01,950 Ja sam slobodan promijeniti str. Ja mogu učiniti p = malloc. 729 01:00:01,950 --> 01:00:06,500 Dakle, to je izvorno je ukazao na niz, a sada to ukazuje na nekom prostoru na hrpi. 730 01:00:06,500 --> 01:00:09,620 Ja ne mogu napraviti array = malloc. 731 01:00:09,620 --> 01:00:13,710 Ako zveka je pametan, on će vikati na mene pravo isključiti šišmiš. 732 01:00:17,000 --> 01:00:21,430 Zapravo, prilično sam siguran gcc će to učiniti previše. 733 01:00:21,430 --> 01:00:25,010 Dakle, niz tipa 'int [5]' nije prenosiv. 734 01:00:25,010 --> 01:00:28,040 Vi ne možete dodijeliti nešto na niz tipa 735 01:00:28,040 --> 01:00:30,500 jer niz je samo konstanta. 736 01:00:30,500 --> 01:00:34,760 To je simbol koji reference te 20 bajtova. Ja to ne mogu promijeniti. 737 01:00:34,760 --> 01:00:37,690 >> [Student] A gdje je veličina polja pohranjena? 738 01:00:37,690 --> 01:00:40,670 [Bowden] To nije pohranjena bilo gdje. To je kada je sastavljanje. 739 01:00:40,670 --> 01:00:46,310 Dakle, gdje je veličina polja pohranjena? 740 01:00:46,310 --> 01:00:51,870 Možete koristiti samo sizeof (array) unutar funkcije koje polje je sama proglasila. 741 01:00:51,870 --> 01:01:03,150 Dakle, ako sam napraviti neke funkcije, Foo, i ja (int niz []) 742 01:01:03,150 --> 01:01:10,450 printf ("% d \ n", sizeof (polje)); 743 01:01:10,450 --> 01:01:21,330 i onda ovdje dolje zovem foo (Niz); 744 01:01:21,330 --> 01:01:24,840 unutar ove funkcije - ajmo ga pokrenuti. 745 01:01:34,200 --> 01:01:36,840 To je jeka bude pametan opet. 746 01:01:36,840 --> 01:01:43,890 To mi govori da je sizeof na polja funkcije parametra 747 01:01:43,890 --> 01:01:46,690 će se vratiti veličinu 'int *'. 748 01:01:46,690 --> 01:01:55,150 To će biti pogreška ako to nije ono što sam htjela da se dogodi. 749 01:01:55,150 --> 01:01:58,960 Ajmo zapravo isključiti Werror. 750 01:02:14,950 --> 01:02:17,590 Upozorenje. Upozorenja su u redu. 751 01:02:17,590 --> 01:02:19,960 To će ipak sastaviti dok ima upozorenje. 752 01:02:19,960 --> 01:02:22,910 . / A.out će ispisati 4. 753 01:02:22,910 --> 01:02:28,650 Upozorenje koje je generiran je jasan pokazatelj onoga što je pošlo po zlu. 754 01:02:28,650 --> 01:02:34,120 Ovo int polje samo ide za ispis sizeof (int *). 755 01:02:34,120 --> 01:02:39,790 Čak i ako sam stavio niz [5] ovdje, to je još uvijek samo ide za ispis sizeof (int *). 756 01:02:39,790 --> 01:02:47,440 Dakle, čim to prođe u funkciji, razlika između polja i pokazivače 757 01:02:47,440 --> 01:02:49,670 je nepostojeći. 758 01:02:49,670 --> 01:02:52,640 To se događa da se niz koji je proglašen na stog, 759 01:02:52,640 --> 01:02:58,300 ali čim mi prođe tu vrijednost, da 0xbf bla, bla, bla, u ovoj funkciji, 760 01:02:58,300 --> 01:03:03,350 onda je to pokazivač pokazuje na tom polju na stog. 761 01:03:03,350 --> 01:03:08,310 Dakle, to znači da sizeof se primjenjuje samo u funkciji da polje je proglašeno, 762 01:03:08,310 --> 01:03:11,230 što znači da kada ste sastavljanju ovu funkciju, 763 01:03:11,230 --> 01:03:17,330 kada zveka prolazi kroz ove funkcije, ona vidi polje je int niz veličine pet. 764 01:03:17,330 --> 01:03:20,640 Pa onda vidi sizeof (niz). Pa, to je 20. 765 01:03:20,640 --> 01:03:26,440 To je zapravo kako sizeof osnovi radi za gotovo svim slučajevima. 766 01:03:26,440 --> 01:03:31,150 Sizeof nije funkcija, to je operater. 767 01:03:31,150 --> 01:03:33,570 Vi ne zvati sizeof funkciju. 768 01:03:33,570 --> 01:03:38,280 Sizeof (int), prevodilac će samo prevesti do četiri. 769 01:03:41,480 --> 01:03:43,700 Kužite? Ok. 770 01:03:43,700 --> 01:03:47,520 >> [Student] Pa što je razlika između sizeof (array) u glavni i foo? 771 01:03:47,520 --> 01:03:52,840 To je zato što smo govoreći sizeof (array), koji je tipa int *, 772 01:03:52,840 --> 01:03:57,120 dok je niz ovdje nije tipa int *, to je int polje. 773 01:03:57,120 --> 01:04:04,540 >> [Student] Dakle, ako ste imali parametar u polju [] umjesto int * niz, 774 01:04:04,540 --> 01:04:09,230 bi to značilo da se još uvijek mogu promijeniti niz, jer sada je pokazivač? 775 01:04:09,230 --> 01:04:14,250 [Bowden] Kao ovo? >> [Student] Aha. Mogu li promijeniti niz u funkciji sada? 776 01:04:14,250 --> 01:04:18,420 [Bowden] Ti bi mogao promijeniti niz u oba slučaja. 777 01:04:18,420 --> 01:04:23,130 U oba slučaja ste slobodni reći array [4] = 0. 778 01:04:23,130 --> 01:04:26,590 [Student] Ali možete napraviti polje točku na nešto drugo? 779 01:04:26,590 --> 01:04:30,230 [Bowden] Aha. Da. U svakom slučaju - >> [student] Aha. 780 01:04:30,230 --> 01:04:38,410 [Bowden] Razlika između niz [] i int * niz, nema. 781 01:04:38,410 --> 01:04:42,570 Također možete dobiti neki višedimenzionalni niz u ovdje 782 01:04:42,570 --> 01:04:47,050 za neke zgodan sintakse, ali to je još uvijek samo pokazivač. 783 01:04:47,050 --> 01:04:56,400 To znači da sam slobodan činiti niz = malloc (sizeof (int)), a sada istaknuti negdje drugdje. 784 01:04:56,400 --> 01:04:59,610 No, baš kao i kako se to radi zauvijek i uvijek, 785 01:04:59,610 --> 01:05:03,210 mijenja ovaj niz čineći ga ukazati na nešto drugo 786 01:05:03,210 --> 01:05:07,570 ne mijenja ovu lepezu ovdje dolje, jer to je kopija argumenta, 787 01:05:07,570 --> 01:05:10,780 to nije pokazivač na taj argument. 788 01:05:10,780 --> 01:05:16,070 A zapravo, baš kao što više naznaka da je to točno isti - 789 01:05:16,070 --> 01:05:21,100 smo već vidjeli što otisaka ispis Array - 790 01:05:21,100 --> 01:05:31,410 što ako smo ispisali adresu niz ili adresu na adresu niz 791 01:05:31,410 --> 01:05:36,290 na bilo koji od tih? 792 01:05:41,770 --> 01:05:45,220 Ajmo ignorirati ovaj jedan. 793 01:05:48,140 --> 01:05:51,660 Ok. To je u redu. Sada je trčanje. / A.out. 794 01:05:51,660 --> 01:06:00,220 Tiskanje polje, a zatim ispisati adresu niz, su ista stvar. 795 01:06:00,220 --> 01:06:02,870 Array jednostavno ne postoji. 796 01:06:02,870 --> 01:06:08,190 To zna kada ste tiskanje niz, ti si ispis simbol koji se odnosi na tih 20 bajtova. 797 01:06:08,190 --> 01:06:11,940 Ispis adresu polju, dobro, polje ne postoji. 798 01:06:11,940 --> 01:06:17,200 To ne imati adresu, tako da samo ispisuje adresu onih 20 bajtova. 799 01:06:20,820 --> 01:06:28,150 Čim sastaviti dolje, kao u vašem sastavio buggy4. / A.out, 800 01:06:28,150 --> 01:06:30,340 Niz je nepostojeći. 801 01:06:30,340 --> 01:06:33,640 Pokazivači postoji. Nizovi ne. 802 01:06:34,300 --> 01:06:38,060 Blokovi memorije predstavljaju niz još uvijek postoje, 803 01:06:38,060 --> 01:06:43,270 ali varijabla polje i varijable tog tipa ne postoje. 804 01:06:46,260 --> 01:06:50,270 Oni su kao glavne razlike između polja i pokazivače 805 01:06:50,270 --> 01:06:55,590 se čim bi funkcijske pozive, ne postoji razlika. 806 01:06:55,590 --> 01:07:00,460 No, unutar funkcije koje polje sama proglasila, sizeof radi drugačije 807 01:07:00,460 --> 01:07:05,190 budući da ispisujete na veličinu blokova umjesto veličini vrsti, 808 01:07:05,190 --> 01:07:08,950 i ne možete ga promijeniti, jer to je simbol. 809 01:07:08,950 --> 01:07:14,370 Ispis stvar i adresu stvar ispisuje istu stvar. 810 01:07:14,370 --> 01:07:18,480 I to je uglavnom to. 811 01:07:18,480 --> 01:07:20,820 [Student] Može li se reći da jedan više vremena? 812 01:07:21,170 --> 01:07:24,170 Možda sam nešto propustio. 813 01:07:24,170 --> 01:07:29,260 Tiskanje polje i adresa niz ispisuje istu stvar, 814 01:07:29,260 --> 01:07:33,180 a ako ispisujete pokazivač u odnosu na adresu pokazivača, 815 01:07:33,180 --> 01:07:36,010 jedna stvar ispisuje adresu što ste pokazujući na, 816 01:07:36,010 --> 01:07:40,360 druga ispisuje adresu pokazivača na stog. 817 01:07:40,360 --> 01:07:47,040 Možete promijeniti pokazivač, vi ne možete promijeniti niz simbola. 818 01:07:47,740 --> 01:07:53,270 A sizeof Pokazivač će se ispisati veličinu tog tipa pokazivača. 819 01:07:53,270 --> 01:07:57,470 Dakle, int * p sizeof (p) će ispisati 4, 820 01:07:57,470 --> 01:08:04,110 ali int niz [5] ispis sizeof (array) ide za ispis 20. 821 01:08:04,110 --> 01:08:07,480 [Student] Pa int niz [5] će ispisati 20? >> Da. 822 01:08:07,480 --> 01:08:13,300 To je razlog zašto unutar buggy4 kada je nekad bila sizeof (array) 823 01:08:13,300 --> 01:08:16,660 to je radio i <20, što nije ono što smo htjeli. 824 01:08:16,660 --> 01:08:20,880 Želimo I <5. >> [Student] Ok. 825 01:08:20,880 --> 01:08:25,569 [Bowden] I onda čim počnete prolazi u funkcijama, 826 01:08:25,569 --> 01:08:34,340 ako nismo int * p = array; 827 01:08:34,340 --> 01:08:39,779 unutar ove funkcije, mi u osnovi može koristiti p i lepezu na isti način, 828 01:08:39,779 --> 01:08:43,710 osim za sizeof problema i mijenja problema. 829 01:08:43,710 --> 01:08:49,810 Ali p [0] = 1; je isti kao i govoreći niz [0] = 1; 830 01:08:49,810 --> 01:08:55,600 I čim smo rekli foo (Niz), ili Foo (p); 831 01:08:55,600 --> 01:08:59,760 unutar foo funkcije, to je isti poziv dvaput. 832 01:08:59,760 --> 01:09:03,350 Nema razlike između tih dvaju poziva. 833 01:09:07,029 --> 01:09:11,080 >> Svatko dobro na to? Ok. 834 01:09:14,620 --> 01:09:17,950 Imamo 10 minuta. 835 01:09:17,950 --> 01:09:28,319 >> Mi ćemo pokušati da se kroz ovaj program Hacker Typer, 836 01:09:28,319 --> 01:09:32,350 ova web stranica, koji je izašao prošle godine ili tako nešto. 837 01:09:34,149 --> 01:09:41,100 To je samo trebao biti poput upišete slučajno i to ispisuje - 838 01:09:41,100 --> 01:09:46,729 Što god datoteka se dogodi da su učitani je ono što izgleda kao da ste tipkati. 839 01:09:46,729 --> 01:09:52,069 To izgleda kao neka vrsta operativnog sustava koda. 840 01:09:53,760 --> 01:09:56,890 To je ono što želimo provesti. 841 01:10:08,560 --> 01:10:11,690 Trebali bi imati binarni executable zove hacker_typer 842 01:10:11,690 --> 01:10:14,350 koji uzima u jedan argument, datoteke "hakerske tipa." 843 01:10:14,350 --> 01:10:16,480 Trčanje izvršnu treba očistiti ekran 844 01:10:16,480 --> 01:10:20,850 a zatim ispisati jedan lik iz položen-u datoteci svaki put korisnik pritisne tipku. 845 01:10:20,850 --> 01:10:24,990 Dakle, bez obzira na tipku pritiskom, to bi trebalo baciti i umjesto toga ispisati lik iz spisa 846 01:10:24,990 --> 01:10:27,810 da je argument. 847 01:10:29,880 --> 01:10:34,350 Ja ću prilično puno vam reći što su stvari koje ćete trebati znati jesu. 848 01:10:34,350 --> 01:10:36,440 No, želimo provjeriti termios knjižnicu. 849 01:10:36,440 --> 01:10:44,840 Ja nikad nisu koristili ovu knjižnicu u mom cijelom životu, tako da ima vrlo minimalne svrhe. 850 01:10:44,840 --> 01:10:48,610 No, ovo će biti knjižnica možemo koristiti za baciti karakter ćete pogoditi 851 01:10:48,610 --> 01:10:52,390 kada kucate u standardu u. 852 01:10:56,970 --> 01:11:05,840 Dakle hacker_typer.c, a mi si idući u ištanje to # include . 853 01:11:05,840 --> 01:11:12,870 Gledajući na čovjeka stranici za termios - Ja sam guessing da je terminal OS ili nešto - 854 01:11:12,870 --> 01:11:16,240 Ne znam kako da ga pročitate. 855 01:11:16,240 --> 01:11:21,040 Gledajući na to, kaže da su ove dvije datoteke, tako da ćemo to učiniti. 856 01:11:37,620 --> 01:11:46,820 >> Prva stvar prvo, želimo da se u jedan argument, koji je datoteka bismo trebali otvoriti. 857 01:11:46,820 --> 01:11:52,420 Dakle, ono što želim učiniti? Kako mogu provjeriti da vidi imam jednu argument? 858 01:11:52,420 --> 01:11:56,480 [Student] Ako argc ga jednako. >> [Bowden] Aha. 859 01:11:56,480 --> 01:12:21,250 Dakle, ako (argc = 2!) Printf ("Korištenje:% s [file otvoriti]"). 860 01:12:21,250 --> 01:12:32,750 Pa sad, ako sam pokrenuti to bez pružanja drugi argument - Oh, trebam novu liniju - 861 01:12:32,750 --> 01:12:36,240 vidjet ćete da kaže korištenja:. / hacker_typer, 862 01:12:36,240 --> 01:12:39,770 i onda drugi argument bi trebao biti file Želim otvoriti. 863 01:12:58,430 --> 01:13:01,260 Sada što da radim? 864 01:13:01,260 --> 01:13:08,490 Želim pročitati iz ove datoteke. Kako sam pročitao iz datoteke? 865 01:13:08,490 --> 01:13:11,920 [Student] Ti ga otvorili prvi. >> Da. 866 01:13:11,920 --> 01:13:15,010 Dakle fopen. Što fopen izgledati? 867 01:13:15,010 --> 01:13:22,980 [Student] slici. >> [Bowden] Naziv će biti argv [1]. 868 01:13:22,980 --> 01:13:26,110 [Student] A onda ono što želite učiniti s njom, pa - >> [Bowden] Aha. 869 01:13:26,110 --> 01:13:28,740 Dakle, ako vam se ne sjeća, samo mogao učiniti čovjek fopen, 870 01:13:28,740 --> 01:13:32,960 gdje će to biti const char * put gdje put je filename, 871 01:13:32,960 --> 01:13:34,970 const char * mod. 872 01:13:34,970 --> 01:13:38,660 Ako vam se dogoditi da se ne sjećam što je način, onda možete tražiti način. 873 01:13:38,660 --> 01:13:44,660 Unutar man stranica, udarac lik je ono što se može koristiti za traženje stvari. 874 01:13:44,660 --> 01:13:49,790 Tako sam upisati / mod za traženje modu. 875 01:13:49,790 --> 01:13:57,130 n i N su ono što možete koristiti za kretanje kroz pretraživanja utakmice. 876 01:13:57,130 --> 01:13:59,800 Evo što kaže bodove argumenata načina na žici 877 01:13:59,800 --> 01:14:01,930 počevši s jednim od sljedećih sekvenci. 878 01:14:01,930 --> 01:14:06,480 Dakle, r, Otvoreno tekstualna datoteka za čitanje. To je ono što želimo učiniti. 879 01:14:08,930 --> 01:14:13,210 Za čitanje, a ja želim da pohraniti. 880 01:14:13,210 --> 01:14:18,720 Stvar će biti SLIKA *. Sada ono što želim učiniti? 881 01:14:18,720 --> 01:14:21,200 Daj mi drugi. 882 01:14:28,140 --> 01:14:30,430 Ok. Sada ono što želim učiniti? 883 01:14:30,430 --> 01:14:32,940 [Student] Provjerite ako je NULL. >> [Bowden] Aha. 884 01:14:32,940 --> 01:14:38,690 Svaki put kada otvorite datoteku, pobrinite se da ste uspješno moći otvoriti. 885 01:14:58,930 --> 01:15:10,460 >> Sada želim to učiniti termios stvari gdje želim da prvo pročitate moje trenutne postavke 886 01:15:10,460 --> 01:15:14,050 i spasiti one u nešto, onda želim promijeniti svoje postavke 887 01:15:14,050 --> 01:15:19,420 baciti bilo koji znak da sam upisati, 888 01:15:19,420 --> 01:15:22,520 i onda želim ažurirati te postavke. 889 01:15:22,520 --> 01:15:27,250 I onda na kraju programa, želim se vratiti na moje izvorne postavke. 890 01:15:27,250 --> 01:15:32,080 Dakle struct će biti tipa termios, a ja ću htjeti dvije od tih. 891 01:15:32,080 --> 01:15:35,600 Prvi će biti moji current_settings, 892 01:15:35,600 --> 01:15:42,010 i onda oni će biti moji hacker_settings. 893 01:15:42,010 --> 01:15:48,070 Prvo, ja ću žele spasiti svoje trenutne postavke, 894 01:15:48,070 --> 01:15:53,790 onda ću htjeti ažurirati hacker_settings, 895 01:15:53,790 --> 01:16:01,570 a zatim način na kraju mog programa, želim se vratiti na trenutnim postavkama. 896 01:16:01,570 --> 01:16:08,660 Dakle štedi trenutne postavke, način na koji funkcionira, mi čovjek termios. 897 01:16:08,660 --> 01:16:15,810 Mi vidimo da imamo ovu int tcsetattr, int tcgetattr. 898 01:16:15,810 --> 01:16:22,960 Ja proći u termios struct po svojoj pokazivača. 899 01:16:22,960 --> 01:16:30,640 Put će to izgledati je - I've već zaboravili što je funkcija zvao. 900 01:16:30,640 --> 01:16:34,930 Kopirajte i zalijepite. 901 01:16:39,150 --> 01:16:45,500 Dakle tcgetattr, onda želim da prođe u struct da sam spremanja informacija u, 902 01:16:45,500 --> 01:16:49,650 koji će biti current_settings, 903 01:16:49,650 --> 01:16:59,120 i prvi argument je datoteka deskriptor za stvar koju želim spasiti atribute. 904 01:16:59,120 --> 01:17:04,360 Što file deskriptor je kao i svaki put kada otvorite datoteku, ona dobiva file deskriptor. 905 01:17:04,360 --> 01:17:14,560 Kad sam fopen argv [1], on dobiva datotečni deskriptor koji ste referenciranje 906 01:17:14,560 --> 01:17:16,730 kada želite čitati ni pisati na njega. 907 01:17:16,730 --> 01:17:19,220 To nije datoteka deskriptor želim koristiti ovdje. 908 01:17:19,220 --> 01:17:21,940 Postoje tri datoteke deskriptori imate po defaultu, 909 01:17:21,940 --> 01:17:24,310 koji su standardni u, standardni van, a standardna pogreška. 910 01:17:24,310 --> 01:17:29,960 Po defaultu, mislim da je to standard u je 0, standardni izlaz je 1, a standardna pogreška je dva. 911 01:17:29,960 --> 01:17:33,980 Dakle, ono što želim promijeniti postavke? 912 01:17:33,980 --> 01:17:37,370 Želim promijeniti postavke svaki put kad sam pogodio karakter, 913 01:17:37,370 --> 01:17:41,590 Želim ga baciti taj lik daleko, umjesto da ga ispisuje na zaslonu. 914 01:17:41,590 --> 01:17:45,960 Što potok - standard u, standardni izlaz, ili standardne pogreške - 915 01:17:45,960 --> 01:17:52,050 reagira na stvari kad sam upisati na tipkovnici? >> [Student] Standardna u. >> Da. 916 01:17:52,050 --> 01:17:56,450 Tako sam može učiniti 0 ili ja mogu učiniti stdin. 917 01:17:56,450 --> 01:17:59,380 Ja sam uzimajući current_settings o standardu u. 918 01:17:59,380 --> 01:18:01,720 >> Sada želim ažurirati te postavke, 919 01:18:01,720 --> 01:18:07,200 pa prvi ću kopirati u hacker_settings što moji current_settings su. 920 01:18:07,200 --> 01:18:10,430 A kako tvorevina, rad je to samo će kopirati. 921 01:18:10,430 --> 01:18:14,510 Ovo kopira sva polja, kao što se i očekuje. 922 01:18:14,510 --> 01:18:17,410 >> Sada želim ažurirati neke od polja. 923 01:18:17,410 --> 01:18:21,670 Gledajući termios, te će morati pročitati kroz mnogo toga 924 01:18:21,670 --> 01:18:24,110 samo da vidim ono što želite tražiti, 925 01:18:24,110 --> 01:18:28,210 ali su zastave idete da želite tražiti su jeka, 926 01:18:28,210 --> 01:18:33,110 tako Echo Echo ulaznih znakova. 927 01:18:33,110 --> 01:18:37,710 Prvo želim postaviti - I've već zaboravili što su polja. 928 01:18:45,040 --> 01:18:47,900 To je ono što struct izgleda. 929 01:18:47,900 --> 01:18:51,060 Dakle, načini unosa Mislim želimo promijeniti. 930 01:18:51,060 --> 01:18:54,210 Mi ćemo gledati na rješenje kako bi bili sigurni da je ono što želimo promijeniti. 931 01:19:04,060 --> 01:19:12,610 Želimo promijeniti lflag kako bi se spriječilo trebaju gledati kroz sve to. 932 01:19:12,610 --> 01:19:14,670 Želimo promijeniti lokalne načina. 933 01:19:14,670 --> 01:19:17,710 Ti bi da pročitate kroz cijelu ovu stvar za razumjeti gdje sve pripada 934 01:19:17,710 --> 01:19:19,320 da želimo promijeniti. 935 01:19:19,320 --> 01:19:24,120 Ali to je unutar lokalnih načina gdje idemo da žele da se to promijeni. 936 01:19:27,080 --> 01:19:33,110 Dakle hacker_settings.cc_lmode je ono što se zove. 937 01:19:39,630 --> 01:19:43,020 c_lflag. 938 01:19:49,060 --> 01:19:52,280 To je mjesto gdje smo dobili u bitovni operatori. 939 01:19:52,280 --> 01:19:54,860 Mi smo vrsta izvan vremena, ali mi ćemo proći kroz to vrlo brzo. 940 01:19:54,860 --> 01:19:56,600 To je mjesto gdje smo dobili u bitovni operatori, 941 01:19:56,600 --> 01:19:59,950 gdje mislim da sam rekao jedno vrijeme davno da kad počnete bave zastavama, 942 01:19:59,950 --> 01:20:03,370 ti si idući u biti koristeći bitovni operateru puno. 943 01:20:03,370 --> 01:20:08,240 Svaki malo u zastavom odgovara nekom vrstom ponašanja. 944 01:20:08,240 --> 01:20:14,090 Dakle, ovo zastava ima hrpa različitih stvari, gdje svi od njih znači nešto drugo. 945 01:20:14,090 --> 01:20:18,690 No, ono što želim učiniti je samo isključiti malo koja odgovara ECHO. 946 01:20:18,690 --> 01:20:25,440 Tako da se to off radim & = ¬ ECHO. 947 01:20:25,440 --> 01:20:30,110 Zapravo, mislim da je to kao tECHO ili nešto. Samo ću provjeriti opet. 948 01:20:30,110 --> 01:20:34,050 Mogu ga termios. To je samo ECHO. 949 01:20:34,050 --> 01:20:38,440 ECHO će biti jedan malo. 950 01:20:38,440 --> 01:20:44,230 ¬ ECHO će značiti sve bitova su postavljena na 1, što znači da su sve zastave postavljen na true 951 01:20:44,230 --> 01:20:47,140 osim za ECHO malo. 952 01:20:47,140 --> 01:20:53,830 Do završetka moje lokalne zastave s tim, to znači sve zastave koje su trenutno postavljene na true 953 01:20:53,830 --> 01:20:56,520 i dalje će biti postavljen na true. 954 01:20:56,520 --> 01:21:03,240 Ako je moja ECHO zastava postavljena na true, onda je to nužno postavljena na False na ECHO zastavom. 955 01:21:03,240 --> 01:21:07,170 Dakle, ova linija koda samo gasi ECHO zastavu. 956 01:21:07,170 --> 01:21:16,270 Druga linija koda, samo ću kopirati ih u interesu vremena, a zatim ih objasniti. 957 01:21:27,810 --> 01:21:30,180 U otopini, rekao 0. 958 01:21:30,180 --> 01:21:33,880 To je vjerojatno bolje da eksplicitno reći stdin. 959 01:21:33,880 --> 01:21:42,100 >> Primijetit ćete da sam i radim ECHO | ICANON ovdje. 960 01:21:42,100 --> 01:21:46,650 ICANON se odnosi na nešto odvojeno, što znači kanonski način. 961 01:21:46,650 --> 01:21:50,280 Što kanonski način znači da je obično kada pišete iz naredbenog retka, 962 01:21:50,280 --> 01:21:54,670 standard u ne obrađuje ništa dok ne pogoditi newline. 963 01:21:54,670 --> 01:21:58,230 Dakle, kada ne GetString, upišete hrpu stvari, onda pogodio novi red. 964 01:21:58,230 --> 01:22:00,590 To je kad je poslan na standardu u. 965 01:22:00,590 --> 01:22:02,680 To je zadana. 966 01:22:02,680 --> 01:22:05,830 Kad sam isključiti kanonski način, sada svaki pojedinačni znak da pritisnete 967 01:22:05,830 --> 01:22:10,910 je ono što dobiva obrađuju, što je obično vrsta loše jer je spor za obradu tih stvari, 968 01:22:10,910 --> 01:22:14,330 što je razlog zašto je dobro da ga tampon u cijelom linije. 969 01:22:14,330 --> 01:22:16,810 Ali ja želim svaki lik koji se obrađuju 970 01:22:16,810 --> 01:22:18,810 jer ne želim da čekati za mene pogoditi newline 971 01:22:18,810 --> 01:22:21,280 prije obrađuje sve znakove sam tipkati. 972 01:22:21,280 --> 01:22:24,760 To isključuje kanonski način. 973 01:22:24,760 --> 01:22:31,320 Ova stvar samo znači kada se zapravo obrađuje likove. 974 01:22:31,320 --> 01:22:35,830 To znači da ih obraditi odmah, čim sam ih tipkati, obraditi ih. 975 01:22:35,830 --> 01:22:42,510 A to je funkcija koja se ažurira svoje postavke za standardne u, 976 01:22:42,510 --> 01:22:45,480 i TCSA znači to učiniti upravo sada. 977 01:22:45,480 --> 01:22:50,310 Ostale opcije su čekati dok sve što je trenutno na potoku obrađuju. 978 01:22:50,310 --> 01:22:52,030 To ne stvarno tvar. 979 01:22:52,030 --> 01:22:56,920 Samo sada promijeniti moje postavke da se ono što je trenutno u hacker_typer_settings. 980 01:22:56,920 --> 01:23:02,210 Mislim da su to nazvali hacker_settings, pa ajmo to promijeniti. 981 01:23:09,610 --> 01:23:13,500 Promjena sve do hacker_settings. 982 01:23:13,500 --> 01:23:16,870 >> Sada je na kraju našeg programa ćemo se želite vratiti 983 01:23:16,870 --> 01:23:20,210 na ono što je trenutno unutar normal_settings, 984 01:23:20,210 --> 01:23:26,560 koji će samo izgledati i normal_settings. 985 01:23:26,560 --> 01:23:30,650 Obavijest nisam promijenio bilo koje od mojih normal_settings od prvotno uzimajući ga. 986 01:23:30,650 --> 01:23:34,520 Zatim ih vratiti, ja ih proći natrag na kraju. 987 01:23:34,520 --> 01:23:38,390 Ovo je ažuriranje. Ok. 988 01:23:38,390 --> 01:23:43,900 >> Sada unutar ovog ću samo objasniti kod u interesu vrijeme. 989 01:23:43,900 --> 01:23:46,350 To nije toliko koda. 990 01:23:50,770 --> 01:24:03,750 Vidimo čitamo lik iz spisa. Zvali smo ga f. 991 01:24:03,750 --> 01:24:07,850 Sada možete Čovjek fgetc, ali kako fgetc ide na posao 992 01:24:07,850 --> 01:24:11,910 se samo da će se vratiti karakter koji ste upravo pročitali ili EOF, 993 01:24:11,910 --> 01:24:15,680 koji odgovara kraju datoteke ili neke pogreške događa. 994 01:24:15,680 --> 01:24:19,900 Mi smo petlje, nastavljajući čitati jedan znak iz datoteke, 995 01:24:19,900 --> 01:24:22,420 dok smo ponestane znakova za čitanje. 996 01:24:22,420 --> 01:24:26,650 I dok radimo da, čekamo na jednom lik iz standarda i. 997 01:24:26,650 --> 01:24:29,090 Svaki put kada upišete nešto u zapovjednoj liniji, 998 01:24:29,090 --> 01:24:32,820 da je čitanje u lik iz standardu u. 999 01:24:32,820 --> 01:24:38,330 Zatim Putchar samo će staviti char čitamo ovdje iz datoteke na standardni izlaz. 1000 01:24:38,330 --> 01:24:42,890 Možete čovjek Putchar, ali to je samo stavljanje na standardu van, to znači tiskanje taj lik. 1001 01:24:42,890 --> 01:24:51,600 Također se može učiniti samo printf ("% c", c); istu ideju. 1002 01:24:53,330 --> 01:24:56,670 To će učiniti većinu našeg rada. 1003 01:24:56,670 --> 01:25:00,300 >> Zadnja stvar koju idete da želite učiniti je samo fclose našu datoteku. 1004 01:25:00,300 --> 01:25:03,310 Ako ne fclose, to je gubljenje memorije. 1005 01:25:03,310 --> 01:25:06,680 Želimo fclose datoteku smo prvotno otvorena, i ja mislim da je to to. 1006 01:25:06,680 --> 01:25:13,810 Ako ćemo napraviti da, ja već imam problema. 1007 01:25:13,810 --> 01:25:17,260 Idemo vidjeti. 1008 01:25:17,260 --> 01:25:19,960 Što je to žaliti? 1009 01:25:19,960 --> 01:25:30,220 Očekivani 'int', ali argument je tipa 'struct _IO_FILE *'. 1010 01:25:36,850 --> 01:25:39,370 Mi ćemo vidjeti ako to radi. 1011 01:25:45,210 --> 01:25:53,540 Samo dozvoljeno C99. Augh. Ok, napraviti hacker_typer. 1012 01:25:53,540 --> 01:25:57,760 Sada smo dobili više korisnih opise. 1013 01:25:57,760 --> 01:25:59,900 Dakle, koristite neprijavljenog identifikator 'normal_settings'. 1014 01:25:59,900 --> 01:26:04,170 Nisam ga zovu normal_settings. Zvao sam ga current_settings. 1015 01:26:04,170 --> 01:26:12,090 Tako ćemo promijeniti sve to. 1016 01:26:17,920 --> 01:26:21,710 Sada prolazi argument. 1017 01:26:26,290 --> 01:26:29,500 Ja ću napraviti ovaj 0 za sada. 1018 01:26:29,500 --> 01:26:36,720 Ok. . / Hacker_typer cp.c. 1019 01:26:36,720 --> 01:26:39,590 Ja također nije jasan zaslon na početku. 1020 01:26:39,590 --> 01:26:42,960 No, možete se osvrnuti na zadnji problema setu vidjeti kako ste izbrisali zaslon. 1021 01:26:42,960 --> 01:26:45,160 To je samo tiskanje neke znakove 1022 01:26:45,160 --> 01:26:47,210 dok se to radi ono što želim učiniti. 1023 01:26:47,210 --> 01:26:48,900 Ok. 1024 01:26:48,900 --> 01:26:55,280 I razmišljam o tome zašto se to moralo biti 0, umjesto stdin, 1025 01:26:55,280 --> 01:27:00,560 koji bi trebao imati # define 0, 1026 01:27:00,560 --> 01:27:03,890 to se žali da je - 1027 01:27:13,150 --> 01:27:19,360 Prije kad sam rekao da postoji datoteka deskriptori, ali onda također imaju svoje FILE *, 1028 01:27:19,360 --> 01:27:23,210 file deskriptor je samo jedan broj, 1029 01:27:23,210 --> 01:27:26,970 dok SLIKA * ima hrpu stvari povezane s njom. 1030 01:27:26,970 --> 01:27:30,380 Razlog moramo reći 0 umjesto stdin 1031 01:27:30,380 --> 01:27:37,480 je da je stdin SLIKA * što ukazuje na stvari koje se pozivom file deskriptor 0. 1032 01:27:37,480 --> 01:27:45,070 Dakle, čak i ovdje kad sam to fopen (argv [1], ja sam uzimajući FILE * natrag. 1033 01:27:45,070 --> 01:27:51,180 No, negdje u tom FILE * je stvar odgovara file deskriptora za tu datoteku. 1034 01:27:51,180 --> 01:27:57,430 Ako pogledate na čovjeka stranici za otvaranje, tako da mislim da ćete morati učiniti čovjek tri otvorena - nope - 1035 01:27:57,430 --> 01:27:59,380 Čovjek dva otvorena - Da. 1036 01:27:59,380 --> 01:28:06,250 Ako pogledate na stranici za opena, otvoren je kao niže razine fopen, 1037 01:28:06,250 --> 01:28:09,350 a to je povratak u stvarni file deskriptor. 1038 01:28:09,350 --> 01:28:12,050 fopen ne hrpa stvari na vrhu opena, 1039 01:28:12,050 --> 01:28:17,640 koji umjesto povratka samo da file deskriptor vraća cijelu datoteku * pokazivač 1040 01:28:17,640 --> 01:28:20,590 unutar koje je naša mala file deskriptor. 1041 01:28:20,590 --> 01:28:25,020 Dakle standard u odnosi na stvar FILE *, 1042 01:28:25,020 --> 01:28:29,120 a 0 se odnosi na samo na standard file deskriptor u sebi. 1043 01:28:29,120 --> 01:28:32,160 >> Pitanja? 1044 01:28:32,160 --> 01:28:35,930 [Smijeh] puhao kroz to. 1045 01:28:35,930 --> 01:28:39,140 U redu. Mi smo učinili. [Smijeh] 1046 01:28:39,140 --> 01:28:42,000 >> [CS50.TV]