[Powered by Google Translate] [Seksyon 4 - Higit kumportableng] [Rob Bowden - Harvard University] [Ito ay CS50. - CS50.TV] Mayroon kaming pagsusulit bukas, kung sakaling guys ay hindi alam na. Ito ay isa lamang sa lahat ng maaari mong nakikita sa klase o dapat na nakikita sa klase. Na kinabibilangan ng payo, kahit na nasa kamakailang mga paksa. Dapat mong hindi bababa sa maunawaan ang mga mataas na antas ng mga ito. Anumang bagay na nawala sa klase dapat mong maunawaan para sa pagsusulit. Kaya kung mayroon kang mga tanong sa kanila, maaari mong hilingin ang mga ito ngayon. Ngunit ito ay pagpunta sa isang napaka mag-aaral-LED session kung saan mo guys magtanong, kaya sana ang mga tao ay may mga katanungan. Ba ang sinuman may mga katanungan? Oo. >> [Mag-aaral] Maaari kang pumunta sa paglipas ng payo muli? Kukunin ko na pumunta sa paglipas ng payo. Ang lahat ng iyong mga variable kinakailangang mabuhay sa memory, ngunit karaniwang hindi mo mag-alala tungkol sa at sabihin mo lang x + 2 at y + 3 at ang tagatala ay malaman kung saan ang mga bagay ay naninirahan para sa iyo. Kapag ikaw ay pagharap sa mga payo, ngayon tahasang gumagamit ka ng mga address memory. Kaya ng isang variable ay lamang kailanman nakatira sa isang solong address sa anumang naibigay na oras. Kung gusto naming upang idedeklara ng pointer, kung ano ang uri ng pagpunta sa hitsura? Gusto kong idedeklara ng pointer p. Ano ang uri ng hitsura? [Mag-aaral] int * p. >> Oo. Kaya int * p. At paano ko ituro ito sa x? >> [Mag-aaral] Ampersand. [Bowden] Kaya ampersand Literal na tinatawag na ang address ng operator. Kaya kapag sinabi ko at x nakakakuha ito ng memory address ng variable x. Kaya ngayon mayroon akong ang pointer p, at kahit saan sa aking code Maaari ko bang gamitin ang * p o maaari ko bang gamitin ang x at ito ay ang eksaktong parehong bagay. (* P). Ano ito ginagawa? Ano ang bituin na ibig sabihin nito? [Mag-aaral] Ito ay nangangahulugan na ang isang halaga sa puntong iyon. >> Oo. Kaya't kung tiningnan namin ito, maaari itong maging lubhang kapaki-pakinabang upang gumuhit ang diagram kung saan ito ay isang maliit na kahon ng memory para sa x, na ang mangyayari sa ang halaga 4, pagkatapos kami ay may isang maliit na kahon ng memory para sa p, at upang p puntos sa x, kaya namin gumuhit ng isang arrow mula p sa x. Kaya kapag sinabi namin * p namin sinasabi na pumunta sa kahon na p. Star ay sundin ang mga arrow at pagkatapos ay anumang nais mo na may na kahon doon. Sa gayon ay maaari kong sabihin * p = 7; at iyon ay pumunta sa kahon na x at pagbabago na sa 7. O maaari ba akong sabihin int z = * p * 2; Iyon ang nakakalito dahil ito ay star, star. Ang isang bituin ay dereferencing p, ang iba pang mga bituin ay multiply ng 2. Mapansin maaari ba akong magkaroon lamang pati na rin pinalitan ang * p may x. Maaari mong gamitin ang mga ito sa parehong paraan. At pagkatapos mamaya sa ko maaaring magkaroon p punto sa isang ganap na bagong bagay. Maaari ko lang sabihin p = &z; Kaya ngayon p hindi na punto upang x; punto upang z. At anumang oras gagawin ko * p katulad ng ginagawa z. Kaya ang kapaki-pakinabang na bagay tungkol sa sandaling sinimulan namin ang pagkuha sa function. Ito ay uri ng walang kaukulan na idedeklara ng pointer na tumuturo sa isang bagay at pagkatapos ka dereferencing ito kapag ginamit mo ang orihinal na variable upang magsimula sa. Ngunit kapag nakakuha ka sa mga function - kaya sabihin nating mayroon kaming ilang function, int foo, na tumatagal ng pointer at ginagawa lang * p = 6; Tulad ng nakita namin bago may makipagpalitan, hindi mo maaaring gawin ng isang epektibong makipagpalitan at isang hiwalay na function na sa pamamagitan ng lamang pagpasa mga integer dahil ang lahat sa C ay palaging pagpasa sa pamamagitan ng halaga. Kahit na kapag ikaw ay pagpasa ng mga payo ka pagpasa sa pamamagitan ng halaga. Ito lang kaya mangyayari ang mga halaga ay ang mga address ng memorya. Kaya kapag sinabi ko foo (p); ako pagpasa sa pointer sa katangian ng foo at pagkatapos foo ginagawa * p = 6; Kaya sa loob ng function na iyon, * p pa rin ang katumbas sa x, ngunit hindi ako maaaring gumamit ng x sa loob ng na function na dahil hindi ito scoped loob na function na. Kaya * p = 6 ay ang tanging paraan na maaari kong ma-access ang isang lokal na variable mula sa isa pang function na. O, mahusay, ang mga payo ay ang tanging paraan na maaari kong ma-access ang isang lokal na variable mula sa isa pang function na. [Mag-aaral] sabihin nating na nais mo upang ibalik ang isang pointer. Paano eksaktong gawin iyon? [Bowden] Bumalik ng pointer sa isang bagay tulad ng int y = 3; return & ya? >> [Mag-aaral] Oo. [Bowden] Okay. Hindi mo dapat gawin ito. Ito ay masama. Tingin ko Nakita ko sa mga slide ng panayam Sinimulan mo nakikita ang buong diagram ng memory kung saan up dito mayroon kang memory address 0 at pababa dito mayroon kang address ng memorya 4 gig o 2 sa 32. Kaya pagkatapos ay mayroon kang ilang mga bagay-bagay at ilang mga bagay-bagay at pagkatapos ay ang iyong stack at mayroon ka iyong magbunton, kung saan mo lamang makapagsimula sa pag-aaral tungkol sa, lumalaking up. [Mag-aaral] Ay hindi ang magbunton sa itaas ng stack? Oo. Magbunton sa itaas, hindi ito? >> [Mag-aaral] Well, ilagay siya ng 0 sa itaas. [Mag-aaral] Oh, siya ilagay 0 sa tuktok. >> [Mag-aaral] Oh, okay. Disclaimer: Saanman may CS50 ka pagpunta upang makita ito sa ganitong paraan. >> [Mag-aaral] Okay. Lang na kapag unang nakakakita ka ng mga stack, bang kapag sa tingin mo ng isang stack na sa tingin mo ng stacking ng mga bagay sa tuktok ng isa't isa. Kaya malamang namin upang i-flip ito sa paligid upang stack ay lumalaking tulad ng stack ng karaniwan mong ginagawa sa halip ng stack lawit. >> [Mag-aaral] Huwag tambak technically lumaki masyadong, bagaman? Depende sa kung ano ang ibig sabihin sa iyo sa pamamagitan ng lumaki. Ang stack at magbunton palaging paglaki sa mga tapat na mga direksyon. Stack ay palaging lumalagong sa kamalayan na ito lumalagong up patungo sa mas mataas na memory address, at ang magbunton ay lumalaking pababa na ito lumalaking patungo sa mas mababang address memory. Kaya itaas ay 0 at ibaba ang mataas na memory address. Sila ay parehong lumalagong, lamang sa paghadlang direksyon. [Mag-aaral] ko lang nilalayong na dahil sinabi mo inilagay mo stack sa ibaba dahil mukhang mas madaling maunawaan dahil para sa stack sa magsimula sa tuktok ng magbunton, magbunton sa tuktok ng mismong masyadong, kaya that's - >> Oo. Mo ring tingin ng magbunton bilang lumalaking up at mas malaki, ngunit ang stack mas kaya. Kaya ang stack namin uri ng nais na ipakita ang lumalaking up. Ngunit lahat ng dako titingnan mo kung hindi man ay upang ipakita ang address 0 sa tuktok at ang pinakamataas na memory address sa ibaba, kaya ito ay ang iyong karaniwang view ng memorya. Mayroon ba kayong isang tanong? [Mag-aaral] Maaari mo bang sabihin sa amin ang higit pa tungkol sa magbunton? Oo. Ako makakakuha ng sa isang segundo. Una, ang pagpunta pabalik sa kung bakit bumabalik at y ay isang masamang bagay, sa stack mayroon ka ng isang bungkos ng mga frame stack na kumakatawan sa lahat ng mga pag-andar na tinatawag. Kaya sa pagbalewala sa ng mga nakaraang mga bagay, sa tuktok ng iyong stack ay palaging na ang pangunahing function na dahil na unang function na tinatawag. At pagkatapos ay kapag tumawag ka ng isa pang function na, stack ang binabalak na palaguin ang. Kaya kung tumawag ako ng ilang function, foo, at ito ay nakakakuha ng sarili nitong stack frame, maaari itong tumawag ilang function, bar, ito ay nakakakuha ng sarili nitong stack frame. At bar ay maaaring recursive at maaaring tumawag mismo, at sa gayon ay ang pangalawang tawag sa bar upang makakuha ng sarili nitong stack frame. At kaya kung ano ang napupunta sa mga frame ng stack ang lahat ng lokal na mga variable at ang lahat ng mga argumento ng function na na - Anumang bagay na lokal scoped na ito function na pumunta sa mga frame ng stack. Kaya nangangahulugan iyon na kapag sinabi ko ang isang bagay tulad ng bar ay isang function, Lang ako na idedeklara ang isang integer at pagkatapos ay ibalik ang isang pointer na integer. Kaya kung saan ay y nakatira? [Mag-aaral] y nakatira sa bar. >> [Bowden] Oo. Sa isang lugar sa maliit na plaza ng memorya ay isang littler parisukat na may y sa loob nito. Kapag bumalik ako & y, ako bumabalik ng pointer sa maliit na bloke ng memorya. Ngunit kapag ang isang function babalik, ang stack frame ay makakakuha ng pop-off ang stack ang. At iyon ang dahilan kung bakit ito ay tinatawag na stack. Ito ay tulad ng istraktura ng data ng stack, kung alam mo kung ano na. O kahit na tulad ng isang stack ng mga trays ay laging Halimbawa, pangunahing ay upang pumunta sa ibaba, pagkatapos ay ang unang function na tawagan ka upang pumunta sa tuktok ng na, at hindi ka maaaring makakuha ng pabalik sa pangunahing hanggang sa bumalik ka mula sa lahat ng mga function na ay tinatawag na na nakalagay sa itaas nito. [Mag-aaral] Kaya kung ginawa mo ibalik ang & ya, ang halaga na ay sakop upang baguhin nang walang abiso. Oo, it's - >> [mag-aaral] Maaaring ito ay mapapatungan. >> Oo. Ito ay ganap - Kung sinubukan mong at - Ito ay isang int * bar dahil ito ay nagbabalik ng isang pointer, kaya ang kanyang return uri int *. Kung sinusubukan mong gamitin ang return halaga ng mga function na ito, ito ay hindi natukoy na pag-uugali dahil ang pointer na mga punto sa masamang memory. >> [Mag-aaral] Okay. Kaya kung ano kung, halimbawa, ipinahayag int * y = malloc (sizeof (int))? Iyon ay mas mahusay. Oo. [Mag-aaral] uusapang namin tungkol sa kung paano kapag namin i-drag ang mga bagay sa aming recycle bin hindi sila aktwal na mabubura; lang namin mawala ang kanilang mga payo. Kaya sa kasong ito namin aktwal burahin ang halaga o ito pa rin doon sa memory? Para sa nakararaming bahagi, ito pa rin doon. Ngunit sabihin nating namin mangyari sa tumawag sa ilang iba pang mga function, baz. Baz ay pagpunta upang makakuha ng sarili nitong stack frame sa dito. Ito na Sasapawan nito ang lahat ng ito bagay, at pagkatapos ay kung ikaw mamaya subukan at gamitin ang pointer na ba kayong bago, hindi ito pagpunta sa parehong halaga. Ito ay pagpunta sa ay nagbago dahil ikaw lamang tinatawag na pag-andar baz. [Mag-aaral] Ngunit ay hindi namin, pa rin namin makakuha ng 3? [Bowden] Sa lahat ng posibilidad, gagawin mo. Ngunit hindi ka maaaring umasa sa na. Sabi lang ng C hindi natukoy na pag-uugali. [Mag-aaral] Oh, ginagawa nito. Okay. Kaya kapag gusto mong ibalik ang isang pointer, ito ay kung saan malloc ay ginagamit. Sumulat ako aktwal na lamang bumalik malloc (3 * sizeof (int)). Susubukan naming pumunta sa paglipas ng malloc higit pa sa isang segundo, ngunit ang ideya ng malloc ay sa lahat ng iyong lokal na variable laging pumunta sa stack. Anumang bagay na malloced napupunta sa magbunton, at ito magpakailanman at palaging sa magbunton hanggang sa tahasan mong magbakante ito. Kaya ito ay nangangahulugan na kapag malloc ka ng isang bagay, ito ay upang mabuhay matapos ang return ng function na. [Mag-aaral] ito nakataguyod makalipas ang pagkatapos Humihinto ang programa tumatakbo? >> No. Okay, kaya ang nangyayari doon hanggang ang programa ay tapos na ang lahat ng paraan sa pagtakbo. >> Oo. Maaari naming pumunta sa paglipas ng mga detalye ng kung ano ang mangyayari kapag Humihinto ang programa tumatakbo. Maaaring kailanganin mong ipaalala sa akin, ngunit iyon ay isang hiwalay na bagay. [Mag-aaral] Kaya malloc lumilikha ng pointer? >> Oo. Malloc - >> [mag-aaral] tingin ko malloc designates isang bloke ng memorya na ang pointer ng maaaring gamitin. [Bowden] gusto ko na diagram muli. >> [Mag-aaral] Kaya gumagana ang function na ito, bagaman? [Mag-aaral] Oo, malloc designates isang bloke ng memorya na maaari mong gamitin, at pagkatapos ay nagbalik ang address ng unang bloke ng memorya na. [Bowden] Oo. Kaya kapag ikaw malloc, ka daklot ilang bloke ng memorya na kasalukuyang sa magbunton. Kung ang magbunton ay masyadong maliit, magbunton ang lamang pagpunta upang lumago, at ito ay lumalaki sa direksyon. Kaya sabihin nating magbunton ay masyadong maliit. Pagkatapos ito ay tungkol sa upang mapalago ang ilang sandali at magbalik ng pointer sa block na ito na lamang lumago. Kapag ikaw libreng mga bagay-bagay, nagsasagawa ka ng higit pang mga kuwarto sa magbunton, kaya pagkatapos ng mamaya tumawag sa malloc maaaring muling gamitin na memory na dati mo ay napalaya. Ang mahalagang bagay tungkol sa malloc at libreng na ito ay nagbibigay sa iyo ng kumpletong kontrol sa ibabaw ng buhay ng mga bloke ng memorya. Pangkalahatang variable ay palaging buhay. Lokal na mga variable ay buhay sa loob ng kanilang mga saklaw. Sa lalong madaling pumunta nakaraang isang kulot suhay, ang mga lokal na variable ay patay. Malloced memory ay buhay kapag gusto mo ito sa buhay at pagkatapos ay inilabas kapag ikaw ay sabihin dito ay ilalabas. Yaong mga aktwal na lamang ang 3 uri ng memorya, talagang. May awtomatikong memory pamamahala, na kung saan ay ang stack. Mga bagay-bagay mangyari para sa iyo awtomatikong. Kapag sinabi mong int x, memory ay inilaan para sa mga int x. Kapag pupunta ng x ng saklaw, memory ay reclaim para sa x. Pagkatapos may dynamic memory pamamahala, na kung ano ang malloc ay, na kapag mayroon kang kontrol. Dynamic kang magpasya kapag memory dapat at hindi dapat na inilalaan. At pagkatapos ay may static, kung saan ay nangangahulugan lamang na ito nakatira magpakailanman, na kung ano ang pangkalahatang variable. Hindi lang nila palagi sa memory. Mga tanong? [Mag-aaral] Maaari mong tukuyin ang isang bloke lamang sa pamamagitan ng paggamit ng mga kulot tirante ngunit hindi kinakailangang magkaroon ng isang kung statement o habang pahayag o anumang bagay tulad na? Maaari mong tukuyin ang isang bloke sa isang function, ngunit na may kulot tirante masyadong. [Mag-aaral] Kaya hindi lamang mo maaaring magkaroon ng tulad ng isang random na pares ng mga kulot tirante sa iyong code na may lokal na mga variable? >> Oo, maaari mong. Inside ng int bar kami {int y = 3;}. Na dapat dito mismo. Ngunit ganap na tumutukoy sa saklaw ng int y. Pagkatapos na pangalawang kulot suhay, y hindi maaaring gamitin ito. Mo halos hindi kailanman gawin iyon, bagaman. Pagbalik sa kung ano ang mangyayari kapag nagtatapos ang isang programa, may uri ng isang maling kuru-kuro / kalahati kasinungalingan na bigyan kami upang lamang gumawa ng mga bagay madali. Sabihin namin sa iyo na kapag maglaan ka ng memory ka paglaan ng ilang tipak ng RAM para sa variable na. Ngunit hindi ka talagang direkta pagpindot RAM kailanman sa iyong mga programa. Kung sa tingin mo nito, kung paano ko ginamit - At aktwal na, kung pumunta ka sa pamamagitan ng sa GDB makikita mo makita ang mga parehong bagay. Hindi alintana kung gaano karaming beses patakbuhin mo ang iyong programa o kung ano ang program nagpapatakbo ka, stack ay palaging pagpunta upang magsimula - Palagi ka upang makita ang mga variable sa paligid address oxbffff isang bagay. Ito ay karaniwang isang lugar sa rehiyon na iyon. Ngunit paano 2 programa posibleng may mga payo sa parehong memorya? [Mag-aaral] May ilang arbitrary pagtatalaga ng kung saan oxbfff ay dapat sa RAM na maaaring tunay na sa iba't-ibang lugar depende sa kapag ang function ay tinatawag na. Oo. Termino virtual memory. Ang ideya ay na ang bawat solong proseso, ang bawat solong programa na tumatakbo sa iyong computer ay may sariling - sabihin ipinapalagay 32 bit - ganap na malayang address espasyo. Ito ang address na espasyo. Ay may sarili nitong ganap na independiyenteng 4 gigabytes upang gamitin. Kaya kung nagpapatakbo ka ng 2 programa nang sabay-sabay, programang ito ay nakikita ng 4 gigabytes sa sarili nito, Ang programang ito ay nakikita ng 4 gigabytes sa sarili nito, at ito ay imposible para sa programang ito sa dereference ng pointer at nagtatapos sa memorya mula sa programang ito. At kung ano ang virtual memory ay pagmamapa mula sa isang proseso ng address ng espasyo sa aktwal na bagay sa RAM. Kaya hanggang sa iyong operating system upang malaman na, hey, kapag ito tao oxbfff dereferences pointer, na talagang ay nangangahulugan na siya gustong RAM byte 1000, samantalang kung sa programang ito oxbfff dereferences, siya talaga gustong RAM byte 10000. Maaari silang mang malayo. Ito ay totoo kahit ng mga bagay sa loob ng isang proseso ng address ng espasyo. Kaya tulad ng nakikita ang lahat ng 4 gigabytes sa sarili nito, ngunit sabihin nating - [Mag-aaral] Gumagana ba bawat solong proseso - Sabihin nating mayroon kang isang computer na may 4 gigabytes lamang ng RAM. Ba ang bawat solong proseso makita ang buong 4 gigabytes? >> Oo. Ngunit ang 4 gigabytes ito nakikita ay isang kasinungalingan. Lamang ito sa tingin nito ay ito ay ang lahat ng ito memory dahil hindi nito malalaman anumang iba pang mga proseso umiiral. Ito ay lamang gamitin ng mas maraming memory bilang aktwal na ito ay kailangang. Ang operating system ay hindi upang bigyan ng RAM sa prosesong ito kung hindi pa ito gamit ang anumang memory sa buong rehiyon na ito. Hindi ito upang bigyan ito ng memory para sa rehiyon na iyon. Ngunit ang ideya ay na - ako sinusubukang mag-isip ng - Hindi ako makapag-isip ng isang pagkakatulad. Analogies ay mahirap. Isa ng ang mga isyu ng virtual memory o isa ng mga bagay na ito paglutas ay ang proseso ay dapat na ganap na alam ng isa't isa. At sa gayon ay maaari mong magsulat ng anumang programa na lamang dereferences anumang pointer, gusto magsulat lamang ng programa na nagsasabing * (ox1234), at iyon ang dereferencing memory address 1234. Subalit hanggang sa operating system pagkatapos isalin ang mga kung ano ang 1234 ay nangangahulugan. Kaya kung 1234 ang mangyayari na maging isang wastong address ng memory para sa prosesong ito, tulad ng ito ay sa stack o isang bagay, pagkatapos ito ay ibalik ang halaga ng memorya na address kasing layo ng proseso alam. Ngunit kung 1234 ay hindi isang wastong address, tulad ng mangyayari para mapunta sa ilang maliit na bahagi ng memory dito na higit sa stack at higit sa magbunton at hindi mo talagang ginagamit na, pagkatapos na kapag ikaw ay makakuha ng mga bagay tulad ng segfaults dahil ka pagpindot ng memorya na hindi mo dapat na nakadikit. Totoo rin ito - Ang isang 32-bit na sistema, 32 bit nangangahulugan na mayroon kang 32 bit upang tukuyin ang isang address ng memorya. Ito ay kung bakit ang mga payo ay 8 bytes dahil 32 bit 8 bytes - o 4 bytes. Payo 4 bytes. Kaya kapag nakita mo ang isang pointer tulad oxbfffff, na - Sa loob ng anumang ibinigay na programa, maaari mo lamang bumuo ng iba pang arbitrary pointer, kahit saan mula ox0 sa baka 8 f's - ffffffff. [Mag-aaral] ba Hindi sinabi mong sila 4 bytes? >> Oo. [Mag-aaral] Pagkatapos byte bawat isa ay may - >> [Bowden] hexadecimal. Hexadecimal - 5, 6, 7, 8. Kaya payo ka laging makita sa hexadecimal. Lang kung paano namin uri-uriin ang mga payo. Bawat 2 digit ng hexadecimal ay 1 byte. Kaya mayroong 8 hexadecimal digit para sa 4 bytes. Kaya ang bawat isang pointer sa isang 32-bit na sistema ay pagpunta sa 4 bytes, na nangangahulugan na sa iyong proseso maaari kang bumuo ng anumang arbitrary 4 bytes at gumawa ng isang pointer nito, na nangangahulugan na ang bilang malayo bilang ito ang kamalayan, maaari itong matugunan ang isang buong 2 sa 32 bytes ng memorya. Kahit na ito ay hindi talagang magkaroon ng access sa, kahit na kung ang iyong computer lamang ay may 512 megabytes, sa tingin nito ay may ganoong karaming memory. At operating system na smart sapat na ito lamang magtalaga ng kung ano ang iyong aktwal na kailangan. Hindi ito pumunta lamang, oh, isang bagong proseso: 4 gig. Oo. >> [Mag-aaral] Ano ang ginagawa ng baka ang ibig sabihin nito? Bakit ka magsulat ang mga ito? Ito ay ang simbolo para sa hexadecimal. Kapag nakita mo ang isang numero ng panimula sa baka, ang mga sunud-sunod na mga bagay ay hexadecimal. [Mag-aaral] ay nagpapaliwanag tungkol sa kung ano ang mangyayari kapag nagtatapos ang isang programa. >> Oo. Ano ang mangyayari kapag nagtatapos ang isang programa ang operating system lamang Buburahin sa pagmamapa na ito para sa mga address na ito, at na ito. Ang operating system ay maaari na ngayong lamang bigyan na memory sa ibang program ang gagamitin. [Mag-aaral] Okay. Kaya kapag maglaan ka ng isang bagay sa magbunton o ang stack o pangkalahatang variable o anumang, lahat sila lamang mawala sa lalong madaling ang programa ay nagtatapos dahil ang operating system na ngayon ang libreng upang bigyan na memory sa anumang iba pang mga proseso. [Mag-aaral] Kahit na ay marahil pa rin halaga na nakasulat sa? >> Oo. Ang mga halaga ay malamang pa rin doon. Lamang ito ito ay mahirap upang makakuha ng sa kanila. Ito ay mas mahirap upang makakuha ng sa kanila kaysa ito ay upang makakuha ng sa isang tinanggal na file dahil ang tinanggal na file ng uri ng makikita doon para sa isang mahabang panahon at hard drive ng maraming mas malaking. Kaya patungan ang mga iba't-ibang bahagi ng memorya bago ito mangyayari patungan ang mga tipak ng memorya na file na ginagamit sa. Ngunit ang pangunahing memorya, RAM, umikot sa pamamagitan ng maraming mas mabilis, kaya napaka mabilis na-o-overwrite. Mga tanong na ito o anumang bagay? [Mag-aaral] Mayroon akong tanong tungkol sa isang iba't ibang mga paksa. >> Okay. Ba ang sinuman tanong na ito? Okay. Iba't ibang paksa. >> [Mag-aaral] Okay. Ako pagpunta sa pamamagitan ng ilang ng ang mga pagsubok ng kasanayan, at sa isa sa mga ito ay pakikipag-usap tungkol sa sizeof at ang halaga na ito ay nagbabalik o ibang mga variable na uri. >> Oo. At sinabi na parehong int at mahabang parehong return 4, kaya sila parehong 4 bytes mahaba. Mayroon bang anumang pagkakaiba sa pagitan ng isang int at isang mahabang, o ito ang parehong bagay? Oo, ang isang pagkakaiba. Ang C standard - Marahil ako pagpunta sa gulo up. Ang C karaniwang ay tulad lamang ng kung ano ang C ay, ang opisyal na dokumentasyon ng C. Ito ay kung ano ang nakasulat. Kaya ang C sabi lang ng standard na ang isang pansamantalang trabaho ay magpakailanman at laging 1 byte. Lahat pagkatapos na - isang maikling ay laging lamang tinukoy bilang mas malaki kaysa sa o katumbas sa isang pansamantalang trabaho. Maaaring ito ay mahigpit na mas malaki kaysa sa, ngunit hindi positibo. Int isang tinukoy bilang mas malaki kaysa sa o katumbas sa isang maikling. At ng mahabang ay lamang tinukoy bilang mas malaki kaysa sa o katumbas sa isang int. At isang mahaba mahaba ay mas malaki kaysa sa o katumbas sa isang mahabang. Kaya ang tanging bagay na ang C karaniwang tumutukoy ang mga kamag-anak na pagkakasunud-sunod ng lahat. Ang aktwal na halaga ng memorya na bagay tumagal ng hanggang sa pangkalahatan hanggang sa pagpapatupad, ngunit ito medyo mahusay na tinukoy sa puntong ito. >> [Mag-aaral] Okay. Kaya shorts ay halos palaging pagpunta sa 2 bytes. Ints ay halos palaging pagpunta sa 4 bytes. Long longs halos palaging pagpunta sa 8 bytes. At longs, ito ay depende sa kung gumagamit ka ng isang 32-bit o 64-bit system. Kaya isang mahabang tumutugma sa uri ng sistema. Kung gumagamit ka ng isang 32-bit na system tulad ng sa Appliance, ito na 4 bytes. Kung gumagamit ka ng 64-bit na tulad ng maraming kamakailang mga computer, ito ay pagpunta sa 8 bytes. Ints ay halos palaging 4 na bytes sa puntong ito. Long longs halos palaging 8 bytes. Sa nakaraan, ang mga ints ginamit lamang 2 bytes. Ngunit mapansin na ito ay ganap na natutugunan ang lahat ng mga relasyon na ito na mas malaki kaysa sa at pantay-pantay sa. Kaya mahaba ang perpektong pinapayagan ang parehong laki bilang isang integer, at din ito pinapayagan na ang parehong laki bilang isang mahabang mahaba. At ito lamang kaya ang mangyayari sa 99.999% ng system, ito ay katumbas ng alinman sa isang int o ng mahabang mahaba. Ito lamang ay depende sa 32-bit o 64-bit. >> [Mag-aaral] Okay. Sa kamay, kung paano ang decimal point na itinalaga sa mga tuntunin ng bit? Gusto bilang binary? >> Oo. Hindi mo na kailangang malaman na para sa CS50. Hindi mo na matuto na sa 61. Hindi ka matuto na talagang sa anumang kurso. Ito ay isang representasyon. Nakalimutan ko ang eksaktong bit allotments. Ang ideya ng lumulutang point na maglaan ka ng isang tiyak na bilang ng mga bits upang kumatawan - Talaga, ang lahat ay sa pagtatandang siyentipiko. Kaya maglaan ka ng isang tiyak na bilang ng mga bits kumakatawan sa bilang mismo, tulad ng 1.2345. Hindi ko maaaring kumakatawan sa isang numero na may higit pang mga digit sa 5. Pagkatapos ka ring magtalaga ng isang tiyak na bilang ng mga bits upang ito ay may kaugaliang tulad ng maaari ka lamang pumunta up sa isang tiyak na numero, tulad na ang pinakamalaking exponent maaari kang magkaroon ng, at maaari ka lamang pumunta down sa isang tiyak na exponent, gusto na ang pinakamaliit na exponent maaari kang magkaroon ng. Hindi ko matandaan ang eksaktong paraan bits ay itinalaga sa lahat ng mga halagang ito, ngunit ang isang tiyak na bilang ng mga bits ay nakatuon sa 1.2345, isa pang tiyak na bilang ng mga bits ay nakatuon sa exponent, at ito ay lamang na posible na kinakatawan ang isang exponent ng isang tiyak na laki. [Mag-aaral] At double? Ay na tulad ng isang dagdag na mahaba Float? >> Oo. Ito ay ang parehong bagay bilang isang Float maliban ngayon gumagamit ka ng 8 bytes sa halip ng 4 bytes. Ngayon magagawa mong gamitin ang 9 digits o 10 digit, at ito ay pumunta ng hanggang sa 300 sa halip ng 100. >> [Mag-aaral] Okay. At sa kamay 4 bytes. >> Oo. Well, muli, marahil ito ay depende pangkalahatang sa pangkalahatang pagpapatupad, ngunit sa kamay 4 bytes, Doubles ay 8. Doubles ay tinatawag na double dahil ang mga ito ay double ang laki ng mga kamay. [Mag-aaral] Okay. At doon ay double doubles? >> Hindi. Tingin ko - >> [mag-aaral] Tulad ng mahabang longs? >> Oo. Hindi sa tingin ko. Oo. [Mag-aaral] Sa huling taon ng pagsubok ay may isang katanungan tungkol sa mga pangunahing function na hindi upang maging bahagi ng iyong programa. Ang sagot na ito ay hindi upang maging bahagi ng iyong programa. Sa anong sitwasyon? Kung ano ang nakita ko. [Bowden] Mukhang - >> [mag-aaral] Ano ang sitwasyon? Mayroon ba kayong ang problema? >> [Mag-aaral] Oo, maaari ko talagang hilahin ito. Hindi ito maging, technically, ngunit isa lamang ito upang maging. [Mag-aaral] Nakita ko isa sa isang iba't ibang mga taon. Ito ay tulad True o Maling: Isang balidong - >> Oh, isang file c.? [Mag-aaral] Anumang file c dapat na magkaroon - [parehong nagsasalita nang sabay-sabay - hindi maintindihan] Okay. Kaya na hiwalay na. Ang isang file na. C kailangang maglaman ng mga function. Maaari mong ipunin ang isang file sa machine code, binary, anumang, nang wala ito executable pa. Isang wastong executable dapat magkaroon ng isang pangunahing function na. Maaari kang magsulat ng 100 function sa 1 file ngunit walang mga pangunahing at pagkatapos makatipon na pababa sa binary, pagkatapos ay isulat mo ng isa pang file na may lamang pangunahing ngunit tawag ng grupo ng mga function sa binary file sa paglipas dito. At kaya kapag nagsasagawa ka ng executable, na kung ano ang ginagawa ng linker ito pinagsasama mga 2 binary file sa isang executable. Kaya ang isang file na. C ay hindi kailangan upang magkaroon ng isang pangunahing function na sa lahat. At sa malaking base ng code na makikita mo ang libu-libong ng mga. File c at 1 pangunahing file. Higit pang mga tanong? [Mag-aaral] May isa pang tanong. Ito sinabi gumawa ng isang tagatala. Totoo o Maling? At ang sagot ay maling, at ko nauunawaan kung bakit ito ay hindi tulad ng kumalatong. Ngunit ano kami tatawag gumawa ng mga kung ito ay hindi? Gawing ay isa lamang - Maaari ko bang makita kung ano mismo ang tawag ito. Ngunit ito lamang tumatakbo ang mga utos. Gawin. Ko hilahin ang up na ito. Oo. Oh, oo. Gawing din ginagawa na. Sabi ito ang layunin ng utility Magsagawa ng upang matukoy awtomatikong kung aling mga piraso ng isang malaking programa kailangan na recompiled at magbigay ng mga utos upang mag-recompile ang mga ito. Maaari kang gumawa ng gumawa ng mga file na ay talagang malaking. Gawing tinitingnan ang mga selyo ng oras ng mga file at, tulad ng sinabi namin bago, maaari mong ipunin ang mga indibidwal na file, at ito ay hindi hanggang sa makakuha ka sa linker na sila ay magkasama sa isang executable. Kaya kung mayroon kang 10 iba't ibang mga file at gumawa ka ng pagbabago sa 1 sa kanila, pagkatapos kung ano ang Magsagawa ng pagpunta sa gawin ay mag-recompile na 1 file at pagkatapos ay relink lahat ng sama-sama. Subalit mas dumber kaysa. Ito ay hanggang sa iyo upang ganap na tukuyin na na kung ano ang dapat ito ginagawa. Ito sa pamamagitan ng default ay may kakayahang nakikilala ang oras stamp bagay, ngunit maaari mong magsulat ng isang Magsagawa ng file gawin. Maaari kang magsulat ng isang gumawa ng file sa gayon ay kapag nag-type ka gawin ito ay cd sa ibang direktoryo. Ako ay nagsisimula bigo dahil tak ko ang lahat sa loob ng aking Appliance at pagkatapos ko bang tingnan ang mga PDF mula sa Mac. Kaya pumunta ako sa Finder at Maaari ko Pumunta, Kumonekta sa Server, at ang server na kumonekta kong ang aking Appliance, at pagkatapos ay ko bang buksan ang PDF na maipo inipon ng LaTeX. Ngunit ako ay nagsisimula bigo dahil sa bawat solong oras na kailangan ko upang i-refresh ang PDF, Mayroon akong upang kopyahin ang mga ito sa isang tukoy na direktoryo na maaaring ma-access ang at ito ay nakakakuha ng nakakainis. Kaya sa halip ko nagsulat ng Magsagawa ng file, kung saan mayroon kang upang tukuyin kung paano ito ay gumagawa ng mga bagay. Paano gumawa ka sa PDF LaTeX. Tulad ng anumang iba pang mga file Magsagawa ng - o hulaan ko hindi mo pa nakikita ang mga file Magsagawa ng, ngunit mayroon kaming sa Appliance global na Magsagawa ng file na lang sabi, kung ikaw ay kino-compile ang isang C file, gamitin ang kumalatong. At kaya dito sa aking Magsagawa ng file na gumawa ako sinasabi ko, ang file na ito ay pagpunta sa nais upang ipunin sa PDF LaTeX. At kaya ito PDF LaTeX na paggawa ng kino-compile ang. Gawing ay hindi kino-compile. Lamang ito patakbuhin ang mga utos na ito sa ang pagkakasunud-sunod ko tinukoy. Kaya nagpapatakbo PDF LaTeX, kinokopya ito sa direktoryo Gusto ko ito kinopya sa, ito cd sa direktoryo at ginagawa ng mga iba pang mga bagay, ngunit ang lahat ng ginagawa nito ay makilala kapag ng mga pagbabago sa file, at kung ito ay nagbabago, pagkatapos ito ay patakbuhin ang mga utos na ito ay dapat na tumakbo kapag ang file pagbabago. >> [Mag-aaral] Okay. Hindi ko alam kung saan ang pandaigdigang Magsagawa ng file para sa akin upang suriin ito. Iba pang mga tanong? Anumang bagay mula sa mga nakaraang pagsusulit? Anumang pointer bagay? May banayad na mga bagay na may mga payo tulad - Hindi ako pagpunta upang makahanap ng isang tanong sa pagsusulit sa - ngunit tulad ng ganitong uri ng bagay. Tiyaking nauunawaan mo na kapag sinabi ko int * x * y - Ito ay hindi eksakto anuman dito, hulaan ko. Ngunit tulad ng * x * y, mga 2 variable na sa stack. Kapag sinabi ko x = malloc (sizeof (int)), x pa rin ang isang variable sa stack, malloc ilang bloke sa paglipas ng sa magbunton, at nagkakaroon kami ng x punto sa magbunton. Kaya isang bagay sa ang mga puntos ng stack sa magbunton. Tuwing malloc mo anumang, hindi maaaring hindi ka pag-imbak nito sa loob ng isang pointer. Kaya ang pointer sa stack, ang malloced bloke ay sa magbunton. A maraming ng mga tao makakuha ng nalilito at sabihin int * x = malloc; x sa magbunton. Hindi. Ano ang x mga punto sa sa magbunton. x mismo sa stack, maliban para sa anumang dahilan x ay isang pandaigdigang variable, kung saan ito ang mangyayari sa ibang rehiyon ng memorya. Kaya pagpapanatiling track, mga kahon at arrow diagram ay medyo karaniwang para sa pagsusulit. O kung ito ay hindi sa pagsusulit 0, ito sa pagsusulit 1. Dapat mong malaman ang lahat ng ito, ang mga hakbang sa kino-compile ang dahil mayroon kang upang sagutin ang mga katanungan sa mga. Oo. [Mag-aaral] ma kami sa mga hakbang - >> Oo naman. Bago mga hakbang at kino-compile ang mayroon kaming preprocessing, kino-compile, assembling, at pag-link. Preprocessing. Ano ang na gawin? Ito ay ang pinakamadaling hakbang sa - na rin, hindi tulad ng - na hindi ibig sabihin dapat ito ay halata, ngunit ito ay ang pinakamadaling hakbang. Mong guys ay maaaring ipatupad ito sarili. Oo. [Mag-aaral] Dalhin kung ano ang mayroon kang sa iyong Kabilang tulad nito at kinokopya ito at pagkatapos din tumutukoy. Tumingin para sa mga bagay tulad ng # include at # tukuyin, at ito lamang kopya at pastes kung ano ang mga aktwal na ibig sabihin. Kaya kapag sinabi mong # include cs50.h, ang Preprocessor ang pagkopya at pag-paste ng cs50.h sa na linya. Kapag sinabi mong # tukuyin ang mga x na 4, Preprocessor napupunta sa pamamagitan ng buong programa at pumapalit sa lahat ng mga pagkakataon ng mga x na may 4 na. Kaya Preprocessor tumatagal ng isang wastong file ng C at output ng isang wastong file C kung saan ang mga bagay na nakopya at nailagay. Kaya ngayon kino-compile. Ano ang na gawin? [Mag-aaral] pupunta ito mula sa C sa binary. [Bowden] Hindi ito pumunta ang lahat ng mga paraan sa binary. [Mag-aaral] Upang machine code? >> Hindi machine code. [Mag-aaral] Assembly? >> Assembly. Napupunta sa Assembly bago ito napupunta ang lahat ng mga paraan upang C code, at karamihan ng mga wika gawin ang isang bagay tulad nito. Pumili ng anumang mataas na antas ng wika, at kung ikaw ay pagpunta upang ipunin ito, malamang upang ipunin sa hakbang. Una ito upang ipunin ang Python sa C, pagkatapos ito upang ipunin ang C sa Assembly, at pagkatapos Assembly ay pagpunta upang isinalin sa binary. Kaya kino-compile ang pagpunta upang dalhin ito mula sa C sa Assembly. Ang salitang kino-compile ay karaniwang ay nangangahulugan na ang nagdadala sa mga ito mula sa isang mas mataas na antas sa isang mas mababang antas ng wika programming. Kaya ito ay ang tanging hakbang sa compilation kung saan simulan mo sa isang mataas na antas ng wika at nagtatapos sa isang mababang antas na wika, at iyon ang dahilan kung bakit hakbang ay tinatawag na kino-compile. [Mag-aaral] Sa panahon kino-compile, sabihin nating na nagawa mo na # include cs50.h. Gagana ba ang tagatala mag-recompile ang cs50.h, tulad ng mga function na doon, at i-translate na sa Assembly code pati na rin, o kopyahin at i-paste ang isang bagay na pre-Assembly? cs50.h ay medyo magkano hindi magtapos sa Assembly. Bagay tulad ng mga function na modelo at mga bagay para lamang sa iyo upang maging maingat. Tinitiyak na tagatala maaaring suriin ng mga bagay tulad ng pagtawag sa function ka na may tamang uri ng return at ang tamang argumento at bagay-bagay. Kaya cs50.h ay preprocessed sa file, at pagkatapos ay kapag ito ay kino-compile isa lamang ito itinapon ang layo pagkatapos tinitiyak na ang lahat ay tinatawag na tama. Ngunit ang mga function na tinukoy sa CS50 library, na hiwalay mula sa cs50.h, mga hindi hiwalay inipon. Na ang aktwal na bumaba sa hakbang na ang pagli-link, kaya ipapakita namin sa isang segundo. Ngunit una, kung ano ang assembling? [Mag-aaral] Assembly sa binary? >> Oo. Assembling. Hindi namin tumawag ito kino-compile dahil Assembly ay medyo magkano ang isang dalisay na pagsasalin ng binary. May napakakaunting logic ng pagpunta mula sa Assembly sa binary. Lamang ito bang hinahanap sa isang table, oh, mayroon kaming ito pagtuturo; na tumutugon sa binary 01,110. At sa gayon ang mga file na assembling pangkalahatan output ay o file. At. O file ay kung ano ang aming sinasabi bago, kung paano ang isang file ay hindi kailangan upang magkaroon ng isang pangunahing function na. File anumang inipon down sa isang file o bilang hangga't ito ay isang wastong file C. Maaari itong inipon pababa. O. Ngayon, pag-uugnay ay kung ano ang aktwal na nagdudulot ng ng grupo ng o file at pinagsasama-sa kanila sa isang executable. At kaya kung ano ang Pag-uugnay ng ginagawa ay maaari mong isipin ng CS50 library bilang isang file o. Na inipon file sa binary. At kaya kapag makatipon mo ang iyong file, iyong hello.c, na tawag GetString, hello.c ay makakakuha inipon down sa hello.o, hello.o ngayon sa binary. Gumagamit GetString, kaya kailangang pumunta sa cs50.o, at ang linker ang smooshes iyon nang magkakasama at kinokopya GetString sa ang file na ito at ay may isang executable na may lahat ng mga function na kailangan nito. Kaya cs50.o ay hindi talagang O file, ngunit ito ay malapit sapat na walang saligan pagkakaiba. Kaya nagli-link lamang ay nagdudulot ng isang bungkos ng mga file nang magkasama na hiwalay na naglalaman ng lahat ng mga pag-andar, kailangan kong gamitin at lumilikha ng executable na ang talagang tumakbo. At kaya na rin kung ano ang aming sinasabi bago kung saan maaari kang magkaroon ng 1000. file c, makatipon mo ang lahat ng ito sa o file, na marahil magtagal, pagkatapos binago mo 1 c file. Kailangan mo lamang na mag-recompile na 1. C file at pagkatapos ay relink lahat ng iba pa, link ang lahat ng pabalik nang magkasama. [Mag-aaral] Kapag nagli-link ka namin isulat namin lcs50? Oo, kaya-lcs50. Signal na bandila sa linker na dapat mong nagli-link sa na library. Mga tanong? Namin nawala sa paglipas ng binary iba pang kaysa sa 5 segundo sa unang panayam? Hindi sa tingin ko. Dapat mong malaman ang lahat ng malaking Os na namin ang nawala sa paglipas ng, at dapat mong ma-, kung ibinigay namin sa iyo ng isang function, dapat mong magagawang upang sabihin ito ang malaking O, halos. O na rin, malaki O ay magaspang. Kaya kung mong makita Nested para sa mga loop na looping sa ibabaw ng parehong bilang ng mga bagay, tulad ng int i, i > [mag-aaral] n squared. >> May kaugaliang n squared. Kung triple ka na Nested, may gawi na n nakakubo. Kaya na uri ng bagay dapat mong magagawang upang ituro ang kaagad. Kailangan mong malaman-uuri ng pagpapasok ng at-uuri ng bubble at sumanib-uri-uriin at ang lahat ng mga. Ito ay madali upang maunawaan kung bakit ang mga ito ay mga n squared at n log n at lahat ng na dahil sa tingin ko nagkaroon sa isang pagsusulit sa isang taon kung saan talaga namin ibinigay mo ng pagpapatupad ng bubble-uuri at sinabing, "Ano ang tumatakbo oras ng function na ito?" Kaya kung makilala ka bilang bubble-uuri, maaari mong agad sabihin n squared. Ngunit kung mo lamang tumingin sa ito, hindi mo na kailangan upang mapagtanto ito ng bubble-uuri; Maaari mo lamang sabihin na ito ay ginagawa ito at ito. Ito n squared. [Mag-aaral] Mayroon bang anumang mga matibay na halimbawa na maaari mong makabuo ng, tulad ng isang katulad na ideya ng pag-uunawa ng? Palagay ko ay hindi namin magbibigay sa iyo ng anumang matigas halimbawa. Ang bubble-uuri ng bagay ay tungkol sa bilang matigas tulad kami, at kahit na, hangga't nauunawaan mo na ikaw ay iterating sa ibabaw ng array para sa bawat elemento sa array, na kung saan ay pagpunta sa isang bagay na n squared. Mayroong mga pangkalahatang katanungan, tulad ng karapatan dito mayroon kaming - Oh. Sa iba pang mga araw, Doug inaangkin, "ako imbento ng isang algorithm na maaaring ayusin ng isang array "Ng mga n numero sa O (log n) oras!" Kaya kung paano namin malalaman na imposibleng? [Hindi marinig na mag-aaral ng tugon] >> Oo. Sa pinakadulo hindi bababa sa, mayroon kang pindutin bawat elemento sa array, kaya imposibleng upang pag-uri-uriin ang isang hanay ng mga - Kung ang lahat ay sa unsorted-sunod, pagkatapos ikaw ay pagpunta sa na nakadikit lahat sa array, kaya imposible na gawin ito sa mas mababa kaysa O ng n. [Mag-aaral] ay nagpakita mo sa amin na halimbawa ng gawin ito sa O ng n kung gumamit ka ng maraming memorya. >> Oo. At that's - nakalimutan ko kung ano ang that's - Ay ito pagbibilang sa-uuri? Hmm. Na ay isang integer na pag-uuri algorithm. Ako ay naghahanap para sa espesyal na pangalan para sa na hindi ko matandaan ang huling linggo. Oo. Ito ay ang mga uri ng mga uri na maaaring maisagawa ang mga bagay sa malaking O ng n. Ngunit may mga limitasyon, tulad ng maaari mo lamang gamitin ang integer hanggang sa ilang. Plus kung sinusubukan mong i-ayusin ang mga that's ng isang bagay - Kung ang iyong array ay 012, -12, 151, 4 na milyong, pagkatapos na iisang elemento ay ganap na sanhi ng pagkapahamak ng buong pag-uuri. Mga tanong? [Mag-aaral] Kung mayroon kang isang recursive function at ito ay gumagawa ng mga recursive tawag sa loob ng isang pahayag ng return, na buntot recursive, at ito ay na hindi gumagamit ng higit pa memory sa oras ng runtime o gusto ng hindi bababa sa gamitin ang maihahambing memory bilang isang umuulit solusyon? [Bowden] Oo. Ay malamang na medyo mas mabagal, ngunit hindi talaga. Buntot recursive ay medyo magandang. Naghahanap muli sa frame stack, sabihin nating mayroon kaming pangunahing at mayroon kaming int bar (int x) o isang bagay. Ito ay hindi isang perpektong recursive function na, ngunit ang return bar (x - 1). Kaya malinaw naman, ito ay flawed. Kailangan mong base at mga kaso ng mga bagay-bagay. Ngunit ang ideya dito ay na ito ay buntot recursive, na nangangahulugan na kapag ang mga pangunahing tawag bar na ito upang makuha ang stack frame. Sa stack frame na ito ay may pagpunta sa isang maliit na bloke ng memorya na tumutugon sa nito argumento x. At kaya sabihin nating pangunahing mangyayari tumawag sa bar (100); Kaya x ay pagpunta upang simulan ang bilang sa 100. Kung tagatala ay kinikilala na ito ay isang buntot recursive function na, pagkatapos ay kapag ang bar ginagawang recursive tawag nito sa bar, sa halip ng paggawa ng isang bagong stack frame, na kung saan ang stack ang nagsimula lumalagong sa kalakhan, kalaunan ito ay tumakbo sa magbunton at pagkatapos mo makakuha ng mga segfaults dahil ang memory nagsisimula nagbabanggaan. Kaya sa halip ng paggawa ng sarili nitong stack frame, maaari itong Napagtanto, hey, hindi ko talagang kailangan upang bumalik sa stack frame na ito, kaya sa halip makikita ko lang palitan ang argument na ito may 99 at pagkatapos ay simulan ang bar sa lahat ng dako. At pagkatapos ito ay gawin itong muli at ito maabot ang return bar (x - 1), at sa halip ng paggawa ng bagong stack frame, ito lamang palitan ang kasalukuyan nitong argument may 98 at pagkatapos ay tumalon pabalik sa pinakadulo simula ng bar. Yaong mga pagpapatakbo, pinapalitan na 1 halaga sa stack at paglukso pabalik sa simula, medyo mahusay. Kaya hindi lamang ito ang parehong paggamit ng memorya bilang isang hiwalay na function na na umuulit dahil ikaw lamang ginagamit 1 stack frame, ngunit hindi ka naghihirap ang downsides ng kinakailangang tumawag function. Pagtawag function ay maaaring medyo mahal dahil ito ay may sa gawin ang lahat ng ito setup at teardown at ang lahat ng ito bagay-bagay. Kaya buntot recursion na ito ay mabuti. [Mag-aaral] Bakit ang hindi lumikha ng mga bagong hakbang? Dahil napagtanto hindi ito kailangang. Ang tawag sa bar bumabalik recursive tawag. Kaya hindi ito kailangan upang gawin ang anumang bagay na may halaga return. Lamang ito upang agad na ibalik ito. Kaya lamang ito upang palitan ang sarili nitong argumento at magsimulang muli. At din, kung wala kang ang buntot recursive bersyon, pagkatapos kang makakuha ng lahat ng mga bar kung saan kapag nagbabalik ang bar na ito ito ay may upang bumalik ang halaga na ito, pagkatapos na bar agad nagbalik at nagbalik ang halaga nito sa isang ito, pagkatapos lamang ito upang agad na bumalik at ibalik ang halaga nito sa isang ito. Kaya ka-save ang popping ang lahat ng mga bagay na ito ng stack dahil ang return halaga lang na pumasa sa lahat ng paraan-back up pa rin. Kaya bakit hindi lamang palitan ang aming mga argumento sa mga na-update na argumento at magsimulang muli? Kung ang function ay hindi buntot recursive, kung gawin mo ang isang bagay tulad ng - [Mag-aaral] kung bar (x + 1). >> Oo. Kaya kung inilagay mo ito sa kundisyon, pagkatapos ikaw ay paggawa ng isang bagay ang halaga ng return. O kahit mo lamang gawin return 2 * bar (x - 1). Kaya ngayon bar (x - 1) kailangang bumalik upang ito upang makalkula ang 2 beses na halaga, kaya ngayon ay kailangan ng sarili nitong hiwalay na stack ng frame, at ngayon, kahit na kung paano mahirap subukan mo, ikaw ay kailangang - Na ito ay hindi recursive na buntot. [Mag-aaral] Gusto kong subukan na magdala ng recursion sa layunin para sa isang buntot recursion - [Bowden] Sa isang perpektong mundo, ngunit sa CS50 hindi mo na kailangang. Upang makakuha ng buntot na recursion, sa pangkalahatan, itinakda mo ng karagdagang argumento kung saan bar tumagal ng int x sa y at y tumutugon sa ang tunay na bagay na gusto mong ibalik. Kaya pagkatapos ito ka na bumabalik bar (x - 1), 2 * y. Kaya na mataas na antas ng kung paano mo ibahin ang anyo ng mga bagay sa buntot recursive. Ngunit ang dagdag na argumento - At pagkatapos ay sa dulo kapag naabot mo ang iyong base kaso, mo lang bumalik y dahil na-iipon ng buong oras ang return halaga na gusto mo. Mong uri ng ay ginagawa ito iteratively ngunit ang paggamit ng mga recursive tawag. Mga tanong? [Mag-aaral] Siguro tungkol pointer aritmetika, tulad ng kapag gumagamit ng string. >> Oo naman. Pointer aritmetika. Kapag gumagamit ng string madali dahil sa mga string magpasinda mga bituin, char ay magpakailanman at palaging isang solong byte, at kaya pointer aritmetika ay katumbas sa regular na pang-aritmetika kapag kayo ay pagharap sa string. Sabihin lang sabihin magpasinda * s = "kumusta". Kaya kami ay may isang bloke sa memorya. Kailangan nito 6 bytes dahil palagi mong kailangan ang null Terminator. At magpasinda * s ay pagpunta upang tumuro sa simula ng array na ito. Kaya s mga punto doon. Ngayon, ito ay isa lamang kung paano gumagana ang array anumang, hindi alintana kung ito ay isang balik sa pamamagitan ng malloc o kung ito ay sa stack. Array anumang ay isa lamang isang pointer sa simula ng array, ang anumang operasyon ng array, anumang pag-i-index, at pagkatapos lamang ng pagpunta sa na array isang tiyak na offset. Kaya kapag sinabi ko ang isang bagay tulad ng mga [3]; ito ay pagpunta sa mga at pagbibilang 3 char. Kaya s [3], kami ay may 0, 1, 2, 3, kaya s [3] ay sumangguni sa ito l. [Mag-aaral] At maaari kaming maabot ang parehong halaga sa pamamagitan ng paggawa ng mga + 3 at pagkatapos ay panaklong star? Oo. Ito ay katumbas sa * (mga + 3); at iyon ay magpakailanman at palaging katumbas hindi mahalaga kung ano ang ginagawa mo. Hindi mo na kailangang gamitin ang syntax ng bracket. Maaari mong palaging gamitin ang (mga + 3) * syntax. Mga tao ay may posibilidad na gusto ang syntax ng bracket, bagaman. [Mag-aaral] Kaya lahat ng mga array ay aktwal na lamang payo. May ay isang bahagyang pagkakaiba kapag sinabi ko int x [4]; >> [mag-aaral] ba na lumikha sa memory? [Bowden] Iyon ay pagpunta upang lumikha ng 4 ints sa stack, kaya 16 na bytes pangkalahatang. Ito upang lumikha ng mga 16 bytes sa stack. x ay hindi naka-imbak sa kahit saan. Ito ay isang simbolo na tumutukoy sa simula ng bagay. Dahil ipinahayag mo ang hanay sa loob ng function na ito, ano ang tagatala ay pagpunta sa gawin ay lamang palitan ang lahat ng mga pagkakataon ng variable x sa kung saan nangyari ito upang pumili upang ilagay ang mga ito 16 bytes. Hindi ito maaaring gawin iyon may magpasinda * s dahil s ay isang aktwal na pointer. Ay libre upang pagkatapos ay tumuturo sa iba pang mga bagay. x ay isang pare-pareho. Hindi ka maaaring magkaroon ng punto sa ibang array. >> [Mag-aaral] Okay. Subalit ang ideyang ito, ang pag-i-index na ito, ay ang parehong alintana kung ito ang isang tradisyonal na array o kung ito ay isang pointer sa isang bagay o kung ang isang pointer sa isang malloced array. At sa katunayan, kaya katumbas na na rin ang parehong bagay. Ito aktwal lamang ibig sabihin kung ano ang sa loob ng mga bracket at kung ano ang kaliwa ng mga bracket, nagdadagdag ng mga iyon nang magkakasama, at dereferences. Kaya ito ay tulad ng wastong bilang * (mga + 3) o mga [3]. [Mag-aaral] Maaari kang magkaroon ng mga payo na tumuturo sa 2-dimensional array? Ito ay mahirap. Tradisyonal, hindi. 2-dimensional array ay 1-dimensional array na may ilang maginhawang syntax dahil kapag sinabi ko int x [3] [3], talaga ito ay may 1 array na may 9 na halaga. At kaya kapag ako ay nag-index, tagatala alam kung ano ang ibig sabihin ko. Kung sinasabi ko x [1] [2], alam na gusto kong pumunta sa pangalawang hilera, kaya ito upang laktawan ang unang 3, at pagkatapos ay nais ang ikalawang bagay na, kaya upang makakuha ng isang ito. Ngunit ito ay pa rin ng isang-dimensional array. At kaya kung Nais kong upang magtalaga ng isang pointer sa array na, Gusto ko sabihin int * p = x; Lamang ang uri ng x - Ito ay magaspang sinasabi uri ng x dahil ito ay isang simbolo at ito ay hindi isang aktwal na variable, ngunit ito ay isang int *. x ay isang pointer sa simula ng ito. >> [Mag-aaral] Okay. At kaya hindi ko upang ma-access ang [1] [2]. Tingin ko may espesyal na syntax para sa deklarasyon ng pointer, isang bagay na katawa-tawa tulad ng int (* p [- ng isang bagay na ganap na katawa-tawa hindi ko alam. Ngunit may syntax para sa deklarasyon ng mga payo tulad ng may mga panaklong at mga bagay. Hindi kahit na ito ay maaaring sabihin gawin mo na. Maaari kong tumingin pabalik sa isang bagay na sabihin sa akin ang katotohanan. Kong hanapin ito sa ibang pagkakataon, kung may syntax para sa punto. Ngunit hindi mo makita ito. At kahit syntax kaya patay na kung gagamitin mo ito, ang mga tao ay baffled. Maraming interes array ay medyo bihirang ito ay. Mong medyo mas - Well, kung gumagawa ka ng mga bagay na matrix ay hindi ito pagpunta sa bihirang, ngunit sa C bihira ka pagpunta sa paggamit ng mga maraming interes array. Oo. >> [Mag-aaral] Sabihin nating mayroon kang isang talagang mahaba array. Kaya sa virtual memory ay lilitaw sa lahat ng magkakasunod, tulad ng mga elemento sa tabi mismo sa bawat isa, ngunit sa pisikal na memorya, ito ay posible para sa maghiwalay? >> Oo. Paano virtual memory gawa ay naghihiwalay lamang ito - Ang yunit ng paglalaan ay isang pahina, na may kaugaliang 4 kilobytes, at kaya kapag ang proseso ng sabi, hey, gusto kong gamitin ang memory, ang operating system upang magtalaga ito ng 4 na kilobytes para sa maliit na bloke ng memorya. Kahit na kung ka lamang gumamit ng isang maliit na byte sa buong bloke ng memorya, ang operating system upang bigyan ito ng buong 4 kilobytes. Kaya kung ano ang Nangangahulugan itong maaari ba akong magkaroon ng - sabihin nating ito ang aking stack. Stack na ito ay maaari na pinaghiwalay. Aking stack mga megabytes at megabytes. Maaaring maging malaking ang Aking stack. Ngunit ng stack mismo ay hatiin sa mga indibidwal na mga pahina, na kung tiningnan namin sa paglipas ng dito sabihin nating ito ang aming RAM, kung mayroon akong 2 gigabytes ng RAM, ito ay aktwal na address ng 0 tulad ng 0 byte ng aking RAM, at ito ay 2 gigabytes ang lahat ng mga paraan pababa dito. Kaya pahinang ito ay maaaring tumutugma sa block na ito sa paglipas dito. Ang pahinang ito ay maaaring tumutugma sa block na ito sa paglipas dito. Ito ay maaaring tumutugma sa isa sa paglipas dito. Kaya ang operating system ay libre upang magtalaga ng pisikal na memory sa anumang indibidwal na pahina sa mang. At na nangangahulugan na kung ang hangganan nangyari ito sa sumaklang isang array, array ng mangyayari sa kaliwa ng ito at karapatan ng order na ito ng isang pahina, array na ay pagpunta sa hatiin sa pisikal na memory. At pagkatapos ay kapag ikaw ay huminto sa programa, kapag ang proseso ay nagtatapos, mga pagmamapa makakuha ng mabubura at pagkatapos ay libre upang gamitin ang mga maliit na mga bloke para sa iba pang mga bagay. Higit pang mga tanong? [Mag-aaral] Ang pointer aritmetika. >> Oh oo. String ay madali, ngunit naghahanap sa isang bagay tulad ng mga ints, kaya bumalik sa int x [4]; Kung ito ay isang array o kung ito ay isang pointer sa isang malloced array ng 4 integer, ito ay pagpunta sa ay ginagamot sa parehong paraan. [Mag-aaral] Kaya array sa magbunton? [Bowden] array ay hindi sa magbunton. >> [Mag-aaral] Oh. [Bowden] Ang uri ng array ay may kaugaliang sa stack maliban kung ipinahayag mo ito sa - pagbalewala sa pangkalahatang variable. Huwag gumamit ng mga pangkalahatang variable. Sa loob ng isang function na sinasabi ko int x [4]; Ito ay pagpunta upang lumikha ng isang 4-integer bloke sa stack para sa array na ito. Ngunit ito malloc (4 * sizeof (int)); upang pumunta sa magbunton. Ngunit pagkatapos ng puntong ito Maaari ko bang gamitin ang x at p sa medyo halos parehong paraan, iba kaysa sa pagbubukod sinabi ko bago tungkol reassign p. Technically, ang kanilang mga laki ay medyo iba, ngunit na ganap na walang-katuturang. Hindi mo aktwal na gamitin ang kanilang mga laki. Ang p maaari kong sabihin p [3] = 2; o x [3] = 2; Maaari mong gamitin ang mga ito sa eksaktong parehong paraan. Kaya pointer aritmetika ngayon - Oo. [Mag-aaral] ba hindi mo gawin p * kung mayroon kang mga bracket? Ang mga bracket ay isang implicit dereference. >> Okay. Aktwal na din kung ano ang sinasabi mo na may maaari kang makakuha ng maraming interes array sa mga payo, kung ano ang maaari mong gawin ay isang bagay tulad ng, sabihin nating, int ** pp = malloc (sizeof (int *) * 5); Kukunin ko na lang isulat ang lahat ng ito out muna. Hindi ko gusto na ang isa. Okay. Ano ang ginawa ko dito - ay dapat na pp [i]. Kaya pp ng pointer sa isang pointer. Ka mallocing pp upang tumuro sa isang array ng 5 int bituin. Kaya sa memorya na ikaw ay may sa stack ang pp. Ito ay upang tumuro sa isang hanay ng mga 5 bloke na ang lahat ang kanilang mga sarili payo. At pagkatapos ay kapag malloc ko pababa dito, malloc ko na ang bawat isa ng mga indibidwal na payo dapat tumuro sa isang hiwalay na bloke ng 4 bytes sa magbunton. Kaya ito ng mga puntos sa 4 bytes. At ito ang isa mga puntos sa isang iba't ibang 4 bytes. At lahat ng mga ito ay tumuturo sa kanilang sariling 4 bytes. Ito ay nagbibigay sa akin ang paraan ng paggawa ng maraming interes bagay. Maaari kong sabihin pp [3] [4], ngunit ngayon ito ay hindi ang parehong bagay bilang maraming interes array dahil maraming interes array na ito isinalin [3] [4] sa isang solong na offset sa array x. Ito dereferences p, access sa ikatlong index, pagkatapos dereferences na at ina-access - 4 ay hindi wasto - ang pangalawang index. Sapagkat kapag nagkaroon kami ang int x [3] [4] bago bilang isang maraming interes array at kapag nag-double bracket ito ay talagang lamang ng isang solong dereference, Sinusundan ka ng isang pointer at pagkatapos ay isang offset, talaga ito 2D reference. Sinusundan mo 2 magkahiwalay na payo. Kaya ito din technically ay nagpapahintulot sa iyo na magkaroon ng maraming interes array kung saan ang bawat indibidwal na array ay iba't ibang laki. Kaya sa tingin ko tulis-tulis maraming interes array ay kung ano ang tawag dahil talaga ang unang bagay na maaaring tumuro sa isang bagay na ay may 10 mga elemento, ang ikalawang bagay ay tumuturo sa isang bagay na ay may 100 mga elemento. [Mag-aaral] Mayroon bang limitasyon sa bilang ng mga payo na maaari kang magkaroon ng na tumuturo sa iba pang mga payo? >> No. Maaari kang magkaroon ng int ***** p. Bumalik sa pointer aritmetika - >> [mag-aaral] Oh. >> Oo. [Mag-aaral] Kung mayroon akong int *** p at gagawin ko ng dereferencing at sinasabi ko ay katumbas sa halagang ito ang p *, ito lamang ang pagpunta sa gawin 1 antas ng dereferencing? >> Oo. Kaya kung nais ko upang ma-access ang bagay na ang huling pointer ay pagturo sa - Pagkatapos gawin mo *** p. >> Okay. Kaya ito ay p ang mga puntos sa 1 bloke, ang mga puntos sa isa pang block, ang mga puntos sa ibang block. Pagkatapos kung gawin mo * p = iba pa, pagkatapos ikaw ay baguhin ang sa ngayon na ituro sa isang iba't ibang mga bloke. >> Okay. [Bowden] At kung ang mga ito ay malloced, pagkatapos ngayon mo pa leaked memory maliban kung mangyari mong magkaroon ng iba't-ibang mga sanggunian sa mga ito dahil hindi ka bumalik sa iyong mga iyan mo lamang threw layo. Pointer aritmetika. int x [4]; pagpunta sa maglaan ng isang hanay ng mga 4 integer kung saan ang x ay upang tumuro sa simula ng array. Kaya kapag sinabi ko ang isang bagay tulad ng x [1], gusto ko bang pumunta sa pangalawang integer sa array, na ang isang ito. Ngunit talagang, na 4 bytes sa array dahil ang integer na ito ay tumatagal ng hanggang 4 bytes. Kaya isang offset ng 1 talagang nangangahulugan isang offset ng 1 beses ang laki ng anuman ang uri ng array ay. Ito ay isang hanay ng mga integer, kaya alam upang gawin ang 1 beses na laki ng int kapag nais upang i-offset. Ang iba pang mga syntax. Tandaan na ito ay katumbas sa * (x + 1); Kapag sinasabi ko ang pointer + 1, ano ang return address na pointer ay ang pag-iimbak ng kasama ang 1 beses ang laki ng uri ng pointer. Kaya kung x = ox100, pagkatapos ay x + 1 = ox104. At maaari mong abusuhin ito at sabihin ang isang bagay tulad ng pansamantalang trabaho * c = (magpasinda *) x; at ngayon c sa parehong address tulad ng x. c ay katumbas ng ox100, ngunit c + 1 ay katumbas ng ox101 dahil ang pointer aritmetika ay depende sa uri ng pointer na pagdaragdag sa. Kaya c + 1, tinitingnan nito c, ito ay isang pansamantalang trabaho na pointer, kaya ito upang magdagdag ng 1 beses na laki ng pansamantalang trabaho, na palaging pagpunta sa 1, kaya makakakuha ka ng 101, samantalang kung gagawin ko x, na kung saan ay din pa rin 100, x + 1 ay magiging 104. [Mag-aaral] Maaari mong gamitin ang c + + upang upang mag-advance ang iyong pointer ng 1? Oo, maaari mong. Hindi mo maaaring gawin na may x dahil ang x ay isang simbolo, ito ay isang pare-pareho, hindi mo maaaring baguhin x. Ngunit c mangyayari lamang ng pointer, kaya c + + perpektong wastong at ito ay dagdagan ng 1. Kung c ay isang int *, pagkatapos c + + ay 104. + + Gumagana ang pointer aritmetika tulad ng c + 1 ay magkakaroon gawin pointer aritmetika. Ito ay talagang kung paano ang isang maraming mga bagay tulad ng pagsasama-uuri - Sa halip ng paglikha ng mga kopya ng mga bagay, maaari mong halip pumasa - Nais kung gusto ko upang pumasa ito kalahati ng array - hayaan ang burahin ang ilan sa mga ito. Sabihin nating gusto ko upang pumasa ito bahagi ng array sa isang function. Ano ang gusto kong ipasa na ang function? Kung pumasa ako x, ako ang pagpasa sa address na ito. Ngunit nais ko upang pumasa sa partikular na address na ito. Kaya ano ang dapat kong ipasa? [Mag-aaral] pointer + 2? [Bowden] Kaya x + 2. Oo. Na pagpunta sa address na ito. Makikita mo rin napaka madalas na makita ang mga ito bilang x [2] at pagkatapos ay ang address na iyon. Kaya kailangan mo ang address ng dahil bracket ay isang implicit dereference. x [2] ay tumutukoy sa halaga na sa kahon na ito, at pagkatapos ay nais mo ang address ng kahon na, kaya sabihin mo & x [2]. Kaya, na kung paano isang bagay sa pagsasama-uuri na kung saan nais mong pumasa sa kalahati ng listahan sa isang bagay mo ba talagang lamang pumasa sa & x [2], at ngayon bilang malayo bilang recursive tawag ay nababahala, aking bagong array nagsisimula doon. Huling minuto tanong. [Mag-aaral] Kung hindi namin maglagay ng isang ampersand o - kung ano ang na tinatawag? >> Star? [Mag-aaral] Star. >> Technically, dereference operator, ngunit - >> [mag-aaral] Dereference. Kung hindi namin maglagay ng star o isang ampersand, ano ang mangyayari kung ko lang sabihin y = x at x ay isang pointer? Ano ang uri ng y? >> [Mag-aaral] kukunin ko na lang sabihin ito ng pointer 2. Kaya kung sabihin mo lamang y = x, ngayon x at y punto sa parehong bagay. >> [Mag-aaral] Point sa parehong bagay. At kung ang x ay isang int pointer? >> Ito magreklamo dahil hindi ka maaaring magtalaga ng mga payo. [Mag-aaral] Okay. Tandaan na payo, kahit na namin gumuhit ng mga ito bilang mga arrow, talagang lahat ng sila tindahan - int * x - talaga x lahat ng pag-iimbak ng isang bagay tulad ng ox100, na mangyari namin upang kumatawan bilang na tumuturo sa block na naka-imbak sa 100. Kaya kapag sinabi ko int * y = x; lang ako pagkopya ox100 sa y, kung saan lang namin ang pagpunta sa kumakatawan sa bilang y, din na tumuturo sa ox100. At kung sinasabi ko int i = (int) x; pagkatapos ay i upang mag-imbak anuman ang halaga ng ox100 sa loob nito, ngunit ngayon ito pagpunta sa kahulugan bilang isang integer sa halip ng isang pointer. Ngunit kailangan mo ang nagsumite ng kung ito ay magreklamo. [Mag-aaral] Kaya mo bang sabihin na pinalayas - Ay ito pagpunta sa paghahagis ng int ng x o Casting int ng y? [Bowden] Ano? [Mag-aaral] Okay. Pagkatapos ng mga panaklong ay mayroong pagpunta sa isang x o ay doon? [Bowden] Alinman. x at y ay katumbas. >> [Mag-aaral] Okay. Dahil hindi nila parehong payo. >> Oo. [Mag-aaral] Kaya ito ay magdudulot ng iimbak ang hexadecimal 100 sa integer anyo? >> [Bowden] Oo. Ngunit hindi ang halaga ng anumang punto upang. [Bowden] Oo. >> [Mag-aaral] Kaya lang ang mga address sa form na integer. Okay. [Bowden] Kung nais mong para sa ilang mga kakaibang dahilan, maaari kang eksklusibong humarap sa payo at hindi kailanman makitungo sa integer at tulad ng int * x = 0. Pagkatapos ka pagpunta upang talagang nalilito sa sandaling pointer aritmetika nagsisimula nangyayari. Kaya ang mga numero na imbak ng sila ay walang kahulugan. Kung lang kung paano mo pagbibigay-kahulugan ang mga ito. Kaya ako libreng upang kopyahin ang ox100 mula sa isang int * sa isang int, at ako ay libreng upang magtalaga - you're marahil pagpunta upang yelled sa para sa hindi paghahagis - Ako libreng upang magtalaga ng isang bagay tulad ng (int *) ox1234 sa ito arbitrary int *. Kaya ox123 ay tulad ng wastong ng memory address na & ya. & Yahin ang mangyayari upang magbalik ng bagay na medyo mas ox123. [Mag-aaral] Gusto na talagang cool na paraan upang pumunta mula sa hexadecimal sa decimal form na, bang kung mayroon kang isang pointer at pinalayas mo ito bilang isang int? [Bowden] Maaari mong talagang lamang print gamit tulad ng printf. Ipagpalagay natin na mayroon akong int y = 100. Kaya printf (% d \ n - bilang dapat alam mo na - i-print na bilang isang integer,% x. Lang namin i-print ang mga ito bilang hexadecimal. Kaya ang pointer ay hindi naka-imbak bilang hexadecimal, at isang integer ay hindi naka-imbak bilang decimal. Lahat ay naka-imbak bilang binary. Lang na may posibilidad namin upang ipakita ang mga payo bilang hexadecimal dahil sa tingin namin ng mga bagay sa mga 4-byte na bloke, at memory address ay may posibilidad na maging pamilyar. Humihingi kami ng tulad ng, kung nagsisimula ito sa bf, ito ang mangyayari sa stack. Kaya aming interpretasyon ng payo bilang hexadecimal. Okay. Anumang huling tanong? Makikita ko dito para sa isang bit pagkatapos kung mayroon kang anumang bagay. At na ang dulo ng na. [Mag-aaral] Yay! [Palakpakan] [CS50.TV]