[Powered by Google Translate] [Seksyon 5 - Higit kumportableng] [Rob Bowden - Harvard University] [Ito ay CS50. - CS50.TV] Tulad ng sinabi ko sa aking email, may maraming mga bagay na maaari mong gamitin iba kaysa sa appliance upang aktwal na gawin ang mga set ng problema. Inirerekomenda namin na gawin mo ito sa appliance dahil lang maaari naming mas madaling makatulong sa iyo at alam namin kung gaano ang lahat upang gumana. Ngunit bilang isang halimbawa ng kung saan maaari mong gawin ang mga bagay na kung, sabihin nating, hindi mo magkaroon ng access sa isang appliance o nais mong upang gumana sa basement ng Science Center - kung saan aktwal na nila ang appliance masyadong - kung gusto mong gumana kahit saan. Ang isang halimbawa ay ang iyong nakita / narinig ng SSH? SSH ay isa lamang tulad kumonekta sa isang bagay. Aktwal na, ngayon ako SSHed papunta sa appliance. Ko hindi gumana nang direkta sa appliance. Narito ang ang appliance, at kung titingnan mo ang dito mo makita ang IP address na ito. Hindi ko kailanman sa appliance mismo; Ko laging darating sa isang iTerm2 window / terminal na window. Maaari mong SSH na IP address, ssh jharvard@192.168.129.128. Natatandaan ko numerong iyon lalong madaling dahil ito ay tulad gandang pattern. Ngunit iyon ay hilingin sa akin para sa aking password, at ngayon ako sa appliance. Talaga, sa puntong ito, kung ikaw ay nagbukas ng isang terminal sa loob ng appliance mismo, interface na ito, gayunpaman, nais mong gamitin ito, ay eksaktong kapareho bilang ang interface ako ginagamit sa paglipas dito ngunit ngayon ka SSHed. Hindi mo na kailangang sa SSH sa appliance. Isang halimbawa ng isa pang lugar na maaari mong SSH sa ako ay medyo sigurado na mayroon ka sa pamamagitan ng default - Oh. Mas malaki. Lahat mo ay dapat magkaroon ng default FAS account sa mga server ng FAS. Para sa akin, gagawin ko SSH sa rbowden@nice.fas.harvard.edu. Ito ay upang hilingin sa iyo na ang unang pagkakataon, at sabihin mo oo. Ang aking password na ang aking password sa FAS. At ito ngayon, ako SSHed sa magaling server, at ang maaari kong gawin ang anumang gusto ko sa dito. Isang maraming ng mga klase na maaari mong gawin, tulad ng 124, pagpunta sa nag-upload ka ng mga bagay-bagay dito sa aktwal na isumite ang iyong mga set ng problema. Ngunit sinasabi hindi ka magkaroon ng access sa iyong appliance. Pagkatapos ay maaari mong gawin ang mga bagay, tulad ng sa dito ay ito sabihin - Ito lamang ang aming seksyon ng mga tanong. Ito ay hilingin mong gawin ito sa appliance. Sa halip kukunin ko na lang gawin ito sa server. Ako pagpunta sa-unzip na. Ang problema ay na ginamit ka gamit ang isang bagay tulad ng gedit o anumang loob ng appliance. Hindi mo ay mayroon na sa server ng FAS. Ito ay lahat lamang ito tekstuwal interface. Kaya maaari mong alinman sa isa, subukan upang matuto ang isang editor ng teksto na sila. Ang mga ito ay may Nano. Nano ay karaniwang medyo madaling gamitin. Maaari mong gamitin ang iyong mga arrow at i-type normal. Kaya na hindi mahirap. Kung nais mong makakuha ng talagang magarbong maaari mong gamitin ang Emacs, kung saan ako marahil ay hindi dapat binuksan dahil hindi ko alam kung paano isara ang Emacs. Control X, Control C? Oo. O maaari mong gamitin Vim, na kung saan ay kung ano ang ko bang gamitin ang. At kaya mga ang iyong mga pagpipilian. Kung hindi mo nais na upang gawin iyon, maaari mo ring, kung tiningnan mo ang manual.cs50.net-- Oh. Sa PC, maaari mong SSH gamit ang masilya, kung saan ka pagpunta upang i-download nang hiwalay. Sa Mac, maaari ka lamang sa pamamagitan ng paggamit ng default Terminal o mo maaaring i-download iTerm2, na ay tulad ng isang magaling, magarbong Terminal. Kung pupunta ka sa manual.cs50.net makikita mo ang isang link sa Notepad + +, na ay kung ano ang maaari mong gamitin sa PC. Ito ay nagbibigay-daan sa SFTP mo mula sa Notepad + +, na kung saan ay isa lamang SSH. Ano ito ay hayaan mong gawin ay i-edit ang iyong mga file sa lokal, at pagkatapos ay kahit kailan mo gusto upang i-save ang mga ito, ito ay i-save sa mga nice.fas, kung saan maaari mong patakbuhin ang mga ito. At ang katumbas sa Mac ay pagpunta sa TextWrangler. Kaya ito ay nagbibigay-daan sa gawin mo ang parehong bagay. Ay nagbibigay-daan sa iyo upang lokal na i-edit ang mga file at i-save ang mga ito sa mga nice.fas, kung saan maaari mong patakbuhin ang mga ito. Kaya kung sakaling ikaw ay natigil nang walang isang appliance, mayroon kang mga pagpipilian na ito pa rin na gawin ang iyong mga hanay ng problema. Ang isang problema na hindi ka ng CS50 library dahil nice.fas ay hindi sa pamamagitan ng default na mayroon na. Maaari mong i-download ang CS50 library - Hindi sa tingin ko kailangan ko na sa puntong ito. Maaari mong i-download ang CS50 library at kopyahin ito sa nice.fas, o tingin ko sa puntong ito hindi namin gamitin ito ngayon pa rin. O kung gagawin namin, maaari mo para sa oras na palitan ito sa ang pagpapatupad ng ang mga function sa CS50 library pa rin. Sa gayon ay hindi dapat na magkano ng isang paghihigpit. At na na. Kukunin ko na bumalik sa appliance ngayon, gagawin namin ang lahat sa appliance. Pagtingin sa aming seksyon ng mga tanong, sa simula, tulad ng sinabi ko sa aking email, mayroon kaming makipag-usap tungkol sa isang maikling ay dapat kang manood. Mayroon kaming ang nagre-redirect & Pipes at ang tatlong tanong. Na kung saan stream ang mga function tulad ng printf sumulat sa pamamagitan ng default? Kaya stream. Ano ang isang stream? Stream ay isa lamang tulad lang ilang - Hindi ito kahit isang pinagmulan ng 1s at 0s. Ang stream na ito ay humihingi para dito ay karaniwang out. At kaya karaniwang out ay isang stream na kapag ka magsulat dito, ito lumilitaw sa screen. Standard out, sa pamamagitan ng stream, ito ay nangangahulugan na magsulat lamang 1s at 0s dito, at ang iba pang mga dulo ng standard out bumabasa mula sa stream. Ito ay isang string ng 1s at 0s. Maaari kang sumulat sa stream o maaari mong basahin mula sa stream depende sa kung ano ang stream talaga. Ang iba pang dalawang default stream Standard sa at karaniwang error. Standard sa tuwing mo GetString, naghihintay para sa iyo sa input bagay. Kaya naghihintay para sa iyo, aktwal na ito ay naghihintay sa Standard sa, na talaga kung ano ang makakakuha ka kapag nag-type sa keyboard. Nagta-type ka sa pamantayan. Standard error ay isa lamang katumbas sa pamantayan out, ngunit nagdadalubhasang sa na kapag-print ka sa standard error, ka dapat upang i-print lamang ang mga mensahe ng error na iyon sa gayon ay maaari mong pagkakaiba sa pagitan ng regular na mga mensahe na naka-print sa screen kumpara sa mga mensahe ng error depende sa kung sila nagpunta sa pamantayan out o standard error. File. Standard out, pamantayan sa, at karaniwang error lamang espesyal stream, ngunit talagang file anumang, kapag binuksan mo ang isang file, ito ay magiging isang stream ng mga byte kung saan maaari mo lamang basahin mula sa stream. Sa iyo, para sa pinaka-bahagi, maaari lamang sa tingin ng isang file bilang isang stream ng mga byte. Kaya kung ano ang stream na ito sumulat sa pamamagitan ng default? Standard out. Ano ang pagkakaiba sa pagitan> at >>? Ba sinuman panoorin muna ang video? Okay. > Ay pagpunta sa kung paano mo pag-redirect sa file, at >> din upang i-redirect ang output sa file, ngunit sa halip ito upang isama sa file. Halimbawa, sabihin nating ko mangyayari sa dict dito mismo, at ang tanging bagay-bagay sa loob ng dict pusa, cat, dog, isda, aso. Isa utos na mayroon ka sa command line ay pusa, na lamang upang i-print kung ano ang sa isang file. Kaya kapag sinabi ko pusa dict, ito upang i-print ang pusa, cat, dog, isda, aso. Na pusa lahat ng ginagawa. Iyon ay nangangahulugan na ito ay naka-print sa standard out pusa, cat, dog, aso isda,. Kung gusto ko sa halip upang i-redirect na sa isang file, maaari ko bang gamitin ang> at i-redirect ang mga ito sa anumang file. Tatawag ako ng file ng file. Kaya ngayon kung ako ls, makikita ko makita ang mayroon akong isang bagong file na tinatawag na file. At kung ako buksan ito, ito ay kung ano mismo ang pusa ilagay sa command line. Kaya ngayon kung gagawin ko na muli, pagkatapos ito upang i-redirect ang output sa file, at ako pagpunta sa ang parehong eksaktong bagay. Kaya technically, ganap na ito overrode kung ano ang nagkaroon kami. At kami na makita kung ko bang baguhin dict, kinuha ko ang aso. Ngayon kung namin pusa dict sa file muli, kami ay pagpunta sa ang bagong bersyon na may aso inalis. Kaya ganap na-override ito. Sa halip, kung ginagamit namin >>, ito upang isama ang file. Ngayon, ang pagbubukas ng file, makikita namin lang namin ang parehong bagay na naka-print na dalawang beses dahil ito ay doon sabay-sabay, pagkatapos namin nakadugtong sa orihinal. Kaya iyon ang> at >> gawin. Ba ang susunod na isa hilingin - Hindi ito magtanong tungkol dito. Ang iba pang isa na mayroon kaming <, na kung> nagre-redirect karaniwang out, gawin mo 2>, na nagre-redirect sa standard error. Kaya kung may nangyaring sa standard error, hindi ito ay makapag-maglagay sa txt2. Ngunit mapansin kung gawin ko 2>, pagkatapos pa rin ito sa pag-print Kumusta, Rob! sa command line dahil lamang ako nagre-redirect ng mga karaniwang error, hindi ako nagre-redirect pamantayan out. Standard na error at pamantayan out ay naiiba. Kung nais mong aktwal na sumulat sa standard error, maaari ko bang baguhin ito sa fprintf sa stderr. Sa printf, sa pamamagitan ng default, Kopya na pamantayan out. Kung gusto kong i-print sa manu-mano ang standard error, pagkatapos ko bang gamitin ang fprintf at tukuyin kung ano ang gusto kong i-print. Kung sa halip ay ginawa ko fprintf stdout, pagkatapos na talaga katumbas sa printf. Ngunit fprintf sa standard error. Sa ngayon, kung ako pag-redirect ito sa txt2, Kamusta, Rob! ay nagsisimula pa rin naka-print sa command line dahil ito nagsisimula naka-print sa standard error at lamang ako nagre-redirect ng pamantayan ang. Kung ako ngayon na-redirect ang standard error, na ngayon ay hindi ito makapag-print, at txt2 ay magiging Kumusta, Rob! Sa ngayon, maaari mong i-print ang iyong aktwal na mga error sa standard error at i-print ang iyong regular na mensahe sa pamantayan out. At kaya kapag pinatakbo mo ang iyong programa, maaari kang magpatakbo ng ito bilang. / Kumusta ganitong uri na may 2> sa gayon na ang iyong programa ay pagpunta sa pagtakbo ng normal, ngunit ang anumang mga mensahe ng error na makakakuha ka ng check sa ibang pagkakataon sa iyong error log, kaya error, at pagkatapos ay tumingin sa ibang pagkakataon at iyong mga error sa file ay magkakaroon ng anumang mga error na nangyari. Mga tanong? Ang huling pipe, na maaari mong tingin ng bilang ng paglalaan ang pamantayan out mula sa isang utos at gawin ito ang pamantayan in ng susunod na utos. Isang halimbawa dito ay echo ay isang bagay sa linya ng command na na lang sa echo anumang ko bang ilagay ang bilang nito argument. Hindi ko ay ilagay ang mga quote. Echo blah, blah, blah ay pagpunta upang i-print ang blah, blah, blah. Bago, kapag sinabi ko ako ay upang ilagay ang Rob sa isang txt file dahil maaari ko lamang pag-redirect file txt, sa halip, / kung echo ko Rob at pagkatapos ay tubo ito sa / kumusta, na ring gawin ang parehong uri ng bagay. Ito ay paglalaan ng output ng command na ito, echo Rob, at gamitin ito bilang input para sa. / kumusta. Maaari mong isipin na ito bilang unang pag-redirect echo Rob sa isang file at pagkatapos input sa. / kumusta na file na ay lamang outputted. Ngunit ito ay tumatagal ang pansamantalang file ng larawan. Mga tanong sa na? Ang susunod na tanong ay upang makasali ito. Ano pipeline ang maaari mong gamitin upang mahanap ang bilang ng mga natatanging pangalan sa isang file na tinatawag names.txt? Ang mga utos na kami ay pagpunta sa gusto mong gamitin dito ay natatangi, kaya uniq, at pagkatapos WC. Maaari mong gawin ang tao uniq sa aktwal na hitsura sa kung ano na ginagawa, at ito upang i-filter ang mga katabi pagtutugma ng linya mula sa input. At tao WC ay pagpunta sa i-print ang newline, salita, at byte bilang para sa bawat file. At ang huling isa na kami ay pagpunta sa nais na gumamit ng uri, na lang na-uri-uriin ang mga linya ng txt file. Kung gumawa ako ng ilang txt file, names.txt, at ito Rob, Tommy, Jose, Tommy, Joseph, RJ, Rob, kung ano ang gusto kong gawin dito ay mahanap ang bilang ng mga natatanging pangalan sa file na ito. Kaya ano ang dapat ang sagot? >> [Mag-aaral] 4. >> Oo. Ito ay dapat 4 dahil Rob, Tommy, Joseph, RJ lamang natatanging pangalan sa file na ito. Ang unang hakbang, kung ko lang ang bilang ng salita sa names.txt, ito ay aktwal na nagsasabi sa akin ang lahat. Ito ay talagang pag-print - hayaan ang makita, tao WC - newline, salita, at byte bilang ng. Kung lamang ako pakialam tungkol sa mga linya, maaari ko lang WC-l names.txt. Kaya na hakbang 1. Ngunit hindi ko nais sa WC-l names.txt dahil names.txt lamang na naglalaman ng lahat ng mga pangalan, at gusto ko upang i-filter ang anumang di-natatanging mga. Kaya kung gagawin ko uniq names.txt, na hindi pa ninyo ako kung ano ang gusto kong dahil ang mga dobleng mga pangalan ay pa rin doon. Bakit na? Bakit uniq hindi ginagawa kung ano ang gusto ko? [Mag-aaral] mga duplicate ay hindi [hindi marinig] >> Oo. Tandaan ang tao na pahina para uniq nagsasabing filter katabing linya ng pagtutugma. Hindi ito mga katabi, kaya hindi ito ay sasalain ang mga ito. Kung uri-uriin ko muna ang mga ito,-uuri names.txt ay upang ilagay ang lahat ng mga duplicate na linya. Kaya ngayon-uuri names.txt na. Ako pagpunta sa gusto upang gamitin ang na bilang ang input sa uniq, na | uniq. Na nagbibigay sa akin Joseph, RJ, Rob, Tommy, at gusto kong gamitin na bilang ang input sa WC-l, na kung saan ay upang bigyan ako ng 4. Tulad ng sinasabi dito, kung ano pipeline maaari mong gamitin? Maaari mong gawin ng maraming mga bagay tulad ng paggamit ng isang serye ng mga utos kung saan ginamit mo ang output mula sa isang utos bilang ang input sa susunod na utos. Maaari mong gawin ng maraming mga bagay, ng maraming mga bagay matalino. Mga tanong? Okay. Iyon ay para sa mga pipe at pag-redirect. Ngayon namin pumunta sa ang aktwal na mga bagay-bagay, ang coding bagay. Inside ng PDF, makikita mo ang command na ito, at makikita mo nais patakbuhin ang command na ito sa iyong appliance. wget ang command para sa pagkuha lamang ng isang bagay mula sa Internet, talaga, kaya wget at ang URL na ito. Kung nagpunta ka sa URL na ito sa iyong browser, i-download na file. Ko lang ang nag-click sa ito, kaya-download ang file para sa akin. Ngunit sa pagsusulat sa wget ng bagay na sa loob ng terminal ay lamang pagpunta upang i-download ang mga ito sa iyong terminal. Mayroon akong section5.zip, at gugustuhin mong i-unzip section5.zip, na kung saan ay upang bigyan ka ng isang folder na tinatawag na section5, na upang magkaroon ng lahat ng mga file na kami ay pagpunta sa gumagamit ngayon sa loob nito. Bilang iminumungkahi ang pangalan ng file ng mga programang ito, hindi sila ng kaunti maraming surot, kaya ang iyong misyon ay upang malaman kung bakit gamit gdb. Ba ang lahat sa kanila-download / malaman kung paano upang makakuha ang mga ito-download sa kanilang appliance? Okay. Pagpapatakbo ng ./buggy1, ito ay sabihin ang Segmentation fault (core dumped), kung saan ang anumang oras na makakakuha ka ng isang segfault, ito ay isang masamang bagay. Sa ilalim kung ano pangyayari kang makakuha ng segfault? [Mag-aaral] Dereferencing null pointer. >> Oo. Kaya na ay isang halimbawa. Dereferencing isang null pointer ka pagpunta upang makakuha ng isang segfault. Anong segfault paraan ka ng pagpindot sa memory hindi mo dapat na nakadikit. Kaya dereferencing null pointer ng pagpindot address 0, at isa lamang, lahat ng mga computer sa kasalukuyan sabihin ang address 0 memory, hindi mo dapat pagpindot. Kaya na kung bakit dereferencing ng isang null pointer resulta sa isang segfault. Kapag mangyari sa hindi nakapagsimula ng pointer, pagkatapos ito ay may halaga ng basura, at iba pa kapag sinubukan mong dereference, sa lahat ng posibilidad ka ng pagpindot sa memory na sa gitna ng wala kahit saan. Kung mangyari sa iyo upang makakuha ng masuwerteng at ang halaga ng basura nangyari upang tumuro sa isang lugar sa stack o isang bagay, pagkatapos kapag dereference mo na pointer na hindi mo pa nasimulan, walang magkamali. Ngunit kung ito ay tumuturo sa, sabihin nating, sa isang lugar sa pagitan ng mga stack at ang magbunton, o pagturo lamang sa isang lugar na hindi pa ginagamit ng iyong programa, ka pagpindot sa memory hindi mo dapat na nakadikit at iyong segfault. Kapag sumulat ka ng isang recursive function na at ito recurses masyadong maraming beses at ang iyong stack ay lumalaki masyadong malaki at ng stack collides sa bagay na hindi ito dapat nagbabanggaan na may, ka ng pagpindot sa memory, hindi mo dapat hinahawakan, kaya segfault. Iyon ay kung ano ang isang segfault. Rin sa parehong dahilan na kung mayroon ka ng isang string tulad ng - sabihin bumalik sa nakaraang programa. Sa hello.c--I'm lamang pagpunta sa iba pa. magpasinda * s = "Hello World!"; Kung gamitin ko * s = isang bagay o mga [0] = 'X'; kaya't kumusta,. / kumusta, bakit ay na segfault? Bakit ito segfault? Ano ang gusto mong asahan na mangyayari? Kung ginawa ko printf ("% s \ n", mga); kung ano ang mong asahan na ipi-print? [Mag-aaral] X halo. >> Oo. Ang problema ay na kapag ikaw ay ipinapahayag ng isang string tulad nito, s ay isang pointer na pumunta sa stack, at kung ano s ay tumuturo sa ay ang string na ito na siyang nakapaloob sa read-only memory. Kaya sa pamamagitan ng pangalan, read-only memory, dapat mong makuha ang ideya na kung susubukan mong baguhin kung ano ang nasa read-only memory, ikaw ay gumagawa ng isang bagay na hindi mo dapat ginagawa sa memory at iyong segfault. Ito ay talagang isang malaking pagkakaiba sa pagitan ng magpasinda * s at magpasinda mga []. Kaya magpasinda mga [], na ngayon ay ang string na ito ay pagpunta sa ilagay sa ang stack, at stack ay hindi na read-only, na nangangahulugan na ito ay dapat na gumana perpektong fine. At ginagawa nito. Tandaan na kapag gagawin ko magpasinda * s = "Hello World!", Mga mismong sa stack ngunit mga puntos sa ibang lugar, at sa iba pang lugar ang mangyayari read-only. Ngunit magpasinda mga [] ay isang bagay sa stack. Kaya, na ang isa pang halimbawa ng isang segfault nangyayari. Nakita namin na ./buggy1 nagresulta sa isang segfault. Sa teorya, hindi ka dapat magmukhang sa buggy1.c. Sa halip, titingnan namin ito sa pamamagitan ng gdb. Pansinin na kapag nakakuha ka ng Segmentation fault (core dumped), sa makuha mo ang file na ito sa paglipas dito tinatawag na core. Kung namin ls-l, gagamitin namin ang core ay karaniwang isang medyo malaking file. Ito ay ang bilang ng mga bytes ng file, kaya mukhang 250-isang bagay na kilobytes. Ang dahilan para sa ay na kung ano ang core dump aktwal ay kapag ang iyong programa nag-crash, ang estado ng memorya ng iyong programa lamang ay makakakuha ng kopyahin at ilagay sa ang file na ito. Ito ay makakakuha dumped sa file na iyon. Ang program na ito, habang ito ay tumatakbo, nangyari sa paggamit ng memory sa loob ng 250 kilobytes, at sa gayon ay ang Nakakuha dumped sa ang file na ito. Ngayon ay maaari kang tumingin sa file na iyon kung gagawin namin gdb buggy1 core. Maaari lamang namin gawin gdb buggy1, at na start up lang gdb regular, Ang gamit ang buggy1 bilang input file nito. Ngunit kung gagawin mo gdb buggy1 core, pagkatapos partikular ito upang simulan ang gdb sa pamamagitan ng pagtingin sa na core file. At ikaw sinasabi buggy1 ay nangangahulugan gdb alam na core file ay mula sa buggy1 programa. Kaya gdb buggy1 core ay pagpunta sa dalhin agad sa amin sa kung saan nangyari ang programa na wakasan. Nakikita namin dito Program itinigil may signal 11, Segmentation fault. Mangyari namin upang makita ang isang linya ng pagpupulong, na kung saan ay malamang na hindi kapaki-pakinabang. Ngunit kung ikaw type ang BT o backtrace, na ang function na na nagbibigay sa amin ang listahan ng aming kasalukuyang mga frame ng stack. Kaya backtrace. Mukhang lamang namin ay may dalawang frame stack. Ang una ay ang aming pangunahing stack frame, at ang pangalawa ay ang stack frame para sa function na mangyayari namin sa, na kamukha lamang namin ang assembly code para sa. Kaya sabihin bumalik sa aming pangunahing function na, at upang gawin na maaari naming gawin frame 1, at sa tingin ko Maaari din namin gawin ang, ngunit ko halos hindi kailanman gawin ang - o up. Oo. Pataas at pababa. Up Pinagsasama-up ng isang stack frame, pinagsasama-mo pababa stack frame. Malamang ko sa hindi kailanman gamitin na. Ko lang ang partikular na sabihin frame 1, na kung saan ay pumunta sa frame na may label na 1. Frame 1 upang dalhin sa amin sa pangunahing stack frame, at sinasabi nito dito mismo ang linya ng code na mangyayari namin na sa. Kung gusto namin ng ilang higit pang mga linya ng code, maaari naming sabihin ang listahan, at na upang bigyan kami ng lahat ng mga linya ng code sa paligid nito. Ang linya namin segfaulted sa 6: kung (strcmp ("CS50 bato", argv [1]) == 0). Kung ito ay hindi pa halata, maaari kang makakuha ng ito tuwid mula dito sa pamamagitan lamang ng pag-iisip kung bakit ito segfaulted. Ngunit maaari naming dalhin ito isang hakbang karagdagang at sabihin, "Bakit argv [1] segfault?" Natin ang naka-print na argv [1], at ito mukhang ito ay 0x0, kung saan ang null pointer. Kami ay strcmping CS50 bato at null, at sa gayon ay pagpunta sa segfault. At bakit argv [1] null? [Mag-aaral] Dahil hindi namin bigyan ito ng anumang command-line argumento. Oo. Hindi namin bigyan ito ng anumang command-line argumento. Kaya ./buggy1 ay lamang pagpunta sa argv [0] na ./buggy1. Hindi ito upang magkaroon ng isang argv [1], kaya na pagpunta sa segfault. Ngunit kung, sa halip, gawin ko lang CS50, ito ay pagpunta sa sabihin mong makakuha ng D dahil na kung ano ang dapat gawin. Naghahanap sa buggy1.c, dapat i-print "Nakakuha ka ng D" - Kung argv [1] ay hindi "CS50 bato", "Makakakuha ka ng D", iba pa "Makakakuha ka ng isang A!" Kaya kung gusto naming ng isang A, kailangan namin ito upang ihambing ang bilang totoo, na nangangahulugan na ito sa 0. Kaya argv [1] ay kailangang "CS50 bato". Kung nais mo bang gawin iyon sa command line, kailangan mong gamitin ang \ upang makatakas ang espasyo. Kaya CS50 \ bato at kang makakuha ng isang A! Kung hindi mo gawin ang backslash, bakit ito hindi gumagana? [Mag-aaral] ang dalawang magkaibang argumento. >> Oo. Argv [1] ay pagpunta sa CS50, at argv [2] ay pagpunta sa bato. Okay. Ngayon ./buggy2 ay pagpunta sa segfault muli. Sa halip na ito binubuksan sa core nito file, makikita namin lamang buksan ang buggy2 direkta, kaya gdb buggy2. Ngayon kung lamang namin patakbuhin ang aming programa, pagkatapos ito ay upang sabihin Program natanggap signal SIGSEGV, na ang segfault signal, at ito ay kung saan ito nangyari mangyari. Naghahanap sa aming backtrace, nakikita namin na kami sa function na ang oh_no, kung saan ay tinatawag na sa pamamagitan ng maliit na lokomotora ang function na, na tinatawag na sa pamamagitan ng function na ang binky, na tinatawag na sa pamamagitan ng pangunahing. Maaari din namin makita ang mga argumento sa mga function. Ang argumento sa maliit na lokomotora at binky 1. Kung naming ilista ang function na oh_no, nakita namin na ang oh_no lang ginagawa magpasinda ** s = null; * S = "Boom"; Bakit na mabigo? [Mag-aaral] Hindi ka maaaring dereference ang null pointer? >> Oo. Ito ay sinasabi s null, kung anuman na mangyayari sa isang pansamantalang trabaho **, kung saan, depende sa kung paano bigyang-kahulugan mo ang mga ito, maaaring ito ay isang pointer sa isang pointer sa isang string o isang hanay ng mga string. S null, kaya * s ay dereferencing null pointer, at kaya ito ng pag-crash. Ito ay isa ng ang pinakamabilis na paraan maaari mong posibleng segfault. Lamang ito deklarasyon null pointer at agad segfaulting. Na ang oh_no ay ginagawa. Kung pumunta kami isang frame, pagkatapos namin ay pagpunta upang makakuha ng sa function na tinatawag na oh_no. Kailangan kong gawin na pababa. Kung hindi mo ipasok ang isang command at pindutin lamang ang Ipasok muli, ito lamang ulitin ang mga nakaraang utos na pinatakbo mo. Namin sa frame 1. Naglilista frame na ito, makikita namin dito ang aming function na. Maaari mong pindutin ang listahan muli, o maaari mong gawin ang listahan 20 at ilista ang higit pa. Ang function na maliit na lokomotora nagsasabing kung i ay 1, pagkatapos ay pumunta sa function na oh_no, tao pumunta sa slinky function na. At alam namin i ay 1 dahil mangyayari namin upang makita dito maliit na lokomotora na tinatawag na sa mga argumento 1. O maaari mo lamang huwag i-print ang i at sabihin i ito ay 1. Kami ay kasalukuyang nasa maliit na lokomotora, at kung kami isa pang frame, alam namin magpapadala kami magtapos sa binky. Up. Ngayon hindi namin binky. Naglilista ito function na - ang listahan mula sa bago kalahating cut sa akin off - ito nagsimula off bilang kung i ay 0, pagkatapos kami ay pagpunta sa tumawag ito oh_no, tao tumawag maliit na lokomotora. Alam namin na i ay 1, kaya tinatawag na maliit na lokomotora. At ngayon hindi namin pabalik sa pangunahing, at pangunahing ay lamang pagpunta sa int i = ribete ()% 3; Na lamang upang bigyan ka ng random na numero na ay alinman sa 0, 1, o 2. Ito ay pagpunta sa tumawag binky sa numerong iyon, at ito ay bumalik 0. Naghahanap sa, lamang paglalakad sa pamamagitan nang manu-mano ang programa nang hindi tumatakbo ito agad, nais mong magtakda ng isang punto ng pahinga sa pangunahing, na nangangahulugan na kapag nagpatakbo kami sa programa tumatakbo ang iyong programa hanggang ito hit sa punto ng pahinga. Kaya't ang pagpapatakbo sa programa, ito ay tumakbo at pagkatapos ay pindutin ang pangunahing function at hihinto sa pagtakbo. Ngayon ay hindi namin sa loob ng pangunahing, at hakbang o sa susunod na pagpunta upang dalhin sa amin sa susunod na linya ng code. Maaari mong gawin ang hakbang o sa susunod. Pagpindot sa tabi, ngayon i ay nakatakda sa ribete ()% 3, upang maaari naming i-print ang halaga ng i, at sabihin i ito ay 1. Ngayon ang bagay kung ginagamit namin susunod o hakbang. Hulaan ko ito mattered sa nakaraang, ngunit nais namin nais na gamitin ang susunod. Kung gagamitin namin ang hakbang, hakbang namin sa pag-andar, na kung saan ay nangangahulugan na ang pagtingin sa ang aktwal na bagay na nangyayari sa loob ng binky. Kung ginagamit namin susunod, pagkatapos ay nangangahulugan ito pumunta sa paglipas ng ang function na at pumunta lamang sa susunod na linya ng code sa aming pangunahing function na. Dito mismo sa linyang ito, ako ay sa kung saan ito sinabi ribete ()% 3; kung ginawa ko hakbang, pumunta sa ang pagpapatupad ng ribete at tingnan kung ano ang nangyayari doon, at maaari kong hakbang sa pamamagitan ng katangian ng ribete. Ngunit Wala akong pakialam tungkol sa mga katangian ng ribete. Gusto ko lang upang pumunta sa susunod na linya ng code sa pangunahing, kaya gamitin ko susunod. Ngunit ngayon gagawin ko pag-aalaga tungkol sa binky function na, kaya gusto kong hakbang sa na. Ngayon ako sa binky. Ang unang linya ng code upang sabihin kung (i == 0), kumuha ako ng hakbang, nakikita namin namin magtapos sa maliit na lokomotora. Kung namin ang listahan ng mga bagay, nakita namin na ito naka-check ay i = 0. i ay hindi katumbas ng 0, kaya napunta sa pang tao kondisyon, na tawagan ang maliit na lokomotora (i). Maaari mong nalilito. Kung kamakailan mo lamang tumingin sa mga linyang ito nang direkta, maaari mong isipin kung (i == 0), okay, pagkatapos ko kinuha ng isang hakbang at ngayon ako sa maliit na lokomotora (i), maaari mong isipin na dapat ibig sabihin i = 0 o isang bagay. Hinde lamang nangangahulugan na ito alam dumikit ito nang direkta sa maliit na lokomotora ang linya (i). Dahil i ay hindi 0, ang susunod na hakbang ay hindi nagtatapos sa pang tao. Iba Pa ay hindi isang linya na ito upang tumigil sa. Lamang ito upang pumunta sa susunod na linya na ito aktwal na execute, na maliit na lokomotora (i). Stepping sa maliit na lokomotora (i), makikita namin kung (i == 1). Namin alam i = 1, kaya kapag hakbang namin, alam namin na kami ay pagpunta upang magtapos sa oh_no dahil i = 1 tawag ang function na oh_no, na maaari mong hakbang sa, na i-set magpasinda ** s = null at agad "Boom". At pagkatapos ay talagang aktwal na tumitingin sa pagpapatupad ng buggy2, ito, lamang i pagkuha ng random na numero - 0, 1, o 2 - pagtawag binky, na kung i ay 0 tawag oh_no, tao tawag sa maliit na lokomotora, kung saan ay dito. Kung i ay 1, tawag oh_no, iba pa tawagan slinky, na darating dito, kung i ay 2, tumawag oh_no. Hindi ko kahit na sa tingin may paraan - Ba ang sinuman makita ang isang paraan ng paggawa ng ito ng programa na hindi segfault? Dahil maliban kung ako nawawalang ng isang bagay, kung i ay 0, makikita mo kaagad segfault, tao mong pumunta sa isang function na kung i ay 1 ka segfault, tao mong pumunta sa isang function na kung saan kung i 2 segfault mo. Kaya hindi mahalaga kung ano ang ginagawa mo, segfault. Hulaan ko ang isang paraan ng pag-aayos na ito ay sa halip ng paggawa magpasinda ** s = null, maaari mong malloc ng puwang para sa string. Namin ang malloc (sizeof) - sizeof kung ano? [Mag-aaral] (magpasinda) * 5? >> Ba ito mukhang tama? Ako ipagpalagay na ito ay gagana kung hindi ko aktwal na tumatakbo ito, ngunit ito ay hindi kung ano ang Naghahanap ako. Hanapin sa uri ng mga. Natin magdagdag ng int *, kaya int * x. Gusto kong gawin malloc (sizeof (int)). O kung gusto ko ang isang hanay ng mga 5, gusto kong gawin (sizeof (int) * 5); Paano kung mayroon akong isang int **? Ano ang gagawin ko malloc? [Mag-aaral] Laki ng pointer. >> Oo. (Sizeof (int *)); Parehong bagay sa pababa dito. Gusto kong (sizeof (pansamantalang trabaho *)); Ito ay upang maglaan ng espasyo para sa pointer na tumuturo sa "Boom". Hindi ko kailangan upang maglaan ng espasyo para sa "Boom" mismo dahil ito ay isa lamang na katumbas sa kung ano ang sinabi ko bago ng pansamantalang trabaho * x = "Boom". "Boom" ay umiiral na. Ang mangyayari sa umiiral sa read-only na rehiyon ng memory. Ngunit ito ay umiiral na, na nangangahulugan na ang linya ng code, kung s ay isang pansamantalang trabaho **, pagkatapos * s ay isang pansamantalang trabaho * at ka-set ang magpasinda * upang tumuro sa "Boom". Kung gusto ko upang kopyahin ang "Boom" sa mga, pagkatapos ay kailangan ko upang maglaan ng espasyo para sa mga. Kong gawin * s = malloc (sizeof (pansamantalang trabaho) * 5); Bakit 5? Bakit hindi 4? Mukhang "Boom" ay 4 na character. >> [Mag-aaral] Ang null character. Oo. Lahat ng iyong mga string ay pagpunta sa kailangan ang null karakter. Ngayon ay maaari kong gawin ang isang bagay tulad strcat - Ano ang pag-andar para sa pagkopya ng isang string? [Mag-aaral] cpy? >> Strcpy. tao strcpy. Kaya strcpy o strncpy. strncpy ng kaunti mas ligtas dahil maaari mong tukuyin kung paano maraming mga character, ngunit hindi mahalaga dahil alam namin. Kaya strcpy at hanapin sa argumento. Ang unang argumento ang aming destination. Ang pangalawang argumento ang aming pinagmulan. Kami ay pagpunta sa kopyahin sa aming destination * s pointer na "Boom". Bakit baka gusto mong gawin ito na may strcpy sa halip na lamang kung ano ang nagkaroon kami bago ng * s = "Boom"? May ay isang dahilan baka gusto mong gawin ito, ngunit kung ano ang dahilan na? [Mag-aaral] Kung nais mong baguhin ang isang bagay sa "Boom". >> Oo. Ngayon ay maaari kong gawin ang isang bagay tulad ng mga [0] = 'X'; dahil ang mga puntos sa magbunton at ang puwang na iyon sa magbunton na s tumuturo sa ay isang pointer sa higit pang puwang sa magbunton, na pag-iimbak ng "Boom". Kaya ito kopya ng "Boom" ay naka-imbak sa ang magbunton. May technically dalawang kopya ng "Boom" sa aming programa. May ang unang na lang ibinigay sa pamamagitan ng ang string na "Boom" pare-pareho, at ang pangalawang kopya ng "Boom", strcpy nilikha ang kopya ng "Boom". Ngunit ang kopya ng "Boom" ay naka-imbak sa magbunton, at magbunton ang libreng upang baguhin. Magbunton ay hindi read-only, kaya na nangangahulugan na s [0] ay upang ipaalam sa iyo na baguhin ang halaga ng "Boom". Ito ay upang ipaalam sa iyo na baguhin ang mga character. Mga tanong? Okay. Paglipat sa buggy3, sabihin gdb buggy3. Lang namin patakbuhin ito at makita namin kami makakuha ng segfault. Kung namin backtrace, may dalawang function lamang. Kung kami sa aming pangunahing function na, tingnan namin na na namin segfaulted sa line na ito. Kaya lang hinahanap sa linya na ito, para sa (int line = 0; fgets ng mga bagay na ito ay ginagawa hindi katumbas null; linya + +). Ang aming nakaraang frame ay tinatawag na _IO_fgets. Makikita mo na ng maraming na may built-in na function C, na kapag nakuha mo ang segfault, ay talagang misteriyoso pangalan ng function na tulad ang _IO_fgets na ito. Ngunit na nauugnay sa ang tawag na ito fgets. Sa isang lugar sa loob dito, kami ay segfaulting. Kung titingnan namin sa argumento sa mga fgets, maaari naming i-print ang buffer. Natin i-print bilang isang - Oh, hindi. Print ay hindi pagpunta upang gumana nang eksakto tulad ng gusto ko ito. Tingnan natin sa aktwal na programa. Buffer ay isang character array. Isang character na hanay ng mga 128 mga character. Kaya kapag sinabi ko ng naka-print na buffer, ito upang i-print ang mga 128 character, kung saan hulaan ko kung ano ang inaasahan. Ano ako ay naghahanap para sa i-print ang address ng buffer, ngunit hindi talagang sabihin sa akin magkano. Kaya kapag mangyayari kong sabihin dito x buffer, ito ay nagpapakita sa akin ng 0xbffff090, kung saan, kung tandaan mo mula sa mas maaga o ilang mga punto, Oxbffff may kaugaliang na stack-ish rehiyon. Stack ang may kaugaliang upang simulan ang isang lugar lamang sa ilalim ng 0xc000. Sa pamamagitan lamang ng nakakakita sa address na ito, alam ko na buffer ang nangyayari sa stack. I-restart ang aking programa, patakbuhin, hanggang, buffer nakita natin ay ang pagkakasunud-sunod ng mga character na medyo mas walang kahulugan. Pagkatapos pag-print ng file, kung ano ang file hitsura? [Mag-aaral] Null. >> Oo. File ay isang ng uri ng FILE *, kaya ito ay isang pointer, at ang halaga ng pointer na null. Kaya fgets pagpunta sa subukan na magbasa mula sa na pointer sa isang hindi direktang paraan, ngunit upang ma-access na pointer, ito ay sa dereference ito. O kaya, upang ma-access ang ano ang dapat na tumuturo sa, dereferences ito. Kaya dereferencing null pointer at ito segfaults. Ko restart ito doon. Kung masira namin sa aming pangunahing punto at patakbuhin, ang unang linya ng code magpasinda * filename = "nonexistent.txt"; Na dapat magbigay ng isang medyo malaking pahiwatig bakit nabigo ang programang ito. Pinagsasama-akin ng pag-type ng susunod sa susunod na linya, kung saan binuksan ko ang file na ito, at pagkatapos ko agad makakuha ng sa aming mga linya, kung saan sabay-sabay ko pindutin ang susunod, pagpunta sa segfault. Ba ang sinuman gusto mong dumura isang dahilan kung bakit maaari naming segfaulting? [Mag-aaral] File ay hindi umiiral. >> Oo. Ito ay dapat na isang hint na tuwing ka ng pagbukas ng file kailangan mo upang suriin na ang file na aktwal na umiiral. Kaya dito, "nonexistent.txt"; Kapag kami fopen filename para sa pagbabasa, kailangan namin pagkatapos sasabihin kung (file == null) at sabihin printf ("File ay hindi umiiral!" o - mas mahusay pa - filename); return 1; Kaya ngayon namin suriin upang makita kung ito ay null bago aktwal na patuloy at sinusubukang basahin mula sa file na iyon. Gumawang muli namin ito lamang upang makita na na gawa. Ko na nilayon upang isama ang isang bagong linya ng. Kaya ngayon nonexistent.txt ay hindi umiiral. Dapat mong palaging suriin para sa ganitong uri ng bagay. Dapat mong palaging suriin upang makita kung fopen nagbabalik null. Dapat mong palaging suriin upang matiyak na malloc hindi nagbabalik null, o tao ka segfault. Ngayon buggy4.c. Tumatakbo. Ako paghula ito ay naghihintay para sa input o posibleng walang katapusan looping. Oo, walang katapusan na looping. Kaya buggy4. Mukhang hindi kami ng walang hangganang looping. Maaari naming masira sa pangunahing, patakbuhin ang aming programa. Gdb, hangga't ang pagpapaikli gamitin mo ay hindi malabo o espesyal na mga pagdadaglat na ibinibigay nila para sa iyo, maaari mong gamitin n na gamitin ang susunod na sa halip na kinakailangang i-type ang susunod na ang lahat ng mga paraan. At ngayon ko na pindutin n sabay-sabay, maaari ko lang pindutin ang Enter upang panatilihin ang pagpunta sa tabi sa halip ng pagkakaroon upang maabot n Ipasok, n Ipasok, n Ipasok. Mukhang ako sa ilang mga uri ng para sa loop na pagtatakda ng array [i] sa 0. Mukhang tulad ng hindi kailanman ako paglabag ng ito para sa loop. Kung ko i-print, kaya i ay 2, pagkatapos ko pumunta sa tabi. Ko i-print, i 3, pagkatapos ay makikita ko pumunta sa tabi. Ko i-print at i 3. Susunod, i-print ang i, i ay 4. Aktwal na, naka-print sizeof (array), kaya ang laki ng array ay 20. Ngunit mukhang mayroong ilang espesyal na command gdb para sa pagpunta hanggang sa may mangyari. Ito ay tulad ng pagtatakda ng isang kondisyon sa halaga ng variable. Ngunit hindi ko matandaan kung ano ito ay. Kaya kung panatilihin namin ang pagpunta - Ano ang sinasabi? Ano mo ilabas? [Mag-aaral] ba ipakita i magdagdag - >> Oo. Kaya ipakita maaari i makatulong. Kung lamang namin ipakita i, ito ilagay dito kung ano ang halaga ng i kaya hindi ko upang i-print ito sa bawat oras. Kung namin lamang panatilihin ang pagpunta sa tabi, makikita namin 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5. Isang bagay ay pagpunta katakut-takot mali, at i ay i-reset sa 0. Naghahanap sa buggy4.c, makikita namin ang lahat ng mangyayari int array [5]; para sa (i = 0; i <= sizeof (array); i + +) array [i] = 0; Ano ang gagawin namin makita na ang mali dito? Bilang isang pahiwatig, kapag ako ay ginagawa ang gdb buggy4 - sabihin lumalabag sa pangunahing, run - Ko ang naka-print na sizeof (array) lamang upang makita kung ano ang kundisyon kung saan ang dapat kong wakas masira ang. Nasaan ako? Ba akong magpatakbo ng? Hindi ko ipinapahayag. Kaya i-print ang sizeof (array) at na 20, na inaasahan dahil ang aking array ng laki 5 at ng 5 integer, kaya ang buong bagay ay dapat 5 * sizeof (int) bytes, kung saan sizeof (int) ay may kaugaliang 4. Kaya sizeof (array) 20. Ano ang dapat ito? [Mag-aaral] na hinati sa pamamagitan ng sizeof (int). >> Oo, / sizeof (int). Mukhang mayroon pa rin ng problema dito. Tingin ko ito ay dapat lamang na < dahil medyo mas laging > [Bowden] Oo. Kapag kami ay lagpas sa pagtatapos ng aming array, sa paanuman na espasyo na aming override-override ang halaga ng i. At kaya kung tiningnan namin sa buggy4, masira pangunahing, run, sabihin i-print ang address ng i. Mukhang ito bffff124. Ngayon sabihin i-print ang address ng array [0]. 110. Paano ang tungkol sa [1]? 114. [2], 118. 11c, 120. array [5] ay bfff124. Kaya array [5] may parehong address tulad ng i, na nangangahulugan na array [5] ay i. Kung mayroon sila ang parehong address, ang mga ito ay ang parehong bagay. Kaya kapag kami itakda ang array [5] sa 0, kami ay pagtatakda ng i sa 0. At kung sa tingin mo tungkol sa ito sa mga tuntunin ng stack, int i ay ipinahayag una, na nangangahulugang i nakakakuha ng ilang espasyo sa stack. Pagkatapos array [5] ay inilalaan, kaya pagkatapos 20 bytes ay inilalaan sa stack. Kaya i maipo inilalaan muna, pagkatapos ay mga 20 bytes makapag inilalaan. Kaya i mangyayari bago ang array, at dahil sa ang paraan, tulad ko sinabi noong nakaraang linggo, kung saan technically stack ang lumalaki pababa, kapag ikaw ay index sa isang array, kami ay katiyakan na ang 0 posisyon sa array palaging nangyayari bago ang unang posisyon sa array. Ito ay uri ng kung paano ko ginamit ito noong nakaraang linggo. Pansinin na sa ilalim namin ang address 0 at sa tuktok namin ang address Max. Stack ay palaging lumalagong. Ipagpalagay natin na naming maglaan i. Magtalaga namin integer i, na nangangahulugan sabihin lamang sabihin dito integer i maipo inilalaan. Pagkatapos namin maglaan ang aming hanay ng mga 5 integer, na nangangahulugan na sa ilalim na, dahil stack ay lumalaking pababa, mga 5 integer inilalaan. Ngunit dahil sa kung paano array gumagana, kami ay katiyakan na ang unang posisyon sa array laging may isang address na mas mababa kaysa sa ikalawang bagay sa array. Kaya 0 array posisyon ay palaging may mangyari muna sa memory, samantalang ang array posisyon 1 ay mangyayari pagkatapos na at array posisyon 2 ay na mangyayari pagkatapos nito, na nangangahulugan na array posisyon 0 ang mangyayari sa isang lugar down na dito, array posisyon 1 ang mangyayari sa itaas na dahil ang paglipat up ay nangangahulugan ng mas mataas address dahil ang maximum address ay dito. Kaya array [0] pababa dito, array [1] hanggang dito, array [2] hanggang dito, array [3] up dito. Pansinin kung paano bago inilalaan namin ang integer i lahat ng mga paraan dito, bilang ilipat namin ng karagdagang at karagdagang sa aming array, kami ay nakakakuha ng mas malapit at mas malapit sa aming integer i. Lamang kaya mangyayari na array [5], na kung saan ay isang posisyon higit pa sa aming array, ay eksaktong kung saan integer i nangyari sa inilalaan. Kaya na ang punto kung saan namin mangyari na pagpindot sa lugar sa stack na inilaan para sa integer i, at namin ang pagse-set na 0. Kung paano na gumagana. Mga tanong? Oo. [Mag-aaral] Huwag kailanman isipan. Okay. [Mag-aaral] Paano mo maiwasan ang mga uri ng mga error? Mga uri ng mga error? Huwag gumamit ng C bilang iyong programming language. Gumamit ng isang wika na may hangganan array check. Hangga't hindi ka maingat, kailangan mo lamang upang maiwasan ang pagpunta nakaraang ang mga hangganan ng iyong array. [Mag-aaral] Kaya dito kapag nagpunta kami nakaraang ang mga hangganan ng iyong array - [Bowden] Iyon ay kung saan ang mga bagay simulan pagpunta mali. >> [Mag-aaral] Oh, okay. Hangga't manatili sa loob ng memory inilalaan para sa iyong array, ikaw fine. Ngunit C ang walang error checking. Kung gawin ko array [1000], ito Masaya lang baguhin ang anumang mangyayari - Pupunta ito sa simula ng array, pagkatapos ito napupunta 1000 posisyon pagkatapos at nagtatakda ito sa 0. Hindi ito gumagawa ng anumang checking na oh, ito ay hindi tunay na 1000 mga bagay sa loob nito. 1000 ay paraan na lampas sa kung ano ang dapat kong pagbabago, samantalang Java o isang bagay na makikita mo makakuha ng array ng mga hanggahan index o index ng mga hanggahan ng pagbubukod. Iyon ay kung bakit ang isang maraming mga mas mataas na mga wika antas ay may mga bagay na ito kung saan kung pumunta ka lampas sa hangganan ng array, hindi mo sa gayon ay hindi mo maaaring baguhin ang mga bagay mula sa ilalim mo at pagkatapos ay mga bagay pumunta mas mas malala pa sa pagkuha ng pagbubukod nagsasabi na nagpunta higit sa dulo ng array. [Mag-aaral] At kaya dapat lamang namin binago ang <= sa makatarungan > [Bowden] Oo. Ito ay dapat > [Mag-aaral] Kanan. Higit pang mga tanong? Okay. [Mag-aaral] Mayroon akong tanong. >> Oo. [Mag-aaral] Ano ang aktwal na array variable? [Bowden] Tulad ng kung ano ang array? Array mismo ay isang simbolo. Ito ay ang address ng simula ng 20 bytes na kami ay tumutukoy lamang. Maaari mong isipin na ito bilang isang pointer, ngunit ito ay isang pare-pareho ang pointer. Sa lalong madaling bagay makapag inipon, ang variable array ay hindi umiiral na ngayon. [Mag-aaral] Kaya paano hanapin ang laki ng array? Laki ng array ay tumutukoy sa laki ng block na ang simbolo na tumutukoy sa. Kapag ginawa ko ang isang bagay tulad ng printf ("% p \ n", array); sabihin patakbuhin ito. Ano ang sinabi ko lang gawin mali? 'Array' Array ipinahayag dito. Oh, hanggang dito. Kumalatong ay matalino, at mangyayari sa mapansin na ipinahayag ko ang array bilang 5 elemento ngunit ako pag-i-index sa posisyon 1000. Maaari itong gawin iyon dahil ito lamang ang constants. Maaari lamang ito pumunta sa ngayon sa makapansin na ako pagpunta lampas sa hangganan ng array. Ngunit mapansin bago kapag nagkaroon kami i hindi tama, hindi ito posibleng matukoy kung gaano karaming mga halaga na maaaring i tumagal sa, kaya hindi ito maaaring matukoy na ay i pagpunta higit sa dulo ng array. Na kumalatong pagiging matalino. Ngunit ngayon buggy4. Kaya ano pa ang ako paggawa ng mali? Deklarasyon nang kataon lamang library function na 'printf'. Ako pagpunta sa nais na # include . Okay. Tumatakbo na ngayon buggy4. Pag-print ang halaga ng array tulad ng ginawa ko dito, pag-print ang mga ito bilang isang pointer print ng isang bagay na ganito ang hitsura - bfb8805c - na ilang address na sa stack-ish rehiyon. Array mismo ay tulad ng isang pointer, ngunit ito ay hindi isang aktwal na pointer, dahil sa isang regular na pointer maaari naming baguhin. Array ay ilan lang pare-pareho. Ang 20 mga bloke ng memorya ay nagsisimula sa address 0xbfb8805c. Kaya bfb8805c sa pamamagitan ng address na ito +20--o hulaan ko -20 - ay ang lahat ng memory na inilalaan para sa array na ito. Array, ang variable mismo ay hindi naka-imbak sa kahit saan. Kapag ikaw ay kino-compile, ang tagatala - wave ng kamay sa ito - ngunit ang tagatala ay gamitin na lamang kung saan ito alam array na. Alam kung saan na magsisimula ang array, at sa gayon ay maaari itong palaging lamang gawin ang mga bagay sa mga tuntunin ng Offset mula sa simula. Ito ay hindi kailangan ng isang variable mismo upang kumatawan array. Ngunit kapag gagawin ko ang isang bagay tulad ng int * p = array; ngayon p ay isang pointer na mga punto na array, at ngayon p aktwal na umiiral sa stack. Ako-atubiling baguhin ang p. Ang maaari kong gawin p = malloc. Kaya orihinal tulis sa array, ito POINTS ngayon sa ilang espasyo sa magbunton. Hindi ko maaaring gawin ang array = malloc. Kung kumalatong ay matalino, ito ay sumigaw sa akin karapatan off ang bat. Aktwal, ako ay medyo sigurado GCC gawin ito masyadong. Kaya array uri 'int [5]' ay hindi naitatalaga. Hindi ka maaaring magtalaga ng isang bagay sa isang uri ng array dahil lamang pare-pareho ang array. Ito ay isang simbolo na reference mga 20 bytes. Hindi ko maaaring baguhin ito. [Mag-aaral] At kung saan naka-imbak ang laki ng array? [Bowden] Hindi ito naka-imbak sa kahit saan. Ito kapag ito kino-compile. Kaya kung saan ay ang laki ng array na naka-imbak? Maaari mo lamang gamitin ang sizeof (array) sa loob ng pag-andar na array ay ipinahayag mismo. Kaya kung gagawin ko ilang function, foo, at gagawin ko (int array []) printf ("% d \ n", sizeof (array)); at pagkatapos ay down na dito tumawag ako foo (array); sa loob ng function na ito - sabihin patakbuhin ito. Ito ay kumalatong pagiging matalino muli. Ito ay nagsasabi sa akin na sizeof sa array function na parameter ay bumalik ang laki ng 'int *'. Ito ay isang error kung ito ay hindi kung ano ang nais kong mangyari. Natin ang aktwal na i-off ang Werror. Babala. Babala ay pinong. Ito ay pa rin makatipon hangga't ay isang babala. . / A.out ay pagpunta upang mag-print ng 4. Ang babala na nabuo ay isang malinaw na tagapagpahiwatig ng kung ano ang nangyaring mali. Ang int array ay pagpunta upang i-print ang sizeof (int *). Kahit na kung ko bang ilagay ang array [5] sa dito, pa rin ito lamang upang i-print ang sizeof (int *). Ito sa lalong madaling kayo na ipasa ito sa isang function, ang pagkakaiba sa pagitan ng mga array at pointer ay nonexistent. Ito ang mangyayari sa isang array na ipinahayag sa stack, ngunit sa lalong madaling pumasa namin na halaga, na 0xbf blah, blah, blah sa ito function na, pointer ito POINTS na array sa stack. Kaya na nangangahulugan na sizeof Nalalapat lamang sa pag-andar na array ay ipinahayag, na nangangahulugan na kapag ikaw ay kino-compile ang function na ito, kapag kumalatong napupunta sa pamamagitan ng function na, nakikita Ang array ay isang int na hanay ng mga laki 5. Kaya ito nakikita sizeof (array). Well, na 20. Na ang aktwal na kung paano talaga gumagana ang sizeof para sa halos lahat ng mga kaso. Sizeof ay hindi isang function, ito ay isang operator. Hindi mo tawagan ang sizeof function na. Sizeof (int), tagatala ay lamang na isalin ang na 4 na. Nakuha ko? Okay. [Mag-aaral] Kaya kung ano ay ang pagkakaiba sa pagitan ng sizeof (array) sa pangunahing at sa foo? Ito ay sapagkat hindi namin sinasabi na sizeof (array), na kung saan ay ng uri int *, samantalang array ang down dito ay hindi ng uri int *, isang int array. [Mag-aaral] Kaya kung mayroon kang ang parameter sa array [] sa halip ng int * array, ay na nangangahulugan na maaari mo pa ring baguhin ang array dahil ngayon ang isang pointer? [Bowden] Tulad ito? >> [Mag-aaral] Oo. Maaari mong baguhin ang array sa loob ng function na ngayon? [Bowden] maaari mong baguhin ang array sa parehong mga kaso. Sa parehong mga kaso na ito ay libre upang sabihin array [4] = 0. [Mag-aaral] Ngunit maaari kang gumawa ng array punto sa iba pa? [Bowden] Oh. Oo. Sa alinmang kaso - >> [mag-aaral] Oo. [Bowden] Ang pagkakaiba sa pagitan ng array [] at isang int array *, ay wala. Maaari ka ring makakuha ng ilang maraming interes array in dito para sa ilang maginhawang syntax, ngunit pa rin ito lamang ang pointer. Nangangahulugan ito na ako libreng upang gawin ang array = malloc (sizeof (int)); at ngayon ay ituro sa ibang lugar. Ngunit tulad lamang ng kung paano ito gumagana magpakailanman at laging, pagbabago ang array na ito sa pamamagitan ng paggawa ng ito tumuro sa iba pa ay hindi baguhin ito array dito dahil ito ay isang kopya ng argument, ito ay hindi isang pointer na argumento. At aktwal, tulad ng higit pang mga pahiwatig na ito ay eksaktong kapareho - Nakita namin na kung ano ang pagpi-print ng mga kopya array - kung ano ang kung-print namin ang address ng array o ang address ng address ng array sa alinman sa mga? Natin hindi pansinin ang isang ito. Okay. Ito ay pinong. Ngayon tumatakbo. / A.out. Pagpi-print ng array, pagkatapos ay pag-print ang address ng array, ang mga parehong bagay. Array na ay hindi umiiral. Alam kapag ikaw ay pag-print array, ka ng pag-print ang simbolo na tumutukoy sa mga 20 bytes. Pag-print ang address ng array, well, array ay hindi umiiral. Hindi ito isang address, kaya lamang ito ng mga Kopya address ng mga 20 bytes. Sa lalong madaling mo makatipon pababa, gusto sa iyong inipon buggy4. / A.out, array ay nonexistent. Payo umiiral. Array hindi. Ang mga bloke ng memorya na kumakatawan sa array Umiiral pa rin, ngunit ang variable array at mga variable ng uri na ay hindi umiiral. Yaong tulad ng mga pangunahing pagkakaiba sa pagitan ng mga array at pointer sa lalong madaling gumawa ka ng tawag function na, ay walang pagkakaiba. Ngunit sa loob ng pag-andar na ang array mismo ay ipinahayag, sizeof gumagana naiiba dahil iyong pag-print ang laki ng mga bloke sa halip ng ang laki ng uri, at hindi mo maaaring baguhin ito dahil ito ay isang simbolo. Pag-print ng mga Kopya ng bagay at ang address ng bagay sa parehong bagay. At na medyo magkano ito. [Mag-aaral] Puwede mong sabihin na ang isa pang oras? Maaaring ko may nakaligtaan. Array ng Pagpi-print at address ng array ng mga Kopya ang parehong bagay, samantalang kung print ka ng isang pointer kumpara sa address ng pointer, isang bagay ng mga Kopya ang address ng kung ano ang iyong na tumuturo sa, ang iba pang mga Kopya address ng ang pointer sa stack. Maaari mong baguhin ang isang pointer, hindi mo maaaring baguhin ang isang simbolo ng array. At sizeof pointer ay pagpunta sa i-print ang laki ng na uri ng pointer. Kaya int * p sizeof (p) ay pagpunta sa i-print ang 4, ngunit int array [5] naka-print sizeof (array) ay pagpunta sa i-print ang 20. [Mag-aaral] Kaya int array [5] ay i-print ang 20? >> Oo. Iyon ay kung bakit sa loob ng buggy4 kapag ginamit sizeof (array) ito ay ginagawa i <20, na kung saan ay hindi kung ano ang gusto namin. Gusto naming i <5. >> [Mag-aaral] Okay. [Bowden] At pagkatapos ay sa lalong madaling simulan mo ang pagpasa sa mga pag-andar, kung ginawa namin int * p = array; sa loob ng function na ito, maaari naming talaga gamitin p at array sa eksaktong parehong paraan, maliban para sa sizeof problema at ang pagbabago ng problema. Ngunit p [0] = 1; katulad ng sinasabi ng array [0] = 1; At sa lalong madaling sabihin namin foo (array); o foo (p); sa loob ng foo function na, ito ay ang parehong tawag dalawang beses. Walang pagkakaiba sa pagitan ng dalawang mga tawag. Ang bawat tao'y mahusay na iyon? Okay. Mayroon kaming 10 minuto. Susubukan naming makakuha ng sa pamamagitan ng programang ito ng Hacker Typer, website na ito, na dumating ang nakaraang taon o isang bagay. Lamang Ito ay dapat na maging tulad mo type random at mga Kopya ang - Anuman file ang mangyayari sa load ang mukhang tina-type mo. Mukhang ilang uri ng operating system code. Iyon ay kung ano ang gusto naming ipatupad. Dapat kang magkaroon ng isang binary executable na may pangalang hacker_typer na tumatagal ng isang argumento, ang file sa "uri ng Hacker." Ang pagpapatakbo ng executable dapat i-clear ang screen at pagkatapos ay i-print ang isang character mula sa ang pumasa sa-in file sa bawat oras na ang user pagpindot sa isang susi. Kaya ang anumang key pindutin, dapat itapon at sa halip ay i-print ang isang character mula sa file na ang argumento. Makikita ko medyo magkano sabihin sa iyo kung ano ang mga bagay na kami ay pagpunta sa kailangan upang malaman. Ngunit nais naming upang suriin ang termios library. Hindi ko ginamit ang library na ito sa aking buong buhay, kaya ito ay napaka kaunting mga layunin ng. Ngunit ito ay pagpunta sa library na maaari naming gamitin upang itapon ng character mo pindutin ang kapag nagta-type ka sa pamantayan. Kaya hacker_typer.c, at kami ay pagpunta sa nais na # include . Pagtingin sa pahina ng tao para sa termios - I'm paghula ito sa terminal OS o isang bagay - Hindi ko alam kung paano basahin. Naghahanap sa, sinasabi nito upang isama ang mga 2 mga file, kaya makikita namin gawin iyon. Muna ang unang bagay, gusto naming gumawa ng sa isang solong argument, na ang file ay dapat namin buksan. Kaya kung ano ang gusto kong gawin? Paano ko suriin upang makita ako ng isang argumento? [Mag-aaral] Kung katumbas ng argc ito. >> [Bowden] Oo. Kaya kung (argc = 2!) Printf ("paggamit:% s [file upang buksan]"). Kaya ngayon kung nagpatakbo ako ng ito nang hindi pagbibigay ng pangalawang argumento - oh, kailangan ko ang mga bagong linya - makikita mo ang sinasabi nito sa paggamit:. / hacker_typer, at pagkatapos ay ang pangalawang argumento ay dapat na ang file na gusto kong buksan. Ngayon ano ang gagawin ko? Gusto ko na magbasa mula sa file na ito. Paano ko basahin mula sa isang file? [Mag-aaral] buksan mo muna ito. >> Oo. Kaya fopen. Ano ang fopen hitsura? [Mag-aaral] Filename. >> [Bowden] Filename pagpunta sa argv [1]. [Mag-aaral] At pagkatapos ay kung ano ang gusto mong gawin dito, kaya ang - >> [Bowden] Oo. Kaya kung hindi mo matandaan, lamang mo maaaring gawin ng tao fopen, kung saan ito const magpasinda * path kung saan ang path filename, const magpasinda * mode. Kung mangyayari mong hindi matandaan kung ano ang mode ay, pagkatapos ay maaari kang tumingin para sa mode. Inside ng mga tao pahina, ang slash character ay kung ano ang maaari mong gamitin upang maghanap para sa mga bagay. Kaya ko type / mode upang maghanap para sa mode. n at N kung ano ang maaari mong gamitin upang umikot sa pamamagitan ng mga tugma ng paghahanap. Narito sinasabi nito na ang mga puntos sa mode ng argumento sa isang string nagsisimula sa isa sa mga sumusunod na pagkakasunud-sunod. Kaya r, Buksan ang text file para sa pagbabasa. Iyon ay kung ano ang gusto naming gawin. Para sa pagbabasa, at gusto ko upang mag-imbak na. Bagay ay pagpunta sa isang FILE *. Ngayon kung ano ang gusto kong gawin? Bigyan mo ako ng isang segundo. Okay. Ngayon kung ano ang gusto kong gawin? [Mag-aaral] Suriin kung ito ang null. >> [Bowden] Oo. Anumang oras na magbubukas ka ng isang file, tiyakin na ikaw ay matagumpay na magagawang upang buksan ito. Ngayon gusto kong gawin na termios bagay kung saan nais ko munang basahin ang aking mga kasalukuyang setting at i-save ang mga sa isang bagay, pagkatapos Gusto kong baguhin ang aking mga setting itapon ang anumang mga karakter na aking i-type, at pagkatapos ay gusto kong i-update ang mga setting na iyon. At pagkatapos ay sa dulo ng programa, Gusto kong baguhin ang bumalik sa aking orihinal na mga setting. Kaya struct ng termios uri, at ako pagpunta sa gusto ng dalawang ng mga. Ang unang pagpunta sa aking current_settings, at pagkatapos ay pagpunta sa aking hacker_settings. Una, ako pagpunta sa gusto upang i-save ang aking kasalukuyang mga setting, pagkatapos ay ako pagpunta sa gusto upang i-update ang hacker_settings, at pagkatapos ay sa dulo ng aking mga programa, gusto kong bumalik sa mga kasalukuyang setting. Kaya sine-save ang mga kasalukuyang setting, ang paraan na gumagana, kami termios tao. Nakikita namin na mayroon kaming ito int tcsetattr, int tcgetattr. Pumasa ako sa isang termios struct sa pamamagitan ng pointer. Ang paraan na ito ang magiging hitsura - I've na nakalimutan kung ano ang function ay tinatawag na. Kopyahin at i-paste ito. Kaya tcgetattr, pagkatapos ay gusto ko upang pumasa sa struct na ako sa pag-save ng impormasyon sa, na pagpunta sa current_settings, at ang unang argumento ang file descriptor para sa mga bagay na gusto kong i-save ang mga katangian ng. Ano ang file descriptor ay tulad ng anumang oras na magbubukas ka ng isang file, nakakakuha ng file descriptor. Kapag ako ay nag fopen argv [1], ay nakakakuha ng isang file descriptor na kung saan ikaw ay tumutukoy sa kahit kailan mo gusto upang basahin o magsulat dito. Na hindi ang file descriptor na gusto kong gamitin dito. May tatlong file descriptors na mayroon ka sa pamamagitan ng default, na pamantayan sa, karaniwang out, at karaniwang error. Sa pamamagitan ng default, tingin ko standard in ay 0, karaniwang out ay 1, at karaniwang error ay 2. Kaya kung ano ang ko gusto mong baguhin ang mga setting ng? Gusto kong baguhin ang mga setting tuwing pindutin ko ang isang character, Gusto ko ito itapon na karakter ang layo sa halip ng pag-print ang mga ito sa screen. Ano stream - pamantayan sa, karaniwang out, o karaniwang error - tumugon sa mga bagay kapag ako ay nag-type sa keyboard? >> [Mag-aaral] Standard. >> Oo. Kaya ko alinman sa gawin 0 o maaari kong gawin stdin. Ako nakakakuha ang current_settings ng standard. Ngayon gusto ko upang i-update ang mga setting na iyon, kaya muna ako kokopya sa hacker_settings kung ano ang aking mga current_settings. At kung paano structs trabaho ito kopyahin lamang. Ito kinokopya lahat ng mga patlang, tulad ng inaasahan mo. Ngayon gusto ko upang i-update ang ilan sa mga field. Naghahanap sa termios, gusto mo upang basahin sa pamamagitan ng maraming ito lamang upang makita kung ano ang gusto mo upang hanapin, ngunit ang mga flag ka ng pagpunta sa gusto upang tumingin para sa echo, kaya Echo Echo input character. Una gusto kong mag-set - I've na nakalimutan kung ano ang mga patlang. Ito ay kung ano ang struct ang kamukha. Kaya input mode sa tingin ko gusto naming baguhin. Titingnan namin ang solusyon upang matiyak na kung ano ang gusto naming baguhin. Gusto naming upang baguhin ang lflag upang maiwasan ang nangangailangan upang tumingin sa pamamagitan ng lahat ng mga. Gusto naming baguhin ang mga lokal na mode. Mayroon kang upang basahin ang buong bagay upang maunawaan kung saan ang lahat ng nabibilang na gusto naming baguhin. Subalit sa loob ng mga lokal na mode na kung saan kami ay pagpunta sa gusto mong baguhin na. Kaya hacker_settings.cc_lmode ano ang tawag dito. c_lflag. Ito ay kung saan nakukuha namin sa bitwise operator. Humihingi kami ng uri ng out ng oras, ngunit gagamitin namin pumunta sa pamamagitan ng ito tunay na mabilis. Ito ay kung saan nakukuha namin sa bitwise operator, kung saan sa tingin ko sinabi ko isang beses matagal na ang nakalipas na kapag sinimulan mo ang pagharap sa flag, ka pagpunta sa gamit ang bitwise operator ng maraming. Bawat bit sa bandila ay tumutugma sa ilang mga uri ng pag-uugali. Kaya dito, i-flag na ito ay may isang bungkos ng mga iba't ibang mga bagay, kung saan ang lahat ng mga ito ay nangangahulugan ng isang bagay na iba't ibang. Ngunit kung ano ang gusto kong gawin ay lamang i-off ang bit na tumutugma sa Echo. Kaya upang i-off ko & = ¬ Echo. Aktwal na, sa tingin ko ito tulad ng tECHO o isang bagay. Lang ako pagpunta upang suriin muli. Ko ito termios. Lamang nito echo. Echo ng isang sandali. ¬ Echo ay pagpunta sa ibig sabihin ng lahat ng mga bits ay nakatakda sa 1, na nangangahulugan na ang lahat ng mga flag ay nakatakda sa true maliban para sa Echo bit. Sa nagtatapos ang aking mga lokal na flag na ito, ito ay nangangahulugan na ang lahat ng mga flag na kasalukuyang nakatakda sa true pa rin ang nakatakda sa true. Kung ang aking Echo bandila ay naka-set sa true, pagkatapos ito ay kinakailangan nakatakda sa False sa bandila Echo. Kaya ang linya ng code off ang echo bandila. Ang iba pang mga linya ng code, ko lang kopyahin ang mga ito sa interes ng oras at pagkatapos ay ipaliwanag ang mga ito. Sa solusyon, sinabi niya 0. Marahil ito ay mas mahusay sa tahasang sabihin ng stdin. Pansinin na din ako ginagawa Echo | ICANON dito. Ang ICANON ay tumutukoy sa isang bagay na hiwalay na, na kung saan ay nangangahulugan na ang canonical mode. Anong canonical mode ay nangangahulugan karaniwan kapag tina-type mo ang command line, Standard sa ay hindi maproseso ang anumang hanggang maabot ang newline. Kaya kapag mo GetString, nag-type ka ng grupo ng mga bagay, at pagkatapos ay pinindot ninyo ang newline. Iyon ay kapag ito ay ipinadala sa pamantayan. Iyon ay ang default. Kapag ko i-off ang ang canonical mode, ngayon bawat solong character mo pindutin ay kung ano ay makakakuha naproseso, na kung saan ay karaniwang uri ng masamang dahil ito ay mabagal upang iproseso ang mga bagay na ito, na kung bakit ito ang magandang buffer ang mga ito sa buong linya. Ngunit Gusto kong ma-proseso ang karakter bawat dahil hindi ko gusto ito maghintay para sa akin upang maabot newline bago maproseso ito sa lahat ang mga character ko na mag-type. Ito off ang canonical mode. Ang bagay na ito ay nangangahulugan na kapag ito aktwal na maproseso ang mga character. Nangangahulugan ito na iproseso ang mga ito agad-agad, sa lalong madaling ako type sa kanila, iproseso ang mga ito. At ito ay ang function na kung saan ay ina-update ang aking mga setting para sa mga karaniwang sa, at TCSA paraan na gawin ito ngayon. Ang iba pang mga pagpipilian ay maghintay hanggang ang lahat na ay kasalukuyang sa stream ay naproseso. Na hindi talagang mahalaga. Lamang ngayon baguhin ang aking mga setting sa anumang kasalukuyang nasa hacker_typer_settings. Hulaan ko tinatawag ko ito hacker_settings, kaya sabihin baguhin ang. Baguhin ang lahat sa hacker_settings. Ngayon sa pagtatapos ng aming programa kami ay pagpunta sa nais upang bumalik sa kung ano ang kasalukuyang loob ng normal_settings, na lang magmukhang & normal_settings. Pansinin na hindi ko nagbago ang anumang ng aking mga normal_settings dahil sa orihinal na pagkuha ito. Pagkatapos upang baguhin lamang ang mga ito pabalik, ipasa ko ang mga ito pabalik sa dulo. Ito ang update. Okay. Ngayon sa loob ng dito ko lang ipaliwanag ang code sa interes ng panahon. Ito ay hindi ganoong karaming mga code. Nakikita namin naming basahin ang isang character mula sa file. Tinatawag namin itong f. Ngayon ay maaari kang tao fgetc, ngunit kung gaano fgetc ay upang gumana ay lamang ito upang ibalik ang karakter na iyong basahin o EOF, na tumutugon sa dulo ng file o ilang mga error mangyari. Namin ay looping, patuloy na basahin ang isang solong character mula sa file, hanggang kami maubusan ng mga character upang basahin. At habang ginagawa namin na, maghintay namin sa isang solong character mula sa pamantayan. Bawat solong oras na nag-type ka ng isang bagay sa command line, na pagbabasa sa isang character mula sa pamantayan. Pagkatapos putchar ay lamang pagpunta upang ilagay ang magpasinda basahin namin dito mula sa file sa standard out. Maaari mong tao putchar, ngunit lamang ito ng paglalagay sa standard ang, ang pag-print na karakter. Maaari mo ring lamang gawin printf ("% c", c), Parehong ideya. Na pagpunta sa gawin ang karamihan ng aming trabaho. Ang huling bagay na kami ay pagpunta sa nais na gawin lamang fclose ang aming file. Kung hindi mo fclose, na ang isang memory mahayag. Gusto naming fclose file na binuksan namin ang orihinal na, at sa tingin ko na ito. Kung namin na, nakuha ko na problema. Natin makita. Ano ang ito magreklamo tungkol sa? Inaasahan na 'int' ngunit argumento ng uri ng 'struct _IO_FILE *'. Susubukan naming makita kung na gumagana. Pinapayagan lamang sa C99. Augh. Okay, gumawa ang hacker_typer. Ngayon makuha namin ang higit pang mga kapaki-pakinabang na mga paglalarawan. Kaya gamitin ng hindi nagbigay-alam identifier 'normal_settings'. Hindi ako tumawag ito normal_settings. Tinatawag ko ito current_settings. Kaya sabihin baguhin ang lahat ng na. Ngayon pagpasa ng argumento. Ko ito 0 sa ngayon. Okay. . / Hacker_typer cp.c. Din ako ay hindi i-clear ang screen sa simula. Ngunit maaari kang tumingin pabalik sa huling hanay ng problema upang makita kung paano mo i-clear ang screen. Lamang ito pag-print ang ilang mga character habang ito ay ginagawa kung ano ang gusto kong gawin. Okay. At iniisip tungkol sa kung bakit ito kinakailangan na ang 0 sa halip ng stdin, na dapat # tukuyin 0, ito ay nagrereklamo na - Bago kapag sinabi ko na may file descriptors ngunit pagkatapos ay mayroon ka ring ang iyong FILE *, isang file descriptor ay lamang ng isang integer, samantalang ang FILE * ay isang buong grupo ng mga bagay-bagay na kaugnay nito. Ang dahilan na kailangan namin upang sabihin ang 0 sa halip ng stdin ang stdin na ng FILE * na mga punto sa bagay na tumutukoy sa file descriptor 0. Kaya kahit up dito kapag gagawin ko fopen (argv [1], Nakakakuha ako ng FILE * bumalik. Ngunit sa isang lugar sa na * FILE ay isang bagay na naaayon sa file descriptor para sa file na iyon. Kung tumingin ka sa pahina ng tao para sa open, kaya tingin ko magkakaroon ka upang gawin ang tao 3 bukas - nope - tao 2 bukas - oo. Kung tumingin ka sa pahina ng para sa bukas, bukas ay tulad ng isang mas mababang antas fopen, at bumabalik ang aktwal na file descriptor. fopen ang ipinapakita ng grupo ng mga bagay-bagay sa itaas ng bukas, kung alin sa halip ng bumabalik lang ang file descriptor nagbalik ng isang buong FILE * pointer sa loob ng na aming maliit na file descriptor. Kaya karaniwang tumutukoy sa bagay FILE *, kung saan 0 ay tumutukoy lamang ang pamantayan file descriptor sa mismong. Mga tanong? [Laughs] Blew pamamagitan na. Ayos lang. Tapos na kami. [Laughs] [CS50.TV]