1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [Oddelek 5 - Več Udobna] 2 00:00:02,500 --> 00:00:04,690 [Rob Bowden - Harvard University] 3 00:00:04,690 --> 00:00:07,250 [To je CS50. - CS50.TV] 4 00:00:08,990 --> 00:00:14,250 >> Kot sem že povedal v e-pošti, obstaja veliko stvari, ki jih lahko uporabite 5 00:00:14,250 --> 00:00:17,060 razen naprave za dejansko storiti težavnih sprejemnikov. 6 00:00:17,060 --> 00:00:19,910 Priporočamo, da to storite v napravi samo zato, ker potem bomo lahko lažje pomagal 7 00:00:19,910 --> 00:00:22,070 in vemo, kako se vse dogaja na delo. 8 00:00:22,070 --> 00:00:26,950 Ampak kot en primer, kjer lahko narediš stvari, če, recimo, nimate dostopa 9 00:00:26,950 --> 00:00:31,570 na napravo ali pa bi radi delali v kleti Science Center - 10 00:00:31,570 --> 00:00:33,090 ki dejansko imajo aparat preveč - 11 00:00:33,090 --> 00:00:35,150 če želite, da dela kjer koli. 12 00:00:35,150 --> 00:00:42,370 Eden od primerov so se ga videli / slišali SSH? 13 00:00:44,380 --> 00:00:47,780 SSH je v bistvu tako, kot povezavo z nečim. 14 00:00:47,780 --> 00:00:51,340 Pravzaprav, zdaj sem SSHed v napravo. 15 00:00:51,340 --> 00:00:54,290 Nikoli ne delajo neposredno v napravi. 16 00:00:55,930 --> 00:01:01,060 Tukaj je aparat, in če pogledate tukaj vidite ta naslov IP. 17 00:01:01,060 --> 00:01:03,650 Ne delam v aparatu samem; 18 00:01:03,650 --> 00:01:08,840 Vedno sem prišel do iTerm2 okno / okna terminala. 19 00:01:08,840 --> 00:01:15,910 Lahko SSH ta IP naslov, ssh jharvard@192.168.129.128. 20 00:01:15,910 --> 00:01:20,390 Spomnim se, da je število zelo enostavno, ker je tako lep vzorec. 21 00:01:20,390 --> 00:01:24,920 Vendar pa bo, da me prosi za geslo, in zdaj sem v napravi. 22 00:01:24,920 --> 00:01:33,060 V bistvu, v tem trenutku, če ste odprli terminal v notranjosti aparata samega, 23 00:01:33,060 --> 00:01:36,350 ta vmesnik, vendar bi jo uporabili, je popolnoma enak 24 00:01:36,350 --> 00:01:40,010 kot vmesnik sem z tukaj, zdaj pa si ti SSHed. 25 00:01:42,240 --> 00:01:44,920 Nimaš SSH na napravi. 26 00:01:44,920 --> 00:01:52,360 En primer drugo mesto si lahko SSH, je Prepričan sem, da imate privzeto - 27 00:01:52,360 --> 00:01:55,020 Oh. Večji. 28 00:01:55,020 --> 00:02:01,130 Vsi vi bi morali z računov privzete FAS na strežnikih FAS. 29 00:02:01,130 --> 00:02:06,840 Za mene, jaz bi SSH za rbowden@nice.fas.harvard.edu. 30 00:02:06,840 --> 00:02:11,610 To se dogaja, da vas prosim, da je prvič, in si rekla da. 31 00:02:11,610 --> 00:02:15,840 Moje geslo je le, da bo moj FAS geslo. 32 00:02:15,840 --> 00:02:22,650 In sedaj, sem SSHed z lepimi strežnikov, in jaz lahko naredim kar želim tukaj. 33 00:02:22,650 --> 00:02:28,560 Veliko razredov se lahko sprejme kot 124, se dogaja, da imajo lahko naložite stvari tukaj 34 00:02:28,560 --> 00:02:30,950 treba dejansko predložiti tvoj problem sklopov. 35 00:02:30,950 --> 00:02:34,100 Ampak pravijo, da nimajo dostopa do vašega aparata. 36 00:02:34,100 --> 00:02:37,910 Potem lahko narediš stvari, kot tukaj bo rekel - 37 00:02:37,910 --> 00:02:42,160 To je samo naš del vprašanj. 38 00:02:42,160 --> 00:02:45,070 Vprašal vas bo, da to stori v napravi. 39 00:02:45,070 --> 00:02:47,790 Namesto tega bom samo to na strežniku. 40 00:02:47,790 --> 00:02:50,560 Grem, da razširite. 41 00:02:50,560 --> 00:02:55,670 Problem se bo, da ste navajeni na uporabo nekaj podobnega gedit 42 00:02:55,670 --> 00:02:58,160 ali karkoli notranjost stroja. 43 00:02:58,160 --> 00:03:01,830 Saj ne bo imel, da na FAS strežniku. 44 00:03:01,830 --> 00:03:04,110 To je vse samo, da bo tako tekstovni vmesnik. 45 00:03:04,110 --> 00:03:09,180 Torej si lahko bodisi eno, naučiti urejevalnik besedila, da to so. 46 00:03:09,180 --> 00:03:12,130 Imajo Nano. 47 00:03:12,130 --> 00:03:14,990 Nano je ponavadi zelo enostaven za uporabo. 48 00:03:14,990 --> 00:03:19,470 Lahko uporabite svoje puščice in vnesite kot običajno. 49 00:03:19,470 --> 00:03:21,250 Torej, to ni težko. 50 00:03:21,250 --> 00:03:24,720 Če želite res fancy znate uporabljati Emacs, 51 00:03:24,720 --> 00:03:29,850 , ki najbrž ne bi smela začeti, ker ne vedo, kako blizu Emacsa. 52 00:03:29,850 --> 00:03:32,760 Nadzor X, nadzor C? Ja. 53 00:03:32,760 --> 00:03:35,310 Lahko pa uporabite vim, ki je tisto, kar sem uporabo. 54 00:03:35,310 --> 00:03:37,800 In tako so se vaše možnosti. 55 00:03:37,800 --> 00:03:43,830 Če ne želiš, da si lahko tudi, če pogledaš na manual.cs50.net, - 56 00:03:43,830 --> 00:03:45,410 Oh. 57 00:03:45,410 --> 00:03:49,920 Na računalniku, lahko uporabljate SSH PuTTY, 58 00:03:49,920 --> 00:03:51,940 kar boste morali ločeno prenesete. 59 00:03:51,940 --> 00:03:55,460 Na Mac, si lahko samo z uporabo privzetega terminala ali si lahko prenesete iTerm2, 60 00:03:55,460 --> 00:03:58,490 ki je kot lep, fancy terminala. 61 00:03:58,490 --> 00:04:03,780 Če greste na manual.cs50.net boste videli povezavo do Beležnica + +, 62 00:04:03,780 --> 00:04:07,120 , ki je tisto, kar lahko uporabite v računalniku. 63 00:04:07,120 --> 00:04:13,340 To vam omogoča, SFTP iz Notepad + +, ki je v bistvu SSH. 64 00:04:13,340 --> 00:04:17,750 Kaj bo to kaj morate storiti, je urejanje datotek na lokalni ravni, 65 00:04:17,750 --> 00:04:20,670 in potem, ko jih želite shraniti, bo shranite na nice.fas, 66 00:04:20,670 --> 00:04:23,670 kjer se lahko nato zagnati. 67 00:04:23,670 --> 00:04:26,880 In enako na Mac se bo TextWrangler. 68 00:04:26,880 --> 00:04:28,760 Tako vam omogoča, da storijo enako stvar. 69 00:04:28,760 --> 00:04:32,800 To vam omogoča urejanje datotek na lokalni ravni in jih shranite v nice.fas, 70 00:04:32,800 --> 00:04:35,730 kjer se lahko nato zagnati. 71 00:04:35,730 --> 00:04:40,400 Torej, če ste kdaj zaljubljen, ne da bi napravo, imate te možnosti 72 00:04:40,400 --> 00:04:44,230 da še vedno vaš problem sklopov. 73 00:04:44,230 --> 00:04:48,250 En problem se bo, da ne boš imel CS50 knjižnico 74 00:04:48,250 --> 00:04:51,580 ker nice.fas ne privzeto imeti. 75 00:04:51,580 --> 00:04:55,970 Lahko prenesete CS50 knjižnice - 76 00:04:55,970 --> 00:04:58,470 Mislim, da ne rabim, da na tej točki. 77 00:04:58,470 --> 00:05:03,270 Lahko prenesete CS50 knjižnico in jo kopirajte v leto nice.fas, 78 00:05:03,270 --> 00:05:07,450 ali Mislim, da na tej točki ne uporabljajo več vseeno. 79 00:05:07,450 --> 00:05:12,720 Ali pa, če mi lahko zaenkrat ga nadomestiti z 80 00:05:12,720 --> 00:05:18,480 izvedb funkcij v knjižnici CS50 vseeno. 81 00:05:18,480 --> 00:05:21,370 Tako, da ne bi smelo biti, da je veliko omejitev. 82 00:05:21,370 --> 00:05:23,710 In to je to. 83 00:05:26,460 --> 00:05:29,820 >> Grem nazaj na aparat zdaj, bomo naredili vse, kar je v napravi. 84 00:05:29,820 --> 00:05:37,510 Če pogledamo na našem oddelku vprašanj, na začetku, kot sem že povedal v e-pošti, 85 00:05:37,510 --> 00:05:43,620 moramo govoriti o eni kratki Moral bi gledati. 86 00:05:43,620 --> 00:05:51,980 Imamo preusmerjanje in cevi in ​​teh treh vprašanj. 87 00:05:51,980 --> 00:05:56,070 >> Na kateri tok ne deluje kot printf napisal privzeto? 88 00:05:56,070 --> 00:05:59,130 Torej tok. Kaj je tok? 89 00:06:06,520 --> 00:06:15,100 Tok je v bistvu, kot da je samo nekaj - 90 00:06:15,100 --> 00:06:21,450 To sploh ni vir 1s in 0s. 91 00:06:21,450 --> 00:06:24,920 Potok se prosi za tukaj je standard ven. 92 00:06:24,920 --> 00:06:27,250 In tako je iz standarda tok, ko pišete z njim, 93 00:06:27,250 --> 00:06:30,940 se pojavi na zaslonu. 94 00:06:30,940 --> 00:06:36,860 Enostavno, tako da jim tok, to pomeni, da le napišeš 1s in 0s z njim, 95 00:06:36,860 --> 00:06:40,220 in drugi konec standardni izhod le bere iz tega toka. 96 00:06:40,220 --> 00:06:43,540 To je samo niz 1s in 0s. 97 00:06:43,540 --> 00:06:45,570 Lahko pišete na vodotokih, ali si lahko preberete iz tokov 98 00:06:45,570 --> 00:06:47,950 odvisno od tega, kaj dejansko je tok. 99 00:06:47,950 --> 00:06:52,800 Drugi dve privzete tokovi so standard v in standardno napako. 100 00:06:52,800 --> 00:06:57,540 Standard je, ko vam GetString, da te čaka, da stvari vhoda. 101 00:06:57,540 --> 00:07:01,570 Torej vas čaka, to je pravzaprav čaka na standard v, 102 00:07:01,570 --> 00:07:04,880 kar je res tisto, kar dobiš, ko vnesete na tipkovnici. 103 00:07:04,880 --> 00:07:07,530 Tipkate v standardu palcev 104 00:07:07,530 --> 00:07:10,050 Standardna napaka je v bistvu enaka standardni izhod, 105 00:07:10,050 --> 00:07:13,280 vendar je specializirana v tem, da pri tiskanju v standardne napake, 106 00:07:13,280 --> 00:07:16,770 ti naj bi samo tiskanje sporočil o napakah v tem 107 00:07:16,770 --> 00:07:20,200 tako da lahko razlikuje med rednimi sporočila izpisujejo na zaslonu 108 00:07:20,200 --> 00:07:24,560 v primerjavi sporočil o napakah glede na to, ali so šli ven standardno ali standardne napake. 109 00:07:24,560 --> 00:07:28,660 Datoteke preveč. 110 00:07:28,660 --> 00:07:32,440 Standardna ven, standard, standardna napaka in so le posebni tokovi, 111 00:07:32,440 --> 00:07:36,810 ampak res vse datoteke, ko odprete datoteko, postane tok bajtov 112 00:07:36,810 --> 00:07:40,740 kjer si lahko prebral iz tega toka. 113 00:07:40,740 --> 00:07:47,770 Ti, za večino del, lahko samo pomislite datoteke kot tok bajtov. 114 00:07:47,770 --> 00:07:51,190 Torej, kaj tokovi pa so napisali, da je privzeto? Standardna ven. 115 00:07:51,190 --> 00:07:56,980 >> Kakšna je razlika med> in >>? 116 00:07:58,140 --> 00:08:03,710 Ali je kdo gledal video vnaprej? Ok. 117 00:08:03,710 --> 00:08:10,960 > Se bo, kako preusmeriti v datoteke, 118 00:08:10,960 --> 00:08:15,240 in >> se tudi dogaja, da preusmerijo proizvodnjo v datoteke, 119 00:08:15,240 --> 00:08:17,820 vendar je namesto tega bo priložiti k spisu. 120 00:08:17,820 --> 00:08:23,430 Na primer, recimo, da sem se zgodi, da imajo narek tukaj, 121 00:08:23,430 --> 00:08:27,020 in edina stvar znotraj narek je mačka, mačka, pes, ribe, pes. 122 00:08:27,020 --> 00:08:31,530 En ukaz, da imate v ukazni vrstici je mačka, 123 00:08:31,530 --> 00:08:34,539 , ki je šele pred tiskanjem, kar je v datoteki. 124 00:08:34,539 --> 00:08:40,679 Torej, ko sem rekel, mačka narek, da se bo tiskanje mačko, mačka, pes, ribe, psa. To je vse kar počne mačka. 125 00:08:40,679 --> 00:08:46,280 To pomeni, da se natisne v skladu s standardom iz mačko, mačka, pes, ribe, pes. 126 00:08:46,280 --> 00:08:53,240 Če bi namesto tega želite preusmeriti, da datoteko, lahko uporabite> in jih preusmerili na kateri koli datoteke. 127 00:08:53,240 --> 00:08:56,460 Poklical bom datoteko datoteko. 128 00:08:56,460 --> 00:09:00,320 Torej, zdaj, če I ls, bom videl, da imam novo datoteko z imenom datoteke. 129 00:09:00,320 --> 00:09:05,700 In če sem jo odprl, da se dogaja, da imajo kaj mačka dal v ukazni vrstici. 130 00:09:05,700 --> 00:09:11,040 Torej, zdaj, če sem to storil še enkrat, nato pa se dogaja, da preusmerite izhod v datoteko, 131 00:09:11,040 --> 00:09:13,930 in jaz bom imel točno isto stvar. 132 00:09:13,930 --> 00:09:17,910 Torej, tehnično, popolnoma razveljavljena, kar smo imeli. 133 00:09:17,910 --> 00:09:22,970 In bomo videli, če spremenim narek, sem peljal psa. 134 00:09:22,970 --> 00:09:29,980 Zdaj, če mačka narek v datoteko znova, da bomo imeli novo različico s psom odstranijo. 135 00:09:29,980 --> 00:09:32,400 Torej je to popolnoma prekrije. 136 00:09:32,400 --> 00:09:36,640 Namesto tega, če bomo uporabili >>, da se bo dodati datoteko. 137 00:09:36,640 --> 00:09:40,860 Zdaj, odpiranje datotek, vidimo, imamo ravno isto stvar dvakrat natisnjen 138 00:09:40,860 --> 00:09:44,920 ker je bila tam nekoč, potem priložen original. 139 00:09:44,920 --> 00:09:48,130 Torej, to je tisto,> in >> storiti. 140 00:09:48,130 --> 00:09:50,580 Ali naslednjič vprašal - ne sprašujejo o tem. 141 00:09:50,580 --> 00:09:59,050 >> Drugi pa, da smo se <, ki bi, če> preusmeri standardni izhod, 142 00:09:59,050 --> 00:10:01,970 00:10:12,050 Poglejmo, če bomo imeli za zgled. 144 00:10:14,750 --> 00:10:16,930 Znam napisati en pravi hitro. 145 00:10:17,870 --> 00:10:25,700 Vzemimo poljubne datoteke, hello.c. 146 00:10:56,060 --> 00:10:59,070 Razmeroma preprosta datoteka. 147 00:10:59,070 --> 00:11:03,570 Jaz sem samo dobili niz in nato tiskanje "Hello", ne glede na niz sem začel bilo. 148 00:11:03,570 --> 00:11:07,990 Torej, da zdravo in potem. / Zdravo. 149 00:11:07,990 --> 00:11:10,720 Zdaj pa me je spodbudilo, da vnesete nekaj, 150 00:11:10,720 --> 00:11:15,070 kar pomeni, da čaka na stvari, ki jih je treba vnesti v standardu palcev 151 00:11:15,070 --> 00:11:20,450 Torej, kar hočem vnesti v standardu noter bomo samo rekli Zdravo, Rob! 152 00:11:20,450 --> 00:11:23,310 Potem je tiskanje s standardom iz Zdravo, Rob! 153 00:11:23,310 --> 00:11:28,860 Če naredim. / Zdravo in preusmerite, 154 00:11:30,740 --> 00:11:34,310 Za zdaj lahko samo preusmeriti iz datoteke. 155 00:11:34,310 --> 00:11:41,720 Torej, če sem dal v nekaj dokumentacije, txt, in sem dal Rob, 156 00:11:41,720 --> 00:11:52,300 če sem teči zdravo in preusmerite v datoteko txt. / halo, to bo rekel Zdravo, Rob! takoj. 157 00:11:52,300 --> 00:11:57,160 Ko se je prvič pride do GetString in čaka na standardu v, 158 00:11:57,160 --> 00:12:01,730 standard ni več čakanja na tipkovnici za podatke, da se je začel. 159 00:12:01,730 --> 00:12:05,980 Namesto tega smo preusmerili standard za branje iz datoteke txt. 160 00:12:05,980 --> 00:12:10,290 In tako se dogaja, da bere iz datoteke txt, ki je ravno črto Rob, 161 00:12:10,290 --> 00:12:13,380 in potem se dogaja, da tiskanje Hello, Rob! 162 00:12:13,380 --> 00:12:18,180 In če bi hotel, bi tudi jaz naredil. / Zdravo 00:12:21,500 in potem standard, da je tiskanje, ki je Zdravo, Rob!, 164 00:12:21,500 --> 00:12:24,700 Ne morem preusmeriti, da v svojo datoteko. 165 00:12:24,700 --> 00:12:29,790 Poklical bom datoteko zdravo - ne, ne bom, ker je to izvedljivo - txt2. 166 00:12:29,790 --> 00:12:40,150 Zdaj txt2 se dogaja, da imajo izhod. / Zdravo 00:12:43,520 >> Vprašanja? 168 00:12:45,900 --> 00:12:49,090 >> Ok. Torej imamo tukaj cevovoda. 169 00:12:49,090 --> 00:12:53,510 Cevi so zadnja enota preusmeritev. 170 00:12:53,510 --> 00:12:58,750 >> Oh. Mislim, da ena enota preusmeritve je, če namesto> narediš 2>, 171 00:12:58,750 --> 00:13:01,070 , ki je preusmeritev standardno napako. 172 00:13:01,070 --> 00:13:06,280 Torej, če je šlo nekaj za standardno napako, da ne bi dobili začnejo txt2. 173 00:13:06,280 --> 00:13:12,480 Toda opazil, če sem naredil 2>, nato pa je še vedno tiskanje Zdravo, Rob! v ukazni vrstici 174 00:13:12,480 --> 00:13:18,600 ker sem samo preusmerjanje standardna napaka, jaz ne preusmerja standarda ven. 175 00:13:18,600 --> 00:13:22,210 Standardna napaka in standard iz drugačne. 176 00:13:24,210 --> 00:13:27,080 Če bi želeli, da bi dejansko napisali, da standardna napaka, 177 00:13:27,080 --> 00:13:35,080 potem bi lahko spremenili, da je to ovrednotenj v stderr. 178 00:13:35,080 --> 00:13:37,850 Torej printf, ki ga privzeto tiska na standardni izhod. 179 00:13:37,850 --> 00:13:41,720 Če želim tiskati na standardne napake ročno, nato pa sem moral uporabiti ovrednotenj 180 00:13:41,720 --> 00:13:45,010 in določite, kaj želite tiskati. 181 00:13:45,010 --> 00:13:49,720 Če namesto tega sem ovrednotenj stdout, nato pa, da je v bistvu enaka printf. 182 00:13:49,720 --> 00:13:55,530 Ampak ovrednotenj za standardno napako. 183 00:13:57,790 --> 00:14:03,650 Torej, zdaj, če sem to preusmeriti v txt2, Zdravo, Rob! se bo še natisnjena v ukazni vrstici 184 00:14:03,650 --> 00:14:08,270 saj je bilo pridobivanje natisnjena na standardne napake in sem samo preusmerjanje standarda ven. 185 00:14:08,270 --> 00:14:16,420 Če sem zdaj preusmeriti standardne napake, zdaj ga ni dobil natisniti in txt2 se bo Pozdravljeni, Rob! 186 00:14:16,420 --> 00:14:21,910 Torej, zdaj, lahko natisnete vaše dejanske napake, s standardno napako 187 00:14:21,910 --> 00:14:24,720 in tiskanje redne sporočila out standard. 188 00:14:24,720 --> 00:14:31,420 In tako, ko zaženete program, ga lahko zaženete kot. / Pozdravi to vrsto z 2> 189 00:14:31,420 --> 00:14:33,800 tako da vaš program se bo normalno teči, 190 00:14:33,800 --> 00:14:38,400 vendar pa lahko sporočila o napaki, ki ga dobiš preverite kasneje v svojem dnevniku napak, 191 00:14:38,400 --> 00:14:44,500 Tako napak, nato pa poiščite in pozneje svoje napake, datoteka ne bo imela nobenih napak, ki so se zgodili. 192 00:14:45,200 --> 00:14:47,540 >> Vprašanja? 193 00:14:47,540 --> 00:14:58,070 >> Zadnji je cev, ki jo lahko mislili, pri čemer standard ven iz enega ukaza 194 00:14:58,070 --> 00:15:01,210 in kar je standard v naslednjem ukazu. 195 00:15:01,210 --> 00:15:05,570 Primer za to je odmev je stvar ukazni vrstici 196 00:15:05,570 --> 00:15:11,840 da se bo kar odmeva, kar sem dal v svoje trditve. Ne bom dal ponudbe. 197 00:15:11,840 --> 00:15:16,150 Echo bla, bla, bla je le, da bo tiskanje bla, bla, bla. 198 00:15:16,150 --> 00:15:20,600 Prej, ko sem rekel, da moram dati Rob v txt datoteko 199 00:15:20,600 --> 00:15:28,830 saj lahko le preusmeriti txt datoteke, namesto, / če bom echo Rob 200 00:15:28,830 --> 00:15:35,520 , nato pa je v cevi. / zdravo, da bo tudi storila isto vrsto stvari. 201 00:15:35,520 --> 00:15:39,160 To traja proizvodnje tega ukaza echo, Rob, 202 00:15:39,160 --> 00:15:43,610 in kot prispevku. / zdravo. 203 00:15:44,790 --> 00:15:49,560 Lahko pomislite, da je prva preusmeritev odmeva Rob v datoteko 204 00:15:49,560 --> 00:15:54,160 in nato vneseni v. / halo tega spisa je bil, da samo izhodne. 205 00:15:54,160 --> 00:15:57,850 Vendar pa meni, začasne datoteke iz slike. 206 00:16:01,890 --> 00:16:04,460 >> Vprašanja o tem? 207 00:16:04,460 --> 00:16:07,150 >> Naslednje vprašanje bo vključevalo to. 208 00:16:07,150 --> 00:16:15,310 Kaj plinovoda lahko uporabite, da bi našli številne edinstvene imen v datoteko, imenovano names.txt? 209 00:16:15,310 --> 00:16:24,160 Ukazi bomo želeli uporabiti tu so edinstveni, tako uniq, nato wc. 210 00:16:24,160 --> 00:16:28,840 To lahko storite človek unikatnega dejansko pogledati, kaj to naredi, 211 00:16:28,840 --> 00:16:34,840 in to je le, da bo filter sosednje ujemanje črte od vhoda. 212 00:16:34,840 --> 00:16:40,690 In človek, wc bo tiskanje novo vrstico, Word in bajtov za vsako datoteko. 213 00:16:40,690 --> 00:16:43,760 In zadnja bomo želeli uporabiti, je vrsta, 214 00:16:43,760 --> 00:16:47,410 ki se bo nekako linije txt datoteko. 215 00:16:47,410 --> 00:16:58,080 Če naredim nekaj datoteko txt, names.txt, in to je Rob, Tommy, Joseph, Tommy, Joseph, RJ, Rob, 216 00:16:58,080 --> 00:17:03,910 kar želim tukaj storiti, je najti številne edinstvene imen v tej zadevi. 217 00:17:03,910 --> 00:17:08,750 Torej, kaj bi moral biti odgovor? >> [Študent] 4. >> Ja. 218 00:17:08,750 --> 00:17:13,780 To bi moral biti 4 leta Rob, Tommy, Jožef, RJ so enolično Imena v tej zadevi. 219 00:17:13,780 --> 00:17:20,180 Prvi korak, če sem naredil število besed na names.txt, 220 00:17:20,180 --> 00:17:24,290 To je pravzaprav vse, kar mi povedal. 221 00:17:24,290 --> 00:17:32,560 To je pravzaprav tisk - Poglejmo, človek wc - novih vrstic, besed in bajtov. 222 00:17:32,560 --> 00:17:38,270 Če sem samo skrbi proge, nato pa sem naredil wc-l names.txt. 223 00:17:41,730 --> 00:17:44,300 Torej, to je 1. korak. 224 00:17:44,300 --> 00:17:50,510 Ampak jaz ne želim wc-l names.txt ker names.txt samo vsebuje vsa imena, 225 00:17:50,510 --> 00:17:54,170 in želim, da izločijo vse tiste, ki niso edinstvene. 226 00:17:54,170 --> 00:18:01,200 Torej, če sem naredil unikatnega names.txt, da ni čisto daj mi tisto, kar hočem 227 00:18:01,200 --> 00:18:03,760 ker se podvaja imena so še vedno tam. 228 00:18:03,760 --> 00:18:07,690 Zakaj je tako? Zakaj se ne uniq to, kar želim? 229 00:18:07,690 --> 00:18:10,500 [Študent] V podvojeni vnosi niso [neslišno] >> Ja. 230 00:18:10,500 --> 00:18:16,370 Ne pozabite, stran man za unikatnega pravi filter sosednje pripadajoči liniji. 231 00:18:16,370 --> 00:18:19,680 Oni niso blizu, tako da jih ne bo filter. 232 00:18:19,680 --> 00:18:31,100 Če bi jih razvrstite najprej uredi names.txt se bo dal vse podvojene vrstice skupaj. 233 00:18:31,100 --> 00:18:34,450 Torej, zdaj je to neke vrste names.txt. 234 00:18:34,450 --> 00:18:40,550 Bom želite uporabiti kot prispevek k unikatnega, kar je | uniq. 235 00:18:40,550 --> 00:18:43,390 To mi daje Jožefa, RJ, Rob, Tommy 236 00:18:43,390 --> 00:18:49,260 in želim uporabiti kot prispevek k wc-l, 237 00:18:49,260 --> 00:18:52,740 ki se dogaja, da mi 4. 238 00:18:52,740 --> 00:18:56,930 Kot piše tukaj, kaj cevovod lahko uporabite? 239 00:18:56,930 --> 00:19:01,390 To lahko storite veliko stvari, kot je uporaba niz ukazov 240 00:19:01,390 --> 00:19:05,130 kjer boste uporabili izhod iz ene ukaz kot prispevku k naslednji ukaz. 241 00:19:05,130 --> 00:19:08,780 To lahko storite veliko stvari, veliko pametnih stvari. 242 00:19:08,780 --> 00:19:11,440 >> Vprašanja? 243 00:19:12,910 --> 00:19:14,600 Ok. 244 00:19:14,600 --> 00:19:17,880 To je to, za cevi in ​​preusmeritev. 245 00:19:18,370 --> 00:19:24,090 >> Zdaj gremo na dejanski stvari, kodiranje stvari. 246 00:19:24,090 --> 00:19:29,100 Znotraj tega PDF, boste videli ta ukaz, 247 00:19:29,100 --> 00:19:32,950 in boste želeli, da zaženete ta ukaz v vaši napravi. 248 00:19:36,240 --> 00:19:42,250 wget je ukaz za ravno nekaj iz interneta, v bistvu, 249 00:19:42,250 --> 00:19:45,180 Tako wget in ta naslov. 250 00:19:45,180 --> 00:19:49,110 Če si šel na ta URL v brskalniku, bi prenos te datoteke. 251 00:19:49,110 --> 00:19:52,510 Pravkar sem kliknil na to, da je naloženo datoteko za mene. 252 00:19:52,510 --> 00:19:55,650 Toda pisanje wget te stvari znotraj terminala 253 00:19:55,650 --> 00:19:58,620 je šele tekoč, da jo naložite na svoj terminal. 254 00:19:58,620 --> 00:20:02,750 Imam section5.zip, in boste želeli, da razširite section5.zip, 255 00:20:02,750 --> 00:20:06,520 ki se dogaja, da vam mapo z imenom section5, 256 00:20:06,520 --> 00:20:11,550 ki se dogaja, da imajo vse datoteke ki jih bomo uporabljali danes notri. 257 00:20:33,380 --> 00:20:37,710 Ker programi "Imena datotek kažejo, da si malo Otroški voziček, 258 00:20:37,710 --> 00:20:40,990 Tako vaša naloga je, da ugotovimo, zakaj z gdb. 259 00:20:40,990 --> 00:20:44,560 Ali so vsi jih prenesli / vedo, kako priti do njih prenesete 260 00:20:44,560 --> 00:20:47,480 v svojo napravo? Ok. 261 00:20:47,480 --> 00:20:56,400 >> Tek ./buggy1, bo rekel segmentacije napako (jedro po dampinških cenah), 262 00:20:56,400 --> 00:21:00,500 kar koli boste dobili segfault, to je slabo. 263 00:21:00,500 --> 00:21:03,810 Pod kakšnimi pogoji ste dobili segfault? 264 00:21:03,810 --> 00:21:08,210 [Študent] Dereferenciranje null kazalec. >> Ja. Tako, da je en primer. 265 00:21:08,210 --> 00:21:11,580 Dereferenciranje null kazalec, da boš dobil segfault. 266 00:21:11,580 --> 00:21:16,720 Kaj segfault način je, da ste se dotika spomin ne smete dotika. 267 00:21:16,720 --> 00:21:21,350 Torej Dereferenciranje null kazalec se dotika naslov 0, 268 00:21:21,350 --> 00:21:28,060 in v bistvu so vsi računalniki danes povedal, da je naslov 0 spomin ne smete dotika. 269 00:21:28,060 --> 00:21:31,920 Torej, to je, zakaj Dereferenciranje null kazalec rezultatov v segfault. 270 00:21:31,920 --> 00:21:37,210 Ko se zgodi, da se ne inicializira kazalec, potem je za smeti vrednost, 271 00:21:37,210 --> 00:21:41,520 in tako, ko poskušate ciljne datoteke, da se po vsej verjetnosti ste se dotika spomin 272 00:21:41,520 --> 00:21:43,540 da je v sredi ničesar. 273 00:21:43,540 --> 00:21:45,650 Če se zgodi, da bi dobili srečo in smeti vrednost 274 00:21:45,650 --> 00:21:48,440 se je zgodilo, da kaže nekje na stack ali kaj podobnega, 275 00:21:48,440 --> 00:21:50,820 potem ko dereference da kazalec, ki ste jih ni inicializirana, 276 00:21:50,820 --> 00:21:52,730 ne bo nič narobe. 277 00:21:52,730 --> 00:21:55,480 Ampak, če je poudariti, da, recimo, nekje med dimnik in kopica, 278 00:21:55,480 --> 00:21:59,850 ali pa je poudaril le, da nekje je, da ni bil uporabljen za svoj program še ni, 279 00:21:59,850 --> 00:22:02,240 potem ste se dotika spomin ne smete dotika in ga segfault. 280 00:22:02,240 --> 00:22:06,370 Ko pišete rekurzivno funkcijo in recurses prevečkrat 281 00:22:06,370 --> 00:22:08,720 in vaš dimnik raste prevelika in Sveženj trči v stvari 282 00:22:08,720 --> 00:22:12,270 da ne bi bilo trka z, ste se dotika spomin ne smete dotika, 283 00:22:12,270 --> 00:22:14,810 tako da segfault. 284 00:22:14,810 --> 00:22:17,010 To je tisto, kar je segfault. 285 00:22:17,010 --> 00:22:21,810 >> To je tudi razlog, da je enako, če imate niz, kot je - 286 00:22:21,810 --> 00:22:23,930 gremo nazaj v prejšnjem programu. 287 00:22:23,930 --> 00:22:28,530 V hello.c--Jaz samo dogaja, da bi nekaj drugega. 288 00:22:28,530 --> 00:22:33,770 char * s = "Pozdravljen svet!"; 289 00:22:33,770 --> 00:22:42,310 Če uporabim * i = nekaj ali s [0] = "X"; 290 00:22:42,310 --> 00:22:47,290 zato poskrbite, zdravo. / zdravo, zakaj se je to segfault? 291 00:22:48,410 --> 00:22:51,250 Zakaj se je to segfault? 292 00:22:55,660 --> 00:22:57,890 Kaj bi lahko pričakovali zgodilo? 293 00:22:57,890 --> 00:23:06,640 Če sem printf ("% s \ n", i); kaj bi lahko pričakovali, da se tiska? 294 00:23:06,640 --> 00:23:09,930 [Študent] X zdravo. >> Ja. 295 00:23:09,930 --> 00:23:15,140 Problem je, da ko se ugotovi niz, kot je ta, 296 00:23:15,140 --> 00:23:18,190 s je kazalec, da se dogaja, da gredo na stack, 297 00:23:18,190 --> 00:23:25,880 in kaj je kaže, da je ta niz, ki je vsebovana v bralnem pomnilniku. 298 00:23:25,880 --> 00:23:30,560 Torej samo z imenom, bralni pomnilnik, bi dobili idejo 299 00:23:30,560 --> 00:23:33,010 da če skušate spremeniti, kaj je v bralnem pomnilniku, 300 00:23:33,010 --> 00:23:36,670 počneš nekaj, kar ne bi smeli početi s spominom in si segfault. 301 00:23:36,670 --> 00:23:45,360 To je pravzaprav velika razlika med char * s in char s []. 302 00:23:45,360 --> 00:23:48,790 Torej char s [], zdaj je ta niz se bo dal na sklad, 303 00:23:48,790 --> 00:23:53,960 in sklad ni samo za branje, kar pomeni, da je treba delati to popolnoma v redu. 304 00:23:55,500 --> 00:23:57,370 In to počne. 305 00:23:57,370 --> 00:24:06,250 Ne pozabite, da ko sem naredil char * s = "Pozdravljen svet!", Je sam na kup 306 00:24:06,250 --> 00:24:10,390 vendar opozarja, da s nekje drugje, in da se nekje drugje zgodi, da je samo za branje. 307 00:24:10,390 --> 00:24:15,640 Ampak char s [] je le nekaj na kupu. 308 00:24:17,560 --> 00:24:21,760 Torej, to je še en primer segfault dogaja. 309 00:24:21,760 --> 00:24:27,820 >> Videli smo, da ./buggy1 povzročilo segfault. 310 00:24:27,820 --> 00:24:31,810 V teoriji ne bi smeli gledati buggy1.c takoj. 311 00:24:31,810 --> 00:24:35,170 Namesto tega bomo pogledamo skozi gdb. 312 00:24:35,170 --> 00:24:37,750 Obvestilo, da ko prideš Napaka pri razčlenjenosti (jedro po dampinških cenah), 313 00:24:37,750 --> 00:24:40,850 dobite te datoteke sem pozval jedra. 314 00:24:40,850 --> 00:24:45,200 Če bomo ls-l, bomo videli, da je jedro je običajno zelo velika datoteka. 315 00:24:45,200 --> 00:24:51,580 To je število bajtov datoteke, tako da izgleda, da je 250-nekaj kilobajtov. 316 00:24:51,580 --> 00:24:56,120 Razlog za to je, da tisto, kar je dejansko Posmrtni 317 00:24:56,120 --> 00:25:01,410 je, ko se program sesuje, stanje pomnilnika vašega programa 318 00:25:01,410 --> 00:25:05,230 Samo dobi kopirali in prilepili v to datoteko. 319 00:25:05,230 --> 00:25:07,270 To postane odvrgli v tej datoteki. 320 00:25:07,270 --> 00:25:13,060 Ta program, medtem ko je bilo tekmovanje v teku, se je zgodilo, da imajo pomnilnika približno 250 kilobajtov, 321 00:25:13,060 --> 00:25:17,040 in da je tisto, kar dobil vrgli v tej zadevi. 322 00:25:17,040 --> 00:25:23,630 Zdaj si lahko ogledate na tej datoteki, če ne bomo gdb buggy1 jedro. 323 00:25:23,630 --> 00:25:30,130 Mi lahko samo to gdb buggy1, in da bo le zagon gdb redno, 324 00:25:30,130 --> 00:25:33,800 z buggy1 kot njegov vhodni datoteki. 325 00:25:33,800 --> 00:25:38,260 Toda, če vam gdb buggy1 jedro, nato pa se bo posebej za začetek gdb 326 00:25:38,260 --> 00:25:40,330 ga je videti na tej osnovni datoteki. 327 00:25:40,330 --> 00:25:45,560 In praviš buggy1 pomeni gdb ve, da je ta osnovna datoteka prihaja iz buggy1 programa. 328 00:25:45,560 --> 00:25:49,580 Torej gdb buggy1 jedro se bo takoj bi nam 329 00:25:49,580 --> 00:25:52,060 kje se je zgodilo, da prekine programa. 330 00:25:57,720 --> 00:26:02,340 Vidimo tukaj, program zaključi s signalom 11, Segmentacija napake. 331 00:26:02,340 --> 00:26:10,110 Se zgodi, da bi videli linijo skupščino, ki verjetno ni zelo koristno. 332 00:26:10,110 --> 00:26:15,360 Ampak, če vtipkate BT ali povratno sledenje, da se dogaja, da je funkcija 333 00:26:15,360 --> 00:26:19,430 ki nam daje seznam naših sedanjih okvirih dimnika. 334 00:26:19,430 --> 00:26:23,150 Torej backtrace '. Izgleda, da imamo le dva dimnih okvirje. 335 00:26:23,150 --> 00:26:26,310 Prvi je naš glavni sklad okvir, 336 00:26:26,310 --> 00:26:29,810 in 2. je sklad okvir za to funkcijo, da se zgodi, da je v, 337 00:26:29,810 --> 00:26:34,440 ki izgleda kot da imamo le sestavljanja kodo. 338 00:26:34,440 --> 00:26:38,050 Torej pojdimo nazaj v našo glavno funkcijo, 339 00:26:38,050 --> 00:26:42,300 in za to lahko storimo okvir 1, in mislim, da smo lahko storite tudi določa, 340 00:26:42,300 --> 00:26:45,160 vendar sem se skoraj nikoli ne dol - ali navzgor. Ja. 341 00:26:45,160 --> 00:26:50,710 Gor in dol. Do vas pripelje do 1 žetonov okvir, kar vas je pripeljalo v kupu okvir. 342 00:26:50,710 --> 00:26:53,240 Jaz ponavadi nikoli ne uporabljajte. 343 00:26:53,240 --> 00:26:59,120 Pravkar sem rekel, posebej okvir 1, ki je šel na okvir z oznako 1. 344 00:26:59,120 --> 00:27:01,750 Okvir 1 se dogaja, da nas pripelje na glavni okvir dimnik, 345 00:27:01,750 --> 00:27:05,570 in pravi, tukaj je kode se zgodi, da bo pri. 346 00:27:05,570 --> 00:27:07,950 Če smo želeli nekaj več vrstic kode, lahko rečemo seznam 347 00:27:07,950 --> 00:27:11,280 in to se dogaja, da nam vse vrstic kode okrog njega. 348 00:27:11,280 --> 00:27:13,360 Vrstica smo segfaulted na bilo 6: 349 00:27:13,360 --> 00:27:17,360 if (strcmp ("CS50 kamenje", argv [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 Če ni očitno še ni, ga lahko dobite neposredno od tukaj, samo z razmišljanjem, zakaj je segfaulted. 351 00:27:24,130 --> 00:27:28,800 Lahko pa si vzamete en korak naprej in reči: "Zakaj bi argv [1] segfault?" 352 00:27:28,800 --> 00:27:38,830 Natisni Gremo argv [1], in izgleda, kot da je 0x0, ki je null kazalec. 353 00:27:38,830 --> 00:27:44,750 Mi smo strcmping CS50 skale in nič, in da se bo segfault. 354 00:27:44,750 --> 00:27:48,280 In zakaj je argv [1] ničen? 355 00:27:48,640 --> 00:27:51,280 [Študent] Ker ni dobila nobenih argumentov v ukazni vrstici. 356 00:27:51,280 --> 00:27:53,390 Ja. Mi ni dala nobenih argumentov v ukazni vrstici. 357 00:27:53,390 --> 00:27:58,460 Torej ./buggy1 je le, da imajo argv [0], je ./buggy1. 358 00:27:58,460 --> 00:28:02,100 To se ne dogaja, da imajo argv [1], tako da se bo segfault. 359 00:28:02,100 --> 00:28:07,450 Ampak, če se namesto, jaz samo CS50, da se bo torej dobite D 360 00:28:07,450 --> 00:28:09,950 ker to je tisto, kar je moral storiti. 361 00:28:09,950 --> 00:28:15,240 Če pogledamo buggy1.c, je to naj bi natisniti "Dobiš D" - 362 00:28:15,240 --> 00:28:20,820 Če argv [1] ni "CS50 skale", "Dobiš D", sicer "Dobiš!" 363 00:28:20,820 --> 00:28:25,660 Torej, če želimo, moramo to primerjavo, kot pravi, 364 00:28:25,660 --> 00:28:28,710 kar pomeni, da v primerjavi z 0. 365 00:28:28,710 --> 00:28:31,100 Torej, argv [1] mora biti "CS50 kamenje". 366 00:28:31,100 --> 00:28:35,660 Če želite to narediti v ukazni vrstici, morate uporabiti \ pobegniti prostor. 367 00:28:35,660 --> 00:28:41,690 Torej CS50 \ skal in dobiš A! 368 00:28:41,690 --> 00:28:44,060 Če tega ne boste storili, da backslash, zakaj to ne deluje? 369 00:28:44,060 --> 00:28:47,190 [Študent] To je dve različni argumenti. >> Ja. 370 00:28:47,190 --> 00:28:52,540 Argv [1], se bo CS50 in argv [2] se bo kamenje. Ok. 371 00:28:52,540 --> 00:28:56,470 >> Zdaj ./buggy2 bo spet segfault. 372 00:28:56,470 --> 00:29:01,880 Namesto, da bi ga odprli s svojo osnovno datoteko, bova odprla buggy2 neposredno, 373 00:29:01,880 --> 00:29:05,000 Tako gdb buggy2. 374 00:29:05,000 --> 00:29:09,590 Zdaj, če smo le teči naš program, potem bo to pravi program prejel signala SIGSEGV, 375 00:29:09,590 --> 00:29:15,530 ki je segfault signal, in to se je zgodilo, da se zgodi. 376 00:29:15,530 --> 00:29:21,250 Če pogledamo našo povratno sledenje, vidimo, da smo bili v funkciji oh_no, 377 00:29:21,250 --> 00:29:23,900 ki je bil imenovan s funkcijo Dinky, ki je bil imenovan s funkcijo Binky, 378 00:29:23,900 --> 00:29:26,460 ki je bil imenovan za glavnega. 379 00:29:26,460 --> 00:29:31,680 Vidimo lahko tudi argumente, da te funkcije. 380 00:29:31,680 --> 00:29:34,680 Trditev, da Dinky in Binky je bil 1. 381 00:29:34,680 --> 00:29:44,390 Če naštejemo funkcije oh_no, vidimo, da se samo delaš oh_no char ** S = null; 382 00:29:44,390 --> 00:29:47,410 * S = "BOOM"; 383 00:29:47,410 --> 00:29:50,330 Zakaj bi to uspelo? 384 00:29:54,330 --> 00:29:58,380 [Študent] Ne, ne moreš dereference ničelno kazalec? >> Ja. 385 00:29:58,380 --> 00:30:06,090 To je le, da je NULL, ne glede na to, da se zgodi, da char ** 386 00:30:06,090 --> 00:30:12,070 ki so, odvisno od tega, kako jo interpretirati, bi bilo kazalec na kazalec na niz 387 00:30:12,070 --> 00:30:15,550 ali niz nizov. 388 00:30:15,550 --> 00:30:21,430 To je NULL, tako da je * i Dereferenciranje null kazalec, 389 00:30:21,430 --> 00:30:24,800 in tako se bo to crash. 390 00:30:24,800 --> 00:30:27,540 To je eden od najhitrejših načinov, kako lahko morebiti segfault. 391 00:30:27,540 --> 00:30:31,300 To je samo razglasitvi null kazalec in takoj segfaulting. 392 00:30:31,300 --> 00:30:34,570 To je tisto, kar oh_no počne. 393 00:30:34,570 --> 00:30:43,400 Če gremo eno sliko, potem pa se bomo dobili v funkcijo, ki se imenuje oh_no. 394 00:30:43,400 --> 00:30:44,830 Moram narediti to. 395 00:30:44,830 --> 00:30:48,610 Če ne vnesete ukaz in si zadeti nastopiti še enkrat, 396 00:30:48,610 --> 00:30:52,350 da bo samo ponovi prejšnji ukaz, ki ste tekel. 397 00:30:52,350 --> 00:30:56,610 Smo v okviru 1. 398 00:30:56,610 --> 00:31:04,650 Ad tem okviru vidimo tukaj, je naša naloga. 399 00:31:04,650 --> 00:31:08,520 Lahko seznam zadetkov znova, ali si lahko naredite seznam 20 in se bo seznam še več. 400 00:31:08,520 --> 00:31:13,640 Funkcija Nakićen pravi, če je i 1, nato pa pojdite na funkcijo oh_no, 401 00:31:13,640 --> 00:31:15,960 pa pojdite na Slinky funkcijo. 402 00:31:15,960 --> 00:31:18,700 In vemo, i je 1, saj se zgodi, da vidim tu gor 403 00:31:18,700 --> 00:31:22,560 Nakićen, da je bil imenovan s trditvijo 1. 404 00:31:22,560 --> 00:31:27,560 Lahko pa tudi samo naj tiskam in bo rekel, da sem se 1. 405 00:31:27,560 --> 00:31:33,770 Trenutno smo v Dinky, in če gremo še en okvir, smo vedeli, da bomo končali v Binky. 406 00:31:33,770 --> 00:31:36,600 Up. Zdaj smo v Binky. 407 00:31:36,600 --> 00:31:41,340 Ad to funkcijo - seznam iz pred polčasom me je prekinil - 408 00:31:41,340 --> 00:31:52,670 je začel kot če jaz 0, potem bomo rekli oh_no, pa pokličite Nakićen. 409 00:31:52,670 --> 00:31:57,000 Vemo, da sem bil 1, zato je pozval Nakićen. 410 00:31:57,000 --> 00:32:05,030 In zdaj smo spet v glavnem, in glavna je le, da bo treba int i = rand ()% 3; 411 00:32:05,030 --> 00:32:08,790 To je le, da bo dal naključno število, ki je bodisi 0, 1 ali 2. 412 00:32:08,790 --> 00:32:12,780 To se dogaja, da pokličete Binky s to številko, in se vrnil 0. 413 00:32:12,780 --> 00:32:16,700 Če pogledamo na to, 414 00:32:16,700 --> 00:32:19,880 Samo sprehod skozi program ročno ne da bi jo takoj prikazovati, 415 00:32:19,880 --> 00:32:25,400 da bi določil odmor točko na glavni, kar pomeni, da ko zaženete program 416 00:32:25,400 --> 00:32:31,020 vaš program teče navzgor, dokler se ne dotakne break točko. 417 00:32:31,020 --> 00:32:35,450 Torej, vodenje programa, deloval pa bo in potem bo zadel glavno funkcijo in preneha delovati. 418 00:32:35,450 --> 00:32:44,700 Zdaj smo znotraj Glavni in korak ali naslednji nam bo prinesla naslednje vrstice kode. 419 00:32:44,700 --> 00:32:47,050 To lahko naredite korak ali Naprej. 420 00:32:47,050 --> 00:32:51,800 Hitting drugega, zdaj pa sem se lotil rand ()% 3, tako da lahko natisnete vrednost i, 421 00:32:51,800 --> 00:32:55,280 in bo rekel, da sem se 1. 422 00:32:55,280 --> 00:32:58,110 Zdaj to ne glede na to, ali bomo uporabili naslednji ali korak. 423 00:32:58,110 --> 00:33:01,000 Mislim, da je važno v prejšnjem, vendar pa bi želeli uporabljati naslednji. 424 00:33:01,000 --> 00:33:06,000 Če bomo uporabili korak, smo korak v funkciji, kar pomeni pogled na stvar dejansko 425 00:33:06,000 --> 00:33:07,940 ki se dogaja znotraj Binky. 426 00:33:07,940 --> 00:33:10,510 Če uporabimo drugo, potem to pomeni, da gredo čez funkcijo 427 00:33:10,510 --> 00:33:14,070 in pojdite na naslednjo vrstico kode v naše delovanje. 428 00:33:14,070 --> 00:33:17,900 Tukaj na tej liniji, sem bil v katerih je pisalo rand ()% 3; 429 00:33:17,900 --> 00:33:21,320 če sem korak, bi šel v izvajanje rand 430 00:33:21,320 --> 00:33:25,110 in poglej, kaj se tam dogaja, in sem lahko korak skozi funkcijo rand. 431 00:33:25,110 --> 00:33:26,920 Ampak ne skrbi funkcijo rand. 432 00:33:26,920 --> 00:33:30,190 Želim samo, da gredo na naslednjo vrstico kode v glavnem, zato sem uporabo naslednje. 433 00:33:30,190 --> 00:33:35,800 Ampak zdaj mi ni vseeno glede Binky funkcijo, zato želim, da korak v to. 434 00:33:35,800 --> 00:33:37,730 Zdaj sem v Binky. 435 00:33:37,730 --> 00:33:42,040 Prva vrstica kode je reči, če (i == 0), jaz bi naredili korak, 436 00:33:42,040 --> 00:33:44,930 vidimo, da končajo na Dinky. 437 00:33:44,930 --> 00:33:51,620 Če smo seznam stvari, vidimo, da je bilo preverjeno, i = 0. 438 00:33:51,620 --> 00:33:55,470 i ni enak 0, zato je šel k drugemu pogoju, 439 00:33:55,470 --> 00:33:59,540 ki se bo klic Dinky (i). 440 00:33:59,540 --> 00:34:04,030 Dobiš lahko zamenjali. 441 00:34:04,030 --> 00:34:07,380 Če samo pogledaš na teh progah, neposredno, morda mislite, če (i == 0), 442 00:34:07,380 --> 00:34:10,800 v redu, potem pa sem naredil korak, zdaj pa sem na Dinky (i), 443 00:34:10,800 --> 00:34:14,120 si morda mislite, da je pomenilo, i = 0, ali kaj podobnega. 444 00:34:14,120 --> 00:34:18,980 Ne samo pomeni, da ve, da lahko neposredno držijo linije Dinky (i). 445 00:34:18,980 --> 00:34:23,300 Ker jaz ne 0, naslednji korak ne bo končala na drugem. 446 00:34:23,300 --> 00:34:26,239 Sicer ni postavka, da se bo ustavil na. 447 00:34:26,239 --> 00:34:31,570 To je le, da bo šel v naslednjo vrstico je dejansko lahko izvrši, kar je Nakićen (i). 448 00:34:31,570 --> 00:34:36,090 Vstopanje v Dinky (i), vidimo, če (i == 1). 449 00:34:36,090 --> 00:34:42,670 Vemo, i = 1, tako da, ko stopimo vemo, da bomo končali v oh_no 450 00:34:42,670 --> 00:34:46,489 ker je i = 1 pokliče funkcijo oh_no, ki jo lahko naredimo korak v, 451 00:34:46,489 --> 00:34:52,969 , ki se bo postavila char ** i = na NULL in takoj »BOOM«. 452 00:34:54,270 --> 00:34:59,690 In potem je dejansko videti na izvajanje buggy2, 453 00:34:59,690 --> 00:35:04,590 to, sem se ravno naključno število - 0, 1 ali 2 - klicanje Binky, 454 00:35:04,590 --> 00:35:10,610 ki je 0, če sem pa poziva oh_no, sicer pa poziva Nakićen, ki pride gor. 455 00:35:10,610 --> 00:35:18,100 Če je i 1, klic oh_no, pa pokličite slinky, ki prihajajo sem gor, 456 00:35:18,100 --> 00:35:20,460 če je i 2, pokličite oh_no. 457 00:35:20,460 --> 00:35:24,720 Sploh ne mislim, da je tako - 458 00:35:24,720 --> 00:35:30,030 Ali kdo vidi način, da bi ta program, ki ne bo segfault? 459 00:35:30,030 --> 00:35:37,530 Ker, če sem kaj spregledal, če sem na 0, boste takoj segfault, 460 00:35:37,530 --> 00:35:41,250 pa greš na funkcijo, ki je, če sem si segfault 1, 461 00:35:41,250 --> 00:35:44,540 pa greš na funkcijo, če je i 2 lahko segfault. 462 00:35:44,540 --> 00:35:46,810 Torej, ni važno, kaj si naredil, ti segfault. 463 00:35:46,810 --> 00:35:52,380 >> Mislim, da en način pritrditve, da bi bilo namesto dela char ** S = NULL, 464 00:35:52,380 --> 00:35:55,610 lahko bi malloc prostor za to vrvico. 465 00:35:55,610 --> 00:36:04,230 Lahko bi naredil malloc (sizeof) - sizeof kaj? 466 00:36:09,910 --> 00:36:15,190 [Študent] (char) * 5? >> Ali to zdi v redu? 467 00:36:15,190 --> 00:36:21,060 Jaz sem ob predpostavki, da bo to delovalo, če bi dejansko tekel, vendar to ni tisto, kar sem iskal. 468 00:36:24,400 --> 00:36:32,940 Pogled na vrsti je. Naj dodamo int *, zato int * x. 469 00:36:32,940 --> 00:36:35,600 Jaz bi naredil malloc (sizeof (int)). 470 00:36:35,600 --> 00:36:40,490 Ali pa, če sem hotel niz 5, bi to storil (sizeof (int) * 5); 471 00:36:40,490 --> 00:36:44,210 Kaj, če imam notr? ** 472 00:36:46,260 --> 00:36:49,140 Kaj bi jaz malloc? 473 00:36:49,140 --> 00:36:53,510 [Študent] Velikost kazalca. >> Ja. (Sizeof (int *)); 474 00:36:53,510 --> 00:36:56,960 Ista stvar tukaj. 475 00:36:56,960 --> 00:37:01,280 Hočem (sizeof (char *)); 476 00:37:06,170 --> 00:37:12,840 To se dogaja, da dodelitev prostora za kazalec, ki kaže na "boom". 477 00:37:12,840 --> 00:37:15,330 Ne rabim za dodelitev prostora za "boom" sam 478 00:37:15,330 --> 00:37:17,210 saj to je v bistvu enaka, kar sem rekel prej 479 00:37:17,210 --> 00:37:20,870 od char * x = "boom". 480 00:37:20,870 --> 00:37:27,950 »BOOM« že obstaja. To se zgodi, da obstaja v bralni regiji pomnilnika. 481 00:37:27,950 --> 00:37:35,200 Ampak to že obstaja, kar pomeni, da te kode, če je je char ** 482 00:37:35,200 --> 00:37:43,900 potem * s char * in ste o tem char * opozoriti na "boom". 483 00:37:43,900 --> 00:37:50,040 Če bi želel, da bi kopirali "boom" v S, potem bi morali dodeliti prostor za s. 484 00:37:55,170 --> 00:38:03,900 Jaz bom * i = malloc (sizeof (char) * 5); 485 00:38:03,900 --> 00:38:06,210 Zakaj 5? 486 00:38:06,210 --> 00:38:10,860 Zakaj ne 4? Izgleda, da "boom" je 4 znake. >> [Študent] ničen učinek. 487 00:38:10,860 --> 00:38:14,580 Ja. Vse vaše strune bodo potrebovali null značaj. 488 00:38:14,580 --> 00:38:23,590 Zdaj lahko naredite nekaj takega strcat - Kaj je funkcija za kopiranje niz? 489 00:38:23,590 --> 00:38:28,520 [Študent] KPJ? >> Strcpy. 490 00:38:28,520 --> 00:38:32,700 Človek strcpy. 491 00:38:36,120 --> 00:38:39,590 Torej strcpy ali strncpy. 492 00:38:39,590 --> 00:38:43,410 strncpy je nekoliko varnejši, saj lahko natančno določite, koliko znakov, 493 00:38:43,410 --> 00:38:46,190 ampak tukaj ni pomembno, saj vemo. 494 00:38:46,190 --> 00:38:50,340 Torej strcpy in pogled v argumentih. 495 00:38:50,340 --> 00:38:53,100 Prvi argument je naš cilj. 496 00:38:53,100 --> 00:38:56,770 Drugi argument je naš vir. 497 00:38:56,770 --> 00:39:10,310 Bomo kopirali v našo destinacijo * S kazalec "boom". 498 00:39:10,310 --> 00:39:19,820 Zakaj bi si želeli, da to stori s strcpy namesto samo tisto, kar smo imeli pred 499 00:39:19,820 --> 00:39:22,800 od * s = "BOOM"? 500 00:39:22,800 --> 00:39:28,630 Obstaja razlog, da si morda želeli, da to storijo, a kaj je to razlog? 501 00:39:28,630 --> 00:39:31,940 [Študent] Če želite nekaj spremeniti v "boom". >> Ja. 502 00:39:31,940 --> 00:39:37,950 Zdaj bom lahko naredil kaj takega S [0] = "X"; 503 00:39:37,950 --> 00:39:48,190 ker s točke na kup in da je prostora na kup, da je obrnjena na 504 00:39:48,190 --> 00:39:52,320 je kazalec več prostora na kup, ki je shranjevanje "boom". 505 00:39:52,320 --> 00:39:55,150 Torej je to kopija "boom", ki se hranijo v kup. 506 00:39:55,150 --> 00:39:58,780 Obstajata dva izvoda tehnično "boom" v našem programu. 507 00:39:58,780 --> 00:40:03,500 Tukaj je prvi, ki je samo zaradi te "boom" konstanta niza, 508 00:40:03,500 --> 00:40:09,250 in drugo kopijo "boom", strcpy ustvaril kopijo "boom". 509 00:40:09,250 --> 00:40:13,100 Vendar pa je kopija "boom", ki se hranijo na kup in kup si svoboden spremeniti. 510 00:40:13,100 --> 00:40:17,250 Kup ni samo za branje, tako da pomeni, da je s [0] 511 00:40:17,250 --> 00:40:20,500 se dogaja, da vam spremeni vrednost "boom". 512 00:40:20,500 --> 00:40:23,130 To se dogaja, da vam lahko spremenite te znake. 513 00:40:23,130 --> 00:40:26,640 >> Vprašanja? 514 00:40:27,740 --> 00:40:29,290 Ok. 515 00:40:29,290 --> 00:40:35,500 >> Selitev na buggy3, kaj je gdb buggy3. 516 00:40:35,500 --> 00:40:39,840 Pravkar smo ga zaženete in vidimo, dobimo segfault. 517 00:40:39,840 --> 00:40:46,550 Če bomo 'backtrace, obstajata le dve funkciji. 518 00:40:46,550 --> 00:40:52,970 Če gremo v našo glavno funkcijo, smo videli, da smo segfaulted na tej progi. 519 00:40:52,970 --> 00:41:00,180 Torej samo gledaš na to progo, za (int vrstica = 0; fgets ta stvar ni enaka NULL; 520 00:41:00,180 --> 00:41:03,770 vrstica + +). 521 00:41:03,770 --> 00:41:08,010 Naš prejšnji okvir je bil imenovan _IO_fgets. 522 00:41:08,010 --> 00:41:10,720 Videli boste, da je veliko z vgrajeno v funkcijah C, 523 00:41:10,720 --> 00:41:15,350 da ko prideš segfault, bo zelo skrivnosten imena funkcij 524 00:41:15,350 --> 00:41:18,090 kot je to _IO_fgets. 525 00:41:18,090 --> 00:41:21,770 Ampak to se dogaja, da se nanašajo na ta razpis fgets. 526 00:41:21,770 --> 00:41:25,850 Nekje notri, smo segfaulting. 527 00:41:25,850 --> 00:41:30,340 Če pogledamo argumente za fgets, lahko natisnete buffer. 528 00:41:30,340 --> 00:41:41,180 Naj natisnete - Oh, ne. 529 00:41:48,980 --> 00:41:51,900 Tiskanje ne bo delovalo točno tako, kot želim, da bi. 530 00:41:55,460 --> 00:41:58,000 Oglejmo si dejansko programa. 531 00:42:02,200 --> 00:42:09,640 Buffer je razporeditve znakov. To je znak array 128 znakov. 532 00:42:09,640 --> 00:42:14,980 Torej, ko rečem natisni buffer, da se bo za tiskanje 128 znakov 533 00:42:14,980 --> 00:42:18,300 Mislim, da je kar, kar se pričakuje. 534 00:42:18,300 --> 00:42:21,390 Kaj sem iskal je tiskanje naslov pufra, 535 00:42:21,390 --> 00:42:23,680 vendar to ni res, povej mi veliko. 536 00:42:23,680 --> 00:42:30,770 Torej, ko sem slučajno rekel sem gor x hranilnik, da mi pokaže 0xbffff090, 537 00:42:30,770 --> 00:42:38,690 ki lahko, če se spomnite od prej ali neki točki, Oxbffff kaže, da je sklad-ish regiji. 538 00:42:38,690 --> 00:42:46,020 Sveženj ponavadi nekje začeti tik pod 0xc000. 539 00:42:46,020 --> 00:42:51,890 Tako ga vidim ta naslov, sem vedel, da pufer se dogaja na kupu. 540 00:42:51,890 --> 00:43:04,500 Ponoven svoj program, teči navzgor, varovalni smo videli, je to zaporedje znakov 541 00:43:04,500 --> 00:43:06,530 da so precej nesmiselna. 542 00:43:06,530 --> 00:43:12,270 Potem tiskanje datoteke, kaj slika izgleda? 543 00:43:15,120 --> 00:43:17,310 [Študent] ničelna. >> Ja. 544 00:43:17,310 --> 00:43:22,610 Datoteka je tipa FILE *, zato je kazalec, 545 00:43:22,610 --> 00:43:26,610 in vrednost tega kazalca je nična. 546 00:43:26,610 --> 00:43:33,240 Torej fgets se bo poskušal brati iz tega kazalca na posreden način, 547 00:43:33,240 --> 00:43:37,320 ampak za dostop do tega kazalca, ga mora dereference. 548 00:43:37,320 --> 00:43:40,550 Ali pa, da bi dostop, kar bi morala biti obrnjena k, ga dereferences. 549 00:43:40,550 --> 00:43:43,810 Torej, to je Dereferenciranje null kazalec in ga sesutja. 550 00:43:46,600 --> 00:43:48,730 Lahko bi ga ponovno tam. 551 00:43:48,730 --> 00:43:52,170 Če si odmor v našem glavnem mestu in teče, 552 00:43:52,170 --> 00:43:57,320 Prva vrstica kode je char * filename = "nonexistent.txt"; 553 00:43:57,320 --> 00:44:00,870 To naj bi precej velik namig, zakaj ta program ne. 554 00:44:00,870 --> 00:44:06,080 Tipkanje poleg me pripelje na naslednjo vrstico, ko odprem datoteko, 555 00:44:06,080 --> 00:44:11,140 in potem sem takoj dobil v naši liniji, kjer se, ko sem udaril drugega, da se bo segfault. 556 00:44:11,140 --> 00:44:16,880 Ali kdo želel vreči ven, zakaj ne bi mi lahko segfaulting? 557 00:44:16,880 --> 00:44:19,130 [Študent] Datoteka ne obstaja. >> Ja. 558 00:44:19,130 --> 00:44:22,250 To naj bi bil namig 559 00:44:22,250 --> 00:44:29,570 da se vedno, ko odprete datoteko, ki jo je treba preveriti, ali datoteka sploh obstaja. 560 00:44:29,570 --> 00:44:31,510 Torej, tukaj, "nonexistent.txt"; 561 00:44:31,510 --> 00:44:34,700 Ko smo fopen ime datoteke za branje, nato pa smo morali reči 562 00:44:34,700 --> 00:44:45,870 if (datoteka == NULL) in reči printf ("Datoteka ne obstaja!" 563 00:44:45,870 --> 00:44:56,340 ali - še bolje - naziv), vrnitev 1; 564 00:44:56,340 --> 00:45:00,300 Zdaj smo preverite, če je NULL 565 00:45:00,300 --> 00:45:03,930 preden se dejansko nadaljuje in poskuša brati iz te datoteke. 566 00:45:03,930 --> 00:45:08,800 Mi lahko remake samo da bi videli, da stvar deluje. 567 00:45:11,020 --> 00:45:14,970 Sem nameraval vključiti v novo vrstico. 568 00:45:21,090 --> 00:45:25,290 Torej, zdaj nonexistent.txt ne obstaja. 569 00:45:26,890 --> 00:45:30,040 Vedno morate preveriti te stvari. 570 00:45:30,040 --> 00:45:33,870 Vedno preverite, da vidim, če fopen vrne NULL. 571 00:45:33,870 --> 00:45:38,170 Vedno preverite, da se prepričajte, da malloc ne vrne NULL, 572 00:45:38,170 --> 00:45:41,410 ali pa si segfault. 573 00:45:42,200 --> 00:45:45,930 >> Zdaj buggy4.c. 574 00:45:49,190 --> 00:45:58,440 Tek. Ugibam, da to čaka na vnos ali morda neskončno zanka. 575 00:45:58,440 --> 00:46:01,870 Ja, to je neskončna zanka. 576 00:46:01,870 --> 00:46:05,560 Torej buggy4. Zdi se, kot da smo neskončno zanka. 577 00:46:05,560 --> 00:46:12,590 Mi lahko razbije na glavnem vodijo naš program. 578 00:46:12,590 --> 00:46:20,180 V gdb, dokler okrajšava boste uporabili, je nedvoumno 579 00:46:20,180 --> 00:46:23,420 ali posebne okrajšave, ki jih ponujajo za vas, 580 00:46:23,420 --> 00:46:29,020 potem lahko uporabite n uporabiti naslednje, namesto da bi tip iz naslednjega konca. 581 00:46:29,020 --> 00:46:33,730 In zdaj, ko sem zadel n enkrat, lahko samo pritisnite tipko Enter, da gremo naprej 582 00:46:33,730 --> 00:46:36,640 namesto da bi udaril n Enter Vpišite n, n Enter. 583 00:46:36,640 --> 00:46:44,630 Zdi se, kot da sem v nekakšnem za zanke, ki se določa niz [i] na 0. 584 00:46:44,630 --> 00:46:50,510 Izgleda, da nikoli ne bom rešil iz tega za zanke. 585 00:46:50,510 --> 00:46:54,780 Če sem tiskam, tako da sem za 2, potem pa grem naprej. 586 00:46:54,780 --> 00:46:59,250 Jaz bom tiskanje, i 3, potem bom šel naprej. 587 00:46:59,250 --> 00:47:05,360 Jaz bom tiskanje in i je 3. Nato sem natisniti, i 4. 588 00:47:05,360 --> 00:47:14,520 Pravzaprav natisni sizeof (array), tako da velikost matrike je 20. 589 00:47:16,310 --> 00:47:32,870 Ampak izgleda, da je nekaj posebnega gdb ukaz za odhod dokler se kaj ne zgodi. 590 00:47:32,870 --> 00:47:37,620 To je, kot določa pogoj o vrednosti spremenljivke. Ampak jaz se ne spomnim, kaj je. 591 00:47:37,620 --> 00:47:44,100 Torej, če nadaljujem - 592 00:47:44,100 --> 00:47:47,120 Kaj si rekel? Kaj si bruhati? 593 00:47:47,120 --> 00:47:50,500 [Študent] Ali prikazati dodam - >> Ja. Torej prikaz morem pomagati. 594 00:47:50,500 --> 00:47:54,530 Če bomo samo prikažem, bo dal gor, kaj je vrednost i je 595 00:47:54,530 --> 00:47:56,470 tako da mi ni treba natisniti vsakič. 596 00:47:56,470 --> 00:48:02,930 Če bomo kar naprej gremo naprej, 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 Nekaj ​​se dogaja hudo narobe, in jaz se se ponastavi na 0. 598 00:48:13,330 --> 00:48:22,220 Če pogledamo buggy4.c, vidimo vse, kar se zgodi, je int array [5]; 599 00:48:22,220 --> 00:48:26,200 for (i = 0; i <= sizeof (array); i + +) 600 00:48:26,200 --> 00:48:28,550 array [i] = 0; 601 00:48:28,550 --> 00:48:31,390 Kaj vidimo, da je tukaj narobe? 602 00:48:31,390 --> 00:48:39,480 Kot namig, ko sem delal gdb buggy4 - kaj je glavni odmor, tek - 603 00:48:39,480 --> 00:48:45,980 Nisem natisni sizeof (array) samo zato, da vidim, kaj je pogoj, če naj končno izbruhnila. 604 00:48:47,690 --> 00:48:51,100 Kje sem? Sem teči? 605 00:48:51,100 --> 00:48:54,280 Nisem še izjavo. 606 00:48:54,280 --> 00:48:58,680 Torej tiskanje sizeof (array) in to je 20, 607 00:48:58,680 --> 00:49:06,690 za katerega se pričakuje od mojega matrika velikosti 5 in je za 5 števil, 608 00:49:06,690 --> 00:49:12,410 tako da bi celotno stvar je 5 * sizeof (int) bajti, kjer je sizeof (int) kaže, da je 4. 609 00:49:12,410 --> 00:49:14,780 Torej, sizeof (array) je 20. 610 00:49:14,780 --> 00:49:17,420 Kaj bi to lahko bilo? 611 00:49:17,420 --> 00:49:21,720 [Študent] Delimo z sizeof (int). >> Ja, / sizeof (int). 612 00:49:21,720 --> 00:49:30,630 Izgleda, da je še vedno težava. Mislim, da bi morala biti samo < 613 00:49:30,630 --> 00:49:36,960 saj je precej vedno 00:49:44,860 Zdaj pa pomislite, zakaj se je to dejansko prekinjena. 615 00:49:44,860 --> 00:49:53,370 Ali kdo so ugibanja, zakaj sem bil ponastavi na 0 prek vsaki ponovitvi zanke? 616 00:50:01,300 --> 00:50:09,350 Edina stvar, ki v notranjosti tukaj, da se dogaja, da je matrika [i] je pa nastavljen na 0. 617 00:50:09,350 --> 00:50:15,350 Tako nekako to vrstico kode povzroča našo int i se določi na 0. 618 00:50:16,730 --> 00:50:23,130 [Študent] Ali je mogoče, saj je nujni spomin na ta del i 619 00:50:23,130 --> 00:50:27,970 ko misli, da je naslednji element array? >> [Bowden] Da. 620 00:50:27,970 --> 00:50:33,880 Ko gremo po koncu našega niza, 621 00:50:33,880 --> 00:50:39,870 nekako, da je prostor, ki smo nujnimi je nujni vrednost i. 622 00:50:39,870 --> 00:50:48,030 In tako, če pogledamo v buggy4, prekinil glavno, tek, 623 00:50:48,030 --> 00:50:53,120 dajmo tiskanje naslov i. 624 00:50:53,120 --> 00:50:57,280 Videti je, da je bffff124. 625 00:50:57,280 --> 00:51:03,930 Zdaj pa natisnite naslov niz [0]. 110. 626 00:51:03,930 --> 00:51:06,290 Kaj pa [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] je bfff124. 629 00:51:14,530 --> 00:51:26,990 Torej, matrike [5] ima isti naslov kot jaz, kar pomeni, da matrika [5] i. 630 00:51:26,990 --> 00:51:30,720 Če imajo isti naslov, gre za isto stvar. 631 00:51:30,720 --> 00:51:38,410 Torej, ko smo postavili niz [5] na 0, smo i Nastavitev na 0. 632 00:51:38,410 --> 00:51:46,070 In če misliš o tem glede na kupu, 633 00:51:46,070 --> 00:51:55,590 int i se najprej razglasi, kar pomeni, da sem dobil nekaj prostora na kupu. 634 00:51:55,590 --> 00:52:04,730 Potem matrika [5], se razporedi tako kot 20 bitov se dodelijo na kupu. 635 00:52:04,730 --> 00:52:08,400 Tako postane i dodeljena, potem se dodelijo teh 20 bajtov. 636 00:52:08,400 --> 00:52:11,400 Torej, jaz se zgodi tik pred matrike, 637 00:52:11,400 --> 00:52:19,230 in zaradi načina, kot sem rekel prejšnji teden, kjer je to tehnično stack raste navzdol, 638 00:52:19,230 --> 00:52:28,520 Ko indeks v matriki, so zagotovljene, da bomo 0. položaj v matriki 639 00:52:28,520 --> 00:52:31,970 Vedno se zgodi pred prvo mesto v matriki. 640 00:52:31,970 --> 00:52:35,900 To je nekako, kako mi je narisal prejšnji teden. 641 00:52:35,900 --> 00:52:42,210 Obvestilo, da je na dnu imamo naslov 0 in na vrhu imamo naslov Maks. 642 00:52:42,210 --> 00:52:44,880 Sveženj je vedno raste navzdol. 643 00:52:48,100 --> 00:52:53,500 Recimo, da smo i dodeliti. 644 00:52:53,500 --> 00:52:59,680 Mi razdeliti celo jaz, kar pomeni, da naj samo povem, tukaj sem celo dobi dodeljena. 645 00:52:59,680 --> 00:53:06,420 Potem smo dodelijo portfelj 5 števil, kar pomeni, da je pod, ki 646 00:53:06,420 --> 00:53:11,230 saj je sklad narašča navzdol, se dodeli 5 te cela števila. 647 00:53:11,230 --> 00:53:15,900 Ampak zato, ker o tem, kako nizi delo, si bomo zagotoviti, da prvo mesto v matriki 648 00:53:15,900 --> 00:53:22,260 Vedno je naslov manj kot v drugem stvar v polje. 649 00:53:22,260 --> 00:53:28,270 Torej matrika položaj 0 mora vedno zgoditi v spominu, 650 00:53:28,270 --> 00:53:30,700 ker matrika položaj 1 je zgodilo po tem 651 00:53:30,700 --> 00:53:33,310 in matrika položaj 2 je zgodilo po tem, 652 00:53:33,310 --> 00:53:37,900 kar pomeni, da matrika položaj 0, bi se zgodilo nekje tukaj, 653 00:53:37,900 --> 00:53:40,690 matrika položaj 1, da bi se zgodilo zgoraj 654 00:53:40,690 --> 00:53:45,530 ker se gibljejo pomeni višje naslove, saj je največja naslov tukaj. 655 00:53:45,530 --> 00:53:50,490 Torej niz [0], tukaj, array [1] tu gor, array [2] tu gor, array [3] tukaj. 656 00:53:50,490 --> 00:53:55,620 Opazuj, kako preden smo namenili celo število i vse tja gor, 657 00:53:55,620 --> 00:54:01,040 kot smo korak naprej in naprej v naši matriki, smo bližje in bližje našemu celo i. 658 00:54:01,040 --> 00:54:07,640 Se pač zgodi, da matriko [5], ki je eno mesto izven našega niza, 659 00:54:07,640 --> 00:54:13,010 je točno tam, kjer sem celo zgodilo, da se dodelijo. 660 00:54:13,010 --> 00:54:16,920 Torej, to je točka, kjer se zgodi, da bo zadel prostor na kupu 661 00:54:16,920 --> 00:54:21,680 , ki je bil namenjen za celo i, in smo nastavitve, ki na 0. 662 00:54:21,680 --> 00:54:26,160 >> Tako, da deluje. Vprašanja? Ja. 663 00:54:26,160 --> 00:54:30,710 [Študent] Pozabi. Ok. 664 00:54:30,710 --> 00:54:33,090 [Študent] Kako lahko izognete te vrste napak? 665 00:54:33,090 --> 00:54:41,190 Te vrste napak? Ne uporabljajte C, kot je vaš programski jezik. 666 00:54:41,190 --> 00:54:45,840 Uporabite jezik, ki ima matrične meje kontrole. 667 00:54:45,840 --> 00:54:55,900 Dokler ste previdni, morate samo, da ne grem mimo meja svojega polja. 668 00:54:55,900 --> 00:54:58,300 [Študent] Torej tukaj, ko smo šli mimo meja svojega niza - 669 00:54:58,300 --> 00:55:01,840 [Bowden] To je, če se stvari začnejo narobe. >> [Študent] V redu. 670 00:55:01,840 --> 00:55:05,730 Dokler boste ostali v spominu, dodeljenega za vaše polje, ti si v redu. 671 00:55:05,730 --> 00:55:12,400 Ampak C pa ni preverjanje napak. Če naredim matriko [1000], bo z veseljem samo spremeniti karkoli se zgodi - 672 00:55:12,400 --> 00:55:16,500 Jasno je, da na začetku niza, nato se pozicije po 1000 in jo nastavi na 0. 673 00:55:16,500 --> 00:55:20,000 To ne naredi nobene preverjanje, da oh, to ni dejansko imel stvari v njej 1000. 674 00:55:20,000 --> 00:55:22,750 1000 je tako tistega, kar bi moral biti spreminjanje, 675 00:55:22,750 --> 00:55:26,940 ker bo Java ali kaj boste dobili matriko iz indeksa igrišča 676 00:55:26,940 --> 00:55:29,820 ali indeks izven igrišča izjeme. 677 00:55:29,820 --> 00:55:33,950 To je razlog, zakaj veliko višjih jezikih ravni imajo te stvari 678 00:55:33,950 --> 00:55:37,340 kjer je, če greš zunaj meja delčka, ne 679 00:55:37,340 --> 00:55:40,070 tako da ne morete spremeniti stvari izpod vas 680 00:55:40,070 --> 00:55:42,590 in potem gredo stvari veliko slabše, kot ravno izjemo 681 00:55:42,590 --> 00:55:44,940 pravijo, da si šel po koncu niza. 682 00:55:44,940 --> 00:55:50,970 [Študent] In zato smo pravkar spremenili <= na samo > [Bowden] Ja. 683 00:55:50,970 --> 00:55:54,800 To bi moralo biti 00:55:59,560 saj sizeof (array) je 20, vendar smo le želeli 5. >> [Študent] desno. 685 00:55:59,560 --> 00:56:04,060 Še vprašanja? Ok. 686 00:56:04,060 --> 00:56:07,380 >> [Študent] Imam vprašanje. >> Ja. 687 00:56:07,380 --> 00:56:16,440 [Študent] Kakšna je dejanska matrika spremenljivka? 688 00:56:16,440 --> 00:56:20,000 [Bowden] Kot kaj je matrika? 689 00:56:20,000 --> 00:56:24,930 Array sam simbol. 690 00:56:24,930 --> 00:56:31,490 To je samo naslov začetkom 20 bajtov, da se sklicujete. 691 00:56:31,490 --> 00:56:38,070 Lahko si o njej mislijo kot kazalce, vendar je konstantno kazalec. 692 00:56:38,070 --> 00:56:44,140 Takoj ko se zbirajo stvari, variabilni matrika ne obstaja več. 693 00:56:44,140 --> 00:56:48,210 [Študent] Torej, kako najti velikost array? 694 00:56:48,210 --> 00:56:54,130 Velikost matrike se nanaša na velikost tega bloka, ki se nanaša na ta simbol. 695 00:56:54,130 --> 00:57:01,240 Ko sem naredil kaj takega printf ("% p \ n", niz); 696 00:57:01,240 --> 00:57:05,140 kaj je prost. 697 00:57:12,960 --> 00:57:15,530 Kaj sem naredil narobe? 698 00:57:15,530 --> 00:57:19,220 Array "matrika" prijavljeno tukaj. 699 00:57:20,820 --> 00:57:23,200 Oh, tukaj. 700 00:57:23,200 --> 00:57:31,250 Jek je pameten, in to se zgodi opazil, da sem izjavil matriko kot 5 elementov 701 00:57:31,250 --> 00:57:34,540 vendar sem indeksiranje na položaj 1000. 702 00:57:34,540 --> 00:57:38,450 To lahko storite, da zato, ker so to le konstante. 703 00:57:38,450 --> 00:57:43,370 Lahko le šel tako daleč opazil, da bom zunaj meja matrike. 704 00:57:43,370 --> 00:57:46,880 Toda opazil prej, ko smo imeli i nepravilne, 705 00:57:46,880 --> 00:57:51,040 ne more ugotoviti, koliko vrednosti lahko vzamem naprej, 706 00:57:51,040 --> 00:57:55,540 tako da ne more določiti, da bom po koncu niza. 707 00:57:55,540 --> 00:57:59,430 To je samo Jek biti pameten. 708 00:57:59,430 --> 00:58:03,340 >> Ampak zdaj bi buggy4. Torej, kaj še delam narobe? 709 00:58:03,340 --> 00:58:05,970 Kaže razglasitvi knjižnico "printf". 710 00:58:05,970 --> 00:58:14,960 Grem želijo # include . 711 00:58:14,960 --> 00:58:18,710 Ok. Zdaj teče buggy4. 712 00:58:18,710 --> 00:58:24,840 Tiskanje vrednosti matrike kot sem tukaj, da bi ga natisnili kot kazalec 713 00:58:24,840 --> 00:58:30,060 natisne nekaj, kar izgleda takole - bfb8805c - kar je nekaj naslov 714 00:58:30,060 --> 00:58:33,450 da je v kup-ish regiji. 715 00:58:33,450 --> 00:58:41,820 Array sama je kot kazalec, vendar to ni dejanski kazalec, 716 00:58:41,820 --> 00:58:45,410 saj redno kazalca lahko spremenimo. 717 00:58:45,410 --> 00:58:54,700 Array je le nekaj konstantna. Med 20 kosi spomin na začetek 0xbfb8805c naslov. 718 00:58:54,700 --> 00:59:09,020 Torej bfb8805c s tega naslova +20--ali Mislim -20 - 719 00:59:09,020 --> 00:59:17,400 je vse pomnilnika, dodeljenih za ta niz. 720 00:59:17,400 --> 00:59:20,350 Array je spremenljivka sama ne shrani nikamor. 721 00:59:20,350 --> 00:59:27,660 Ko ste prevajanje, prevajalnik - ročno val na to - 722 00:59:27,660 --> 00:59:33,060 vendar bo prevajalnik enostavno uporabite, če ve, da je matrika. 723 00:59:33,060 --> 00:59:36,090 To, da ne ve, kje se začne matrika, 724 00:59:36,090 --> 00:59:40,910 in tako lahko vedno samo stvari na področju nadomestil iz tega začetka. 725 00:59:40,910 --> 00:59:43,960 Ne potrebujemo spremenljivko samo za zastopanje matriko. 726 00:59:43,960 --> 00:59:53,730 Toda, ko sem naredil nekaj takega int * p = niz, zdaj p je kazalec, ki kaže na to polje, 727 00:59:53,730 --> 00:59:57,830 in zdaj p dejansko ne obstaja na kupu. 728 00:59:57,830 --> 01:00:01,950 Sem brez sprememb str. Lahko naredim, p = malloc. 729 01:00:01,950 --> 01:00:06,500 Tako se je prvotno poudaril niz, zdaj pa opozarja, da nekaj prostora na kup. 730 01:00:06,500 --> 01:00:09,620 Ne morem malloc niza =. 731 01:00:09,620 --> 01:00:13,710 Če Jek je pameten, bo kričal name pravico off kij. 732 01:00:17,000 --> 01:00:21,430 Pravzaprav sem prepričan, gcc bi to preveč. 733 01:00:21,430 --> 01:00:25,010 Torej matrika tipa "int [5]" ni prenosljiva. 734 01:00:25,010 --> 01:00:28,040 Ne morete dodeliti nekaj matrično tip 735 01:00:28,040 --> 01:00:30,500 ker matrika je le konstantna. 736 01:00:30,500 --> 01:00:34,760 To je simbol, ki te navedbe 20 bajtov. Ne morem spremeniti. 737 01:00:34,760 --> 01:00:37,690 >> [Študent] In kje je velikost matrike shranjeno? 738 01:00:37,690 --> 01:00:40,670 [Bowden] To se ne shrani nikamor. To je, ko se pripravi. 739 01:00:40,670 --> 01:00:46,310 Torej, če je velikost matrike shranjeno? 740 01:00:46,310 --> 01:00:51,870 Uporabljate lahko samo sizeof (array) znotraj funkcije, ki je matrika sama prijavljeni. 741 01:00:51,870 --> 01:01:03,150 Torej, če sem naredil nekaj funkcij, foo, in jaz (int polje []) 742 01:01:03,150 --> 01:01:10,450 printf ("% d \ n", sizeof (array)); 743 01:01:10,450 --> 01:01:21,330 in potem dol kličem foo (array); 744 01:01:21,330 --> 01:01:24,840 znotraj te funkcije - kaj je to teči. 745 01:01:34,200 --> 01:01:36,840 To je Jek biti pameten znova. 746 01:01:36,840 --> 01:01:43,890 Govori mi, da sizeof na matrično funkcija parameter 747 01:01:43,890 --> 01:01:46,690 vrne velikost "int *". 748 01:01:46,690 --> 01:01:55,150 To bi bilo napak, če to ni tisto, kar sem želel, da se zgodi. 749 01:01:55,150 --> 01:01:58,960 Naj se dejansko izklopite Werror. 750 01:02:14,950 --> 01:02:17,590 Opozorilo. Opozorila so v redu. 751 01:02:17,590 --> 01:02:19,960 To bo še pripraviti tako dolgo, kot je opozorilo. 752 01:02:19,960 --> 01:02:22,910 . / A.out bo tiskanje 4. 753 01:02:22,910 --> 01:02:28,650 Opozorilo, da je bila ustvarjena, je jasen pokazatelj, kaj je šlo narobe. 754 01:02:28,650 --> 01:02:34,120 Ta int matrika je le, da bo tiskanje sizeof (int *). 755 01:02:34,120 --> 01:02:39,790 Tudi če sem dal vrsto [5] tukaj, je še vedno le, da bo tiskanje sizeof (int *). 756 01:02:39,790 --> 01:02:47,440 Torej takoj, ko ga posredovati v funkciji, razlikovanje med polji in kazalci 757 01:02:47,440 --> 01:02:49,670 je sploh ni. 758 01:02:49,670 --> 01:02:52,640 To se zgodi, da je matrika, ki je bila razglašena na sklad, 759 01:02:52,640 --> 01:02:58,300 ampak takoj, ko se peljemo to vrednost, da 0xbf bla, bla, bla, bla v tej funkciji, 760 01:02:58,300 --> 01:03:03,350 potem je ta kazalec kaže na to polju na kupu. 761 01:03:03,350 --> 01:03:08,310 To pomeni, da je sizeof uporablja le v funkciji, ki je bila razglašena matrika, 762 01:03:08,310 --> 01:03:11,230 kar pomeni, da ko se pripravi to funkcijo, 763 01:03:11,230 --> 01:03:17,330 Jek, ko gre skozi to funkcijo, vidi array je matrika int velikosti 5. 764 01:03:17,330 --> 01:03:20,640 Torej se ji zdi sizeof (array). No, to je 20. 765 01:03:20,640 --> 01:03:26,440 To je pravzaprav, kako sizeof v bistvu deluje skoraj v vseh primerih. 766 01:03:26,440 --> 01:03:31,150 Sizeof ni funkcija, to je upravljavec. 767 01:03:31,150 --> 01:03:33,570 Vi ne kliči sizeof funkcijo. 768 01:03:33,570 --> 01:03:38,280 Sizeof (int), bo prevajalnik prevesti le, da je 4. 769 01:03:41,480 --> 01:03:43,700 Razumeš? Ok. 770 01:03:43,700 --> 01:03:47,520 >> [Študent] Torej, kaj je razlika med sizeof (array) v glavni in v foo? 771 01:03:47,520 --> 01:03:52,840 To je zato, ker si rekel sizeof (polje), ki je tipa int *, 772 01:03:52,840 --> 01:03:57,120 ker je matrika tukaj ni tipa int *, je int matrika. 773 01:03:57,120 --> 01:04:04,540 >> [Študent] Torej, če si imel parameter v polju [] namesto int * array, 774 01:04:04,540 --> 01:04:09,230 bi to pomenilo, da se lahko še vedno spremenite vrsto, ker zdaj je kazalec? 775 01:04:09,230 --> 01:04:14,250 [Bowden] Tako? >> [Študent] Ja. Lahko spremenite niz v funkciji zdaj? 776 01:04:14,250 --> 01:04:18,420 [Bowden] Lahko spremenite zaporedje v obeh primerih. 777 01:04:18,420 --> 01:04:23,130 V obeh primerih vas prosimo, da reči, array [4] = 0. 778 01:04:23,130 --> 01:04:26,590 [Študent] Vendar si lahko matrično točko za kaj drugega? 779 01:04:26,590 --> 01:04:30,230 [Bowden] Oh. Ja. V vsakem primeru - >> [Študent] Ja. 780 01:04:30,230 --> 01:04:38,410 [Bowden] Razlika med matrike [] in int * polje, je ni. 781 01:04:38,410 --> 01:04:42,570 Dobite lahko tudi nekaj večdimenzionalno matriko tukaj 782 01:04:42,570 --> 01:04:47,050 za nekatere priročno sintakso, vendar je še vedno le kazalec. 783 01:04:47,050 --> 01:04:56,400 To pomeni, da sem svoboden narediti niz = malloc (sizeof (int)), sedaj pa točko nekje drugje. 784 01:04:56,400 --> 01:04:59,610 Toda tako kot kako to deluje vedno in vedno, 785 01:04:59,610 --> 01:05:03,210 spremenite to vrsto, da postane kaže na nekaj drugega 786 01:05:03,210 --> 01:05:07,570 ne spremenite to vrsto dol, ker je kopija trditev, 787 01:05:07,570 --> 01:05:10,780 to ni kazalec na te trditve. 788 01:05:10,780 --> 01:05:16,070 In dejansko, tako kot več navedbo, da je popolnoma enaka - 789 01:05:16,070 --> 01:05:21,100 smo že videli, kaj odtisov matrične tisk - 790 01:05:21,100 --> 01:05:31,410 Kaj pa, če tiskamo naslov matrike ali naslov naslovu matrike 791 01:05:31,410 --> 01:05:36,290 bodisi tistih? 792 01:05:41,770 --> 01:05:45,220 Naj prezreti to. 793 01:05:48,140 --> 01:05:51,660 Ok. To je v redu. To je zdaj teče. / A.out. 794 01:05:51,660 --> 01:06:00,220 Tisk niz, nato pa tiskanje naslov niz, so ista stvar. 795 01:06:00,220 --> 01:06:02,870 Array preprosto ne obstaja. 796 01:06:02,870 --> 01:06:08,190 Ve, ko tiskate niz, tiskate simbol, ki se nanaša na teh 20 bajtov. 797 01:06:08,190 --> 01:06:11,940 Tiskanje naslov niz, no, matrika ne obstaja. 798 01:06:11,940 --> 01:06:17,200 To nima naslova, tako da natisne samo naslov teh 20 bajtov. 799 01:06:20,820 --> 01:06:28,150 Takoj, ko se zbere navzdol, tako kot v vašem zbrali buggy4. / A.out, 800 01:06:28,150 --> 01:06:30,340 array je ni. 801 01:06:30,340 --> 01:06:33,640 Kazalci obstajajo. Polja ne. 802 01:06:34,300 --> 01:06:38,060 Bloki pomnilnika, ki predstavljajo niz še vedno obstajajo, 803 01:06:38,060 --> 01:06:43,270 ampak spremenljivka polje in spremenljivke te vrste ne obstajajo. 804 01:06:46,260 --> 01:06:50,270 Tisti, ki so kot glavne razlike med nizi in kazalci 805 01:06:50,270 --> 01:06:55,590 se takoj, ko se ti klici funkcij, ni nobene razlike. 806 01:06:55,590 --> 01:07:00,460 Toda znotraj funkcije, ki je bila prijavljena array sama, sizeof deluje drugače 807 01:07:00,460 --> 01:07:05,190 ker tiskate velikost blokov namesto velikosti tipa, 808 01:07:05,190 --> 01:07:08,950 in ga ne morete spremeniti, ker je simbol. 809 01:07:08,950 --> 01:07:14,370 Tiskanje stvar in naslov stvar natisne isto stvar. 810 01:07:14,370 --> 01:07:18,480 In to je vse. 811 01:07:18,480 --> 01:07:20,820 [Študent] Bi lahko rekli, da še enkrat? 812 01:07:21,170 --> 01:07:24,170 Mogoče sem kaj zamudil. 813 01:07:24,170 --> 01:07:29,260 Tisk polje in naslov sklopa natisne enako, 814 01:07:29,260 --> 01:07:33,180 ker če tiskate kazalec v primerjavi naslov kazalca, 815 01:07:33,180 --> 01:07:36,010 ena stvar natisne naslov, kaj kaže na, 816 01:07:36,010 --> 01:07:40,360 drugi natisne naslov kazalca na kupu. 817 01:07:40,360 --> 01:07:47,040 Spremenite lahko kazalec, da ne morete spremeniti matrično simbol. 818 01:07:47,740 --> 01:07:53,270 In sizeof kazalec se bo natisnila velikost tega kazalca tipa. 819 01:07:53,270 --> 01:07:57,470 Torej, int * p sizeof (p) se bo tiskanje 4, 820 01:07:57,470 --> 01:08:04,110 ampak int array [5] natisni sizeof (array) bo tiskanje 20. 821 01:08:04,110 --> 01:08:07,480 [Študent] Torej bo int array [5] natisniti 20? >> Da. 822 01:08:07,480 --> 01:08:13,300 Zato notranjosti buggy4, ko je bilo nekoč sizeof (array) 823 01:08:13,300 --> 01:08:16,660 To je delal i <20, ki pa ni tisto, kar smo želeli. 824 01:08:16,660 --> 01:08:20,880 Želimo i <5. >> [Študent] Ok. 825 01:08:20,880 --> 01:08:25,569 [Bowden] In takoj, ko se začne prenos v delovanju, 826 01:08:25,569 --> 01:08:34,340 če smo int * p = array; 827 01:08:34,340 --> 01:08:39,779 znotraj te funkcije, lahko uporabite v bistvu p in paleto v popolnoma enak način, 828 01:08:39,779 --> 01:08:43,710 razen tega problema sizeof in spreminjajoče problem. 829 01:08:43,710 --> 01:08:49,810 Ampak p [0] = 1; je enaka kot pravi niz [0] = 1; 830 01:08:49,810 --> 01:08:55,600 In takoj, ko rečemo foo (array); ali foo (p); 831 01:08:55,600 --> 01:08:59,760 znotraj funkcije foo, to je isti poziv dvakrat. 832 01:08:59,760 --> 01:09:03,350 Ni razlike med tema dvema klicema. 833 01:09:07,029 --> 01:09:11,080 >> Vsi dobro na to? Ok. 834 01:09:14,620 --> 01:09:17,950 Imamo 10 minut. 835 01:09:17,950 --> 01:09:28,319 >> Mi bomo poskušali priti skozi ta program Hacker Typer, 836 01:09:28,319 --> 01:09:32,350 ta spletna stran, ki je izšel lansko leto ali kaj podobnega. 837 01:09:34,149 --> 01:09:41,100 To je samo domneva, da se kot vnesete naključno in se natisne - 838 01:09:41,100 --> 01:09:46,729 Karkoli se zgodi, da slika je naložena tako kot izgleda tipkanjem. 839 01:09:46,729 --> 01:09:52,069 Izgleda kot neke vrste operacijskega sistema kode. 840 01:09:53,760 --> 01:09:56,890 To je tisto, kar želimo izvajati. 841 01:10:08,560 --> 01:10:11,690 Moral bi imeti binarno izvedljivo imenom hacker_typer 842 01:10:11,690 --> 01:10:14,350 da se v enem samem argumentu, datoteka na "vrsto hacker." 843 01:10:14,350 --> 01:10:16,480 Vodenje izvršljiv treba počistiti zaslon 844 01:10:16,480 --> 01:10:20,850 in nato natisnete en znak iz spregledanih, ki so v spisu vsakič, ko uporabnik pritisne na tipko. 845 01:10:20,850 --> 01:10:24,990 Torej, ne glede tipko pritisnete, mora zavreči in namesto tega natisne znak iz datoteke 846 01:10:24,990 --> 01:10:27,810 da je argument. 847 01:10:29,880 --> 01:10:34,350 Jaz bom precej povedal, kaj stvari, ki jih bomo morali vedeti so. 848 01:10:34,350 --> 01:10:36,440 Vendar želimo, da preverite knjižnico termios. 849 01:10:36,440 --> 01:10:44,840 Nikoli nisem uporabil to knjižnico v mojem življenju, zato je zelo minimalno namene. 850 01:10:44,840 --> 01:10:48,610 Toda to se bo knjižnica lahko uporabimo, da mečejo znak, ki ga je prizadel 851 01:10:48,610 --> 01:10:52,390 ko tipkate v standardu palcev 852 01:10:56,970 --> 01:11:05,840 Torej hacker_typer.c in bomo želeli # include . 853 01:11:05,840 --> 01:11:12,870 Če pogledamo na stran man za termios - Jaz sem ugibati, da je terminal OS ali kaj podobnega - 854 01:11:12,870 --> 01:11:16,240 Ne vem, kako, da ga preberete. 855 01:11:16,240 --> 01:11:21,040 Ob pogledu na to, se pravi, da se te 2 datoteke, tako da bomo storili. 856 01:11:37,620 --> 01:11:46,820 >> Prva stvar, prvič, želimo, da bi v enem samem argumentu, ki je datoteko moramo odpreti. 857 01:11:46,820 --> 01:11:52,420 Torej, kaj bi rad naredil? Kako preverite, da imam en argument? 858 01:11:52,420 --> 01:11:56,480 [Študent] Če argc je enak. >> [Bowden] Ja. 859 01:11:56,480 --> 01:12:21,250 Torej, če (argc = 2!) Printf ("Uporaba:% s [odpreti datoteko]"). 860 01:12:21,250 --> 01:12:32,750 Torej, zdaj, če sem teči ta ne zagotavlja drugo trditev - oh, rabim novo linijo - 861 01:12:32,750 --> 01:12:36,240 boste videli, da piše uporaba: /. hacker_typer, 862 01:12:36,240 --> 01:12:39,770 in potem se drugi argument je datoteka želim odpreti. 863 01:12:58,430 --> 01:13:01,260 No, kaj naj storim? 864 01:13:01,260 --> 01:13:08,490 Želim brati iz te datoteke. Kako brati iz datoteke? 865 01:13:08,490 --> 01:13:11,920 [Študent] Odprete ga najprej. >> Ja. 866 01:13:11,920 --> 01:13:15,010 Torej fopen. Kaj fopen videti? 867 01:13:15,010 --> 01:13:22,980 [Študent] datoteke. >> [Bowden] datoteke se bo argv [1]. 868 01:13:22,980 --> 01:13:26,110 [Študent] In potem, kaj želite storiti z njim, tako da - >> [Bowden] Ja. 869 01:13:26,110 --> 01:13:28,740 Torej, če ni spomnil, si lahko naredil človek fopen, 870 01:13:28,740 --> 01:13:32,960 če se bo char * pot, kjer pot naziv, 871 01:13:32,960 --> 01:13:34,970 char * mode. 872 01:13:34,970 --> 01:13:38,660 Če se zgodi, da se ne spomnim, kaj je način, potem si lahko ogledate način. 873 01:13:38,660 --> 01:13:44,660 Znotraj priročnikov, znak slash je tisto, kar lahko uporabite za iskanje stvari. 874 01:13:44,660 --> 01:13:49,790 Torej, sem tip / način za iskanje načina. 875 01:13:49,790 --> 01:13:57,130 n in N, kar lahko uporabite, da skozi cikel iskalnih zadetkov. 876 01:13:57,130 --> 01:13:59,800 Tukaj piše točk v načinu argumentov v niz 877 01:13:59,800 --> 01:14:01,930 začenši z eno od naslednjih zaporedij. 878 01:14:01,930 --> 01:14:06,480 Torej r, Odpri besedilno datoteko za branje. To je tisto, kar želimo narediti. 879 01:14:08,930 --> 01:14:13,210 Za branje, in želim, da za shranjevanje. 880 01:14:13,210 --> 01:14:18,720 Stvar se bo FILE *. Zdaj, kaj hočem narediti? 881 01:14:18,720 --> 01:14:21,200 Daj mi sekundo. 882 01:14:28,140 --> 01:14:30,430 Ok. Zdaj, kaj hočem narediti? 883 01:14:30,430 --> 01:14:32,940 [Študent] Preverite, če je NULL. >> [Bowden] Ja. 884 01:14:32,940 --> 01:14:38,690 Vsakič, ko odprete datoteko, se prepričajte, da ste uspešno mogli odpreti. 885 01:14:58,930 --> 01:15:10,460 >> Zdaj bi rad to naredil termios stvari, kjer želim najprej prebrati moje trenutne nastavitve 886 01:15:10,460 --> 01:15:14,050 in razen tistih, ki v nekaj, potem želim, da spremenim svoje nastavitve 887 01:15:14,050 --> 01:15:19,420 da mečejo vse znake, da sem tipa, 888 01:15:19,420 --> 01:15:22,520 in potem hočem posodobiti teh nastavitev. 889 01:15:22,520 --> 01:15:27,250 In potem na koncu programa, želim spremeniti nazaj v moje prvotne nastavitve. 890 01:15:27,250 --> 01:15:32,080 Torej struct se bo tipa termios, in bom želel 2 teh. 891 01:15:32,080 --> 01:15:35,600 Prvi se bo moje current_settings, 892 01:15:35,600 --> 01:15:42,010 in potem boš moji hacker_settings. 893 01:15:42,010 --> 01:15:48,070 Najprej bom želite shraniti svoje trenutne nastavitve, 894 01:15:48,070 --> 01:15:53,790 potem grem želite posodobiti hacker_settings, 895 01:15:53,790 --> 01:16:01,570 nato pa pot na koncu mojega programa, želim, da se vrne na trenutne nastavitve. 896 01:16:01,570 --> 01:16:08,660 Torej, shranite trenutne nastavitve, tako da deluje, mi človek termios. 897 01:16:08,660 --> 01:16:15,810 Vidimo, da imamo to int tcsetattr, int tcgetattr. 898 01:16:15,810 --> 01:16:22,960 Grem mimo v struct termios njegov kazalec. 899 01:16:22,960 --> 01:16:30,640 Pot bo to videti, je - I've že pozabil, kaj se je imenoval funkcijo. 900 01:16:30,640 --> 01:16:34,930 Kopirajte in prilepite. 901 01:16:39,150 --> 01:16:45,500 Torej tcgetattr, potem pa želim prenesti v struct, da sem shranite podatke, 902 01:16:45,500 --> 01:16:49,650 , ki se bo current_settings, 903 01:16:49,650 --> 01:16:59,120 in prvi argument je datoteka Deskriptor stvar, želim, da shranite atribute. 904 01:16:59,120 --> 01:17:04,360 Kaj je datoteka deskriptor je kot kadar koli odprete datoteko, da postane datotečni deskriptor. 905 01:17:04,360 --> 01:17:14,560 Ko sem fopen argv [1], da dobi deskriptorju datoteke, ki ste referenciranja 906 01:17:14,560 --> 01:17:16,730 , če želite prebrati ali pisati. 907 01:17:16,730 --> 01:17:19,220 To ni datoteka deskriptor želim tukaj uporabiti. 908 01:17:19,220 --> 01:17:21,940 Obstajajo tri datoteke deskriptorji imate privzeto, 909 01:17:21,940 --> 01:17:24,310 ki so standard v, standard ven in standardna napaka. 910 01:17:24,310 --> 01:17:29,960 Privzeto je, da mislim, da je standard v 0, ki je standardna 1 in 2 je standardna napaka. 911 01:17:29,960 --> 01:17:33,980 Torej, kaj želim spremeniti nastavitve? 912 01:17:33,980 --> 01:17:37,370 Rad bi spremenil nastavitve, ko sem zadel značaj, 913 01:17:37,370 --> 01:17:41,590 Želim, da bi vrgel proč značaj, namesto da bi ga natisnili na platno. 914 01:17:41,590 --> 01:17:45,960 Kaj tok - standard, standardni izhod, ali standardna napaka - 915 01:17:45,960 --> 01:17:52,050 se odziva na stvari, ko sem tipa na tipkovnici? >> [Študent] Standard noter >> Ja. 916 01:17:52,050 --> 01:17:56,450 Tako sem lahko naredila nobene 0 ali lahko storim stdin. 917 01:17:56,450 --> 01:17:59,380 Grem na current_settings standardnih noter 918 01:17:59,380 --> 01:18:01,720 >> Zdaj hočem posodobiti teh nastavitev, 919 01:18:01,720 --> 01:18:07,200 tako da najprej bom skopirala v hacker_settings kakšne so moje current_settings so. 920 01:18:07,200 --> 01:18:10,430 In kako konstrukti delo bo le kopija. 921 01:18:10,430 --> 01:18:14,510 Ta kopije vseh področjih, kot bi lahko pričakovali. 922 01:18:14,510 --> 01:18:17,410 >> Zdaj hočem, da posodobitev nekaterih področjih. 923 01:18:17,410 --> 01:18:21,670 Če pogledamo termios, bi morali prebrati veliko tega 924 01:18:21,670 --> 01:18:24,110 Samo da vidim, kaj bi si želeli iskati, 925 01:18:24,110 --> 01:18:28,210 ampak zastav jih boste želeli iskati, so odmev, 926 01:18:28,210 --> 01:18:33,110 Tako ECHO znakov vhodnih Echo. 927 01:18:33,110 --> 01:18:37,710 Najprej želim set - I've že pozabili, kaj so polja. 928 01:18:45,040 --> 01:18:47,900 To je tisto, kar struct izgleda. 929 01:18:47,900 --> 01:18:51,060 Torej načinov vnosa mislim, da želimo spremeniti. 930 01:18:51,060 --> 01:18:54,210 Bomo pogled na rešitev, se prepričajte, da je tisto, kar želimo spremeniti. 931 01:19:04,060 --> 01:19:12,610 Želimo spremeniti lflag, da se prepreči da bi morali pogledati skozi vse to. 932 01:19:12,610 --> 01:19:14,670 Želimo, da spremenite lokalne načine. 933 01:19:14,670 --> 01:19:17,710 Ti bi morali prebrati skozi to celotno stvar, da bi razumeli, kje vse pripada 934 01:19:17,710 --> 01:19:19,320 da želimo spremeniti. 935 01:19:19,320 --> 01:19:24,120 Ampak to je znotraj lokalne načine, kam gremo, da želijo to spremeniti. 936 01:19:27,080 --> 01:19:33,110 Torej hacker_settings.cc_lmode je, kako se imenuje. 937 01:19:39,630 --> 01:19:43,020 c_lflag. 938 01:19:49,060 --> 01:19:52,280 To je, če gremo v bitni operaterjev. 939 01:19:52,280 --> 01:19:54,860 Mi smo nekako izven časa, ampak bomo šli skozi to hitro. 940 01:19:54,860 --> 01:19:56,600 To je, če gremo v operaterji bitni, 941 01:19:56,600 --> 01:19:59,950 kjer mislim, da sem rekel, enkrat dolgo nazaj, ko ste začeli, ki se ukvarjajo z zastavami, 942 01:19:59,950 --> 01:20:03,370 boste uporabljali bitni strojniku veliko. 943 01:20:03,370 --> 01:20:08,240 Vsak bit v zastavo ustreza neke vrste vedenja. 944 01:20:08,240 --> 01:20:14,090 Torej, tukaj je ta zastava ima kup različnih stvari, kjer je vse od njih pomenijo nekaj drugega. 945 01:20:14,090 --> 01:20:18,690 Toda tisto, kar želim storiti, je le izklopiti bit, ki ustreza ECHO. 946 01:20:18,690 --> 01:20:25,440 Torej, da bi se to spremenilo off jaz & = ¬ ECHO. 947 01:20:25,440 --> 01:20:30,110 Mislim, da je kot tECHO ali kaj podobnega. Grem še enkrat preveriti. 948 01:20:30,110 --> 01:20:34,050 Lahko ga termios. To je samo odmev. 949 01:20:34,050 --> 01:20:38,440 ECHO bo še en košček. 950 01:20:38,440 --> 01:20:44,230 ¬ ECHO bo pomenilo vsi biti nastavljeni na 1, kar pomeni, da so vse oznake so na true 951 01:20:44,230 --> 01:20:47,140 razen ECHO bit. 952 01:20:47,140 --> 01:20:53,830 Z konča svoje lokalne zastave s tem, to pomeni, da vse zastave, ki so trenutno določene na true 953 01:20:53,830 --> 01:20:56,520 bo še vedno nastavljena na true. 954 01:20:56,520 --> 01:21:03,240 Če je moja ECHO zastave nastavljena na true, potem je to nujno nastavljena na false v ECHO zastavo. 955 01:21:03,240 --> 01:21:07,170 Torej, ta vrstica kode preprosto izklopi ECHO zastavo. 956 01:21:07,170 --> 01:21:16,270 Drugi vrstic kode, bom kopirati jim je v interesu časa, nato pa jih razložiti. 957 01:21:27,810 --> 01:21:30,180 V rešitvi, je dejal 0. 958 01:21:30,180 --> 01:21:33,880 Verjetno je bolje, da se izrecno povedati stdin. 959 01:21:33,880 --> 01:21:42,100 >> Obvestilo, da sem tudi početje ECHO | icanon tukaj. 960 01:21:42,100 --> 01:21:46,650 Icanon nanaša na nekaj ločenega, kar pomeni, kanonično način. 961 01:21:46,650 --> 01:21:50,280 Kaj pomeni canonical način je ponavadi, ko tipkate iz ukazno vrstico, 962 01:21:50,280 --> 01:21:54,670 standard ne obdeluje ničesar, dokler ne dosežete vrstico. 963 01:21:54,670 --> 01:21:58,230 Torej, ko vam GetString, vnesete kup stvari, potem ste zadeli vrstico. 964 01:21:58,230 --> 01:22:00,590 To je, ko je bilo poslano v skladu s standardom noter 965 01:22:00,590 --> 01:22:02,680 To je privzeta nastavitev. 966 01:22:02,680 --> 01:22:05,830 Ko izklopite kanonično način, zdaj vsak znak, ko pritisnete 967 01:22:05,830 --> 01:22:10,910 se dobi kaj predela, ki je običajno vrste slabo, ker je počasi obdelali te stvari, 968 01:22:10,910 --> 01:22:14,330 zato je dobro, da se omili v celotnih linij. 969 01:22:14,330 --> 01:22:16,810 Ampak rad vsak znak, ki se obdelujejo 970 01:22:16,810 --> 01:22:18,810 ker ne želim, da počakate, da sem zadel novo vrstico 971 01:22:18,810 --> 01:22:21,280 preden jih obdeluje vse znake sem bil tipkanje. 972 01:22:21,280 --> 01:22:24,760 Ta izklopi kanonično način. 973 01:22:24,760 --> 01:22:31,320 Ta stvar pomeni samo, ko je dejansko obdeluje znakov. 974 01:22:31,320 --> 01:22:35,830 To pomeni, da jih obdelajo takoj, takoj, ko sem jih vnesete, jih obdeluje. 975 01:22:35,830 --> 01:22:42,510 In to je funkcija, ki se posodablja svoje nastavitve za standard v, 976 01:22:42,510 --> 01:22:45,480 in TCSA pomeni to prav zdaj. 977 01:22:45,480 --> 01:22:50,310 Druge možnosti so počakati, dokler se obdelajo vse, kar je trenutno na potoku. 978 01:22:50,310 --> 01:22:52,030 To sploh ni pomembno. 979 01:22:52,030 --> 01:22:56,920 Ravno zdaj spremenim svoje nastavitve za vse, kar je trenutno v hacker_typer_settings. 980 01:22:56,920 --> 01:23:02,210 Mislim, da so jo imenovali hacker_settings, tako da je spremenila. 981 01:23:09,610 --> 01:23:13,500 Spremenite vse do hacker_settings. 982 01:23:13,500 --> 01:23:16,870 >> Zdaj na koncu našega programa bomo želeli vrniti 983 01:23:16,870 --> 01:23:20,210 s tem, kar je trenutno znotraj normal_settings, 984 01:23:20,210 --> 01:23:26,560 ki se bo šele izgledal & normal_settings. 985 01:23:26,560 --> 01:23:30,650 Obvestilo sem se niso spremenili vse moje normal_settings od prvotno dojemaš. 986 01:23:30,650 --> 01:23:34,520 Potem se jih samo spremeniti nazaj, sem jih posredovali nazaj na koncu. 987 01:23:34,520 --> 01:23:38,390 To je bila posodobitev. Ok. 988 01:23:38,390 --> 01:23:43,900 >> Zdaj notranjosti tukaj bom samo razložiti kodo v interesu časa. 989 01:23:43,900 --> 01:23:46,350 Saj ne, da je veliko kode. 990 01:23:50,770 --> 01:24:03,750 Vidimo beremo znak iz datoteke. Poklicali smo ga f. 991 01:24:03,750 --> 01:24:07,850 Sedaj lahko človek fgetc, ampak kako fgetc se bo delo 992 01:24:07,850 --> 01:24:11,910 je samo, da se bo vrnil znak, ki ste ga pravkar prebral ali EOF, 993 01:24:11,910 --> 01:24:15,680 ki ustreza koncu datoteke ali nekaj napak dogaja. 994 01:24:15,680 --> 01:24:19,900 Mi smo zanka, nadaljuje, da se glasi en znak iz spisa, 995 01:24:19,900 --> 01:24:22,420 dokler ne bo zmanjkalo črk za branje. 996 01:24:22,420 --> 01:24:26,650 In medtem, ko delamo, da bomo čakali na en znak iz standarda palcev 997 01:24:26,650 --> 01:24:29,090 Vsakič vnesete nekaj v ukazni vrstici, 998 01:24:29,090 --> 01:24:32,820 da je branje v lik iz standarda noter 999 01:24:32,820 --> 01:24:38,330 Potem je samo putchar bo dal znak beremo tu gor iz spisa v standardni izhod. 1000 01:24:38,330 --> 01:24:42,890 Lahko človek putchar, vendar je samo polaganje v skladu s standardom ven, to je, da se tiskanje značaja. 1001 01:24:42,890 --> 01:24:51,600 Lahko tudi samo ne printf ("% c", c); isto idejo. 1002 01:24:53,330 --> 01:24:56,670 To bo naredil večino našega dela. 1003 01:24:56,670 --> 01:25:00,300 >> Zadnja stvar, boste želeli storiti, je le fclose našo datoteko. 1004 01:25:00,300 --> 01:25:03,310 Če ne fclose, da je pomnilnika. 1005 01:25:03,310 --> 01:25:06,680 Želimo fclose datoteko smo sprva odprli, in mislim, da je to. 1006 01:25:06,680 --> 01:25:13,810 Če naredimo, da že imam probleme. 1007 01:25:13,810 --> 01:25:17,260 Pa poglejmo. 1008 01:25:17,260 --> 01:25:19,960 Kaj pa pritožujejo? 1009 01:25:19,960 --> 01:25:30,220 Pričakovan "int", ampak argument je tipa "struct _IO_FILE *". 1010 01:25:36,850 --> 01:25:39,370 Bomo videli, če deluje. 1011 01:25:45,210 --> 01:25:53,540 Dovoljeno samo v C99. Augh. Ok, da hacker_typer. 1012 01:25:53,540 --> 01:25:57,760 Zdaj smo dobili bolj uporabne opise. 1013 01:25:57,760 --> 01:25:59,900 Torej, uporabite črno identifikator "normal_settings". 1014 01:25:59,900 --> 01:26:04,170 Nisem klical, da normal_settings. Poklical sem ga current_settings. 1015 01:26:04,170 --> 01:26:12,090 Torej, kaj je vse to spremeniti. 1016 01:26:17,920 --> 01:26:21,710 Zdaj gre mimo argument. 1017 01:26:26,290 --> 01:26:29,500 Naredil bom to 0, za zdaj. 1018 01:26:29,500 --> 01:26:36,720 Ok. . / Hacker_typer cp.c. 1019 01:26:36,720 --> 01:26:39,590 Prav tako ni jasno, zaslon na začetku. 1020 01:26:39,590 --> 01:26:42,960 Vendar pa lahko ozremo na zadnji sklop problemov, kako ste počistiti zaslon. 1021 01:26:42,960 --> 01:26:45,160 To je samo nekaj znakov tiskanje 1022 01:26:45,160 --> 01:26:47,210 pa to je to, kar želim storiti. 1023 01:26:47,210 --> 01:26:48,900 Ok. 1024 01:26:48,900 --> 01:26:55,280 In razmišljal o tem, zakaj je to potrebno, da je 0 namesto standardnega vhoda, 1025 01:26:55,280 --> 01:27:00,560 ki jih je treba opredeliti # 0, 1026 01:27:00,560 --> 01:27:03,890 To se pritožuje, da je - 1027 01:27:13,150 --> 01:27:19,360 Prej, ko sem rekel, da je datoteka deskriptorjev, nato pa imate tudi svojo datoteko *, 1028 01:27:19,360 --> 01:27:23,210 Datotečni deskriptor je samo ena celo število, 1029 01:27:23,210 --> 01:27:26,970 ker FILE * ima cel kup stvari, povezane z njo. 1030 01:27:26,970 --> 01:27:30,380 Razlog moramo reči 0 namesto standardnega vhoda 1031 01:27:30,380 --> 01:27:37,480 je, da je stdin FILE * kar opozarja na stvari, ki se sklicujete datotečnega deskriptorja 0. 1032 01:27:37,480 --> 01:27:45,070 Torej tudi tu gor, ko sem naredil fopen (argv [1], sem že DATOTEKE * nazaj. 1033 01:27:45,070 --> 01:27:51,180 Ampak nekje v tej datoteki * je stvar, ki ustreza datoteke deskriptorjev za te datoteke. 1034 01:27:51,180 --> 01:27:57,430 Če pogledate na stran man za odprt, tako da mislim, da boste morali narediti človek 3 odprta - nope - 1035 01:27:57,430 --> 01:27:59,380 Človek 2 odprta - ja. 1036 01:27:59,380 --> 01:28:06,250 Če pogledate na stran za odprt, odprt je kot nižji ravni fopen, 1037 01:28:06,250 --> 01:28:09,350 in to je dejansko vrnil datotečnega deskriptorja. 1038 01:28:09,350 --> 01:28:12,050 fopen pa kup stvari na vrhu odprta, 1039 01:28:12,050 --> 01:28:17,640 ki je namesto vračanja le, da datoteka deskriptor vrne celoten spis * kazalec 1040 01:28:17,640 --> 01:28:20,590 Notranjost, ki je naš mali datoteke deskriptor. 1041 01:28:20,590 --> 01:28:25,020 Tako standard se nanaša na stvar, FILE *, 1042 01:28:25,020 --> 01:28:29,120 ker se nanaša le 0 datoteke standarda deskriptor sam po sebi. 1043 01:28:29,120 --> 01:28:32,160 >> Vprašanja? 1044 01:28:32,160 --> 01:28:35,930 [Smeh] Odpihnil skozi to. 1045 01:28:35,930 --> 01:28:39,140 V redu. Končali smo. [Smeh] 1046 01:28:39,140 --> 01:28:42,000 >> [CS50.TV]