[Powered by Google Translate] [SECTION 5: mas kumportable] [Nate Hardison, Harvard University] [Ito ay CS50.] [CS50.TV] Kaya maligayang pagdating pabalik, guys. Maligayang pagdating sa seksyon 5. Sa puntong ito, ang pag-nakumpleto pagsusulit 0 at nagki makikita kung paano nagawa mo na, sana sa tingin mo ba talagang magandang dahil napaka ako ay impressed sa pamamagitan ng ang mga marka sa seksyon na ito. Para sa aming online na mga manonood, kami ay may ilang mga katanungan tungkol sa huling dalawang mga problema sa hanay ng problema - o sa pagsusulit, sa halip. Kaya kami ay pagpunta sa pumunta sa paglipas ng mga talagang mabilis kaya na ang lahat ay nakikita kung ano ang nangyari at kung paano pumunta sa pamamagitan ng aktwal na solusyon sa halip na lamang tinitingnan ang solusyon mismo. Kami ay pagpunta sa pumunta sa ibabaw ng huling ilang mga problema talagang mabilis, 32 at 33. Lang, muli, kaya na ang mga online na mga manonood ay maaaring makita ito. Kapag isinara mo sa iyong problema 32, na kung saan ay sa pahina 13, 13 ng 16, problema 32 ay tungkol sa swaps. Ito ay lahat ng tungkol sa pagpapalit dalawang integer. Ang problema na gusto namin nawala sa paglipas ng ilang beses sa panayam. At in dito, kung ano ang namin ang humihiling sa iyo na gawin ang isang mabilis na trace ng memory. Upang punan ang mga halaga ng variable habang ang mga ito ay sa stack ng code napupunta sa pamamagitan ng function na makipagpalitan na ito. Sa partikular, kung ano ang aming iyong hinahanap sa - I'm pagpunta sa ilagay ang iPad - partikular, kung ano ang iyong hinahanap namin sa linya na ito bilang 6 karapatan dito. At ito bilang 6 para lamang pagkamalapit sa nakaraang problema. Ang gusto naming gawin ay ipakita o label ang estado ng memorya tulad ng ito ay sa oras kapag execute namin ang line number 6, na epektibo ng kita mula sa aming makipagpalitan ng function na dito mismo. Kung mag-scroll pababa namin dito, nakita namin na ang mga address ng lahat sa memory para sa amin. Ito ay napaka key, magpapadala kami bumalik dito sa sandali lamang. At pagkatapos ay down na dito sa ibaba, kami ay nagkaroon ng isang maliit na diagram ng memorya na kami ay pagpunta sa sumangguni sa. Aktwal na tapos ko na ito sa aking iPad. Kaya ako pagpunta sa pagsalitin pabalik-balik sa pagitan ng iPad at ang code na ito para sa reference. Magsimula tayo. Una, sabihin tumutok sa unang dalawang linya ng pangunahing karapatan dito. Upang magsimula, kami ay pagpunta sa simulan ang x sa 1 at y sa 2. Kaya mayroon kaming dalawang integer variable, sila ay parehong pagpunta sa ilagay sa stack. Kami ay pagpunta sa maglagay ng 1 at 2 sa kanila. Kaya kung i-flip ko sa aking iPad, sana, sabihin makita - Apple TV mirror, at doon kami. Okay. Kaya kung i-flip ko sa aking iPad, Gusto kong simulan ang x sa 1 at y sa 2. Ginagawa namin na medyo lamang sa pamamagitan ng pagsusulat ng 1 sa box na may markang x at ng 2 sa kahon sa minarkahan y. Medyo simple. Kaya ngayon sabihin bumalik sa laptop, makita kung ano ang susunod na mangyayari. Kaya ang susunod na linya ay kung saan ang mga bagay makakuha ng nakakalito. Pumasa namin ang address ng x at ang address ng y bilang ang mga parameter at b sa function na makipagpalitan. Ang address ng x at ang address ng y ang mga bagay na hindi namin maaaring kalkulahin nang hindi nagre-refer sa mga bullet POINTS kanan pababa dito. At sa kabutihang-palad, ang unang dalawang mga punto ng bullet sabihin sa amin nang eksakto kung ano ang mga sagot. Ang address ng x sa memorya ay 10, at ang address ng y sa memorya ay 14. Kaya mga ang mga halaga na makapag ang pumasa sa bilang isang at b tuktok hanggang sa aming makipagpalitan ng function na. Sa muli, lumipat pabalik sa aming diagram, ang maaari kong magsulat ng isang 10 sa isang at 14 sa b. Ngayon, ang puntong ito ay kung saan naming magpatuloy na may makipagpalitan. Kaya flipping pabalik sa laptop muli, nakikita namin na ang paraan makipagpalitan gumagana ang ako unang dereference at store ang resulta sa tmp. Kaya ang operator ng dereference sabi, "Uy Tratuhin ang mga nilalaman ng variable ng bilang isang address. Pumunta sa anumang ay naka-imbak sa address na iyon, at i-load ito. " Ano ang nag-load ka ng variable ay pagpunta sa naka-imbak sa aming tmp variable. Flipping pabalik sa iPad. Kung pumunta namin upang matugunan ang 10, alam namin na ang address 10 ang varible x dahil kami ay sinabi sa pamamagitan ng aming bullet point na ang address ng x sa memorya ay 10. Upang maaari naming pumunta doon, kumuha ng ang halaga nito, na 1, tulad ng nakikita namin sa aming iPad, at i-load na sa tmp. Muli, ito ay hindi ang panghuling nilalaman. Kami ay pagpunta sa lakad sa pamamagitan ng at magpapadala kami sa aming huling katayuan ng programa sa dulo. Ngunit ngayon, mayroon kaming ang halaga 1 na naka-imbak sa tmp. At may isang mabilis na tanong sa paglipas dito. [Alexander] ang dereference operator - na lamang ang star kanan sa harap ng variable? >> Oo. Kaya ang dereference operator, bilang namin i-flip pabalik sa aming laptop muli, ay ang star na ito sa harap mismo. Sa pakiramdam na iyon, ito ay - Contrast mo ito sa mga operator ng pagpaparami na nangangailangan ng dalawang bagay, ang dereference operator ay isang unary operator. Lamang inilapat sa isang halaga na taliwas sa isang binary operator, kung saan kang mag-aplay sa dalawang iba't ibang mga halaga. Kaya na kung ano ang mangyayari sa linya. Namin load ang halaga 1 at naka-imbak ito sa aming pansamantalang integer variable. Ang susunod na linya, iniimbak namin ang mga nilalaman ng b sa - o, sa halip, iniimbak namin ang mga nilalaman na b ay tumuturo sa sa lugar na kung saan ay tumuturo sa. Kung pag-aralan namin ito mula sa karapatan sa kaliwa, kami ay ng pagpunta sa dereference b, kami ay pagpunta upang matugunan ang 14, kami ay pagpunta upang makakuha ng integer na doon, at pagkatapos namin pumunta sa address na 10, at kami ay magtapon ang resulta ng aming dereference ng b sa puwang na iyon. Flipping pabalik sa aming iPad, kung saan maaari naming gawin ito ng kaunti pa kongkreto, maaaring makatulong sa kung ako sumulat ng mga numero sa lahat ng mga address dito. Upang malaman namin na sa y, hindi namin sa address 14, x sa address 10. Kapag nagsimula kami sa b, namin dereference b, kami ay pagpunta sa grab ang halaga 2. Kami ay pagpunta sa grab ang halaga na ito dahil na ay ang halaga na nakatira sa address na 14. At kami ay pagpunta sa ilagay ang mga ito sa variable na nakatira sa address na 10, na doon, na nakaayon sa aming mga variable na x. Upang maaari naming gawin ng kaunting Sasapawan nito dito kung saan nakukuha namin mapupuksa ng aming 1 at sa halip namin magsulat ng isang 2. Kaya lahat ng mahusay at magandang sa mundo, kahit na namin mapapatungan x ngayon. Naka-imbak namin ang lumang halaga ng x sa aming tmp variable. Upang maaari naming kumpletuhin ang makipagpalitan sa susunod na linya. Flipping pabalik sa aming laptop. Ngayon ang lahat na labi ay upang gawin ang mga nilalaman ng aming pansamantalang integer variable at mag-imbak ang mga ito sa variable na nakatira sa address na b ay may hawak. Kaya kami ay pagpunta sa epektibong dereference b upang makakuha ng access sa variable na sa address na b pagpipigil sa loob nito, at kami ay pagpunta sa bagay-bagay na ang halaga na tmp ay may hawak na ito. Flipping pabalik sa iPad minsan pa. Maaari ko bang burahin ang halaga dito, 2, at sa halip naming kopyahin ang 1 pakanan papunta dito. Pagkatapos ay sa susunod na linya na executes, siyempre - kung i-flip namin pabalik sa laptop - ay puntong ito 6, na ang punto kung saan gusto naming ang aming diagram ay ganap na napunan ang. Kaya flipping sa iPad minsan pa, lamang kaya maaari mong makita ang kumpletong diagram, maaari mong makita na mayroon kami ng 10 sa isang, isang 14 sa b, 1 sa tmp, 2 sa x, at 1 sa y. Mayroon bang anumang mga katanungan tungkol sa? Ba ito gumawa ng higit pang kahulugan, pag-lumakad sa pamamagitan nito? Gawing mas kahulugan? Sana hindi. Okay. Pointer ay isang nakakalito paksa. Isa ng guys nakikipagtulungan kami sa may kasabihan: "Upang maunawaan ng mga payo, dapat mo munang maunawaan payo." Na sa palagay ko ay lubos na totoo. Ang magtagal upang magamit ito. Pagguhit maraming ng mga larawan, magkaroon ng maraming ng mga diagram ng memory tulad ng isang ito ay kapaki-pakinabang, at pagkatapos maglakad sa iyo sa pamamagitan ng halimbawa pagkatapos ng halimbawa pagkatapos Halimbawa, magsimulang gumawa ng kaunti pa sa kahulugan at ng kaunti pa sa kahulugan at ng kaunti pa sa pakiramdam. Sa wakas, isang araw, makikita mo ito ang lahat ng ganap na pinagkadalubhasaan. Anumang mga katanungan bago ilipat namin sa sa susunod na problema? Ayos lang. Kaya i-flip pabalik sa laptop. Ang susunod na problema na mayroon kami bilang 33 ng problema sa file ako / O. Mag-zoom in sa ito ng kaunti. Problema 33 - Oo? [Daniel] ko lang ay isang mabilis na tanong. Bituin na ito, o ang asterisk, ito ay tinatawag na dereferencing kapag gumamit ka ng isang asterisk sa bago. Ano ang tinatawag kapag ginamit mo ang ampersand bago? >> Ampersand Ang bago ay ang address ng operator. Kaya sabihin mag-scroll back up. Oops. Ako sa zoom mode kaya hindi ko talagang mag-scroll. Kung titingnan namin sa ang code na ito talagang mabilis dito mismo, muli, ang parehong bagay mangyari. Kung titingnan namin sa ang code na ito dito mismo, sa linyang ito kung saan namin ang tawag sa swap, ampersand ang sinasabi "makuha ang address kung saan variable x buhay." Kapag ang iyong tagatala compiles ang iyong code, ito ay aktwal na pisikal na markahan ang isang lugar sa memory para sa lahat ng iyong mga variable upang mabuhay. At kaya kung ano ang tagatala maaaring gawin sa sandaling ito ay pinagsama-sama ang lahat, ito alam, "Oh, ko bang ilagay ang x sa address 10 ko bang ilagay ang y sa address 14." Maaari itong pagkatapos ay punan ang mga halaga na ito para sa iyo. Sa gayon ay maaari mong - ito ay maaaring ipasa ito sa at pass & y sa pati na rin. Mga guys makakuha ng address, ngunit din sila, kapag pinapasa mo ang mga ito sa function na makipagpalitan ng, ganitong uri ng impormasyon, ito int * dito mismo, ay nagsasabi tagatala, "Okay, kami ay pagpunta sa pagbibigay-kahulugan sa address na ito bilang isang address ng isang integer variable." Bilang isang address ng isang int, na naiiba mula sa address ng isang variable ng character dahil int tumatagal hanggang, sa isang 32-bit na machine, tumatagal ng hanggang 4 bytes ng espasyo, kung saan ang character na tumatagal lamang ng 1 byte ng puwang. Kaya Mahalagang malaman din kung ano ang - kung ano ang nakatira, kung anong uri ng halaga nakatira sa address na Nakakuha ang pumasa. O ang address na iyong pagharap sa. Sa ganoong paraan, alam mo kung gaano karaming mga byte ng impormasyon sa aktwal na-load ng iyong RAM. At pagkatapos, oo, ito dereference operator, tulad mo ay humihiling sa, pupunta at access ng impormasyon sa isang partikular na address. Kaya sinasabi nito, na ito sa isang variable dito, ituring ang mga nilalaman ng isang bilang isang address, pumunta sa address na iyon, at hilahin out, load sa processor, ng pagkarga sa isang rehistro ang aktwal na halaga o ang mga nilalaman na nakatira sa address na iyon. Anumang higit pang mga tanong? Ito ang mga mahusay na mga katanungan. Ng maraming ng mga bagong terminolohiya. Ring uri ng funky, nakikita at at * sa iba't-ibang mga lugar. Ayos lang. Kaya sa problema 33, maghain ako / O. Ito ay isa sa mga problema na sa tingin ko ang ilang mga bagay ang nangyari. Isa, ito ay isang medyo bagong paksa. Ito ay ipinakita medyo madaling bago ang pagsusulit, at pagkatapos ay sa tingin ko ito ay uri ng tulad ng isa sa mga problema ng salita sa matematika kung saan sila magbibigay sa iyo ng maraming impormasyon, ngunit ang iyong aktwal na ay hindi kinakailangang gumamit ng isang tonelada ng. Ang unang bahagi ng problema na ito ay naglalarawan kung ano ang isang file na CSV. Ngayon, ang isang CSV file, ayon sa paglalarawan, ay isang comma-separated file halaga. Ang dahilan kung bakit ito ay sa lahat ng kawili-wili, at ang dahilan mo man gamitin ang mga ito, , dahil, kung gaano karami ng iyong kailanman ginamit bagay tulad ng Excel? Figure pinaka-mo na, marahil, o gamitin sa ilang mga punto sa iyong buhay. Mong gamitin ang isang bagay tulad ng Excel. Upang makuha ang data ng isang Excel spreadsheet o gawin ang anumang uri ng pagpoproseso sa mga ito, kung nais mong magsulat ng isang C programa o Python programa, Java programa, upang harapin ang data na naka-imbak sa doon, isa sa mga pinaka-karaniwang paraan upang makakuha ng ito sa isang CSV file. At maaari mong buksan ang Excel at kapag ikaw ay pumunta sa 'I-save Bilang' dialogue, maaari kang makakuha ng isang aktwal na CSV file. Madaling gamiting malaman kung paano haharapin ang mga bagay na ito. Ang paraan ito gumagana ay na pareho ito sa - Ibig kong sabihin, mahalagang ito ay paggaya sa isang spreadsheet, kung saan, bilang makita namin dito, sa napaka-kaliwa-pinaka-piraso, Mayroon namin ang lahat ng mga huling pangalan. Kaya mayroon kaming Malan, pagkatapos Hardison, at pagkatapos Bowden, MacWilliam, at pagkatapos Chan. Ang lahat ng mga huling pangalan. At pagkatapos kuwit na naghihiwalay sa huling pangalan mula sa unang pangalan. David, Nate, Rob, Tommy, at Zamyla. Ko laging ihalo up ng Robby at Pedro. At pagkatapos, sa wakas, ang ikatlong haligi ay ang email address. Sandaling nauunawaan mo na, ang natitirang bahagi ng programa ay medyo direkta ipatupad. Ano ang ginawa namin upang gayahin ang parehong istraktura sa aming programa sa C ay ginamit namin ang istraktura ng. Sisimulan naming ipinapalabas na may mga isang maliit na higit pa pati na rin. Nakita namin ang mga ito para sa unang kaunti sa problema sa set 3, kapag kami ay pagharap sa ang diksyunaryo. Ngunit ito kawani struct nag-iimbak ng apelyido, unang pangalan, at ng isang email. Lamang tulad ng ating CSV file ay ang pag-iimbak. Kaya ito ay nagko-convert mula sa isang format sa ibang. Mayroon kaming i-convert, sa kasong ito, ang isang kawani struct sa isang linya, comma-separated line, tulad na. Ba na magkaroon ng kahulugan? Mong guys lahat kinuha ang pagsusulit, kaya isipin ko mo na ang hindi bababa sa may ilang oras upang isipin ang tungkol sa. Sa pag-andar ng hire, ang problema ay humihiling sa amin upang kumuha sa - we'll mag-zoom in sa ito ng kaunti - sa istraktura ng isang kawani, kawani struct, may pangalan s, at ikabit ang mga nilalaman nito sa aming staff.csv file. Ito lumiliko out na ito ay medyo direkta upang gamitin. Padadalhan ka namin ng uri ng i-play sa paligid na may mga function ng kaunti higit pa ngayon. Ngunit sa kasong ito, ang fprintf function na ay talagang ang susi. Kaya may fprintf, maaari naming i-print, tulad mo guys ay gamit printf ito buong termino. Maaari mong printf isang linya sa isang file. Kaya sa halip na lamang sa paggawa ng dati printf tawag kung saan mo bigyan ito ang format string at pagkatapos mo palitan ang lahat ng mga variable na may mga sumusunod na mga argumento, may fprintf, ang iyong unang argumento sa halip ang file na nais mong sumulat sa. Kung kami ay upang tumingin sa ito sa appliance, halimbawa, tao fprintf, maaari naming makita ang mga pagkakaiba sa pagitan ng printf at fprintf. Kukunin ko na mag-zoom in dito nang kaunti. Kaya may printf, hindi namin bigyan ito ng isang string ng format, at pagkatapos ay ang kasunod na argumento ay ang lahat ng mga variable para sa kapalit o pagpapalit sa aming format string. Sapagkat may fprintf, ang unang argumento ay talagang * ang file na ito na tinatawag na stream ng. Paglipat pabalik sa paglipas dito sa aming hire, na Mayroon namin ang aming file stream * binuksan para sa atin. Na kung ano ang unang linya na ito, ito ay bumubukas ang staff.csv file, bubukas ito sa Magkabit mode, at ang lahat na natitira para sa amin upang gawin ay isulat ang kawani istraktura sa file. At, sabihin makita, nais kong gamitin ang iPad? Makikita ko bang gamitin ang iPad. Mayroon kaming walang bisa - ipaalam sa ay ilagay ito sa talahanayan sa gayon ay maaari kong isulat ng kaunti mas mahusay na - void hire at tumatagal ito sa isang argument, isang kawani ng istraktura na tinatawag na mga. May aming mga tirante, Mayroon namin ang aming * ng file na tinatawag na file, namin ang aming fopen line na ibinigay sa atin, at kukunin ko na magsulat lamang ito bilang tuldok dahil nasa pedia sa. At pagkatapos ay sa aming susunod na linya, kami ay pagpunta sa tumawag sa fprintf at kami ay pagpunta sa pumasa sa file na gusto naming i-print, at pagkatapos ay ang aming format string, na - Ipapaalam ko ka guys sabihin sa akin kung ano ang mukhang. Paano tungkol sa iyo, Stella? Alam mo ba kung ano ang unang bahagi ng string ng format kamukha? [Stella] Hindi ako sigurado. >> Huwag mag-atubiling magtanong Jimmy. Alam mo ba, Jimmy? [Jimmy] Gusto ito ay hindi huling? Hindi ko alam. Hindi ako ganap na sigurado. >> Okay. Paano tungkol sa, ay sinuman makuha ang tamang sa pagsusulit? Hindi. Lahat ng karapatan. Ito lumiliko out na dito ang lahat ng mayroon kaming gawin ay gusto namin ang bawat bahagi ng aming kawani istraktura na ipi-print bilang isang string sa aming file. Lang namin gamitin ang pagpapalit ng karakter ng string tatlong iba't ibang oras dahil mayroon kaming isang apelyido sinusundan ng kuwit, pagkatapos ng unang pangalan sinusundan ng isang kuwit, at pagkatapos ay sa wakas ang email address kung saan sinundan - na hindi umaangkop sa aking screen - ngunit ito ay sinundan sa pamamagitan ng isang newline character. Kaya ako pagpunta sa magsulat lamang ito pababa doon. At pagkatapos ay pagsunod sa aming mga string ng format, lang namin ang mga pamalit, na namin ng access na gamit ang tuldok pagtatanda na nakita natin sa problema sa set 3. Maaari naming gamitin ang s.last, s.first, at s.email ihalili sa mga tatlong mga halaga sa aming format string. Kaya kung paano ay na pumunta? Kabuluhan? Oo? Hindi? Posibleng? Okay. Ang huling bagay na ginagawa namin matapos naming naka-print at matapos naming binuksan ang aming file: tuwing namin na binuksan ng isang file, lagi naming tandaan na isara ang mga ito. Dahil kung hindi namin makikita tagas ang memorya, gamit descriptors file. Kaya upang isara ito, kung aling mga function na namin ang? Daniel? [Daniel] fclose? >> Fclose, eksakto. Kaya't ang huling bahagi ng problema na ito ay upang maayos na isara ang file, gamit ang fclose function na, na lang kamukha na. Hindi masyadong mabaliw. Cool. Kaya na problema 33 sa pagsusulit. Namin talagang higit pang mga file I / O paparating na. Gagawin namin ng kaunti higit pa sa panayam ngayon, o sa seksyon ngayon, dahil na kung ano ang nangyayari upang mabuo ang bulk ng mga ito paparating na pset. Natin lumipat sa mula sa pagsusulit sa puntong ito. Oo? [Charlotte]] Bakit fclose (file) sa halip ng fclose (staff.csv)? >> Ah. Dahil ito ay lumiliko na - kaya ang tanong, na kung saan ay isang mahusay na, ay kung bakit, kapag isulat namin fclose, kami pagsusulat ng fclose (file) star variable na iba sa pangalan ng file, staff.csv? Iyan ba ang tama? Oo. Kaya sabihin tingnan. Kung lumipat ako pabalik sa aking laptop, at tingnan natin sa fclose function na. Kaya ang fclose function na isinasara stream at tumatagal ito sa ang pointer sa stream na gusto naming upang isara, bilang laban sa ang aktwal na pangalan ng file na gusto naming upang isara. At ito ay dahil sa likod ng mga eksena, kapag gumawa ka ng isang tawag sa fopen, kapag binuksan mo ang isang file, aktwal ka paglaan ng memorya upang mag-imbak ng impormasyon tungkol sa mga file. Kaya mayroon kang file na pointer na may impormasyon tungkol sa mga file, tulad ng ito ay bukas, ang laki, kung saan ikaw ay kasalukuyang sa file, sa gayon ay maaari kang magsagawa ng pagbabasa at pagsusulat ng mga tawag sa partikular na lugar sa loob ng file. Magtapos mong isara ang pointer sa halip na isara ang pangalan ng file. Oo? [Daniel] Kaya upang magamit hire, nais mong sabihin - paano ito makuha ang input ng user? Ba fprintf kumilos tulad ng GetString sa ang kahulugan na lamang maghintay para sa input ng user at hilingin sa mong i-type ito - o maghintay para sa iyo upang i-type ang tatlong bagay sa? O kailangan mong gamitin ang isang bagay na ipapatupad ang hire? >> Oo. Kaya hindi namin - tanong ay, kung paano namin makuha ang input ng user upang ipatupad ang hire? At kung ano ang mayroon kami dito ang tumatawag ng hire, ang pumasa sa struct ito kawani sa lahat ng mga data na naka-imbak sa struct na. Kaya fprintf ay magsulat lamang ang data na iyon nang direkta sa file. Walang naghihintay para sa input ng user. Gumagamit na ibinigay ang input sa pamamagitan ng paglalagay ng maayos ito sa struct kawani na ito. At bagay, siyempre, masira kung anumang ng mga payo ay null, kaya mag-scroll namin back up dito at tinitingnan namin ang aming struct. Mayroon kaming string huling, unang string, string email. Alam namin ngayon na ang lahat ng mga talagang, sa ilalim ng hood, magpasinda * variable. Na maaaring o hindi maaaring tumuturo sa null. Maaari silang nagtuturo sa memory sa magbunton, siguro memory sa stack. Hindi namin talaga alam, ngunit kung mayroon man sa mga payo null, o di-wasto, na na kailangan talagang pag-crash ng aming hire function na. Na isang bagay na uri ng higit sa saklaw ng pagsusulit. Hindi kami nag-aalala tungkol na. Mahusay. Okay. Kaya gumagalaw sa mula sa pagsusulit. Natin isara ang tao na ito, at kami ay pagpunta sa tumingin sa pset 4. Kaya kung guys tumingin sa spec pset, sa sandaling maaari mong i-access ito, cs50.net/quizzes, kami ay pagpunta sa pumunta sa pamamagitan ng ilang ng mga problema sa ngayon ng seksyon. Ako scroll pababa - seksyon ng tanong nagsisimula sa ikatlong pahina ng spec pset. At ang unang bahagi ay humihiling sa iyo na pumunta at panoorin ang maikling sa pag-redirect at pipe. Aling mga uri ng isang cool na maikling, ay nagpapakita sa iyo ng ilang mga bagong, cool na utos trick linya na maaari mong gamitin. At pagkatapos Mayroon kami ng ilang mga katanungan para sa iyo pati na rin. Ang unang tanong tungkol sa mga stream, na printf nagsusulat sa pamamagitan ng default, namin uri ng hinawakan sa lamang ng kaunti ng ilang sandali ang nakalipas. Ito fprintf na lang namin ay tinatalakay tumatagal sa isang stream ng file * bilang nito argument. fclose tumatagal sa isang stream ng file * pati na rin, at ang return halaga ng fopen ay nagbibigay sa iyo ng isang stream ng file * pati na rin. Ang dahilan kung bakit hindi namin nakita mga bago kapag kami Aaksyunan printf ay dahil printf ay may default stream. At ang default na stream na ito nagsusulat makikita mo ang tungkol sa maikling. Kaya talagang tumagal ng isang pagtingin sa. Sa seksyon ngayon, kami ay makipag-usap ng kaunti tungkol sa GDB, dahil mas pamilyar ka sa ito, ang mas maraming mga kasanayan kang makakuha sa ito, mas mahusay na magagawang makikita mo sa aktwal na manghuli down na mga bug sa iyong sariling code. Ito mga bilis ang proseso ng pag-debug tremendously. Kaya sa pamamagitan ng paggamit ng printf, sa tuwing gagawin mo na mayroon kang mag-recompile ang iyong code, mayroon kang upang patakbuhin itong muli, minsan mayroon kang ilipat ang printf tawag sa paligid, magkomento ang code, ito lamang tumatagal ng isang habang. Ang aming layunin ay upang subukan at kumbinsihin sa iyo na may GDB, maaari mong mahalagang printf anumang bagay sa anumang punto sa iyong code at hindi mo kailangang mag-recompile ito. Hindi mo upang simulan at panatilihin ang paghula kung saan printf susunod. Ang unang bagay na gawin ay upang kopyahin ang linya na ito at makakuha ng seksyon ng code ng web. Ako kopyahin ito linya ng code na nagsasabing, "wget ​​http://cdn.cs50.net". Ako pagpunta sa kopyahin ito. Ako pagpunta upang pumunta sa aking appliance, mag-zoom out sa gayon maaari mong makita kung ano ang ako ginagawa, paste ito sa doon, at kapag ako ay pindutin ang Enter, ito wget command na literal ay isang web makakuha. Ito ay pagpunta sa pull down ang file na ito ng Internet, at ito upang i-save ang mga ito sa kasalukuyang direktoryo. Ngayon kung ilista ko ang aking kasalukuyang direktoryo maaari mong makita na Mayroon akong ito section5.zip file mismo sa doon. Ang paraan upang makitungo sa tao na unzip ito, na maaari mong gawin sa command line, tulad ng ito. Section5.zip. Na makikita unzip ito, lumikha ng mga folder para sa akin, awdit ng lahat ng nilalaman, ilagay ang mga ito sa doon. Kaya ngayon maaari kong pumunta sa aking direktoryo seksyon 5 gamit ang command na cd. I-clear ang screen gamit ang malinaw. Kaya i-clear ang screen. Ngayon Mayroon akong isang magaling na malinis terminal humarap sa. Ngayon kung ilista ko ang lahat ng mga file na nakikita ko sa direktoryong ito, makikita mo na Mayroon akong apat na file: buggy1, buggy2, buggy3, at buggy4. Din Mayroon akong kanilang naaayon. File ng c. Hindi namin ay pagpunta upang tumingin sa file c sa ngayon. Sa halip, kami ay upang gamitin ang mga ito kapag binuksan namin hanggang GDB. Namin ang iningatan ito kaya na kami ay may access sa aktwal na source code kapag ginagamit namin GDB, ngunit ang mga layunin ng bahaging ito ng seksyon ay sa latero sa paligid may GDB at makita kung paano namin maaaring gamitin ito upang malaman kung ano ang nangyayari mali sa bawat isa sa mga apat na mga programa sa maraming surot. Kaya lang namin ang pagpunta sa buong kuwarto ay talagang mabilis, at ako upang humingi ng isang tao upang patakbuhin ang isa sa mga maraming surot programa, at pagkatapos ay gagamitin namin bilang isang grupo sa pamamagitan ng GDB, at kami na makita kung ano ang maaari naming gawin upang ayusin ang mga programang ito, o sa hindi bababa sa kilalanin kung ano ang nangyayari mali sa bawat isa sa kanila. Natin magsimula muli dito na may Daniel. Kang magpatakbo buggy1? Natin makita kung ano ang mangyayari. [Daniel] Sinasabi nito ang isang application kasalanan. >> Oo. Eksakto. Kaya kung nagpatakbo ako ng buggy1, nakakuha ako ng seg kasalanan. Sa puntong ito, maaari ba akong pumunta at buksan buggy1.c, subukan at malaman kung ano ang nangyayari mali, ngunit isa ng ang pinaka-kasuklam-suklam na mga bagay tungkol sa ito seg kasalanan error na hindi ito sabihin sa iyo sa kung ano ang linya ng mga bagay na programa aktwal nangyaring mali at sinira. Uri ng upang tingnan ang code at malaman gamit ng hula at i-check o printf upang makita kung ano ang nangyayari mali. Isa sa mga pinaka-cool na bagay tungkol sa GDB na ito ay talagang, talagang madali upang malaman kung ang linya sa kung saan ang iyong programa-crash. Lubos Ito ay nagkakahalaga ito upang gamitin ito, kahit na para lamang sa na. Kaya sa bota up GDB, ako type GDB, at pagkatapos ko bigyan ito ang landas sa executable na gusto kong patakbuhin. Narito nagta-type ako ng gdb ./buggy1. Pindutin ang Enter. Ay nagbibigay sa akin ang lahat ng ito impormasyon ng copyright, at pababa dito makikita mo ang line na nagsasabing, "Binabasa ng mga simbolo mula sa / home / jharvard/section5/buggy1. " At kung ang lahat ng napupunta na rin, makikita mo itong i-print ang isang mensahe na ganito ang hitsura. Makikita ito basahin ang mga simbolo, makikita ito sabihin "ako pagbabasa ng mga simbolo mula sa iyong executable file," at pagkatapos na ito "tapos" na mensahe sa paglipas dito. Kung nakikita mo ang ilang iba pang mga pagkakaiba-iba ng mga ito, o nakikita mo hindi ito mahanap ang mga simbolo o isang bagay tulad na, kung ano ang nangangahulugan iyon na hindi mo lang inipon iyong executable nang maayos. Kapag namin makatipon ng mga programa para sa paggamit na may GDB, mayroon kaming gamitin na espesyal na-g-flag, at na ginawa sa pamamagitan ng default kung makatipon mo ang iyong mga programa, sa lamang sa pamamagitan ng pag-type ng gumawa o gumawa ng maraming surot o gumawa mabawi, anuman sa mga. Ngunit kung ikaw ay kino-compile ang manu-mano sa may kalatong, pagkatapos makikita mo upang pumunta sa at isama ang na-g bandila. Sa puntong ito, ngayon na mayroon namin ang aming GDB prompt, medyo simple upang patakbuhin ang program. Maaari naming alinman type ang run, o maaari naming i-type lamang ang r. Karamihan sa mga utos GDB dinaglat. Karaniwan sa isa lamang o ng ilang mga titik, na medyo magaling. Kaya Saad, kung nag-type ka r at pindutin ang Enter, ano ang mangyayari? [Saad] Nakatanggap ako SIGSEGV, segmentation fault, at pagkatapos ang lahat ng ito gobbledygook. >> Oo. Tulad ng aming nakikita sa screen ngayon, at tulad ng Saad sinabi, kapag type namin run o r at pindutin ang Enter, pa rin namin makuha ang parehong kasalanan seg. Ito gamit GDB ay hindi malutas ang aming problema. Ngunit ito ay nagbibigay sa amin ilang gobbledygook, at ito ay lumiliko out na ito gobbledygook aktwal na nagsasabi sa amin kung saan ito nangyayari. Upang i-parse ang ilang sandali, ang unang bit ay ang function na kung saan lahat ng pagpunta mali. Mayroong __ strcmp_sse4_2 na ito, at ito ay nagsasabi sa amin na ito nangyayari sa file na ito tinatawag sysdeps/i386, ang lahat ng ito, muli, uri ng gulo - ngunit linya 254. Na uri ng mahirap upang i-parse. Karaniwan kapag mong makita ang mga bagay na tulad nito, na nangangahulugan na ito ay seg faulting sa isa ng library ng sistema. Kaya isang bagay gawin sa strcmp. Mong guys nakita strcmp bago. Hindi masyadong mabaliw, ngunit ang ibig sabihin nito na strcmp ay nasira o na ang isang problema sa strcmp? Ano ang tingin mo, Alexander? [Alexander] ba na - 254 ang linya? At ang - hindi binary, ngunit ito ay hindi sa kanilang kisame, at pagkatapos ay may isa pang wika para sa bawat function na. Ay na ang 254 sa function na iyon, o -? >> Line 254. Mukhang sa ito. File mga, kaya ito ang assembly code marahil. Subalit, hulaan ko ang mas pagpindot bagay, dahil hindi namin nakuha ang seg kasalanan, at mukhang ito ay darating mula sa strcmp function na, ito magpahiwatig, pagkatapos, ang strcmp na ay nasira? Hindi ito dapat, sana. Kaya lamang dahil mayroon kang isang segmentation fault sa isa sa mga pag-andar ng system, karaniwang na nangangahulugan na hindi mo lamang na tinatawag na ito nang tama. Ang pinakamabilis na bagay na dapat gawin upang malaman kung ano ang aktwal na pagpunta sa kapag nakita mo ang isang bagay na mabaliw tulad nito, tuwing makikita mo ang isang seg kasalanan, lalo na kung mayroon kang isang programa na sa paggamit ng higit pa sa pangunahing, ay gumamit ng backtrace. Ko pagpapaiksi backtrace sa pamamagitan ng pagsusulat ng BT, bilang kabaligtaran sa buong salita backtrace. Ngunit Charlotte, ano ang mangyayari kapag nag-type ka BT at pindutin ang Enter? [Charlotte] Ipinapakita nito sa akin ang dalawang linya, linya 0 at linya 1. >> Oo. Kaya linya 0 at linya 1. Mga ito ay aktwal na frame ng stack na kasalukuyang nasa laro kapag nag-crash ang iyong programa. Simula mula sa ang pinakamataas na frame, frame 0, at pagpunta sa ibaba karamihan, na ang frame 1. Aming pinakamataas na frame ang strcmp frame. Maaari mong isipin na ito bilang mga katulad na problema na lang namin ay ginagawa sa pagsusulit na may mga payo, kung saan namin swap stack frame sa tuktok ng pangunahing stack frame, at nagkaroon kami ang mga variable na makipagpalitan ay gamit sa tuktok ng mga variable na pangunahing ay gamit. Narito aming pag-crash ang nangyari sa aming strcmp function, na tinatawag na sa pamamagitan ng aming mga pangunahing function na, at backtrace ay nagbibigay sa amin hindi lamang ang mga function na kung saan ang mga bagay Nabigo, ngunit din ito ng pagsasabi sa amin kung saan ang lahat ay tinawag mula sa. Kaya kung mag-scroll ko sa paglipas ng kaunti pa sa kanan, maaari naming makita na oo, kami on line 254 ng ito strcmp-sse4.s file. Ngunit ang tawag ay ginawa sa buggy1.c, linya 6. Kaya na nangangahulugan na maaari naming gawin - ay maaaring pumunta lamang namin tingnan at makita kung ano ang nangyayari sa sa buggy1.c, linya 6. Muli, may mga ilang paraan upang gawin ito. Isa ay upang lumabas ng GDB o ang iyong code na buksan sa ibang window at cross reference. Na, sa loob at ng sarili nito, ay medyo madaling gamiting dahil ngayon kung handa ka sa mga oras ng opisina at mayroon ka ng seg kasalanan at ang iyong tf ang nagtataka kung saan ang lahat ay paglabag, Maaari mo lamang sabihin, "Oh, linya 6 Hindi ko alam kung ano ang nangyayari sa, ngunit ang isang bagay tungkol sa linya 6 na nagiging sanhi upang masira ang aking programa. " Ang iba pang mga paraan upang gawin ito ay maaari mong gamitin ang command na ito na tinatawag na listahan sa GDB. Maaari mo ring pagpapaiksi dito sa l. Kaya kung namin pindutin l, ano ang gagawin namin dito? Makuha namin ang maramihang mga bagay na kakaiba. Ito ay ang aktwal na code sa pagpupulong na sa strcmp_sse4_2. Ito ganito ang uri ng funky, at ang dahilan namin ay ang pagkakaroon ng ganitong dahil ngayon, May amin ng GDB sa frame 0. Kaya anumang oras tinitingnan namin ang variable, anumang oras na tinitingnan namin ang source code, kaming naghahanap sa source code na hinggil sa stack frame hindi namin kasalukuyang in Kaya upang makakuha ng anumang makahulugang, mayroon kaming ilipat sa stack frame na gumagawa ng higit pang kahulugan. Sa kasong ito, ang pangunahing stack frame ng kaunti pa sa kahulugan, dahil iyon ay talagang ang code na aming sinulat ni. Hindi ang strcmp code. Ang paraan maaari kang lumipat sa pagitan ng mga frame, sa kasong ito, dahil mayroon kaming dalawang, kami ay may 0 at 1, gawin mo na gamit ang pataas at pababang mga utos. Kung ilipat ko isang frame, ngayon ako sa pangunahing stack frame. Maaari kong ilipat pababa upang bumalik sa kung saan ako ay, pumunta up muli, pumunta down na muli, at pumunta muli. Kung sakaling ang iyong programa sa GDB, makakakuha ka ng pag-crash, makukuha mo ang backtrace, at makikita mo na ito sa ilang mga file na hindi mo alam kung anong nangyayari sa. Subukan mong listahan, ang code ay hindi mukhang pamilyar sa iyo, tingnan ang iyong mga frame at malaman kung nasaan ka. Ikaw ay marahil sa maling frame ng stack. O hindi bababa sa isang stack frame na ay hindi isa na maaari mo ba talagang i-debug. Ngayon na kami sa naaangkop na stack frame, hindi namin sa pangunahing, ngayon maaari naming gamitin ang listahan na command upang malaman kung anong linya ay. At maaari mong makita ang mga ito;-print ito sa ito para sa amin dito mismo. Ngunit maaari naming pindutin ang ilista ang lahat ng mga parehong, at ang listahan ay nagbibigay ito sa amin magaling printout ng aktwal na source code na nangyayari sa dito. Sa partikular, maaari naming tumingin sa linya 6. Maaari naming makita kung ano ang nangyayari sa dito. At mukhang namin ang paggawa ng isang string paghahambing sa pagitan ng mga string "CS50 bato" at argv [1]. Ang isang bagay tungkol sa pag-crash. Kaya Missy, mayroon kang anumang saloobin sa kung ano ang maaaring pagpunta sa dito? [Missy] Hindi ko alam kung bakit ito ay pag-crash. >> Hindi mo alam kung bakit ito ay pag-crash? Jimmy, anumang saloobin? [Jimmy] ako hindi ganap na sigurado, ngunit ang huling beses na ginamit namin string ihambing, o strcmp, nagkaroon kami tulad ng tatlong iba't ibang mga kaso sa ilalim ito. Hindi namin magkaroon ng ==, hindi ko sa tingin, sa na unang linya. Sa halip ito ay pinaghihiwalay sa tatlong, at ang isa ay == 0, isa ay <0, tingin ko, at isa> 0. Kaya marahil ng isang bagay tulad na? >> Oo. Kaya may isyu na ito ng namin ay ang paggawa ng tama ang paghahambing? Stella? Anumang saloobin? [Stella] Hindi ako sigurado. >> Hindi sigurado. Daniel? Saloobin? Okay. Ito lumiliko kung ano ang nangyayari dito mismo kapag tumakbo kami sa programa at nakuha namin ang seg kasalanan, kapag pinatakbo mo ang programa para sa unang pagkakataon, Daniel, mo bigyan ito ng anumang mga argumento command line? [Daniel] No. >> No. Sa kasong iyon, ano ang ang halaga ng argv [1]? >> May ay walang halaga. >> Karapatan. Well, may hindi naaangkop na halaga ng string. Ngunit ang ilang mga halaga. Ano ay ang halaga na ay makakakuha ng naka-imbak sa may? >> Ang isang halaga ng basura? >> Ito ay alinman sa isang halaga ng basura o, sa kasong ito, ang dulo ng array argv ay laging winakasan na may null. Kaya kung ano ang aktwal na Nakakuha na naka-imbak sa may null. Ang iba pang mga paraan upang malutas ito, kaysa sa iniisip ito sa pamamagitan, ay upang subukan ang pag-print ito. Ito ay kung saan ako ay nagsasabi na gamit GDB ay mahusay, dahil maaari mong i-print ang lahat ng mga variable, ang lahat ng mga halaga na nais mong gamit ang madaling-gamiting-napakainam na utos p. Kaya kung type ko p at pagkatapos ko i-type ang mga halaga ng isang variable o ang pangalan ng isang variable, sabihin, argc, nakikita ko na argc ay 1. Kung gusto kong i-print ang argv [0], maaari kong gawin ito tulad na. At tulad ng nakita natin, argv [0] ay laging ang pangalan ng iyong programa, lagi ang pangalan ng executable. Narito mong makita ito ay nakuha ang buong pangalan ng landas. Ko ring i-print ang argv [1] at makita kung ano ang mangyayari. Narito namin nakuha ito uri ng mystical halaga. Nakuha namin ito 0x0. Tandaan sa simula ng termino kapag usapan natin ang tungkol sa hexadecimal numero? O na maliit na tanong sa dulo ng pset 0 tungkol sa kung paano upang kumatawan 50 sa hex? Ang paraan na isulat namin hex numero sa CS, hindi lituhin ang ating sarili may decimal na numero, ay lagi naming prefix sa kanila na may 0x. Kaya ito 0x prefix na laging lamang ibig sabihin nito ay mabibigyang-kahulugan ang mga sumusunod na bilang bilang isang hexadecimal numero, hindi bilang isang string, hindi bilang isang decimal na numero, hindi bilang isang binary numero. Dahil ang bilang 5-0 ng isang wastong numero sa hexadecimal. At ito ay isang numero sa decimal, 50. Kaya ito ay lamang kung paano namin disambiguate. Kaya 0x0 paraan hexadecimal 0, na rin decimal 0, binary 0. 0 ang halaga. Ito lumiliko out na ito ay kung ano null ay, aktwal na, sa memorya. Null ay 0. Dito, ang elemento na naka-imbak sa argv [1] ay null. Kaya kami ay sinusubukan upang ihambing ang aming "CS50 bato" na string sa isang null string. Kaya dereferencing null, sinusubukan upang ma-access ang mga bagay sa null, mga karaniwang pagpunta sa maging sanhi ng ilang mga uri ng segmentation fault o iba pang masamang mangyari. At ito ay lumiliko out na strcmp hindi suriin upang makita mo man o hindi ang pumasa sa isang halaga na null. Sa halip, ito ay napupunta magpatuloy, sinusubukan na gawin ang bagay, at kung ito seg faults, seg faults, at ito ang iyong problema. Mayroon kang pumunta ayusin ito. Talagang mabilis, kung paano namin ayusin ang problemang ito? Charlotte? [Charlotte] Maaari mong suriin ang paggamit ng kung. Kaya kung argv [1] ay null, == 0, pagkatapos ay bumalik 1, o isang bagay na [hindi maintindihan]. >> Oo. Kaya na isang mahusay na paraan upang gawin ito, tulad ng maaari naming suriin upang makita, ang halaga na hindi namin upang pumasa sa strcmp, argv [1], ito Null? Kung ito ay null, maaari naming sabihin okay, i-abort. Ang isang mas karaniwang paraan upang gawin ito ay upang gamitin ang argc halaga. Maaari mong makita dito mismo sa simula ng pangunahing, tinanggal namin na unang pagsubok na ating kadalasang kapag ginagamit namin na command argumento line, na ay upang subukan man o hindi ang aming argc ang halaga ng kung ano ang inaasahan namin. Sa kasong ito, kami ay umaasa sa hindi bababa sa dalawang argumento, ang pangalan ng programa kasama ang isang iba pa. Dahil hindi namin tungkol sa gamitin ang pangalawang argumento dito mismo. Kaya pagkakaroon ng ilang mga uri ng pagsubok muna, bago ang aming strcmp tawag na pagsubok man o hindi argv ay hindi bababa sa 2, ay ring gawin ang parehong uri ng bagay. Maaari naming makita kung na gumagana sa pamamagitan ng pagpapatakbo ng programa muli. Maaari mong palaging i-restart ang iyong programa sa loob ng GDB, na talagang magaling. Maaari kang magpatakbo ng, at kapag pumasa ka sa mga argumento sa iyong programa, pumasa ka sa mga ito sa kapag ka call magpatakbo ng, hindi kapag ikaw sipain hanggang GDB. Na paraan na maaari mong panatilihin na invoking iyong programa na may iba't ibang mga argumento sa bawat oras. Kaya tatakbo, o muli, ang maaari kong i-type ang r, at sabihin makita kung ano ang mangyayari kung namin type "hoy". Ito ay palaging hilingin sa iyo kung nais mong simulan ang mga ito muli mula sa simula. Karaniwan, mo nais upang simulan ang mga ito muli mula sa simula. At sa puntong ito, restart itong muli, mga Kopya ang ang programa na kami ay tumatakbo, buggy1, ang argumento kumusta, at mga Kopya ang pamantayang ito out, sinasabi nito, "Nakakuha ka ng D," malungkot na mukha. Ngunit hindi namin seg ng kasalanan. Sinabi ito ang proseso na lumabas normal. Kaya na mukhang medyo magandang. Wala nang seg kasalanan, ginawa namin itong nakaraan, kaya kamukha na talaga ang seg bug kasalanan namin ay nakakakuha ng. Sa kasamaang-palad, ito ay nagsasabi sa amin na kami ay pagkuha ng D. Maaari naming bumalik at tumingin sa ang code at makita kung ano ay pagpunta sa may upang malaman kung anong ay - kung bakit ito ay nagsasabi sa amin na namin Mayroon D. Natin makita, dito ay ito printf sinasabi na Mayroon D. Kung namin type ang listahan, bilang patuloy kang mag-type listahan, iniingatan nito ang-iterating sa pamamagitan ng iyong programa, kaya ito ay ipakita sa iyo ang unang ilang mga linya ng iyong programa. Pagkatapos ito ay magpapakita sa iyo ng susunod na ilang mga linya, at sa susunod na tipak at ang susunod na tipak. At ito ay patuloy na sinusubukan upang pumunta pababa. At ngayon namin sa "linya bilang 16 ay wala sa sakop." Dahil lamang ito ay may 15 linya. Kung ikaw ay makakuha sa puntong ito at ang iyong nagtataka, "Ano ang gagawin ko?" Maaari mong gamitin ang utos ng tulong. Gamitin ang tulong at pagkatapos ay bigyan ito ng pangalan ng isang command. At makikita mo ang GDB ang nagbibigay sa amin ng lahat ng ito uri ng mga bagay-bagay. Sinasabi nito, "Nang walang argument, naglilista ng sampung higit pang mga linya pagkatapos o sa buong nakaraang listahan. Listahan - naglilista ng mga sampung linya bago - " Kaya natin subukang gamit ang minus listahan. At na naglilista sa 10 linya sa nakaraang, maaari mong i-play sa paligid na may listahan ng kaunti. Maaari mong gawin ang listahan, listahan -, maaari mong kahit bigyan ilista ang isang numero, tulad ng listahan 8, at ilista ang 10 linya sa buong linya 8. At maaari mong makita kung anong nangyayari sa dito ay mayroon kang isang simpleng kung tao. Kung nagta-type ka sa CS50 bato, ng mga Kopya "Makakakuha ka ng A." Kung hindi man ito ng mga Kopya "Nakakuha ka ng D." Nakakainis bayan. Ayos lang. Oo? [Daniel] Kaya kapag sinubukan ko paggawa ng CS50 bato nang walang mga panipi, sinasabi nito na "Nakakuha ka ng D." Ko kailangan ang mga quote upang makakuha ng ito upang gumana; kung bakit ay na? >> Oo. Ito ay lumiliko out na kapag - ito ay isa pang masaya maliit na maliit na piraso - kapag nagpatakbo ka sa programa, kung nagpapatakbo namin ito at type namin sa CS50 bato, tulad lamang ng Daniel ay sinasabi ginawa niya, at pindutin ang Enter, pa rin ito nagsasabing naming makakuha ng D. At tanong ay, kung bakit ito? At ito ay lumiliko out na ang aming parehong terminal at GDB-parse ang mga ito bilang dalawang magkahiwalay na mga argumento. Dahil kapag may isang puwang, na ipinahiwatig bilang ang unang argumento natapos, sa susunod na argumento ay tungkol sa upang simulan. Ang paraan upang pagsamahin ang mga sa dalawang, o ng paumanhin, sa isang argument, ay upang gamitin ang mga quote. Sa ngayon, kung namin itong ilagay sa mga quotes at patakbuhin itong muli, makakakuha kami ng A. Kaya lang sa paglalagom, walang mga quote, CS50 at bato parse bilang dalawang magkahiwalay na mga argumento. Sa mga quote, parse bilang isang argument sa kabuuan. Maaari naming makita ang mga ito gamit ang isang breakpoint. Sa ngayon kami tumatakbo aming programa, at ito ay tumatakbo hanggang sa alinman ito seg faults o hit ng isang error o hanggang sa ito ay lumabas at lahat ng ay lubos pinong. Ito ay hindi kinakailangan ang pinaka-kapaki-pakinabang na bagay, dahil minsan mayroon kang isang error sa iyong programa, ngunit hindi ito nagdudulot ng segmentation fault. Hindi ito na nagiging sanhi ng iyong programa upang ihinto o anumang bagay tulad na. Ang paraan upang makakuha ng GDB i-pause ang iyong programa sa isang partikular na punto upang itakda ang isang breakpoint. Maaari mong gawin ito sa pamamagitan ng pagtatakda ng isang breakpoint sa isang pangalan ng function na o maaari mong itakda ang isang breakpoint sa isang partikular na linya ng code. Gusto kong magtakda ng mga breakpoints sa pangalan ng function na, dahil - madaling tandaan, at kung aktwal mong pumunta sa at baguhin ang iyong source code up ng kaunti, ang iyong breakpoint ay aktwal na manatili sa parehong lugar sa loob ng iyong code. Sapagkat kung gumagamit ka ng numero ng linya, at ang mga numero ng linya baguhin dahil kang magdagdag o magtanggal ng ilang mga code, pagkatapos ay ang iyong mga breakpoints lahat ng lubos screwed up. Isa sa mga pinaka-karaniwang mga bagay na gagawin ko ay itakda ang isang breakpoint sa pangunahing function na. Madalas makikita ko sipain hanggang GDB, makikita ko type b main, pindutin ang Enter, at na kailangan itakda ang isang breakpoint sa pangunahing function na kung saan lamang sabi, "I-pause ang programa sa lalong madaling simulan mo sa pagtakbo," at na paraan, kapag nagpatakbo ako ng aking programa sa, sabihin nating, CS50 bato sa bilang ng dalawang argumento at pindutin ang Enter, nakakakuha ng sa pangunahing function na at humihinto mismo sa unang linya, kanan bago ito sinusuri ang strcmp function na. Dahil ako naka-pause, ngayon maaari kong simulan ang mucking sa paligid at nakikita kung anong nangyayari sa sa lahat ng ibang mga variable na lumipas sa aking programa. Dito ko i-print argc at makita kung ano ang nangyayari sa. Tingnan na ang argc ay 3, sapagkat ito ay nakakuha ng 3 iba't ibang mga halaga sa loob nito. Ito ay nakuha ang pangalan ng programa, ito ay nakuha ang unang argumento at ang pangalawang argumento. Maaari naming i-print ang mga sa pamamagitan ng pagtingin sa argv [0], argv [1], at argv [2]. Kaya ngayon maaari mo ring makita kung bakit ito strcmp tawag ay pagpunta sa mabibigo, dahil nakita mo na ito ay nahati ang CS50 at ang mga bato sa dalawang magkahiwalay na mga argumento. Sa puntong ito, sa sandaling pindutin ang breakpoint, maaari mong patuloy na hakbang sa pamamagitan ng iyong programa linya sa pamamagitan ng linya, bilang kabaligtaran sa muling simulan ang iyong programa. Kaya kung hindi mo nais na upang simulan muli ang iyong programa at patuloy mula dito, maaari mong gamitin ang Magpatuloy utos at patuloy na tatakbo ang programa sa dulo. Lamang tulad ng ginawa ito dito. Gayunpaman, kung ako i-restart ang programa, CS50 bato, mga hit muli ang aking breakpoint, at oras na ito, kung hindi ko nais upang pumunta lamang ang lahat ng mga paraan sa pamamagitan ng iba pang mga bahagi ng programa, Maaari ko bang gamitin ang susunod na utos, na ako din pagpapaiksi may n. At ito ay hakbang sa pamamagitan ng linya ng programa sa pamamagitan ng linya. Sa gayon maaari mong panoorin bilang ang mga bagay execute, tulad ng variable pagbabago, tulad ng mga bagay na makapag-update. Aling ay medyo magaling. Ang iba pang mga cool na bagay ay kaysa sa paulit-ulit na ang parehong utos nang paulit-ulit at mahigit muli, kung ikaw pindutin ang Enter - kaya dito mo makita Hindi ko pa nai-type sa anumang - kung ko lang pindutin ang Enter, ulitin ang mga nakaraang utos, o sa nakaraang utos ng GDB ko lang ilagay. Maaari kong panatilihin ang pagpindot sa Ipasok at ito ang stepping sa pamamagitan ng aking code sa linya sa pamamagitan ng linya. Gusto ko hinihikayat ka guys upang pumunta tingnan ang iba pang mga programa sa maraming surot pati na rin. Wala kaming oras upang makakuha ng sa pamamagitan ng lahat ng mga ito ngayon sa seksyon. Ang source code ay doon, kaya maaari mong uri ng makita kung ano ang nangyayari sa likod ng mga eksena na kung talagang hindi ka makaalis, ngunit sa pinakadulo hindi bababa sa, magsanay booting up GDB, ang pagpapatakbo ng programa hanggang Pinaghihiwa sa iyo, pagkuha ng backtrace, ang pag-uunawa kung ano ang gumana ng pag-crash ay sa, kung ano ang linya na ito ay sa, pag-print ang ilang mga variable na halaga, lang kaya mo makakuha ng isang pakiramdam para dito, dahil na ay talagang makakatulong sa iyo pasulong. Sa puntong ito, kami ay na umalis ng GDB, kung saan mo gamit quit o q. Kung ang iyong programa ay sa gitna ng tumatakbo pa rin, at hindi ito lumabas, ito ay palaging hilingin sa iyo, "Sigurado ka bang gusto mo talagang mag-quit?" Maaari mong pindutin lamang ang oo. Ngayon kami ay upang tingnan ang susunod na problema na mayroon kami, na ang pusa programa. Kung panoorin ang maikling sa pag-redirect at pipe, makikita mo na gumagamit ng Tommy sa programang ito na talaga mga Kopya lahat ng mga output ng isang file sa screen. Kaya kung nagpatakbo ako ng pusa, ito ay talagang isang built-in na programa sa appliance, at kung mayroon kang Mac maaari mong gawin ito sa iyong Mac, kapag binuksan mo ang terminal. At hindi na namin - pusa, sabihin nating, cp.c, at pindutin ang Enter. Kung ano ang ginawa, kung mag-scroll up namin ng kaunti at makita kung saan tumakbo kami sa line, o kung saan namin tumakbo ang pusa utos, literal lamang print ang mga nilalaman ng cp.c sa aming screen. Maaari naming patakbuhin itong muli at maaari mong ilagay sa maramihang mga file nang magkasama. Sa gayon ay maaari mong gawin ang cat cp.c, at maaari rin naming pagdugtungin ang cat.c file, na programa na hindi namin na magsulat, at makikita ito i-print ang parehong mga file pabalik upang i-back sa aming screen. Kaya kung mag-scroll namin ng kaunti, nakita namin na kapag tumakbo namin ito pusa cp.c, cat.c, una itong-print ang cp file, at pagkatapos ay sa ibaba nito, naka-print ang cat.c file kanan pababa dito. Kami ay pagpunta sa gamitin ito lamang makakuha ng aming mga paa basa. I-play sa paligid na may simpleng pag-print sa terminal, makita kung paano na gumagana. Kung ikaw guys buksan up sa gedit cat.c, pindutin ang Enter, maaari mong makita ang mga programa na hindi namin tungkol sa upang magsulat. Nagsama kami ito magaling kuluan plate, kaya hindi namin upang magpalipas ng oras sa pag-type ng lahat na out. Din namin suriin ang dami ng mga argument ang pumasa. -Print namin ang gandang mensahe ng paggamit. Ito ang uri ng bagay, muli, tulad namin na pinag-uusapan, ito ay halos tulad ng kalamnan memory. Tandaan lamang upang panatilihin ang paggawa ng ang parehong uri ng mga bagay-bagay at laging pag-print ang ilang mga uri ng mga kapaki-pakinabang na mensahe kaya na alam ng mga tao kung paano patakbuhin ang iyong programa. Sa pusa, ito ay medyo simple; lang kami upang pumunta sa pamamagitan ng lahat ng ibang argumento na ang pumasa sa aming programa, at kami ay pagpunta upang i-print kanilang mga nilalaman sa screen ng paisa-isa. Upang makapagpa-print ang mga file sa screen, kami ay pagpunta sa gawin ng isang bagay na katulad na katulad sa kung ano ang ginawa namin sa dulo ng pagsusulit. Sa dulo ng pagsusulit, na umarkila programa, nagkaroon kami upang buksan ang isang file, at pagkatapos namin ay upang i-print ito. Sa kasong ito, kami ay pagpunta upang buksan ang isang file, at kami ay pagpunta upang basahin mula dito sa halip. Pagkatapos kami ay pagpunta sa print, sa halip na sa isang file, kami ay pagpunta upang i-print sa screen. Kaya pag-print sa screen lahat ng nagawa mo na bago may printf. Sa gayon ay hindi masyadong mabaliw. Ngunit sa pagbabasa ng isang file ay uri ng kakaiba. Susubukan naming pumunta sa pamamagitan ng na ang isang kaunti sa isang pagkakataon. Kung ikaw guys bumalik sa na huling problema sa iyong pagsusulit, problema 33, ang unang linya na kami ay pagpunta sa gawin dito, pagbubukas ng file, ay lubos na katulad sa kung ano ang ginawa namin doon. Kaya Stella, ano ang na linya itsura, kapag naming buksan ang isang file? [Stella] Capital FILE *, file - >> Okay. >> - Katumbas ng fopen. >> Yup. Aling sa kasong ito ay? Ito sa komento. >> Sa komento? argv [i] at r? >> Mismong. Kanan sa. Kaya Stella lubos na karapatan. Ito ay kung ano ang linya kamukha. Kami ay pagpunta upang makakuha ng isang file ng stream ng variable, iimbak ito sa isang FILE *, kaya lahat ng mga caps, FILE, *, at ang pangalan ng variable na ito ay ang file na. Kami maaaring tumawag ito anumang gusto namin. Kami maaaring tumawag ito first_file, o file_i, anumang nais naming. At pagkatapos ay ang pangalan ng file ay naipasa sa linya ng command sa program na ito. Kaya ito na naka-imbak sa argv [i,] at pagkatapos namin ay pagpunta upang buksan ang file na ito sa basahin mode. Ngayon na iyong binuksan namin ang file, ano ang bagay na lagi naming tandaan na gawin tuwing namin na binuksan ang file? Itong isara. Kaya Missy, kung paano namin isara ang isang file? [Missy] fclose (file) >> fclose (file). Eksakto. Mahusay. Okay. Kung titingnan namin sa upang gawin ang komento dito mismo, sinasabi nito, "Buksan argv [i] at i-print ang mga nilalaman nito sa stdout." Standard out ay kakaiba pangalan. Stdout ay lamang ang aming paraan ng pagsabi gusto naming upang i-print ang mga ito sa terminal, gusto naming upang i-print ang mga ito sa karaniwang output stream. Maaari namin ang aktwal na makakuha ng mapupuksa ang komentong ito dito mismo. Ako pagpunta upang kopyahin ang mga ito at i-paste ito dahil na kung ano ang ginawa namin. Sa puntong ito, ngayon ay mayroon kaming upang basahin ang mga file na unti-unti. Tinalakay namin ang ng ilang mga paraan ng pagbabasa ng mga file. Kung alin ang iyong mga paborito sa ngayon? Aling mga paraan na nakikita o mo tandaan, upang basahin ang mga file? [Daniel] fread? >> Fread? Kaya fread ay isa. Jimmy, alam mo ang anumang iba? [Jimmy] No. >> Okay. Nope. Charlotte? Alexander? Anumang iba? Okay. Kaya ang iba pang mga fgetc, na gagamitin namin ng maraming. Mayroon ding fscanf; mo guys makita ang isang pattern dito? Ang lahat ng mga ito ay nagsisimula sa f. Anumang bagay na gawin sa isang file. Mayroong fread, fgetc, fscanf. Ito ay lahat ng pagbabasa function. Para sa pagsusulat mayroon kaming fwrite, mayroon kaming fputc sa halip na fgetc. Din namin na fprintf bang nakita natin sa pagsusulit. Dahil ito ay isang problema na nagsasangkot pagbabasa mula sa isang file, kami ay gamitin ang isa sa mga tatlong function. Hindi namin ay pagpunta sa gamitin ang mga function hanggang dito. Mga function na ito ay matatagpuan sa standard I / O library. Kaya't kung tiningnan mo sa tuktok ng programang ito, maaari mong makita na isinama namin ang header na file para sa standard I / O library. Kung gusto naming malaman kung saan ang isa gusto naming gamitin, maaari naming laging buksan ang pahina ng tao. Kaya maaari naming i-type ang tao stdio at basahin ang lahat ng tungkol sa stdio input at output function sa C. At maaari namin na makita oh, hanapin. Ito ay pagbanggit fgetc, ito pagbanggit fputc. Gayon ay maaari mong mag-drill down ng kaunti at tumingin sa, sabihin nating, fgetc at tumingin sa kanyang pahina ng tao. Maaari mong makita ang na ito napupunta kasama ng buong bungkos ng iba pang mga function: fgetc, fgets, getc, getchar, ay nakakakuha, ungetc, at ang input ng mga character at mga string. Kaya ito ay kung paano basahin namin sa mga character at mga string mula sa mga file mula sa standard input, na mahalagang mula sa user. At ito ay kung paano gawin namin ito sa aktwal C. Kaya ito ay hindi gumagamit ng ang GetString at GetChar function na ginamit namin mula sa CS50 library. Kami ay pagpunta sa gawin ang problemang ito sa dalawang paraan sa gayon ay maaari mong makita ang dalawang magkaibang mga paraan ng paggawa nito. Parehong fread function na nabanggit Daniel at fgetc ang mga mahusay na paraan upang gawin ito. Tingin ko fgetc ng kaunti mas madali, dahil ito lamang ay may, tulad ng nakikita mo, isang argument, ang FILE * na sinusubukan naming basahin ang karakter mula sa, at ang ang return halaga nito ay isang int. At ito ay isang maliit na nakalilito, kanang? Dahil kami ay nakakakuha ng isang character, kaya bakit hindi ang return ito ng pansamantalang trabaho? Mong guys ay may anumang mga ideya kung bakit hindi ito maaaring magbalik ng pansamantalang trabaho? [Missy sagot, hindi maintindihan] >> Oo. Kaya Missy lubos na karapatan. Kung ito ang ASCII, integer na ito ay maaaring mai-map sa isang aktwal na pansamantalang trabaho. Maaaring maging isang ASCII na character, at na tama. Iyon ay eksakto kung ano ang nangyayari. Ginagamit namin isang int lamang dahil ito ay may higit pang mga bit. Ito ay mas malaki kaysa sa isang pansamantalang trabaho; aming magpasinda lamang ay may 8 bits, na 1 byte sa aming 32-bit na machine. At int ng lahat ng 4 bytes halaga ng puwang. At lumiliko ito na ang paraan na ang fgetc gumagana, kung mag-scroll namin sa aming buod sa pahina ang taong ito ng kaunting, mag-scroll ang lahat ng mga paraan down. Ito lumiliko out na gamitin nila ang espesyal na halaga na tinatawag na EOF. Ito ay isang espesyal na pare-pareho ang bilang ang return halaga ng mga function na ang fgetc tuwing pindutin ang dulo ng file o kung ikaw ay nakakakuha ng error. At lumiliko ito na upang gawin ang mga paghahambing na ito na may EOF maayos, gusto mo na ang dagdag na halaga ng impormasyon na mayroon ka sa isang int kumpara sa gamit ang isang pansamantalang trabaho variable. Kahit fgetc ay epektibo ng isang character mula sa isang file, nais mong tandaan na ito ay nagbabalik ng isang bagay na ng uri int sa iyo. Na sinabi, ito ay medyo madaling gamitin. Ito ay upang bigyan kami ng isang character, kaya lahat kami ay may sa gawin ay panatilihin ang pagtatanong sa ang file, "Bigyan mo ako sa susunod na character, ninyo ako sa susunod na character, ninyo ako sa susunod na character," hanggang sa makuha namin sa dulo ng file. At iyon ay hilahin sa isang character sa isang oras mula sa aming mga file, at pagkatapos ay maaari naming gawin ang anumang gusto namin dito. Maaari kaming mag-imbak ito, maaari naming idagdag ito sa isang string, maaari naming i-print ito. Gawin ang anumang ng na. Pag-zoom pabalik at pagpunta sa aming cat.c programa, kung kami ay pagpunta sa gamitin fgetc, kung paano namin lapitan ang susunod na linya ng code? Kami ay pagpunta sa gamitin - fread gawin ang isang bagay na bahagyang naiiba. At oras na ito, lamang kami ay upang gamitin ang fgetc upang makakuha ng isang character sa isang pagkakataon. Upang maproseso ang isang buong file, kung ano ang maaari naming gawin? Gaano karaming mga character ay sa isang file? Mayroong maraming isang. Kaya marahil ay gusto mo upang makakuha ng isa at pagkatapos ay makakuha ng isa at makakuha ng isa at makakuha ng isa. Anong uri ng mga algorithm tingin mo maaaring namin upang gamitin dito? Anong uri ng -? [Alexander] A para sa loop? >> Mismong. Ang ilang mga uri ng loop. A para sa loop ay talagang mahusay, sa kasong ito. At tulad ng ikaw ay sinasabi, ito tunog tulad ng gusto mo ng loop sa ibabaw ng buong file, ng isang character sa isang pagkakataon. Anumang mga mungkahi sa kung ano na maaaring magmukhang? [Alexander, hindi maintindihan] >> Okay, lamang sabihin sa akin sa Ingles kung ano ang iyong sinusubukang gawin? [Alexander, hindi maintindihan] Kaya sa kasong ito, ito tunog tulad lamang sinusubukan namin sa loop sa buong file. [Alexander] Kaya i > Ang laki ng -? Hulaan ko ang laki ng file, i-right? Ang laki - we'll magsulat lamang ito tulad nito. Laki ng file para sa oras, i + +. Kaya ito lumiliko na ang paraan mo ito gamit fgetc, at ito ay bagong, ay na mayroong walang madaling paraan upang makuha ang laki ng isang file na may ganitong uri ng "sizeof" bumuo na nakita mo bago. Kapag ginagamit namin na fgetc function na, ipinapakilala namin ang ilang mga uri ng bagong, funky na syntax na ito para sa loop, kung saan sa halip ng paggamit lamang ng isang pangunahing counter pumunta karakter sa pamamagitan ng karakter, kami ay pagpunta sa pull isang character sa isang pagkakataon, isang character sa isang pagkakataon, at ang paraan na alam namin na hindi namin sa dulo hindi kapag namin ang binibilang ng isang tiyak na bilang ng mga character, ngunit kapag ang mga character na hilahin namin ang ay na espesyal na dulo ng file na character. Upang maaari naming gawin ito sa pamamagitan ng - tawagan ko ito ch, at kami ay pagpunta sa initialize ito sa aming unang tawag upang makuha ang unang character ng file. Kaya ito bahagi dito mismo, ito ay upang makakuha ng isang character ng file at mag-imbak ang mga ito sa variable ch. Kami ay pagpunta sa patuloy na paggawa nito hanggang sa makuha namin sa dulo ng file, na aming ginagawa sa pamamagitan ng pagsubok para sa character na hindi katumbas na espesyal na character EOF. At pagkatapos ay sa halip ng paggawa ch + +, na nais lamang dagdagan ang halaga, kaya kung binabasa namin ang A ng file, kabisera A, sabihin, ch + + ay bigyan kami ng b, at gusto namin c at pagkatapos d. Iyon ay malinaw na hindi kung ano ang gusto namin. Ano ang gusto namin dito sa huling sandali ay gusto naming makuha ang susunod na character mula sa file. Kaya kung paano namin makuha ang susunod na character mula sa file? Paano kami makakuha ng unang character mula sa file? [Mag-aaral] fgetfile? >> Fgetc, o, paumanhin, ay lubos na karapatan. Maling nabaybay ko ito doon. Kaya oo. Dito sa halip ng paggawa ch + +, lang kami tawagan fgetc (file) muli at mag-imbak ang mga resulta sa aming parehong variable ch. [Estudyante tanong, hindi maintindihan] >> Ito ay kung saan ang mga FILE * guys mga espesyal na. Ang paraan na gumagana ang mga iyon sila - noong una mong buksan - noong una mong gumawa na fopen tawag, ang FILE * epektibo nagsisilbing bilang isang pointer sa simula ng file. At pagkatapos ay sa bawat oras na tawagan ka fgetc, gumagalaw isang character sa pamamagitan ng file. Kaya kapag Tinatawag mo ito, ikaw ay ng incrementing ang file pointer sa pamamagitan ng isang character. At kapag fgetc ka muli, ikaw ay gumagalaw ito sa isa pang character na at ibang character at ibang character at isa pang character na. [Estudyante tanong, hindi maintindihan] >> At that's - oo. Ito ay uri ng magic na ito sa ilalim ng hood. Mo lamang panatilihin ang incrementing sa pamamagitan ng. Sa puntong ito, hindi mo aktwal na gumagana sa isang character. Kaya kung paano namin i-print ito sa screen, ngayon? Maaari naming gamitin ang parehong printf bagay na ginamit namin bago. Na ginagamit namin ang lahat ng semestre. Maaari naming tawagan printf, at maaari naming pumasa sa ang mga character na katulad nito. Ang isa pang paraan upang gawin ito ay sa halip na gamitin ang printf at upang gawin ito format string, Maaari rin naming gamitin ang isa sa mga iba pang mga function. Maaari naming gamitin ang fputc, na mga Kopya ng character sa screen, maliban kung tinitingnan namin ang fputc - hayaan mo akong mag-zoom out ng kaunti. Nakikita namin kung ano ang magaling ay tumatagal sa karakter na binabasa namin ang paggamit ng fgetc, ngunit pagkatapos ay mayroon kaming upang bigyan ito ng isang stream upang i-print. Maaari din naming gamitin ang putchar function, na kung saan ay ilagay direkta sa pamantayan out. Kaya may isang buong grupo ng mga iba't ibang mga pagpipilian na maaari naming gamitin para sa pag-print. Ang mga ito ay lahat sa standard I / O library. Kahit kailan mo gusto upang i-print - kaya printf, sa pamamagitan ng default, ang mag-print sa espesyal na pamantayan out stream, na stdout na. Upang maaari naming lamang sumangguni sa ito bilang uri ng ito magic na halaga, stdout in dito. Oops. Ilagay ang semicolon sa labas. Ito ay isang maraming bagong, funky impormasyon sa dito. Isang maraming ng mga ito ay masyadong pansalitain, sa kamalayan na ito ay code na nakasulat sa ganitong paraan dahil lang sa ito ang malinis na basahin, madaling basahin. Mayroong maraming iba't ibang mga paraan upang gawin ito, maraming iba't ibang mga function na maaari mong gamitin, ngunit may posibilidad namin upang sundin lamang ang mga parehong pattern ng paulit-ulit. Kaya huwag magulat kung makakita ka ng code tulad nito paparating na muli at muli. Ayos lang. Sa puntong ito, kailangan naming buksan para sa araw. Salamat para sa darating na. Salamat para sa panonood kung online ka. At kami na nakikita mo sa susunod na linggo. [CS50.TV]