[Powered by Google Translate] [Java 4] [David J. Malan] [Universiteti i Harvardit] [Kjo është CS50.] [CS50.TV] Të gjithë të drejtë, kjo është CS50, dhe ky është fillimi i javës 4, dhe kjo është një nga algoritme zgjidhja slowest të jetë e mundur. Cili ishte ajo që ne vetëm shikuar atje? Kjo ishte lloj flluskë, në mënyrë madhe O (n ^ 2) + shuma, dhe në të vërtetë ne nuk jemi të vetmit në këtë botë për të duket të dini çfarë lloj flluskë është ose koha e tij drejtimin. Në të vërtetë, kjo ishte një intervistë me Eric Schmidt e Google dhe ish-senatori Barack Obama vetëm disa vite më parë. Tani, senatori, ju jeni këtu në Google, dhe unë doja të mendoj për presidencën si një intervistë për punë. Tani, është e vështirë për të marrë një punë si president, dhe ju jeni duke kaluar nëpër masa të rrepta tani. Është gjithashtu e vështirë për të marrë një punë në Google. Ne kemi pyetje dhe ne pyetje kandidatët tanë, dhe kjo është nga Larry Schwimmer. Ju djema mendoni se unë jam kidding? Kjo është e drejtë këtu. Cila është mënyra më efikase për të zgjidhur një milion 32-bit integers? [Qeshura] Well- Unë jam i keq. >> Jo, jo, jo, jo. Unë mendoj se lloj flluskë do të jetë mënyra e gabuar për të shkuar. Come on, i cili i tha atij këtë? Javën e kaluar kujtohet ne e mori një pushim nga kodi, të paktën për një ditë, dhe filloi duke u fokusuar në disa ide të nivelit të lartë dhe zgjidhjen e problemeve në përgjithësi në kontekstin e kërkimit dhe klasifikim, dhe ne kemi prezantuar diçka që ne nuk mu këtë emër në javën e kaluar, por simbol asymptotic, O Big, Big Omega, dhe nganjëherë Big simbol Theta, dhe këto ishin thjesht mënyra për të përshkruar kohën drejtimin e algoritmeve, sa kohë ajo merr për një algoritmi për të kandiduar. Dhe ju mund të kujtojnë se keni folur në lidhje me kohën që kalon në aspektin e madhësisë të dhëna, të cilat ne zakonisht e quajmë n, çfarëdo problemi mund të jetë, ku n është numri i njerëzve në dhomë, numri i faqeve në një libër telefoni, dhe kemi filluar të shkruaj gjëra jashtë si O (n ^ 2) ose O (n) ose O (n log n), dhe madje edhe kur matematikë nuk ka mjaft të punojnë jashtë në mënyrë të përkryer dhe ajo ishte n ² - n / 2 ose diçka si kjo ne do të në vend të vetëm hedhin larg disa nga termat e rendit më të ulët, dhe motivimi nuk është që ne të vërtetë duan një lloj mënyrë objektive të vlerësimit performanca e programeve ose kryerjen e algoritmeve që në fund të ditës nuk ka asgjë për të bërë, për shembull, me shpejtësinë e kompjuterit tuaj sot. Për shembull, në qoftë se ju të zbatuar lloj flluskë, ose keni zbatuar bashkojë lloj lloj ose të përzgjedhjes në kompjuterin e sotme, 2 GHz një kompjuter, dhe ju drejtuar atë, dhe kjo merr disa numrin e sekondave, vitin e ardhshëm ka një 3 GHz ose një kompjuter 4 GHz, dhe pastaj ju mund të pretendojnë se "Wow, algoritmi im tani është dy herë më shpejt ", kur në realitet që nuk është padyshim rasti. Është vetëm hardware ka marrë të shpejtë, por kompjuteri juaj nuk ka, dhe kështu që ne të vërtetë duan të hedhin larg gjëra të tilla si multiples e 2 ose shumëfisha të 3 kur është fjala për të përshkruar se sa shpejt apo sa i ngadalshëm një algoritmi është dhe me të vërtetë vetëm të përqëndrohet on n apo ndonjë faktor të saj, disa fuqi të tyre si në rastin e llojeve nga java e fundit. Dhe kujtojnë se me ndihmën e lloj Merge ne kemi qenë në gjendje të bëjë shumë më mirë se lloj lloj flluskë dhe përzgjedhjes dhe madje edhe lloj futje. Ne mori poshtë për të n log n, dhe përsëri, kujtojnë se log n në përgjithësi i referohet diçkaje që rritet më ngadalë, atëherë n, kështu që n log n deri tani ka qenë i mirë sepse ajo ishte më pak se n ². Por për të arritur n log n me lloj Merge çfarë ishte embrion themelor i një ide që ne kishim për të levave se ne leveraged të kthehet në javë 0? Si e kemi trajtuar këtë problem zgjidhja cleverly me lloj Merge? Cili ishte çelësi pasqyrë, ndoshta? Çdokush në të gjitha. Mirë, le të marrin një hap prapa. Përshkruani bashkojë lloj në fjalët tuaja. Si e bëri atë punë? Mirë, ne do të kthehet në rresht 0 javë. Mirë, po. [E padëgjueshme-studenti] Mirë, mirë, kështu që ne ndarë rrjet të numrave në 2 copa. Ne renditura secilin nga këto copa, dhe pastaj ne u bashkua atyre, dhe ne kemi parë këtë ide para se të marrë një problem që kjo të mëdha dhe i shëndoshë atë në një problem që është ky i madh apo kjo e madhe. Kujtojnë shembullin librin e telefonit. Kujtojnë algorithm vetë-llogaritur nga javë më parë, kështu renditjes bashkojë ishte përmbledhur nga ky pseudokod këtu. Kur ju jeni të dhënë elemente n, së pari kontrolloni mendje e shëndoshë ajo ishte. Nëse n <2 atëherë nuk bëni asgjë në të gjitha sepse në qoftë se n <2 pastaj n është padyshim 0 ose 1, dhe kështu që nëse kjo është ose 0 ose 1 nuk ka asgjë për të zgjidhur. Ju jeni bërë. Lista juaj tashmë është renditur trivially. Por ndryshe qoftë se ju keni marrë 2 ose më shumë elemente të shkojnë përpara dhe të ndani ato në 2 gjysmave, majtas dhe djathtas. Lloj secili prej atyre gjysmave, dhe pastaj bashkojë gjysmave renditen. Por problemi këtu është se në shikim të parë kjo duket si ne jemi punting. Ky është një përkufizim rrethore në se në qoftë se unë kam pyetur ju për të zgjidhur këto elemente n dhe ju jeni duke thënë mua "Në rregull, në rregull, ne do të zgjidhim ato elemente n / 2 dhe ato n / 2," atëherë pyetja ime e ardhshme do të jetë "Fine, si ju zgjidhur n / 2 elemente?" Por për shkak të strukturës së këtij programi, sepse nuk është ky rasti bazë, në mënyrë që të flasin, Në këtë rast të veçantë që thotë se nëse n është > Sara, të gjithë të drejtë. Kelly. >> Kelly dhe? Willy. >> Willy, Sara, Kelly, dhe Willy. Tani për tani unë kam qenë i kërkuar pyetje nga dikush sa njerëz janë deri në këtë fazë, dhe unë nuk kam asnjë ide. Kjo është një listë të gjatë me të vërtetë, dhe kështu në vend që unë jam duke shkuar për të bërë këtë mashtrim. Unë jam duke shkuar për të kërkuar personin tjetër për mua për të bërë më të madhe të punës, dhe një herë ajo është bërë bërë më të madhe të punës Unë jam duke shkuar për të bërë sa më pak të jetë e mundur e punës dhe vetëm të shtoni 1 për çdo gjë e saj është përgjigje, kështu që këtu ne do të shkojmë. Unë kam qenë i pyetur se sa shumë njerëz janë në skenë. Sa njerëz janë në skenë në të majtë të ju? E majta prej meje? >> Mirë, por nuk mashtrojnë. Kjo është e mirë, kjo është e saktë, por në qoftë se ne duam të vazhdojmë këtë logjikë le të supozojmë që ju doni të ngjashme sandall këtë problem në të majtë prej jush, kështu që në vend se përgjigje të drejtpërdrejtë të shkojnë përpara dhe vetëm të kalojë dollar. Oh, sa njerëz janë në të majtë të mua? Sa njerëz janë në të majtë? 1. [Qeshura] Mirë, kështu 0, kështu që çfarë tani Willy ka bërë po ju keni kthyer përgjigjen tuaj këtë drejtim duke thënë 0. Tani, çfarë duhet të bëni? >> 1. Mirë, kështu që ju jeni 1, kështu që ju thonë: "Në rregull, unë jam duke shkuar për të shtuar 1 për çfarëdo numërimin Willy ishte, "kështu që 1 + 0. Ju jeni tani 1 deri përgjigjja juaj për të drejtën tani është- 1. >> Dhe minave do të jetë 2. Mirë, kështu që ju jeni duke marrë përgjigjen e mëparshme 1, duke shtuar sasinë minimale të punës që ju doni të bëni, e cila është +1. Ju tani keni 2, dhe ju pastaj të dorëzojnë mua cilat vlera? 3, Unë do të thotë, sorry, 2. Mirë. E pra, ne kishim 0 të majtë. Pastaj kemi pasur 1, dhe pastaj ne shtoni 2, dhe tani ju jeni dorëzimin mua numrin 2, dhe kështu që unë jam duke thënë, në rregull, +1, 3. Ka të vërtetë 3 persona duke qëndruar pranë meje në këtë fazë, kështu që ne mund të kemi bërë këtë shumë të qartë linear, shumë në mënyrë të dukshme, por çfarë nuk kemi të vërtetë? Ne patëm marrë një problem të madhësisë 3 fillimisht. Ne pastaj e thyen atë në një problem të madhësisë 2, pastaj një problem i madhësisë 1, dhe pastaj në fund rasti bazë ishte me të vërtetë, oh, nuk ka një atje, në të cilën pikë Willy kthye në mënyrë efektive një hard-coded përgjigja disa herë, dhe e dyta u bubbled pastaj, bubbled lart, bubbled deri, dhe pastaj duke shtuar në këtë 1 një shtesë ne kemi zbatuar këtë ide bazë të recursion. Tani, në këtë rast ajo nuk ka të vërtetë të zgjidhur një problem më efektive, atëherë ne kemi parë deri tani. Por mendoj rreth algoritmeve ne kemi bërë në skenë deri tani. Ne kemi pasur 8 copa letre në dërrasë, në video kur Sean ishte në kërkim për numrin 7, dhe çfarë bëri ai me të vërtetë të bëjë? E pra, ai nuk ka bërë asnjë lloj përçaj dhe sundo. Ai nuk e ka bërë asnjë lloj recursion. Përkundrazi ai vetëm e bëri këtë algorithm linear. Por kur kemi futur idenë e numrave të renditura në skenë jetojnë javën e kaluar atëherë kemi pasur këtë instinkt për të shkuar në mes, në të cilën pikë kemi pasur një listë të vogël të madhësisë 4 apo në një tjetër listë të madhësisë 4, dhe pastaj kemi pasur problemin e saktë të njëjta, kështu që ne kemi përsëritur, përsëritet, përsëritet. Me fjalë të tjera, ne recursed. Thank you very much për vullnetarët 3 tanë këtu për demonstrimin recursion me ne. Le të shohim nëse ne nuk mund të bëjë këtë tani betonit e një pak më shumë, zgjidhjen e një problemi që përsëri ne mund të bëjmë shumë lehtë, por ne do të përdorin atë si një hap drejt zbatimit këtë ide themelore. Në qoftë se unë dua të llogaritur përmbledhje e një bandë të numrave, për shembull, në qoftë se ju të kalojë në numrin 3, Unë dua të ju jap vlerën e 3 Sigma, kështu që shuma e 3 + 2 + 1 + 0. Unë dua të të marrë përsëri përgjigjen 6, kështu që ne do të zbatojë këtë funksion SIGMA, ky funksion përmbledhje që, përsëri, merr në të dhëna, dhe pastaj kthehet mbledhje e këtij numri të gjithë rrugën poshtë për 0. Ne mund të bëjmë këtë mjaft thjesht, apo jo? Ne mund të bëjmë këtë me një lloj të strukturës looping, kështu që le të shkoj përpara dhe të marrë këtë filluar. Përfshijnë stdio.h. Më lejoni të merrni veten në kryesore për të punuar me këtu. Le të ruani këtë si sigma.c. Atëherë unë jam duke shkuar për të shkuar në këtu, dhe unë jam duke shkuar për të deklaruar një int n, dhe unë jam duke shkuar për të bërë në vijim, ndërsa përdoruesi nuk bashkëpunon. Ndërsa përdoruesi nuk ka dhënë mua një numër pozitiv më lejoni të shkoj përpara dhe të nxisë ata për n = GetInt, dhe më lejoni t'u dhënë atyre disa udhëzime se çfarë të bëjë, kështu printf ("numër i plotë pozitiv lutem"). Vetëm diçka relativisht e thjeshtë si kjo në mënyrë që me kohë kemi goditur vijën 14 ne tani kemi një numër i plotë pozitiv me sa duket në n. Tani le të bëjë diçka me të. Më lejoni të shkoj përpara dhe të llogaritin përmbledhje, kështu int shuma = SIGMA (n). Sigma është vetëm përmbledhje, kështu që unë jam vetëm duke e shkruar atë në mënyrë njohës. Ne vetëm do të thërrasë atë SIGMA atje. Kjo është shuma, dhe tani unë jam duke shkuar për të shtypur jashtë rezultatin, printf ("Shuma eshte% d \ n", shuma). Dhe atëherë unë do të kthehet 0 për masë të mirë. Ne kemi bërë gjithçka që ky program kërkon përveç pjesën interesante, e cila është në fakt zbatojë funksionin SIGMA. Më lejoni të shkoj këtu poshtë në fund, dhe më lejoni të deklaroj funksion SIGMA. Është marrë për të marrë një ndryshore që është numër i plotë i tipit, dhe çfarë lloji të dhënave nuk dua të kthehen me sa duket nga Sigma? Int, sepse unë dua që ajo të shkojë pritjet e mia on line 15. Këtu më lejoni të shkoj përpara dhe të zbatojnë këtë në një mënyrë mjaft të thjeshtë. Le të shkojnë përpara dhe të thonë se shuma int = 0, dhe tani unë jam duke shkuar për të shkuar të ketë një pak për lak këtu që do të thotë diçka si kjo, për (int i = 0; I <= numri; i + +) shuma + = i. Dhe atëherë unë jam duke shkuar për të kthyer shumën. Unë mund të ketë zbatuar këtë në çdo numër të mënyra. Unë mund të ketë përdorur një lak kohë. Unë mund të ketë skipped duke përdorur ndryshore shuma në qoftë se unë me të vërtetë të kërkuar për të, por në të shkurtër, ne vetëm kemi një funksion që në qoftë se unë nuk e kam budalla deklaron shuma është 0. Pastaj ai iterates nga 0 në UP përmes numrit, dhe në çdo përsëritje ajo shton se vlera aktuale të shumës dhe pastaj kthehet shumë. Tani, ka një optimization të vogël këtu. Kjo është ndoshta një hap tretur, por kështu të jetë ajo. Kjo është në rregull tani për tani. Ne jemi të paktën të qenë të plotë dhe do 0 të gjithë rrugën deri në. Jo shumë e vështirë dhe shumë e drejtpërdrejtë, por kjo rezulton se me funksionin Sigma kemi të njëjtën mundësi si ne e bëmë këtu në skenë. Në skenë llogaritet ne vetëm sa njerëz ishin pranë meje, por në qoftë se ne të kërkuar për të numëruar numrin 3 + 2 + 1 më poshtë për të 0 ne mund ngjashme sandall në një funksion se unë do të në vend të përshkruar si rekursive. Këtu le të bëjë një mendje e shëndoshë të shpejtë të kontrolluar dhe të sigurt nuk e kam budalla. Unë e di se ka të paktën një gjë në këtë program që unë kam bërë gabim. Kur unë goditi të hyjë jam unë do të marrë ndonjë lloj të yelling në mua? Çfarë jam unë do të yelled në rreth? Po, kam harruar prototip, kështu që unë jam duke përdorur një funksion të quajtur sigma on line 15, por kjo nuk është deklaruar deri më 22 linjë, kështu që unë më mirë të shkojnë deri këtu në mënyrë proaktive dhe të deklarojë një prototip, dhe unë do të them int SIGMA (int numri), dhe kjo është ajo. Është realizuar në pjesën e poshtme. Ose në një tjetër mënyrë unë mund të zgjidhur këtë, Unë mund të lëvizin funksionin deri atje, e cila nuk është e keqe, por të paktën kur programet tuaja të fillojë të marrë shumë kohë, sinqerisht, Unë mendoj se ka disa vlera në gjithmonë duke pasur kryesor në krye kështu që ju lexuesi në mund të hapur dosjen dhe pastaj menjëherë të parë çfarë programi është bërë pa pasur nevojë për të kërkuar nëpërmjet saj kërkoni për atë funksion kryesor. Le të shkojë poshtë në dritaren time terminal këtu, provoni duke bërë SIGMA bëjë Sigma, dhe unë i dehur deri këtu shumë. Deklarata e nënkuptuar GetInt funksion do të thotë unë kam harruar të bëj çfarë tjetër? [E padëgjueshme-studenti] Mirë, kështu që me sa duket një gabim i përbashkët, kështu që le të vënë këtë deri këtu, cs50.h, dhe tani le të kthehemi në dritaren time terminal. Unë do të qartë në ekran, dhe unë do të bëjë përsëritje SIGMA. Kjo duket të ketë hartuar. Më lejoni tani të drejtuar SIGMA. Unë do të shkruani në numrin 3, dhe unë kam marrë 6, kështu që nuk është një kontroll rigoroz, por të paktën kjo duket të jetë duke punuar në shikim të parë, por tani le të shqyej atë larg, dhe le të levave të vërtetë idenë e recursion, përsëri, në një kontekst shumë të thjeshtë në mënyrë që në kohë disa javësh " kur ne fillojmë eksplorimin strukturat njohës të dhënave se vargjeve ne kemi një tjetër mjet në veglën me të cilin do të manipuluar ato struktura të dhënave si ne do të shohim. Kjo është qasja përsëritës, lak-bazuar qasje. Më lejoni tani në vend që të bëjë këtë. Më lejoni të them se në vend të kësaj përmbledhje e numrit më poshtë për 0 është me të vërtetë e njëjta gjë si Numri + SIGMA (numër - 1). Me fjalë të tjera, ashtu si në skenë unë punted për secilin nga njerëzit pranë meje, dhe ata nga ana e punting mbahen deri ne fund u ndal në Willy, i cili kishte për t'u kthyer një përgjigje vështirë-koduar si 0. Ja tani ne jemi në mënyrë të ngjashme për të punting Sigma funksioni njëjtë si u quajt fillimisht, por pasqyrë kyçe këtu është se ne nuk jemi duke bërë thirrje Sigma identike. Ne nuk jemi duke kaluar n. Ne jemi të qartë duke kaluar në numër - 1, kështu një problem pak më e vogël, problemi pak më e vogël. Për fat të keq, kjo nuk është mjaft e një zgjidhje ende, dhe para se ne të rregullojmë çfarë mund të jetë hedhur jashtë si të dukshme në disa prej jush më lejoni të shkoj përpara dhe të bëjë përsëritje. Kjo duket të përpilojë rregull. Më lejoni përsëritje Sigma me 6. Uh, më lejoni përsëritje Sigma me 6. Ne kemi parë këtë më parë, edhe pse koha e kaluar si edhe aksidentalisht. Pse nuk kam marrë këtë faj fshehtë segmentimit? Po. [E padëgjueshme-studenti] Nuk ka asnjë rast bazë, dhe më konkretisht, çfarë ka ndodhur ndoshta? Kjo është një simptomë e asaj sjellje? Thuaj atë pak louder. [E padëgjueshme-studenti] Kjo është një loop pafund në mënyrë efektive, dhe problemi me sythe pafund kur ato përfshijnë recursion në këtë rast, një funksion që e quan veten, çfarë ndodh çdo herë që të thërrasë një funksion? E pra, mendoj se mbrapa se si kemi hedhur jashtë kujtesës në një kompjuter. Ne thamë se nuk është kjo copë e kujtesës quajtur stack që është në fund, dhe çdo herë që të thërrasë një funksion memorie pak më merr vënë në këtë turrë të ashtuquajturës përmban variablat lokale që funksionojnë ose parametrat, kështu që nëse SIGMA SIGMA SIGMA thirrje thirrje thirrje SIGMA  Sigma quan ku ka marrë fund kjo histori? E pra, ajo përfundimisht overruns shuma totale e kujtesës që ju keni në dispozicion në kompjuterin tuaj. Ju muar segmentin që ju jeni menduar për të qëndruar brenda, dhe ju merrni këtë fajin segmentimit, core hedhur, dhe çfarë thelbi hedhur të thotë është se unë tani kam një skedar të quajtur thelbësore cila është një file që përmban zero dhe ato që në fakt në të ardhmen do të jetë e dobishme diagnostikuese. Nëse kjo nuk është e qartë për ju se ku bug juaj është ju mund të bëjë në fakt një grimë e analizave mjeko-ligjore, në mënyrë që të flasin, në këtë skedar hale bazë, e cila, përsëri, është vetëm një bandë e tërë e zero dhe ato që në thelb paraqet gjendjen e programit tuaj në kujtesë momenti ai u rrëzua në këtë mënyrë. Fix këtu është se ne nuk mund të kthehen vetëm verbërisht Sigma, numri + sigma një problem pak më të vogël. Ne duhet të ketë disa lloj e rastit bazë këtu, dhe çfarë duhet të rastit bazë ndoshta do të jetë? [E padëgjueshme-studenti] Mirë, për sa kohë që numri është pozitive që ne duhet të vërtetë të kthehet kjo, ose të vënë një tjetër mënyrë, nëse numri është, të themi, <= 0 për ju e dini se çfarë, unë do të shkoj përpara dhe të kthehen 0, shumë si Willy bëri, dhe tjetër, unë jam duke shkuar për të shkuar përpara dhe të kthehet këtë, kështu që nuk është se shumë më e shkurtër se versioni përsëritës që ne whipped up e parë duke përdorur një për lak, por vëreni se ekziston kjo lloj hijeshi ndaj saj. Në vend që të kthehen disa numrin dhe kryerjen e të gjitha matematikë këtë dhe duke shtuar gjëra me variablat lokale ju jeni në vend duke thënë: "Mirë, në qoftë se ky është një problem i super i lehtë, si numri është <0, më lejoni të kthehen menjëherë 0 ". Ne nuk do të shqetësojë numrat negative mbështetëse, kështu që unë jam duke shkuar për kodin vështirë vlerën e 0. Por ndryshe, për të zbatuar këtë ide të mbledhur të gjitha këto së bashku numrat që ju mund të në mënyrë efektive të marrë një pickim të vogël nga e problemit, ashtu si ne e bëmë këtu në skenë, pastaj sandall pjesa tjetër e problemit tek personi tjetër, por në këtë rast personi tjetër është vetë. Kjo është një funksion të quajtur identike. Vetëm të kalojë një problem të vogël dhe më të vogla dhe të vogla çdo kohë, dhe edhe pse ne nuk e kemi formalizuar gjëra mjaft në kodin këtu kjo është pikërisht ajo që po ndodhte në javën 0 me librin e telefonit. Kjo është pikërisht ajo që po ndodhte në javët e fundit me Sean dhe me demonstratat tona të kërkoni për numrat. Është marrë një problem dhe ndarë atë përsëri dhe përsëri. Me fjalë të tjera, ka një mënyrë tani e përkthyer ky konstrukt reale botë, ky konstrukt të nivelit të lartë i përça dhe sundo dhe duke bërë diçka përsëri dhe përsëri në kodin, kështu që kjo është diçka që ne do të shohim sërish me kalimin e kohës. Tani, si një mënjanë, në qoftë se ju jeni e re në recursion ju duhet të paktën të kuptojnë tani pse kjo është qesharake. Unë jam duke shkuar për të shkuar në google.com, dhe unë jam duke shkuar për të kërkuar për disa këshilla dhe truket për recursion, të hyjë. Tregoj personin tjetër për ju, nëse ata nuk ishin të qeshur vetëm tani. Did you mean recursion? Did you mean-ah, atje ne do të shkojmë. Mirë, tani që është pjesa tjetër e të gjithëve. Pak vezë të Pashkëve ngulitur diku atje në Google. Si një mënjanë, një nga lidhjet ne kemi vënë në faqen e internetit të kursit të për sot është vetëm ky rrjet e algoritme zgjidhja ndryshme, disa prej të cilave kemi shikuar në javën e kaluar, por ajo që është e bukur në lidhje me këtë vizualizimit si ju të përpiqet të përfundojë mendjen tuaj rreth gjërave të ndryshme që lidhen me algoritme dini se ju mund shumë lehtë të filloni tani me lloje të ndryshme të inputeve. Inputeve të gjitha përmbyset, inputet renditura më së shumti, të inputeve të rastit dhe kështu me radhë. Si ju përpiqeni për të, përsëri, dallojnë këto gjëra në mendjen tuaj kuptojnë se kjo URL në faqen e internetit të kursit mbi faqen e leksione mund të ju ndihmojë arsyeja nëpër disa nga ato. Sot ne të merrni në fund të zgjidhur këtë problem nga një kohë prapa, e cila ishte se ky funksion swap thjesht nuk keni punuar, dhe çfarë ishte problemi themelor me këtë shkëmbim funksion, qëllimi i së cilës ishte, përsëri, për të shkëmbyer një vlerë këtu dhe këtu tillë që të ndodhë kjo? Kjo nuk ka të vërtetë punojnë. Pse? Po. [E padëgjueshme-studenti] Pikërisht, shpjegimi për këtë bugginess thjesht ishte sepse kur ju telefononi funksionet në C dhe ato funksione të marrë argumente, si a dhe b këtu, ju jeni duke kaluar në kopje të çfarëdo vlerë që ju jeni të siguruar në atë funksion. Ju nuk janë duke ofruar vlera origjinale veten, kështu që ne pamë këtë në kontekstin e buggyc, buggy3.c, i cili dukej një diçka të vogël si kjo. Kujtojnë se ne kishim x dhe y nisur me 1 dhe 2, përkatësisht. Ne pastaj të shtypura atë që ata ishin. Unë pastaj pretendoi se unë u shkëmbejnë ato me thirrjen shkëmbim të x, y. Por problemi ishte se shkëmbejnë punuar, por vetëm në kuadër të swap-it të funksionojnë vetë. Sa më shpejt që ne e goditi linjë 40 atyre vlerave swapped u hodhën larg, dhe kështu asgjë në funksion të origjinal kryesor është ndryshuar në të vërtetë në të gjitha, kështu që nëse ju mendoni atëherë se çfarë kjo duket si në aspektin e kujtesës sonë nëse kjo majtë anë e bordit përfaqëson- dhe unë do të bëj çmos për të gjithë për të parë këtë, nëse kjo majtë anë e bordit përfaqëson, të themi, RAM tuaj dhe rafte do të rritet në dorë këtë mënyrë, dhe ne e quajmë si një funksion kryesor, dhe kryesore ka 2 variabla lokale, x dhe y, le të përshkruajnë ato si x këtu, dhe le të përshkruajnë këto si y këtu, dhe le të vënë në vlerat 1 dhe 2, kështu që kjo këtu është kryesore, dhe kur funksioni kryesor i quan shkëmbim të sistemit operativ jep funksioni Swap brez i kositur e vet të kujtesës në rafte, kornizë e vet në rafte, në mënyrë që të flasin. Ajo gjithashtu ndan 32 bit për këto ints. Kjo ndodh për të thirrur ata a dhe b, por kjo është krejtësisht arbitrare. Ajo mund të ketë thirri çfarëdo që dëshiron, por çfarë ndodh kur kryesore thirrjet swap-i është ai merr këtë 1, vë një kopje atje, vë një kopje atje. Ka 1 ndryshueshme tjera lokale në shkëmbim, pse, quhet ajo? Tmp. >> Tmp, kështu që më lejoni t'ju jap vetes një tjetër 32 bit këtu, dhe çfarë nuk kam bërë në këtë funksion? Unë i thashë tmp int merr, kështu që një ka 1, kështu që unë e bëri këtë, kur ne kemi luajtur kaluar me këtë shembull. Pastaj një merr b, kështu që është 2 b, kështu që tani kjo bëhet 2, dhe tani merr temp b, kështu temp është 1, kështu që tani b bëhet kjo. Kjo është e madhe. Ajo ka punuar. Por pastaj sa më shpejt të kthimit funksion kujtesës swap efektivisht zhduket në mënyrë që ajo të mund të ripërdoren disa nga funksioni tjetër në të ardhmen, dhe kryesore është padyshim plotësisht e pandryshuar. Ne kemi nevojë për një mënyrë për të krejtësisht të zgjidhur këtë problem, dhe sot ne do të kemi më në fund një mënyrë për të bërë këtë të cilën ne mund të vendosë diçka që quhet një akrep. Ajo rezulton se ne mund të zgjidhur këtë problem jo duke kaluar në formë të x dhe y por në vend duke kaluar në atë, a mendoni se, në funksion swap? Po, çka në lidhje me adresën e? Ne nuk kemi biseduar me të vërtetë në lidhje me adresat në detaje shumë, por në qoftë se kjo dërrasë e zezë paraqet kujtesën e kompjuterit tim ne me siguri mund të fillojnë të numërojnë bytes në RAM e mia dhe thonë se kjo është # 1 byte, kjo është bajt # 2, # 3 bajt, bajt # 4, # bajt ... 2 miliard nëse kam 2 gigabajt RAM, kështu që ne me siguri mund të dalë me disa skemë arbitrare numeracionit për të gjitha bytes individuale në kujtesë të kompjuterit tim. Çka nëse në vend kur unë e quaj swap në vend se të kalojë në kopje të x dhe y pse nuk kam vend të kalojë në adresën e x këtu, adresa e y këtu, në thelb adresën postare nga x dhe y, sepse atëherë bie në ujdi, në qoftë se ai është i informuar e adresës në kujtim të x dhe y, pastaj swap, në qoftë se ne të trajnuar atë pak, ai potencialisht mund të përzënë në atë adresë, kështu që të flasin, x, dhe për të ndryshuar numrin e atje, pastaj me makinë në adresën e y, ndryshojë numrin atje, edhe kur në të vërtetë nuk bëhet kopje e atyre vlerave veten, kështu që edhe pse kemi biseduar në lidhje me këtë si memorie kryesore e dhe kujtesës Kete swap si të fuqishëm dhe një pjesë e rrezikshme e C është se çdo funksion mund të prekë kujtesën kudo në kompjuter, dhe kjo është e fuqishme në atë që ju mund të bëni shumë gjëra të dashuroj me programe kompjuterike në C. Kjo është e rrezikshme, sepse ju gjithashtu mund të vidhos deri shumë lehtë. Në fakt, një nga mënyrat më të zakonshme për programet këto ditë për t'u shfrytëzuar ende është për të mos një programues për të realizuar se ai ose ajo është e lejuar një të dhënave të jetë e shkruar në një vend në kujtesën që nuk ishte menduar. Për shembull, ai ose ajo deklaron një rrjet të madhësisë 10 por pastaj përpiqet për të vënë aksidentalisht 11 bytes në atë grup të kujtesës, dhe ju filloni duke prekur pjesët e kujtesës që nuk janë më të vlefshme. Vetëm për kontekstuale këtë, disa nga ju mund të dini se software shpesh ju bën për numrat serik ose çelësat e regjistrimit, Photoshop dhe Word dhe programet e pëlqejnë këtë. Ekzistojnë të çara, si disa nga ju e dini, online ku ju mund të kandidojë një program pak, dhe voila, asnjë kërkesë më shumë për një numër serial. Si është se duke punuar? Në shumë raste këto gjëra janë thjesht të gjetur në kompjuter segmente tekst në zero aktuale e kompjuterit dhe atyre ku është se funksioni ku numri serik është kërkuar, dhe ju të prishësh atë hapësirë, ose kur programi është i rrjedhshëm ju mund të kuptoj se ku çelësi është ruajtur në të vërtetë duke përdorur diçka që quhet Rregullues, dhe ju mund të goditur në këtë mënyrë software. Kjo nuk do të thotë se ky është objektivi ynë për të dy ditëve të ardhshme, por ajo ka shumë e vërtetë të botës degëzime. Se një ndodh të përfshijë vjedhjen e software, por ka edhe kompromisi i makinave të tëra. Në fakt, kur faqet e internetit këto ditë janë shfrytëzuar dhe komprometuar dhe të dhënat është zbuluar dhe fjalëkalimet janë vjedhur kjo shpesh lidhet me menaxhimin e dobët të kujtesës së dikujt, ose, në rastin e të dhënave, dështimi tek parashikojnë input kundërshtuese, kështu që më shumë se në javët që do të vijnë, por tani për tani vetëm një vrojtim vjedhës i lloj e dëmit që ju mund të bëni duke mos kuptuar mjaft se si gjërat punojnë nën kapuç. Le të shkojë në lidhje me të kuptuarit se pse kjo është e thyer me një mjet që do të bëhet gjithnjë e më e dobishme si programet tona të merrni më shumë komplekse. Deri tani, kur ju keni pasur një bug në programin tuaj si keni shkuar për debugging atë? Cilat kanë qenë teknikat tuaja deri më tani, qoftë mësohet nga TF tuaj ose thjesht vetë-mësohet? [Student] printf. Printf, kështu printf ka qenë ndoshta miku juaj në se në qoftë se ju doni të shihni çfarë po ndodh në brendësi të programit tuaj ju vetëm të vënë printf këtu, printf këtu, printf këtu. Pastaj ju drejtuar atë, dhe ju merrni një bandë e tërë e gjëra në ekran që ju mund të përdorni për të nxjerr një përfundim se çfarë është, atëherë vërtetë do të gabuar në programin tuaj. Printf tenton të jetë një gjë shumë e fuqishme, por kjo është një proces shumë manual. Ju keni për të vënë një printf këtu, një printf këtu, dhe në qoftë se keni vënë atë në brendësi të një lak që ju mund të merrni 100 linja e prodhimit që atëherë ju duhet të shosh përmes. Kjo nuk është një mekanizëm shumë përdorues-miqësor apo për programe interaktive debugging, por fatmirësisht ekziston alternativa. Ka një program, për shembull, i quajtur GDB, Debugger GNU, e cila është një misterioze pak në atë se si ta përdorni atë. Është një kompleks pak, por sinqerisht, kjo është një nga ato gjëra ku në qoftë se ju vendosni në këtë javë dhe të ardhshëm orë shtesë për të kuptuar diçka si gdb ajo do të ju kursejnë ndoshta dhjetëra orë në afat të gjatë, Pra, me këtë, më lejoni t'ju jap një ngacmues të asaj se si funksionon kjo gjë. Unë jam në dritaren time terminal. Më lejoni të shkojnë përpara dhe të hartojnë këtë program, buggy3. Kjo është tashmë deri në datën. Më lejoni të drejtuar atë ashtu si ne e bëmë një prapa kohë, dhe në të vërtetë, ajo është e thyer. Por pse është kjo? Ndoshta unë dehur funksionin swap. Ndoshta ajo është a dhe b. Unë nuk jam mjaft i lëvizur rreth tyre të saktë. Më lejoni të shkojnë përpara dhe të bëjë këtë. Në vend se vetëm të drejtuar buggy3 lejoni të drejtuar këtë vend GDB program, dhe unë jam duke shkuar për të treguar atë për të kandiduar buggy3, dhe unë jam duke shkuar për të përfshirë një argument command line,-TUI, dhe ne do të vënë këtë në të ardhmen probleme në spekulim për t'i kujtuar. Dhe tani kjo ndërfaqe të zezë dhe të bardhë popped up se, përsëri, është pak më e madhe në fillim, sepse nuk është e gjitha kjo Informacioni garanci poshtë këtu, por të paktën ka diçka të njohur. Në krye të dritares është kodi im aktuale, dhe në qoftë se unë lëviz deri këtu më lejoni të shkoni në krye të dosjes sime, dhe në të vërtetë, nuk ka buggy3.c, dhe njoftim në fund të kësaj dritare Unë kam këtë Prompt GDB. Kjo nuk është njëjtë si prompt time normale John Harvard. Kjo është një shpejtë që do të më lejoni të kontrolluar GDB. Gdb është një korrigjuesin. Një Rregullues është një program që ju lejon të ecin nëpër Ekzekutimi i linjës tuaj të programit duke rresht pas rreshti, bashku mënyrë duke bërë çdo gjë që ju dëshironi të programit, edhe funksionet e quajtur, ose në kërkim, më e rëndësishmja, në vlerat e ndryshueshme të ndryshme së. Le të shkojnë përpara dhe të bëjë këtë. Unë jam duke shkuar për të shkuar përpara dhe të shkruani në afat të shpejtë në GDB-së, kështu njoftim në pjesën e poshtme të majtë të ekranit kam shtypur të kandiduar, dhe unë kam goditur të hyjë, dhe çfarë bëri që të bëni? Është fjalë për fjalë u zhvillua programin tim, por unë në fakt nuk shoh shumë të shkojnë në këtu sepse unë nuk kam fakt tha Rregullues për pauzë në një moment të veçantë në kohë. Vetëm shtypni kandidojë shkon programin. Unë nuk shoh asgjë të vërtetë. Unë nuk mund ta manipulojë atë. Në vend të kësaj më lejoni të bëjë këtë. Në këtë prompt Gdb lejoni vend shkruani pushim, të hyjë. Kjo nuk është ajo që unë do të thotë të tipit. Le të shkruani në vend pushim kryesore. Me fjalë të tjera, unë dua të vendosur diçka të quajtur një breakpoint, e cila është quajtur me vend, sepse ajo do të thyejnë apo pauzë Ekzekutimi i programit tuaj në atë vend të veçantë. Kryesor është emri i funksionit tim. Vini re se Gdb është shumë i zgjuar. Është realizuar artistikisht se ndodh kryesore për të filluar afërsisht në linjë 18 e buggy3.c, dhe pastaj të vini re këtu në të majtë krye b + është e drejtë tjetër të linjës 18. Kjo është kujtuar mua se unë kam vendosur një breakpoint në linjë 18. Këtë herë, kur unë lloji të kandidojë, unë jam duke shkuar për të drejtuar programin tim deri ajo godet atë breakpoint, kështu që programi do të pauzë për mua në linjë 18. Këtu ne do të shkojmë, e drejtuar. Asgjë nuk duket të ketë ndodhur, por në fund u largua njoftim Programi filluar, buggy3, 1 në breakpoint kryesor në përputhje buggy3.c 18. Çfarë mund të bëj unë tani? Njoftim unë mund të filloni të shtypni gjëra të tilla si të shtypura, Nuk printf, x shtypura, dhe tani që është e çuditshme. $ 1 është vetëm një kuriozitet, si ne do të shohim çdo herë që të shtypura diçka që ju të merrni një të ri vlerë $. Kjo është kështu që ju mund t'i referohet përsëri në vlerat e mëparshme vetëm në rast, por tani për tani ajo shtyp është thënë mua është se vlera e x në këtë pikë në histori është me sa duket 134.514.032. Çfarë? Ku ka që vijnë edhe nga? [E padëgjueshme-studenti] Në të vërtetë, kjo është ajo që ne do të thërrasë një vlerë plehrash, dhe ne nuk kemi biseduar në lidhje me këtë ende, por arsyeja që ju nisja variabla është e qartë në mënyrë që ata të kenë disa vlera që ju dëshironi që ata të kenë. Por kapur është kujtojnë se ju mund të deklarojë variablave si unë e bëri një moment më parë në shembullin tim SIGMA pa të vërtetë duke u dhënë atyre një vlerë. Kujtojnë se çfarë kam bërë këtu në Sigma. I shpallur n, por çfarë vlerë nuk kam dhënë atë? Asnjë, sepse e dija se në linjat e ardhshme GetInt do të marrë kujdesin e problemit të vënë një vlerë brenda n. Por në këtë pikë në historinë e linjës 11 dhe 12 e linjës dhe linjës 13 dhe 14 linja gjithë atyre disa linja çfarë është vlera e n? Në C që ju thjesht nuk e di. Kjo është në përgjithësi disa vlera plehrash, disa Numri krejtësisht të rastit që e la mbi thelb nga një funksion mëparshme duke qenë të drejtuar, në mënyrë që programi juaj shkon kujtojmë se funksioni i merr, funksion funksion funksion,. Të gjitha këto korniza të merrni vënë në memorie, dhe pastaj ato kthimin funksioneve, dhe ashtu si kam sugjeruar me gomë kujtimi i tyre është ripërdoren përfundimisht. E pra, kjo ndodh pikërisht kështu që X Kjo variabël në këtë program duket të ketë të përfshira disa vlera si mbeturina 134514032 nga disa funksion të kaluar, jo ai që kam shkruar. Kjo mund të jetë diçka që vjen në mënyrë efektive me sistemin operativ, disa funksion nën kapuç. Mirë, kjo është në rregull, por tani le të përparuar në linjë tjetër. Nëse unë tipit "tjetër" në ftim tim GDB dhe unë goditi të hyjë, vëreni se duke theksuar lëviz poshtë në linjë 19, por implikimi logjik është se linja 18 ka mbaruar tani ekzekutimin, kështu që nëse unë përsëri shkruani "print x" Unë tani duhet të shihni 1, dhe në të vërtetë, unë bëj. Përsëri, $ stuff është një mënyrë për të kujtuar ju GDB ajo historia e printime janë që ju keni bërë. Tani më lejoni të shkoj përpara dhe të shtypura nga y, dhe në të vërtetë, y disa vlera çmendur, si edhe, por jo e madhe, sepse në përputhje 19 ne jemi gati për të caktojë atë vlera 2, kështu që më lejoni të tipit "tjetër" përsëri. Dhe tani ne jemi në përputhje printf. Më lejoni të bëj x shtypura. Më lejoni të bëj y shtypura. Sinqerisht, unë jam duke marrë një pak të lodhur e shtypjes këtë. Më lejoni në vend të tipit "ekranit x" dhe "y", ekranit dhe tani çdo herë që unë të shkruani një komandë në të ardhmen Unë do të kujtoi se çka është x dhe y, çfarë është x dhe y, çfarë është x dhe y. Unë gjithashtu mund të, si një lloj mënjanë, në "vendasit info." Info është një komandë të veçantë. Vendorët do të thotë kjo tregon mua variablave lokale. Vetëm në rast se të harroj apo kjo është një i çmendur, funksioni i komplikuar që unë apo dikush tjetër shkruante vendasit info do ju them çfarë janë të gjitha variablat lokale brenda këtij funksioni lokale që ju mund të kujdesen për ju, nëse doni të thes rreth. Tani, printf është gati për të ekzekutuar, kështu që më lejoni të shkoj përpara dhe vetëm lloji "tjetër." Sepse ne jemi në këtë mjedis, ne nuk jeni në të vërtetë duke parë atë ekzekutuar poshtë këtu, por vini re se është duke marrë një pak të coptuar këtu. Por vini re kjo është thelbësore në ekran atje, kështu që nuk është një program i përsosur këtu, por kjo është në rregull, sepse unë gjithmonë mund të thes rreth përdorimin e shtypura në qoftë se unë dua. Më lejoni të shkruani tjetër përsëri, dhe tani këtu është pjesa interesante. Në këtë moment në histori y është 2, dhe x është 1, siç sugjerohet këtu, dhe përsëri, Arsyeja e kësaj është automatikisht shfaqur tani është për shkak se kam përdorur komandën Ekran x dhe y ekranit, kështu që momenti unë lloji tjetër Në teori x dhe y duhet të bëhet swapped. Tani, ne tashmë e dimë se nuk do të jetë rasti, por ne do të shohim në një moment se si ne mund të zhyten më thellë të kuptoj se pse kjo është e vërtetë. Ardhshëm, dhe për fat të keq, është ende y 2 dhe x është ende 1, dhe unë mund të konfirmojë sa më shumë. Print x, y shtypura. Në të vërtetë, nuk shkëmbejnë ka ndodhur në të vërtetë, kështu që le të fillojnë këtë gjatë. Swap është prishur në mënyrë të qartë. Le vend tipit "drejtuar" përsëri. Më lejoni të them po, unë dua për të rifilluar atë nga fillimi, të hyjë. Tani unë jam mbrapa deri në vijën 18. Tani njoftim x dhe y janë vlera mbeturina përsëri. Tjetra, tjetër, tjetër, tjetër. Nëse unë të mërzitem unë gjithashtu mund të shkruani vetëm n për të ardhshëm. Ju mund të shkurtoj atë në rend të shkurtër të mundshme të karaktereve. Swap është prishur tani. Le pikiatë në, kështu që në vend të shtypni tjetër, tani unë jam duke shkuar për të tipit hap në mënyrë që unë jam shkelën në brendësi të këtij funksioni në mënyrë që unë mund të ecin nëpër atë, kështu që unë goditi hap dhe pastaj të hyjë. Vini re se hedhje poshtë theksuar ulët në programin tim të vijë 36. Tani çfarë janë variablat lokale? Vendasit info. Asgjë vetëm ende, sepse ne nuk kemi marrë në atë linjë, kështu që le të shkojnë përpara dhe të thonë "tjetër." Tani ne duket të ketë, tmp tmp shtypura. Garbage vlera, e drejtë? Unë mendoj kështu. Si për të shkruar një të shtypura, b, 1 dhe 2? Në një moment, sa më shpejt që unë lloji tjetër përsëri tmp do të marrë në një vlerë prej 1, me shpresë, sepse tmp do të caktohet vlera e a. Tani le të mos shtypur një B, të shtypura, por tani shtypura tmp, dhe kjo është me të vërtetë 1. Më lejoni të bëjë tjetër. Më lejoni të bëjë tjetër. Unë kam mbaruar funksionin swap. Unë jam ende në brendësi të saj, në përputhje 40, kështu që më lejoni të shtypur një, b shtypura, dhe unë nuk bëj kujdes atë që tmp është. Ajo duket si swap-i është i saktë kur është fjala për një shkëmbimi dhe b. Por në qoftë se unë tani lloji tjetër, unë kërcej prapa në linjë 25, dhe natyrisht, në qoftë se unë lloji në x dhe y të shtypura ata janë ende të pandryshuara, kështu që ne nuk kemi fiksuar problemin. Por diagnostikuese tani ndoshta me këtë program GDB ne kemi marrë të paktën një hap më afër për të kuptuar çfarë po ndodh gabuar pa pasur nevojë për të pjellë kodin tonë duke vënë një printf këtu, printf këtu, këtu dhe pastaj printf drejtimin atë përsëri dhe përsëri duke u përpjekur të kuptoj se çfarë po ndodh gabuar. Unë jam duke shkuar për të shkuar përpara dhe u largua nga kjo së bashku me lë. Kjo do të thotë, atëherë, "Quit anyway?" Po. Tani unë jam kthyer në prompt time normale, dhe unë jam bërë duke përdorur gdb. Si një mënjanë, ju nuk keni nevojë të përdorni këtë TUI-flamur. Në fakt, në qoftë se ju heq atë që ju merrni në thelb gjysmën e poshtme të ekranit. Nëse unë pastaj shtypni pushim kryesore dhe pastaj të drejtuar Unë ende mund të drejtuar programin tim, por ajo që do të bëjë më shumë tekstualisht vetëm tregoni mua një linjë aktual në një kohë. -TUI, ndërfaqe tekstuale përdoruesit, vetëm tregon se ju më e programit në të njëjtën kohë, e cila është ndoshta pak më e lehtë konceptualisht. Por në të vërtetë, unë vetëm mund të bëjë tjetër, tjetër, tjetër, dhe unë jam duke shkuar për të parë një linjë në një kohë, dhe në qoftë se unë me të vërtetë duan të shohin se çfarë po ndodh Unë mund të shtypni listë dhe shoh një bandë e tërë e linjave fqinje. Ka një video që ne kemi kërkuar që ju të shikojnë për problemi përcakton 3 në të cilën Nate mbulon disa prej intricacies e GDB, dhe kjo është një nga ato gjëra, sinqerisht, ku disa jo-parëndësishëm përqindje prej jush kurrë nuk do të prekë GDB, dhe se do të jetë një gjë e keqe sepse fjalë për fjalë ju do të përfundojë duke shpenzuar më shumë kohë më vonë këtë semestër ndiqte poshtë mete atëherë ju do të qoftë se keni vënë në atë orë e gjysmë / orë këtë javë dhe të mësuarit e ardhshme për të marrë të kënaqur me GDB. Printf ishte shoku juaj. Gdb tani duhet të jetë miku juaj. Çdo pyetje në GDB? Dhe këtu është një listë e shpejtë të disa nga komandat më të fuqishme dhe të dobishme. Po. >> Mund të shkruar një varg? Ju mund të shtypura një varg? Absolutisht. Ajo nuk duhet të jetë vetëm integers. Nëse një s ndryshueshme është një varg vetëm lloji në s shtypura. Kjo do të ju tregojnë se çfarë është e ndryshueshme string. [E padëgjueshme-studenti] Kjo do t'ju japë adresën dhe string vetë. Ajo do të tregojë që ju të dy. Dhe një gjë e fundit, vetëm për shkak se këto janë të mira për të dini shumë. Backtrace dhe kornizë, më lejoni të zhyten në këtë kohë të fundit, programi i njëjtë me GDB saktë. Më lejoni të shkoj përpara dhe të drejtuar ndërfaqe tekstuale versionin e përdoruesit, thyejnë kryesore. Më lejoni të shkoj përpara dhe të kandidojë përsëri. Unë jam këtu. Tani më lejoni të shkoj tjetër, tjetër, tjetër, tjetër, tjetër, hap, të hyjë. Dhe tani mendoj unë jam tani në shkëmbim me dashje, por unë jam si "Damn, çfarë ishte vlera e x?" Unë nuk mund të bëjë x më. Unë nuk mund ta bëjë y, sepse ata nuk janë në fushëveprimin. Ata nuk janë në kontekst, por nuk ka problem. Unë mund të shtypni backtrace. Kjo tregon mua të gjitha funksionet që kanë ekzekutuar deri në këtë moment në kohë. Vini re se një në pjesën e poshtme, kryesore, linjat deri me kryesore qenë në fund të foto tonë këtu. Fakti që swap-i është e mësipërme linjave me shkëmbim të qenit më lart atë në kujtesë këtu, dhe në qoftë se unë dua të merrni Kthehu tek Qendrori përkohësisht mund të them "kornizë". Çfarë numri? Kryesor është kornizë # 1. Unë jam duke shkuar për të shkuar përpara dhe të thonë "kornizë 1." Tani unë jam kthyer në kryesore, dhe unë mund të shtypura X, dhe unë mund të shtypura y, por unë nuk mund të shtypura një ose b. Por unë mund të, nëse unë them: "Mirë, prisni një minutë. Swap Ku ishte?" Më lejoni të shkojnë përpara dhe të thonë "0 frame." Tani unë jam kthyer aty ku unë dua të jem, dhe si një mënjanë, ka komanda të tjera shumë, si në qoftë se ju jeni me të vërtetë duke shtypur mërzitur tjetër, tjetër, tjetër, tjetër, ju mund të në përgjithësi thonë gjëra të tilla si "10 vitet e ardhshme", dhe se do të hap përmes 10 linjave ardhshme. Ju gjithashtu mund të shkruani "vazhdojnë" kur ju me të vërtetë të merrni ngopur me rrit nëpërmjet saj. Vazhdo do të drejtuar programin tuaj pa ndërprerje deri sa ajo godet një tjetër breakpoint, nëse në një lak ose ulur poshtë në programin tuaj. Në këtë rast ne kemi vazhduar deri në fund, dhe programi exited normalisht. Kjo është një mënyrë e sofistikuar, procesi inferiore. Vetëm programi juaj exited normalisht. Më shumë se në video dhe në debugging seanca që do të vijnë. Kjo ishte një shumë. Le të marrin 5-minutësh pushim tonë këtu, dhe ne do të kthehemi me structs dhe fotografi. Nëse keni fetar në pset kësaj jave tashmë ju do të dini që ne i përdorim në kodin e shpërndarjes, burim kodin që ne ofrojmë për ju si një pikënisje, disa teknika të reja. Në veçanti, ne kemi prezantuar këtë fjalen ri të quajtur struct, për strukturën, kështu që ne mund të krijojë customized variablave të terezi. Ne gjithashtu paraqiti idenë e I / O, e file input output file dhe, dhe kjo është në mënyrë që ne mund të shpëtojë shtetin i bordit tuaj ngjitem në një skedar në disk në mënyrë që miqtë e mësimdhënies dhe unë mund ta kuptoj çfarë po ndodh në brendësi të programit tuaj, pa pasur në dorë të luajtur dhjetra e lojrave të Scramble. Ne mund të bëjmë këtë më automatedly. Kjo ide e një struct zgjidh një problem mjaft bindëse. Supozoni se ne duam të zbatojë ndonjë program që në njëfarë mënyre mban gjurmët e informacionit për studentët, dhe studentët mund të ketë, për shembull, një ID, një emër dhe një shtëpi në një vend si Harvard, kështu që këto janë 3 pjesë të informacionit ne duam të mbajnë përreth, kështu që më lejoni të shkoj përpara dhe të filloni të shkruani një program të vogël këtu, përfshijnë stdio.h. Më lejoni të bëj përfshijnë cs50.h. Dhe pastaj të fillojë funksionin tim kryesor. Unë nuk do të shqetësojë me ndonjë argumente command line, dhe këtu unë dua që të ketë një student, kështu që unë jam duke shkuar për të thënë një student ka një emër, kështu që unë jam duke shkuar për të thonë "emrin string." Atëherë unë jam duke shkuar për të thonë se një nxënës ka gjithashtu një ID, ID kështu int, dhe një student ka një shtëpi, kështu që unë jam gjithashtu do të thotë "shtëpi string." Atëherë unë do të urdhërojë këto pak më të pastër si kjo. Mirë, tani kam 3 variablave me të cilën të paraqesin një student, kështu që "një nxënës." Dhe tani unë dua të populloj këto vlera, kështu që më lejoni të shkoj përpara dhe të thonë diçka si "Id = 123." Emri është duke shkuar për të marrë Davidin. Le të thonë se shtëpia do të merrni Mather, dhe atëherë unë jam duke shkuar për të bërë diçka në mënyrë arbitrare si printf ("% s, të cilit është ID% d, jeton në% s. Dhe tani, çfarë unë dua të vihet në prizë këtu, njëri pas tjetrit? Emri, id, shtëpi; kthim 0. Mirë, nëse unë dehur diku këtu Unë mendoj se ne kemi një program mjaft të mirë që ruan një student. Sigurisht, kjo nuk është e gjitha që interesante. Çka nëse unë dua që të ketë 2 studentëve? Kjo nuk është punë e madhe. Unë mund të mbështesin 2 persona. Më lejoni të shkojnë përpara dhe të nxjerrë në pah këtë dhe të shkojnë poshtë këtu, dhe unë mund të them "id = 456" për dikë si Rob që jeton në Kirkland. Mirë, prisni, por unë nuk mund të telefononi këto njëjta gjë, dhe kjo duket si unë jam do të duhet të kopjoni këtë, kështu që më lejoni të them se këto do të jenë variabla e Davidit, dhe më lejoni të merrni disa kopje të këtyre për Rob. Ne do të quajmë këto të Rob, por kjo nuk do të punojë tani sepse kam-pritur, le të ndryshojë mua id1, name1 dhe house1. Rob do të jetë 2, 2. Unë kam marrë për të ndryshuar këtë këtu, këtu, këtu, këtu, këtu, këtu. Prisni, çfarë lidhje Tommy? Le ta bëjmë këtë përsëri. Natyrisht, nëse ju ende mendoni se kjo është një mënyrë e mirë për ta bërë këtë, nuk është, kështu kopje / paste keqe. Por ne zgjidhur këtë një javë më parë. Cila ishte zgjidhja jonë kur kemi dashur të kemi raste të shumta të të njëjtit lloj të të dhënave? [Studentët] Një grup. Një grup, kështu që më lejoni të përpiqen për të pastruar këtë ide. Më lejoni të bëjë disa hapësirë ​​për veten time në krye, dhe më lejoni të bëjë këtë në vend këtu. Ne do të quajmë këta njerëz, dhe në vend që unë jam duke shkuar për të thonë "ID int," dhe unë jam duke shkuar për të mbështetur 3 prej nesh tani për tani. Unë jam duke shkuar për të thënë "emrat string," dhe unë do të mbështes 3 prej nesh, dhe atëherë unë jam duke shkuar për të thënë "shtëpi string", dhe unë jam duke shkuar për të mbështetur 3 prej nesh. Tani në këtu në vend të gjetjes së David variablave veta lokale ne mund të shpëtoj nga ata. Që ndihet mirë që ne jemi pastrimin ky lart. Unë pastaj mund të them David do të jetë [0] dhe emrat [0] dhe shtëpitë [0]. Dhe pastaj Rob ne mund të ruani në mënyrë të ngjashme me këtë. Le të vënë këtë këtu poshtë, kështu që ai do të jetë në mënyrë arbitrare IDS [1]. Ai do të jetë emra [1], dhe pastaj së fundi, shtëpitë [1]. Ende pak i lodhshëm, dhe tani unë duhet të kuptoj këtë, kështu që le të themi "Emrat [0], id [0], shtëpitë [0] dhe le të bëj shumës këtë. IDS, IDS, IDS. Dhe përsëri, unë jam duke bërë atë, kështu që përsëri, unë tashmë jam përdorur për të kopje / paste përsëri, kështu që shanset janë ka një tjetër zgjidhje këtu. Unë ndoshta mund të pastruar këtë deri tej me një lak ose diçka si kjo, kështu që në pak fjalë, kjo është një pak më të mirë, por ende ndjehet si Unë jam përdorur për të kopje / paste, por edhe kjo, unë pretendojnë, nuk është me të vërtetë krejtësisht zgjidhje e drejtë, sepse çka nëse ne vendosim diku ju e dini se çfarë? Ne me të vërtetë duhet të ketë qenë ruajtjen adresat e-mail për Davidin dhe Rob dhe të gjithë të tjerët në këtë program. Ne gjithashtu duhet të ruajtur numrat e telefonit. Ne gjithashtu duhet të ruajtur numrat e kontaktit emergjente. Ne kemi të gjitha këto pjesë të të dhënave që ne duam për të ruajtur, kështu si bëni ju shkoni për të bërë këtë? Ju deklarojë një tjetër grup në krye, dhe pastaj ju shtuar manualisht një adresë e-mail [0], adresë e-mail [1] për Davidin dhe Rob dhe kështu me radhë. Por ka të vërtetë vetëm një supozim themelor këtë dizajn se unë jam duke përdorur sistemin e nderit të dini se [I] në secilin prej vargjeve disa pikërisht kështu ndodh për t'iu referuar të njëjtit person, kështu [0] në kartat e identitetit është numri 123, dhe unë jam duke shkuar për të marrë se emrat [0] është emri i njëjti person dhe shtëpitë [0] është shtëpia njëjti person dhe kështu me radhë për të gjitha vargjeve të ndryshme që kam krijuar. Por vini re se nuk ka asnjë lidhje themelore në mesin e atyre 3 copa e informacionit, id, emri dhe shtëpi, edhe pse njësia ekonomike ne jemi duke u përpjekur për të modelit në këtë program nuk është vargjeve. Vargjeve janë vetëm në këtë mënyrë programatike për ta bërë këtë. Ajo që ne të vërtetë duan të modeluar në programin tonë është një person si Davidi, një person si Rob brenda të cilave ose encapsulating është një Emri dhe ID dhe një shtëpi. Mund ta shprehim këtë ide disi e encapsulation ku një person ka një ID, një emër dhe një shtëpi dhe nuk mbështeten në të vërtetë këtë hack ku ne vetëm besojnë se diçka parantezë referohet subjektit të njëjtë të njeriut në secilën prej këtyre vargjeve të ndryshëm? Ne fakt mund ta bëjë këtë. Më lejoni të shkoj më lart kryesor tani për tani, dhe më lejoni të krijojnë llojin mi dhënave për herë të parë me të vërtetë. Ne kemi përdorur këtë teknikë në Scramble, por këtu unë jam duke shkuar për të shkuar përpara dhe për të krijuar një lloj të dhënave, dhe ju e dini se çfarë, unë jam duke shkuar për të thirrur atë student ose person, dhe unë jam duke shkuar për të përdorur për të përcaktuar typedef një lloj. Unë jam duke shkuar për të thonë se kjo është një strukturë, dhe pastaj kjo strukturë do të jetë e tipit studenti, ne do të themi, edhe pse kjo është një datë pak tani për mua. Ne do të thonë: "int id". Ne do të thonë: "emrin string." Atëherë ne do të themi "shtëpi" string, kështu që tani deri në fund të këtyre disa rreshta të kodit Unë kam mësuar vetëm tingulli që ekziston një lloj të dhënave përveç ints, përveç vargjet, përveç dyshe, përveç gjithandej. Që nga ky moment në linjë kohore 11, tani ka një lloj të ri të dhënave të quajtur studentë, dhe tani unë mund të deklarojë një ndryshore studentore kudo që unë dua, kështu që më lejoni të lëvizni poshtë këtu për njerëzit. Tani unë mund të shpëtoj nga kjo, dhe unë mund të shkojnë përsëri poshtë Davidit këtu, dhe për Davidin unë në fakt mund të them se David, ne mund të vërtetë emrin e ndryshueshme pas vetes, do të jetë e tipit studenti. Kjo mund të duket pak i çuditshëm, por kjo nuk është e gjitha që të ndryshme nga shpallja e diçka si një int ose një varg ose një noton. Kjo ndodh pikërisht kështu që të quhet nxënës tani, dhe në qoftë se unë dua të vënë diçka në brendësi të kësaj strukture Unë tani duhet të përdorni një pjesë të re të sintaksës, por kjo është goxha e drejtpërdrejtë, david.id = 123, david.name = "Davidi" në kryeqytetin D, dhe david.house = "Mather" dhe tani unë mund të shpëtoj të këtij stuff këtu. Njoftim ne kemi redesigned tani programin tonë në të vërtetë një mënyrë shumë më të mirë se tani në programin tonë pasqyron botën reale. Ka një të vërtetë të botës nocioni i një personi ose një student. Këtu ne kemi tani një version C e një personi apo më saktësisht një student. Brenda atij personi janë këto karakteristika të rëndësishme, ID, emri dhe shtëpi, kështu Rob thelb bëhet e njëjta gjë këtu poshtë, kështu që studenti rob, dhe tani rob.id = 456, rob.name = "Rob". Fakti që është e ndryshueshme quajtur Rob është lloj i pakuptimtë. Ne mund të e kanë quajtur atë x ose y ose Z. Ne vetëm e quajti atë Rob të jetë në përputhje semantike, por me të vërtetë emri është brenda vetë këtë fushë, kështu që tani unë kam këtë. Kjo shumë nuk do të ndjehen si dizajn të mirë në atë që unë e kam të vështirë koduar Davidin. Unë e kam të vështirë koduar Rob. Dhe unë ende duhet të mbështetet në disa kopje dhe ngjitur çdo herë që unë dua variablave të reja. Për më tepër, unë kam për të të dhënë duket secili prej këtyre variablave një emër, edhe pse unë do të shumë më tepër të përshkruar këto variabla  Nxënësit më generically si. Tani ne mund të bashkojë idetë që kanë qenë duke punuar mirë për ne dhe në vend të thonë, "Ju e dini se çfarë, më jep mua një nxënës ndryshueshme quajtur, dhe le të ketë jetë të madhësisë 3 ", kështu që tani unë mund të përsosin më tej këtë, të hequr qafe të Davidit deklaruar dorë, dhe unë mund të them diçka në vend si studentët [0] këtu. Unë pastaj mund të them studentët [0] këtu, studentët [0] këtu, dhe kështu me radhë, dhe unë mund të shkojnë rreth dhe të pastër që për Rob. Unë mund të shkoni edhe për tani ndoshta duke shtuar një lak dhe duke përdorur getString dhe GetInt që në fakt të marrë këto vlera nga përdoruesi. Unë mund të shkoni në lidhje me shtimin e një konstante, sepse kjo është në përgjithësi praktikë e keqe të kodit të vështirë disa numër arbitrar si 3 drejtë këtu dhe pastaj vetëm mos harroni se ju duhet të vënë jo më shumë se 3 studentë në të. Kjo ndoshta do të jetë më mirë për të përdorur # define në krye të dosjes sime dhe faktor që jashtë, kështu që në të vërtetë, më lejoni të shkoj përpara dhe të përgjithësojmë këtë. Më lejoni të hapur një shembull që është në mesin e sotme shembuj paraprakisht, structs1. Ky është një program më i plotë që përdor # përcaktojë deri këtu dhe thotë se ne do të kemi 3 studentët by default. Këtu unë jam deklaruar një vlerë klasë të nxënësve, kështu që një klasë të nxënësve, dhe tani unë jam duke përdorur një lak vetëm për të bërë kodin pak më elegante, populloj klasë me kontributin e përdoruesit, kështu që iterate nga i = 0 deri në për studentët, e cila është 3. Dhe atëherë unë shpejtë e përdoruesit në këtë version  çfarë është ID e nxënësit, dhe unë të marrë atë me GetInt. Çfarë është emri i nxënësit, dhe atëherë unë të marrë atë me getString. Çfarë është shtëpia e studentit? Unë të marrë atë me getString. Dhe pastaj në fund këtu unë vetëm vendosi të ndryshojë se si unë jam shtypjen këto jashtë dhe që në fakt përdorin një lak, dhe kush jam unë shtypjes? Sipas komentit që unë jam shtypjen askënd në Mather, dhe kjo është ajo mënyrë Rob dhe revole dhe kështu me radhë, në fakt e Tommy në Mather. Tommy dhe David do të shtypen në këtë rast, por sa është kjo pune? Ne nuk kemi parë këtë funksion më parë, por të marrë një guess si për atë që këtë e bën. Krahason vargjet. Kjo është një jo-pak e qartë se si ajo krahason vargjet sepse ai del në qoftë se ajo kthehet 0 do të thotë se vargjet janë të barabartë. Në qoftë se kjo kthen një -1 që do të thotë një fjalë alfabetike para të tjera, dhe nëse ajo kthehet 1 që do të thotë fjalën tjetër vjen alfabetik para të tjera, dhe ju mund të shikoni online ose në faqen e njeriut për të parë saktësisht se cilat rrugë është që, por e gjithë kjo tani është bërë është ajo e thënë nëse [i]. Shtëpia është e barabartë me "Mather" pastaj të shkojnë përpara dhe të shtypura jashtë kështu dhe kështu është në Mather. Por këtu është diçka që ne nuk e kemi parë më parë, dhe ne do të kthehen në këtë. Unë nuk e kujtojnë kurrë që të bëni këtë në ndonjë nga programet e mia. Lirë është me sa duket i referohet kujtesës, çlirimin e kujtesës, por çfarë memorie jam unë duket liruar në këtë lak në fund të këtij programi? Ajo duket si unë jam liruar emrin e një personi dhe shtëpia e një personi, por pse është kjo? Kjo rezulton nga të gjitha këto javë që ju keni qenë duke përdorur getString ne kemi qenë të futur lloj i një bug në çdo një nga programet tuaja. GetString nga shpërndan kujtesës projektimit në mënyrë që ajo mund të kthehet tek ju një varg, si Davidi, ose Rob, dhe pastaj ju mund të bëni çfarë të doni me këtë varg në programin tuaj, sepse ne kemi rezervuar e kujtesës për ju. Problemi është e gjitha kjo kohë çdo kohë që ju e quani getString Ne, autorët e getString, kanë qenë duke kërkuar të sistemit operativ për të na dhënë një grimë e RAM për këtë varg. Na jep një grimë e RAM për këtë vargun e ardhshëm. Na jep disa RAM më shumë për këtë vargun e ardhshëm. Çfarë ju, programues, kurrë nuk janë bërë është duke na dhënë atë prapa kujtesës, kështu që për këto disa javë të gjitha programet që ju keni shkruar kanë pasur atë që quhet një hap të kujtesës ku ata mbajnë përdorur më shumë memorie dhe më shumë çdo herë që ju e quani getString, dhe kjo është në rregull. Ne qëllimisht të bëjë që në javët e para, sepse ajo nuk është se interesante të ketë për t'u shqetësuar rreth ku vargu po vjen nga. Të gjithë ju duan është fjala Rob të kthehen kur përdoruesi lloje atë in Por duke shkuar përpara, ne tani duhet të filloni të keni më të sofistikuar në lidhje me këtë. Çdo herë kemi kujtesës kemi të mirë përfundimisht dorë atë. Ndryshe në botën reale në Mac apo PC tuaj ju mund të ketë herë pas here me përvojë Simptomat ku kompjuteri juaj është i rëndë për të ndalur një fund ose budallaqe topin tjerrje plazh është vetëm zënë kompjuteri të Vëmendje e tërë dhe ju nuk mund të bëni gjëra. Kjo mund të shpjegohet me ndonjë numër të mete, por në mesin e atyre mete e mundshme janë gjëra të quajtur rrjedhjet e kujtesës ku dikush që shkruan se pjesë e software ju jeni duke përdorur nuk mbani mend në kujtesën e lirë se ai ose ajo i kërkoi sistemit operativ, mos përdorur getString, sepse kjo është një gjë e CS50, por duke përdorur funksione të ngjashme që të kërkojë sistemit operativ për kujtesën. Nëse ju apo ata vidhos deri dhe në fakt nuk kthehet se kujtesa një simptomë e që mund të jetë që një program ngadalëson dhe ngadalëson dhe ngadalëson nëse nuk ju kujtohet për të thirrur të lirë. Ne do të vijnë përsëri në kur dhe pse ju do të telefononi lirë, por le të shkojë përpara vetëm për masë të mirë dhe të përpiqemi për drejtimin e këtij programi të veçantë. Kjo u quajt structs1, të hyjë. Më lejoni të shkojnë përpara dhe për të drejtuar structs1, 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather, dhe ne shohim e Davidit në Mather, e Tommy në Mather. Kjo është vetëm një kontroll pak mendje e shëndoshë se programi është duke punuar. Tani, për fat të keq, ky program është pak frustruese në atë Unë kam të gjitha që punojnë, i shtypur në 9 strings ndryshme, goditi të hyjë, u tha që ishte në Mather, por natyrisht unë e dija që ishte në Mather tashmë, sepse kam shtypur atë. Ajo do të jetë mirë në qoftë se paku ky program është më shumë si një bazë të dhënash dhe në fakt ajo kujton atë që kam shtypur në kështu që unë kurrë nuk përsëri duhet të input këto shënime studentore. Ndoshta kjo është si një sistem registrarial. Ne mund të bëjmë këtë duke përdorur këtë teknikë e njohur si I / O, e file input output file dhe, një mënyrë shumë të përgjithshme për të thënë çdo kohë që ju dëshironi për të lexuar fotografi ose shkruani fotografi ju mund ta bëni këtë me një grup të caktuar të funksioneve. Më lejoni të shkojnë përpara dhe hapni këtë structs2.c shembull, e cila është pothuajse identik, por le të shohim se çfarë ajo tani bën. Në krye të dosjes Unë deklaroj një klasë të nxënësve. Unë pastaj populloj klasë me kontributin e përdoruesit, kështu ato rreshta të kodit janë saktësisht si më parë. Pastaj në qoftë se unë lëviz nëpër këtu kam shkruar të gjithë ata që është në Mather arbitrarisht si më parë, por kjo është një tipar interesant i ri. Këto rreshta të kodit janë të reja, dhe ata të futur diçka këtu, File, të gjithë kapele, dhe ajo ka * në edhe këtu. Më lejoni të lëvizë mbi këtë këtu, një * mbi këtu si. Ky funksion nuk kemi parë më parë, fopen, por kjo do të thotë fotografi të hapur, kështu që le të skremuar me këto, dhe kjo është diçka që ne do të kthehemi në psets ardhshme, por kjo linjë këtu thelb hap një dosje të quajtur Baza e të dhënave, dhe kjo veçanërisht hap atë në një mënyrë të tillë që ajo mund të bëjë çfarë të saj? [E padëgjueshme-studenti] Drejtë, kështu që "w" thjesht do të thotë se është thënë e sistemit operativ hapur këtë file në një mënyrë të tillë që unë mund të shkruaj për të. Unë nuk duan të lexojnë atë. Unë nuk dua të vetëm të shikojnë atë. Unë dua të ndryshojë atë dhe shtoni sende potencialisht të, dhe dosja do të quhet database. Kjo mund të quhet asgjë. Kjo mund të jetë database.txt. Kjo mund të jetë. Db. Kjo mund të jetë një fjalë si foo, por unë në mënyrë arbitrare zgjodhi për emrin e bazës së të dhënave file. Kjo është një kontroll pak mendje e shëndoshë se ne do të kthehen në hollësi të madhe me kalimin e kohës, nëse FP, për treguesin e file, nuk NULL barabartë do të thotë se të gjitha është e mirë. Histori të gjatë të shkurtër, funksionon si fopen ndonjëherë dështojnë. Ndoshta nuk ekziston. Ndoshta ju jeni nga hapësira disk. Ndoshta ju nuk keni leje për atë dosje, kështu që nëse diçka kthehet fopen null ndodhur keqe. Në anën tjetër, në qoftë se nuk ka kthim fopen null gjithë është mirë dhe unë mund të filloni të shkruani tek kjo skedë. Këtu ka një mashtrim të ri. Kjo është një lak për të që është mbi çdo iterating nga nxënësit e mi, dhe kjo duket aq e ngjashme me atë që ne kemi bërë më parë, por ky funksion është një kushëri i quajtur printf fprintf për dosjen printf, dhe vini re kjo është e ndryshme vetëm në 2 mënyra. Një, ajo fillon me vend të f p, por pastaj argumenti i saj i parë është me sa duket ajo? [Studentët] dokumentit. >> Kjo është një file. Kjo gjë quhet FP, të cilat ne përfundimisht do të vë në lojë përveç asaj një tregues skedë është, por tani për tani fp thjesht paraqet dosjen që kam hapur, kështu që këtu është thënë fprintf shtypura ID ky përdorues ndaj dosjen, jo në ekran. Print emrin e përdoruesit në dosjen, jo në ekran, Shtëpia në dosjen, jo në ekran, dhe pastaj poshtë këtu, natyrisht, mbyllur dosjen, dhe pastaj këtu poshtë pa memorie. Dallimi i vetëm në mes këtë version 2 dhe versionin 1 është futja e fopen dhe kjo skedë me * dhe ky nocion i fprintf, kështu që le të shohim se çfarë rezultati përfundimtar është. Më lejoni të shkoj në dritaren time terminal. Më lejoni të drejtuar structs2, të hyjë. Duket si të gjitha është mirë. Le përsëritje structs2. 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather, shkruani. Duket si ajo sillen njëjtë, por në qoftë se unë tani bëj ls njoftim se çfarë file është këtu në mesin e të gjithë kodin tim, bazës së të dhënave, kështu që le të hapur atë, duken Gedit i bazës së të dhënave, dhe në atë. Kjo nuk është sexiest e file formats. Kjo është me të vërtetë një pjesë e linjës të dhënave për linjë për linjë, por ata prej jush që e përdorin Excel ose CSV fotografi, të ndara me presje vlerat, Unë me siguri mund të ketë përdorur për të fprintf vend ndoshta bëni diçka si kjo kështu që unë në fakt mund të krijojnë ekuivalentin e një file Excel duke i ndarë gjërat me presje, jo vetëm linjat e reja. Në këtë rast, nëse unë kam përdorur në vend commas në vend të linjave të reja Unë mund të vërtetë të hapur këtë file bazës së të dhënave në Excel, nëse unë e bëri atë në vend të duket si ky. Me pak fjalë, tani që ne kemi fuqinë për të shkruar në fotografi ne tani mund të fillojnë të dhënave të vazhdueshme, duke e mbajtur atë rreth në disk kështu që ne mund të mbajë informacion rreth përsëri dhe përsëri. Vini re disa gjëra të tjera që janë tani pak më shumë të njohur. Në krye të këtij file C ne kemi një typedef sepse ne të kërkuar për të krijuar një lloj të dhënave që përfaqëson një fjalë, kështu që kjo lloj quhet fjala, dhe brenda kësaj strukture kjo është pak fancier tani. Pse është një fjalë e përbërë nga një grup me sa duket? Çfarë është një fjalë vetëm intuitive? Kjo është një grup të karaktereve. Kjo është një sekuencë e karaktereve të kthehet prapa për të mbështetur. LETRA në të gjitha shkronja kapitale ndodh të jetë ne themi arbitrarisht gjatësia maksimale e ndonjë fjale në fjalorin që ne jemi duke përdorur për Scramble. Pse nuk kam një 1? Karakteri null. Kujtoj kur ne e bëmë shembull Bananagrams kishim nevojë për një vlerë të veçantë në fund të fjalës në mënyrë që të mbajnë gjurmët e ku fjalët përfundoi në fakt, dhe si grup problemi specifikimet thotë këtu ne jemi shoqëruar me një fjalë të caktuar një vlerë boolean, një flamur, në mënyrë që të flasin, e vërtetë apo e rreme. A keni gjetur këtë fjalë tashmë, pasi ne kemi realizuar ne me të vërtetë nevojë për një mënyrë për të kujtuar jo vetëm atë që një fjalë është në Scramble por nëse janë apo jo ju, e njeriut, kanë gjetur atë kështu që nëse ju do të gjeni fjala "e" ju nuk mund të shtypni, shkruani, të, hyjë, të, hyjë dhe për të marrë 3 pikë, 3 pikë, 3 pikë, 3 pikë. Ne duam që të jetë në gjendje për të listën atë fjalë duke vendosur një bool të vërtetë në qoftë se ju keni gjetur tashmë atë, dhe kështu që kjo është arsyeja pse ne encapsulated atë në këtë strukturë. Tani, këtu poshtë në Scramble ka kjo struct tjetër quhet fjalor. Mungon këtu është fjala typedef sepse në këtë rast kemi nevojë për të encapsulate idenë e një fjalori, dhe një fjalor përmban një bandë e tërë e fjalëve, nënkuptohet nga ky grup, dhe sa prej atyre fjalëve janë atje? E pra, çdo gjë këtë madhësi të ndryshueshme quajtur thotë. Por ne vetëm duhet një fjalor. Ne nuk kemi nevojë për një lloj të dhënave të quajtur fjalor. Ne vetëm duhet një prej tyre, kështu që rezulton në C se në qoftë se ju nuk e thoni typedef, ju them vetëm struct, atëherë brenda formatimin e teksteve kaçurrel ju vënë variablave tuaja, atëherë ju vënë emrin. Kjo është deklaruar nga një fjalor ndryshueshme quajtur që duket si kjo. Në të kundërt, këto linja janë duke krijuar një strukturë të quajtur Fjala reusable dhënave që ju mund të krijojë kopje të shumta të, ashtu si kemi krijuar kopje të shumta të nxënësve. Çfarë e bën këtë në fund të fundit na lejojnë të bëjmë? Më lejoni të shkoj përsëri në, le të themi, një shembull të thjeshtë nga kohët më të thjeshta, dhe më lejoni të hapur, le të themi, compare1.c. Problemi këtu në dorë është që në fakt të zhvishem përsëri shtresa e një varg dhe të fillojë të marrë jashtë këtyre rrota trajnimit sepse kjo rezulton se një varg gjithë këtë kohë është si ne premtuar në të vërtetë vetëm 1 javë pseudonimin një, një sinonim nga biblioteka CS50 për diçka që duket pak më i fshehtë, * char, dhe ne kemi parë këtë yll më parë. Ne pamë atë në kontekstin e dosjeve. Le të shohim tani se pse ne kemi qenë të fshehur këtë detaj për një kohë tani. Këtu është një file i quajtur compare1.c, dhe kjo me sa duket kërkon të përdoruesit për 2 vargjet, s dhe t, dhe pastaj ajo përpiqet për të krahasuar këto vargje për barazi në linjë 26, dhe në qoftë se ata janë të barabartë ai thotë, "Ju shtypen njëjtën gjë", dhe në qoftë se ata nuk janë të barabartë ai thotë, "Ju shtypur gjëra të ndryshme." Më lejoni të shkojnë përpara dhe për të drejtuar këtë program. Më lejoni të shkoj në directory burim tim, të bëjë një compare1. Ajo përpiluar në rregull. Më lejoni të drejtuar compare1. Unë do të zoom në, të hyjë. Thuaj diçka. HELLO. Unë do të them diçka përsëri. HELLO. Unë definitivisht nuk shkruani gjëra të ndryshme. Më lejoni të provoni këtë përsëri. BYE BYE. Definitivisht nuk e ndryshme, kështu që ajo që po ndodh këtu? E pra, ajo që është me të vërtetë duke u krahasuar në linjë 26? [E padëgjueshme-studenti] Po, kështu rezulton se një varg, të dhënat lloji, është lloj i një gënjeshtër të bardhë. Një varg është një char *, por ajo është një char *? A * char, siç thonë ata, është një tregues, dhe një akrep është efektivisht një adresë, një vend shumë në kujtesë, dhe nëse ju ndodh që të keni shtypur në një fjalë si HELLO, kujtojnë nga diskutimet e fundit të strings kjo është si fjala HELLO. Mos harroni se si një fjalë përshëndetje mund të përfaqësohen si një grup të karaktereve si kjo dhe pastaj me një karakter të veçantë në fund të quajtur karakterin null, si tregon \. Çfarë është në të vërtetë një varg? Vini re se kjo është chunks e shumta të kujtesës, dhe në fakt, fundi i tij është i njohur vetëm një herë ju shikoni nëpër varg të tërë kërkoni për karakterin null veçantë. Por në qoftë se kjo është një copë e kujtesës nga kujtesën e kompjuterit tim, le të thonë se kjo mënyrë arbitrare string mori vetëm fat, dhe ajo u vendosur në fillim të RAM kompjuterit tim. Kjo është bajt 0, 1, 2, 3, 4, 5, 6 ... Kur them diçka si getString dhe bëj String s = getString çfarë është me të vërtetë duke u kthyer? Për këto disa javëve të fundit, çfarë është me të vërtetë duke u ruajtur në s nuk është ky varg në vetvete, por në këtë rast ajo është duke u ruajtur është 0 Numri sepse ajo që në fakt nuk getString po ajo nuk kthehet fizikisht një varg. Kjo nuk ka edhe kuptim konceptual të vërtetë. Çfarë ajo nuk kthimi është një numër. Ky numër është adresa e PËRSHËNDETJE në kujtesë, dhe string s atëherë, në qoftë se ne zhvishem përsëri kjo shtresë, string nuk ekziston në të vërtetë. Kjo është vetëm një thjeshtësim në bibliotekë CS50. Kjo është me të vërtetë diçka që quhet * char. Char ka kuptim, sepse ajo është një fjalë, si HELLO? E pra, kjo është një seri e karaktere, një seri e karaktereve. * Char thotë adresën e një karakter, Pra, çfarë do të thotë të kthehet një varg? A nice, mënyrë e thjeshtë për të kthyer një varg është vend se të përpiqet të kuptoj se si ta kthej në 5 ose 6 bytes ndryshme më lejoni të kthehet në adresën e cila bajt? I pari. Me fjalë të tjera, më lejoni t'ju jap një adresë të një karakter në kujtesë. Kjo është ajo që përfaqëson * char, adresa e një karakter të vetëm në kujtesë. Telefononi Kjo është e ndryshueshme. Shitore në s që adresa të veçantë, që unë në mënyrë arbitrare thënë është 0, vetëm për të mbajtur gjërat e thjeshta, por në realitet kjo është në përgjithësi një numër më i madh. Prisni një minutë. Në qoftë se ju jeni vetëm duke i dhënë mua adresën e karakterit të parë, si mund ta di se çfarë është adresa të karakterit të dytë, të tretë, të katërt dhe të pestë? [E padëgjueshme-studenti] Ju vetëm e di se ku fundi i vargut është me anë të këtij mashtrim i dobishëm, kështu që kur ju përdorni diçka si printf, çfarë printf fjalë për fjalë merr si argument të saj, kujtojnë se ne përdorim placeholder Kete% s, dhe pastaj ju kaloni në ndryshore që është ruajtjen e një varg. Çfarë ju jeni me të vërtetë kalon është adresa e parë të karakterit atë varg. Printf pastaj përdor një për lak ose një lak, ndërsa pas marrjes atë adresë, për shembull, 0, kështu që më lejoni të bëjë këtë tani, printf ("% s \ n", s); Kur unë e quaj printf ("% s \ n", s); ajo që unë jam me të vërtetë duke siguruar me printf është adresa e parë në karakterin s, e cila në këtë rast është arbitrare H. Si nuk e dini se çfarë saktësisht printf për të shfaqur në ekran? Personi i cili zbatohet zbatuar printf një lak, ndërsa për ose një lak që thotë se e bën këtë karakter e barabartë me karakter të veçantë null? Nëse jo, të shtypura atë. Si në lidhje me këtë? Nëse jo të shtypura atë, print it, të shtypura, të shtypura atë. Oh, kjo është e veçantë. Ndaluar shtypjen dhe të kthehet në të përdoruesit. Dhe kjo është fjalë për fjalë të gjitha ato që po ndodh është nën kapuç, dhe që është një shumë të tretet në ditën e parë të një klasë, por tani për tani kjo është me të vërtetë bllok ndërtimi i çdo gjëje të kuptuarit që është në vazhdim e sipër brenda kujtesën e kompjuterit tonë, dhe përfundimisht ne do të vë në lojë përveç kësaj me një ndihmë të vogël nga një prej miqve tanë në Stanford. Profesor Nick Parlante në Stanford ka bërë këtë rend mrekullueshme video nga të gjitha llojet e gjuhëve të ndryshme që futur kjo pak karakter Claymation Binky. Zëri ju jeni gati për të dëgjuar në vetëm një vrojtim vjedhës të dytë disa është ai i një profesor Stanford, dhe ju jeni duke marrë vetëm 5 ose 6 sekonda e kësaj të drejte tani, por ky është shënim në të cilën ne do të përfundojë sot dhe të fillojë të mërkurën. Unë ju jap Fun treguesin me Binky, preview. [♪ ♪ Music] [Profesor Parlante] Hej, Binky. Zgjoheni. Është koha për argëtim akrep. [Binky] Çfarë është ajo? Mësoni rreth pointers? Oh, me mirësi të shtrirë! Ne do të shohim se të mërkurën. [CS50.TV]