[Powered by Google Translate] [Nädal 4] [David J. Malan] [Harvardi Ülikool] [See on CS50.] [CS50.TV] Olgu, see on CS50, ja see on algus 4. nädalal ja see on üks aeglaseim võimalik sorteerimise algoritme. Kumb oli see, et me lihtsalt vaatasin seal? See oli mull sorteerida, et suur O (n ^ 2) + summa, ja tõepoolest me ei ole ainsad selles maailmas tundub, et tean mida mull sorteerida on või tema töötamise aja. Tõepoolest, see oli intervjuu Eric Schmidt Google ja endine senaator Barack Obama paar aastat tagasi. Nüüd, senaator, et sa siin oled Google, ja mulle meeldib mõelda eesistujariigi nagu tööintervjuu. Nüüd, see on raske tööd saada presidendiks, ja sa lähed läbi külmavärinad nüüd. Samuti on raske saada tööd Google. Meil on küsimusi, ja me palume meie kandidaatide küsimused, ja see üks on Larry Schwimmer. Te arvate, et ma teen nalja? See on siinsamas. Mis on kõige tõhusam viis sorteerida miljonit 32-bitise täisarvu? [Naer] Hästi- Mul on kahju. >> Ei, ei, ei, ei. Ma arvan, et mull sorteerida oleks vale tee. Tule, kes rääkis talle seda? Eelmisel nädalal meenutada võtsime pausi kood, vähemalt kord päevas, ja hakkas keskendudes mõnele kõrgemale tasemele ideede ja probleemide lahendamine üldisemalt kontekstis otsimine ja sorteerimine, ja tutvustasime midagi, mida me ei laksu selle nime eelmisel nädalal, kuid asümptootilisest märge, Big O, Big Omega, ja mõnikord Big Theta märke, ja need olid lihtsalt võimalusi kirjeldada sõiduaega algoritme, kui palju aega kulub algoritm joosta. Ja ehk mäletate, et sa rääkisid sõiduaega poolest suurus sissetulevate, mida me tavaliselt kutsume n olenemata võib probleem olla, kus n on inimeste arv toas, lehekülgede arv telefoniraamatust ja hakkasime kirjutama asju teha nagu O (n ^ 2) või O (n) ehk O (n log n), ja isegi kui matemaatikat ei ole päris välja töötada nii perfektselt ja see oli n ² - n / 2 või midagi sellist me oleks selle asemel lihtsalt ära visata mõned väiksemad mõttes ja motivatsioon on, et me tõesti tahame omamoodi objektiivselt hinnata tulemuslikkust programmide või täitmise algoritmid et lõpus päeval ei ole midagi, näiteks koos kiirust oma arvuti täna. Näiteks, kui sa ellu mull sorteerida, või sa ellu ühendada sorteerida või valik omamoodi tänapäeva arvuti, 2 GHz arvuti, ja sa jooksed ta, ja see võtab mitu sekundit, järgmisel aastal seal 3 GHz või 4 GHz arvuti, ja sa võiks siis väita, et "Wow, minu algoritm Nüüd on kaks korda kiirem, "kui tegelikult see on ilmselt nii ei ole. See on lihtsalt riistvara on saanud kiiremini, kuid arvuti ei ole, ja nii me tõesti tahame visata asjad 2-kordselt või 3-kordselt, kui tegemist on kirjeldava kui kiiresti või kuidas aeglane algoritm on ja tõesti keskenduda ainult n või mõni tegur selle mõned väge kui puhul kehvasti eelmisel nädalal. Ja meelde tuletada, et abiga ühendamise sorteeri suutsime teha nii palju parem kui mull sorteerida ning valik omamoodi ja isegi sisestamise omamoodi. Meil alla n log n, ja jälle, tuletada meelde, et log n üldiselt viitab millelegi, mis kasvab aeglasemalt siis n, nii et n log n siiani oli hea sest see oli väiksem kui n ². Kuid selleks, et n log n koos ühendamise sorteeri Mis oli põhiline alge mõte, et meil oli võimendada et meil on ka võimendatud tagasi nädal 0? Kuidas me lahendada sorteerimine probleem nutikalt koos ühendamise sorteerida? Mis oli Võtmeküsimuseks, ehk? Igaüks üldse. Okei, astuda samm tagasi. Kirjelda liita omamoodi oma sõnadega. Kuidas see toimib? Hästi, me reale tagasi nädal 0. Okei, jah. [Kuuldamatu-õpilane] Okei, hea, et me jagatud array numbrid 2 tk. Me järjestatud kõik need tükid ja siis liitis need, ja me oleme näinud seda mõtet enne võtmise probleem, et see on suur ja tükeldamist it up probleem, et see on suur või see suur. Meenuta telefoniraamatust näiteks. Meenuta ise loendamise algoritmi alates nädalat tagasi nii liita omamoodi tegi kokkuvõtte selle pseudokoodi siin. Kui olete antud n elementi, esimene oli meelerahu vaadata. Kui n <2, siis ei tee üldse midagi sest kui n <2, siis n on ilmselt 0 või 1, ja nii kui see on 0 või 1, ei midagi sorteerida. Sa oled teinud. Sinu nimekirjas on juba triviaalselt sorteerida. Aga muidu kui sul 2 või rohkem elemente minna ja jagada neid jagatakse 2 poolt, vasakule ja paremale. Sorteeri kõik need pooleks ja seejärel ühendada järjestatud pooleks. Aga probleem on selles, et esmapilgul tundub see me punting. See on ümmarguse määratlust, et kui ma olen palunud teil sorteerida neid n elementi ja sa räägid mulle "Olgu, me ajame need n / 2 ja need n / 2 elementi" siis minu järgmine küsimus saab olema "Olgu, kuidas sa sorteerimise n / 2 elementi?" Aga struktuuri tõttu on see programm, sest seal on see alus juhul, kui nii võib öelda, see eriline juhtum, mis ütleb, et kui n on > Sara, eks. Kelly. >> Kelly ja? Willy. >> Willy, Sara, Kelly, ja Willy. Just nüüd on mul palutud seda küsimust keegi kui palju inimesi on üles antud etapis ja ma ei tea. See on tõesti pikk nimekiri, ja et selle asemel ma lähen tegema seda trikki. Ma küsin inimene minu kõrval teha suurema osa tööst, ja kui ta on teinud teed suurema osa tööst Ma lähen tegema vähemalt töömahtu võimalik ja lihtsalt lisage 1 mis iganes tema vastus on, et siin me läheme. Mul paluti kuidas paljud inimesed on laval. Kui paljud inimesed on laval vasakul oled? Vasakul mind? >> Okei, aga ära peta. See on hea, see on õige, kuid kui me tahame jätkata seda loogikat Oletame, et sa samamoodi tahavad punt see probleem vasakule sa, Nii et pigem vastus otse minna ja lihtsalt vastutusest kõrvale hiilima. Oh, kui palju inimesi on vasakul profiili? Mitu inimest on vasakule? 1. [Naer] Okei, nii et 0, mis siis nüüd Willy teinud on sul tagasi oma vastus selles suunas öeldes 0. Nüüd, mida peaksite tegema? >> 1. Okei, nii et sa oled 1, seega sa ütled "Olgu, ma lähen lisada 1 mis iganes Willy arv oli, "nii 1 + 0. Sa oled nüüd 1 nii oma vastus õige on nüüd- 1. >> Ja minu oleks 2. Hea, et te võtate eelmises vastuses: 1, lisades minimaalselt tööd sa teha tahad, mis on +1. Sul on nüüd 2 ja siis pead andma mulle mis väärtus? 3 Ma mõtlen, vabandust, 2. Hea. Noh, meil oli 0 kuni vasakule. Siis oli meil 1 ja seejärel lisame 2 ja nüüd sa üleandmise mulle number 2, ja nii ma räägin, okei, 1, 3. Seal on tõesti 3 inimest alalise kõrval mind selles etapis nii me oleks võinud ilmselt seda teinud väga lineaarselt, vägagi selge mood, aga mida me siis tegelikult teeme? Võtsime probleemi suurus 3 esialgu. Siis murdis ta jaguneb probleemi suurus 2, siis probleemi suurus 1, ja siis lõpuks tugipunkti oli tõesti, oh, seal on keegi seal, kus punkt Willy tagasi tõhusalt kodeeritud vastus paar korda, ja teine ​​oli siis mullidena üles, mullidena üles, mullidena üles ja siis lisades selle ühe lisanduva 1 oleme rakendanud seda põhiidee rekursioon. Nüüd, sel juhul ei ole ta tegelikult lahendada probleemi enam tõhusalt siis oleme näinud siiani. Aga mõtle algoritme oleme teinud laval siiani. Meil oli 8 tükki raamat kriiditahvel, video kui Sean otsisin number 7, ja mida ta tegelikult teha? Noh, ta ei teinud mingeid jaga ja valitse. Ta ei teinud mingeid rekursioon. Pigem ta lihtsalt tegi seda lineaarne algoritm. Aga kui me tutvustas ideed järjestatud numbrite laval elama eelmisel nädalal siis meil oli see instinkt läheb keskel, kus punkt oli meil väiksem nimekirja suurus 4 või teise nimekirja size 4, ja siis meil oli täpselt sama probleem, nii et me korrata, korrata, korrata. Teisisõnu, me rekursiivselt. Tänan teid väga, et meie 3 vabatahtlikele siin näitamaks, rekursioon koos meiega. Vaatame, kas me ei saa teha seda nüüd natuke konkreetsem, lahendada probleem, et jälle me võiks teha päris kergesti, kuid me kasutame seda nagu hüppelaud rakendatakse seda põhimõtet. Kui ma tahan arvutada liitmise hunnik numbreid, Näiteks, kui te kaotate arv 3, Ma tahan teile anda väärtus sigma 3, nii summa 3 + 2 + 1 + 0. Ma tahan saada tagasi vastus 6 nii me rakendada seda sigma funktsioon, see liitmise funktsioon veel kord, et küsimus võetakse sisend ja tagastab liitmise et number kogu tee alla 0-ga. Me võiksime seda teha üsna lihtsalt, eks? Me võiksime seda teha mingi silmuspõletamise struktuur, seega lubage mul minna ja saada see algas. Kaasa stdio.h. Las ma saan ise võtta peamised tööd siin. Lähme päästa seda sigma.c. Siis ma lähen siia, ja ma lähen kuulutada int n, ja ma teen järgmised samas kui kasutaja ei tee koostööd. Kuigi kasutaja ei ole andnud mulle positiivne arv lubage mul minna ja kallutada neid n = GetInt, ja lubage mul anda neile mõned juhised, mida teha, nii printf ("positiivne täisarv palun"). Lihtsalt midagi suhteliselt lihtne, nagu seda nii, et selleks ajaks oleme tabanud rida 14 nüüd on meil positiivne täisarv arvatavasti n. Nüüd teeme midagi koos sellega. Lubage mul minna ja arvutama liitmise, nii int summa = sigma (n). Sigma on lihtsalt liitmise, nii et ma lihtsalt kirjutan seda Kasvataja viis. Me lihtsalt nimetame seda sigma seal. See on summa, ja nüüd ma lähen välja printida tulemus, printf ("summa on% d \ n", summa). Ja siis ma return 0 hea meede. Me oleme teinud kõik, et see programm vajab välja huvitav osa, mis on tegelikult rakendada sigma funktsioon. Lubage mul minna siia alla ja andke mulle kuulutada funktsioon sigma. See ju võtta muutuja, mis on tüüpi täisarv, ja milliseid andmeid tüüp ma tahan tagasi arvatavasti Sigma? Keskmine, sest ma tahan, et see vastaks mu ootustele real 15. Siin lubage mul minna ja rakendada seda aastal üsna lihtne viis. Lähme edasi ja öelda int summa = 0, ja nüüd ma lähen on vähe loop siin et ei ütle midagi sellist, jaoks (int i = 0; ma <= arv; i + +) summa + = i. Ja siis ma lähen tagasi summa. Ma oleks võinud rakendada seda igal mitmel viisil. Ma oleks võinud kasutada samas silmus. Ma oleks võinud vahele kasutades summa muutuja kui ma tõesti tahtsin, aga lühidalt öeldes, me lihtsalt peame funktsioon, et kui ma ei tobu deklareerib summa on 0.. Siis ta kordab 0 püsti arvu kaudu, ja iga iteratsiooni ta lisab, et praeguse väärtuse summa ja tagastab summa. Nüüd, seal on kerge optimeerimine siin. See on ilmselt raisatud samm, kuid olgu nii. See on hea nüüd. Oleme vähemalt on põhjalik ja läheb 0 koik teed üles. Mitte väga raske ja üsna otsekohene, aga tuleb välja, et koos sigma funktsioon on meil samad võimalused nagu me tegime siin laval. Laval me lihtsalt arvestada, kui palju inimesi oli minu kõrval, vaid siis, kui me tahtsime loendada 3 + 2 + 1 mööda kuni 0 võiksime sarnaselt punt funktsioon et ma selle asemel kirjeldada nagu oleks rekursiivne. Siin teeme kiire meelerahu vaadata ja veenduda, ma ei tobu. Ma tean, et vähemalt üks asi selles programmis, et ma tegin valesti. Kui ma Enter ma hakka mingeid karjud mu peale? Mida ma nüüd peale karjutakse umbes? Jah, ma unustasin prototüüp, et ma kasutan funktsiooni nimetatakse sigma real 15, kuid see ei ole deklareeritud kuni liin 22, nii et ma parim ennetavalt tõusevad siin ja kuulutada prototüüp, ja ma ütlen int sigma (int arv), ja ongi kõik. See on rakendatud allosas. Või teine ​​viis, kuidas ma saaks seda lahendada, Ma võiks liikuda funktsioon seal üleval, mis ei ole halb, kuid vähemalt kui teie programmid hakkama saada kaua, ausalt öeldes Ma arvan, et seal on mõned väärtus alati võttes peamine tipus nii et sa lugeja saab faili avada ja siis kohe näha mida programm teeb, ilma et otsida seda otsin, et peamine ülesanne. Lähme alla minu terminaliakent siin, proovige sigma teha sigma, ja ma silmamunad ka siin. Kaudsed deklaratsiooni funktsioon GetInt tähendab, et ma olen unustanud teha, mida veel? [Kuuldamatu-õpilane] Hea, et ilmselt levinud viga, et paneme selle siia üles, cs50.h, ja nüüd lähme tagasi oma terminali aknas. Ma Ekraani tühjendamiseks ja ma uuesti, teha sigma. Tundub, et on koostatud. Lubage mul nüüd jooksma sigma. Ma kirjuta number 3, ja ma ei saa 6, nii ei range kontroll, kuid vähemalt see näib toimivat esmapilgul, kuid nüüd lähme rippida ta peale, ja olgem tegelikult võimendada idee rekursioon taas väga lihtne kontekstis nii, et mõne nädala pärast kui me alustada uurimist Kasvataja andmestruktuurid kui massiivid meil on veel üks hend, mille abil manipuleerida neid andmestruktuure nagu me näeme. See on iteratiivne lähenemine, silmus lähenemine. Lubage mul selle asemel nüüd seda teha. Lubage mul selle asemel öelda, et liitmise arv kohta allapoole 0 on tõesti sama, mis number + sigma (arv - 1). Teisisõnu, nagu laval ma punted igale inimesed minu kõrval, ja need omakorda hoida punting kuni me lõpuks madalaima tasemeni Willy, kes tuli tagasi kodeeritud vastus nagu 0. Siin nüüd oleme sarnaselt punting et sigma sama funktsioon oli algselt nimega, kuid Võtmeküsimuseks siin on see, et me ei sea sigma identselt. Me ei läbides n. Me selgelt läbivad arv - 1 nii veidi väiksem probleem, veidi väiksem probleem. Kahjuks see ei ole päris lahendus veel, ja enne kui me määrata mida võiks välja hüpates nii ilmne on mõned teist lubage mul minna ja uuesti teha. Tundub, et koostada midagi. Lubage mul uuesti, sigma koos 6. Oih, lubage mul uuesti, sigma koos 6. Me oleme näinud seda enne, kuid kogemata eelmine kord ka. Miks ma selle segasena killustatust süü? Jah. [Kuuldamatu-õpilane] Pole mingit alust juhul, täpsemalt, mida ilmselt juhtus? See on sümptom, mida käitumist? Ütle seda veidi valjemini. [Kuuldamatu-õpilane] See on lõputu silmuse tõhusalt, ja probleem lõpmatu ring kui need hõlmavad rekursioon sel juhul funktsiooni kutsutakse ise, juhtub iga kord, kui helistate funktsiooni? Noh, arvan, et tagasi kuidas me sätestatud mälu arvutis. Me ütlesime, et seal on see patakas mälu nimetatakse korstnat, mis on allosas, ja iga kord, kui helistate funktsiooni natuke rohkem mälu saab panna Selle nn korstna sisaldab seda funktsiooni kohalik muutujate või parameetrite, nii et kui sigma kutsub sigma kõned sigma kutsub sigma  kutsub sigma Kuhu see lugu lõpeb? Noh, see lõpuks ülekulu kogusumma mälu, et teil on olemas arvuti. Sa ületatud segmendi et sa peaksid jääma, ja sa saad seda killustatust süü, tuum dumpinguhinnaga, ja mida tuum dumpinguhinnaga tähendab, et mul on nüüd fail nimega tuum mis on fail, mis sisaldab nulle ja ühtesid et tegelikult tulevikus olema diagnostiliselt kasulik. Kui see ei ole selge, kust teie viga on tegelikult võite teha natuke kohtuekspertiis, kui nii võib öelda, Selle tuum dump faili, mis jällegi on lihtsalt terve hunnik nulle ja ühtesid et sisuliselt esindab riiki oma programmi mälu Praegu ta kukkus niimoodi. Fix on selles, et me ei saa lihtsalt pimesi naasta sigma, number + sigma on veidi väiksem probleem. Meil peab olema mingi alus juhul, ja mida peaks tugipunkti arvatavasti? [Kuuldamatu-õpilane] Okei, nii kaua, kui arv on positiivne peaksime tegelikult naasma seda, Või teisiti öeldes, kui number on, ütleme, <= 0 tead mis, ma lähen edasi ja tagastab 0, palju nagu Willy tegi, ja teine, et ma lähen edasi minna ja tagastab selle, et see ei ole nii palju lühem kui iteratiivne versioon, et me Õhutas esimene kasutades jaoks silmus, aga märgata, et seal on selline elegants ta. Asemel, et tagastada mõned number ja täites kõik see matemaatika ja lisades asju kohalike muutujate sa selle asemel öelda "Okei, kui see on super lihtne probleem, nagu number on <0, andke mulle kohe tagasi 0 ". Me ei kavatse viitsinud toetamine negatiivsed arvud, nii et ma lähen kõvasti koodi väärtus 0. Aga muidu, selle idee elluviimiseks summeerides kõik need numbrid kokku saate tõhusalt võtta väike amps välja probleemi, palju nagu meie tegime laval, siis punt ülejäänud probleem järgmisele isikule, kuid sel juhul järgmine inimene on ise. See on identselt nimega funktsioon. Lihtsalt andke seda väiksemaks ja väiksemaks ja väiksemaks probleem iga kord, ja kuigi me ei ole päris vormistatakse asju kood siia see on täpselt, mis juhtus aastal nädal 0 ja telefoni raamat. See on täpselt, mis juhtus möödunud nädalal koos Sean ja meie meeleavaldusi otsides numbrid. See võtab probleem ja jagades seda uuesti ja uuesti. Teisisõnu, seal on juba praegu tõlkimise see reaalses maailmas ehitada, seda kõrgem konstrukti jaga ja valitse ja midagi ikka ja jälle kodeeritud, nii et see on midagi, mida me näeme jälle ajas. Nüüd, kui kõrvale, kui sa oled uus rekursioon siis peaks vähemalt aru nüüd miks see on naljakas. Ma lähen minema google.com, ja ma lähen otsima mõned näpunäiteid, rekursioon, siseneda. Ütle inimene sinu kõrval, kui nad ei naera just nüüd. Kas mõtlesite rekursioon? Kas mõtlesite-ah, seal läheme. Okei, nüüd, et ülejäänud kõigile. Vähe lihavõttemuna varjatud kusagil Google. Nagu kõrvale, üks lingid paneme rajal veebilehte täna on lihtsalt see ruudustik sorteerimise algoritme, millest mõned me vaatasime eelmisel nädalal, kuid mis on tore selle visualiseerimine nagu te üritate wrap meelt umbes erinevaid asju seotud algoritme tean, et saab väga lihtsalt nüüd alustada erinevaid sisendeid. Sisendite kõik vastupidiseks, sisendite enamasti järjestatud, sisendite juhuslik ja nii edasi. Nagu te üritate jällegi eristada neid asju meelt aru, et see link on muidugi koduleheküljel Loengud lehele võib aidata teil põhjust läbi mõned neist. Täna me lõpuks ometi seda probleemi lahendada alates aega tagasi, mis oli, et see swap funktsiooni lihtsalt ei tööta, ja milline oli põhiprobleem see funktsioon swap, mille eesmärgiks oli jällegi vahetada raha siin ja siin nii, et see juhtub? See tegelikult ei tööta. Miks? Jah. [Kuuldamatu-õpilane] Täpselt, seletus bugginess lihtsalt oli, sest kui sa kasutad funktsioone C ja need funktsioonid võtta argumendid, nagu a ja b siin, läbite koopiates iganes väärtus pakute sellele funktsioonile. Sa ei paku Algsete ise, nii et me nägime seda seoses buggyc, buggy3.c, mis tundus natuke midagi sellist. Tuletame meelde, et meil oli x ja y algväärtusega 1 ja 2 nimetatud isikud. Me siis prinditakse välja, mida nad olid. Siis väitis, et olin nende vahetamisest, kutsudes swap x, y. Aga probleem oli, et vahetada töötanud, kuid ainult reguleerimisalasse swap funktsiooni. Niipea kui me tabanud rida 40 need vahetasid väärtused visati ära ja nii midagi esialgse funktsiooni main tegelikult üldse muutunud, nii et kui te arvate tollal, mida see välja näeb nii meie mälu kui see vasakus servas juhatuse esindab- ja ma teen oma parima kõigile näha seda, kui vasakul küljel juhatuse esindab, ütleme, oma RAM ja korstna läheb kasvavad üles nii, ja me nimetame funktsiooni nagu põhiline ja peamine on 2 kohalikud muutujad x ja y, olgem kirjeldab neid kui x siin ja olgem kirjeldada kui y siin, ja paneme väärtuste 1 ja 2, nii et see siin on peamine, ja kui peamine nõuab swap funktsiooni operatsioonisüsteemi annab swap funktsiooni oma loog mälu korstnat oma raami korstnat, kui nii võib öelda. Samuti eraldab 32 bitti nende täisarvudega. See juhtub, et helistada neile ja b, kuid see on täiesti meelevaldne. Ta oleks võinud kutsus nad iganes ta soovib, kuid mis juhtub, kui peamine kutsub swap on ta võtab selle 1 seab koopia olemas, seab koopia olemas. Seal on 1 teiste kohalike muutuja swap, kuigi ehk mida? >> Tmp. Tmp, nii et las ma annan endale teise 32 bitti siin, ja mis ma teha seda funktsiooni? Ma ütlesin int tmp saab, nii on 1, nii et ma tegin seda, kui me viimati mängis selles näites. Siis saab b, seega b on 2, nii et nüüd see muutub 2 ja nüüd b saab temp, nii temp on 1, nii nüüd b muutub see. See on tore. See toimis. Aga siis niipea, kui funktsioon tagastab swap mälu sisuliselt kaob, nii et seda saab taaskasutada mõne muu funktsiooni tulevikus, ja peamine on loomulikult täiesti muutumatuna. Vajame viis põhimõtteliselt selle probleemi lahendamiseks, ja täna me lõpuks ometi võimalus seda kusjuures saame tutvustada midagi, mida nimetatakse pointer. Tuleb välja, et me saame selle probleemi lahendada ei sooritades koopiates x ja y kuid selle asemel, läbides, mida, sa arvad, et swap funktsiooni? Jah, mis aadress? Me ei ole tegelikult rääkinud aadressid palju detaile, aga kui see tahvel kujutab minu arvuti mälu me võiks kindlasti alustada nummerdamist baiti minu RAM ja öelda, see on bait # 1, see on bait # 2, bait # 3, bait # 4, bait # ... 2000000000 kui mul on 2 GB RAM, nii et me võiks kindlasti tulla mõned suvalise numeratsiooniplaani kõikidele üksikutele baiti minu arvuti mällu. Mis siis, kui selle asemel, kui ma nimetan vahetusleping mitte passi koopiad x ja y miks ma ei asemel viiakse aadress x siin, aadress y siin sisuliselt postiaadress x ja y, sest siis vahetada, kui ta on teavitanud Euroopa aadress mälestuseks x ja y, siis vahetada, kui me teda koolitanud natuke, ta võiks juhtida sellele aadressile, nii et rääkida, x ja arvu muuta seal, siis sõita aadress y, Numbri muutmiseks seal, isegi kui tegelikult ei saada nende koopiaid väärtused ise, Nii et kuigi me rääkisime sellest nagu oleks peamine mällu ja seda kui swap mälu võimas ja ohtlik osa C on see, et mingit ülesannet võib puudutada mälu kusagil arvutis ja see on võimas, mida saate teha väga uhke asju Arvutiprogrammide C. See on ohtlik, sest nii võib ka kägardama väga lihtsalt. Tegelikult üks levinumaid viise programmide nendel päevadel ära kasutada ikka on programmeerija ei mõista et ta võimaldab andmete tuleb kirjutada asukohta mälus, mis ei olnud ette nähtud. Näiteks ta deklareerib massiivi suurus 10 aga siis kogemata üritab panna 11 baiti sellesse hulga mälu ja hakkate liigutav osad mälu, mis enam ei kehti. Lihtsalt konteksti, on mõned võiksite teada, et tarkvara sageli küsib seerianumbrid või registreerimine võtmed, Photoshop ja Word ja programmid niimoodi. On olemas praod, nagu mõned teist teavad, online, kus saab joosta väike programm, ja voila, enam taotlust seerianumber. Kuidas see töötab? Paljudel juhtudel on need asjad lihtsalt järeldus arvutid teksti segmentide arvuti tegelik nulle ja ühtesid Kus on see funktsioon juhul, kui seerianumber on taotletud, ja te kirjutate, et ruumi või kui programm töötab saate aru saada, kus võti on tegelikult ladustatav kasutades midagi, mida nimetatakse siluri ja saate crack tarkvara nii. See ei tähenda, et see on meie eesmärk järgmise paari päeva jooksul, kuid see on väga reaalse tagajärgi. Et üks juhtub, et kaasata varguse tarkvara, kuid seal on ka kompromiss kogu masinad. Tegelikult, kui veebilehed nendel päevadel on ära ja ohustatud ning andmed on lekkinud ja paroolid varastatakse see väga sageli seotud halva juhtimise ühe mällu või, kui tegemist on andmebaasid, suutmatus ennetada võistleva sisend, nii rohkem, et lähinädalatel, kuid nüüd lihtsalt vargsi eelvaade omamoodi kahju, mida saate teha mitte päris mõista, kuidas asjad töötavad all kapuuts. Lähme umbes aru, miks see on katki tööriista, mis muutub üha kasulik nagu meie programmide saada keerulisem. Nii kaugele, kui olete olnud viga teie programm kuidas olete läinud umbes silumiseks? Mis on teie tehnikat olnud siiani, kas õpetanud oma TF või lihtsalt iseõppinud? [Student] printf. Printf, nii printf olnud ilmselt su sõber, et kui soovite näha mis toimub sees oma programmi sa lihtsalt panna printf siin printf siin printf siin. Siis sa jooksed ta, ja sa saad terve hunniku asju ekraanil , mida saab kasutada, et siis järeldan, mis tegelikult valesti oma programmi. Printf kipub olema väga võimas asi, aga see on väga käsitsi protsessi. Sul on panna printf siin printf siin, ja kui paned ta sees silmus võid saada 100 rida toodangut, siis pead sõeluma kaudu. See ei ole väga kasutajasõbralik või interaktiivne süsteem silumiseks programme, kuid õnneks on olemas alternatiive. Seal on programm, näiteks nimega gdb GNU siluri, mis on veidi kauge, kuidas sa seda kasutada. See on natuke keeruline, kuid ausalt öeldes see on üks nendest asjadest kus kui paned käesoleval ja järgmisel nädalal pildi tund mõista midagi GDB see säästab ilmselt kümneid tundi pikas perspektiivis, Nii et, las ma annan sulle teaser, kuidas see asi toimib. Ma olen oma terminali aknas. Lubage mul minna ja koostada selle programmi buggy3. See on juba kursis. Lubage mul kasutada seda nagu me tegime aega tagasi, ja tõepoolest, see on katki. Aga miks see nii on? Võib-olla ma silmamunad swap funktsiooni. Ehk on see a ja b. Ma pole päris liigutades neid ümber õigesti. Lubage mul minna ja seda teha. Selle asemel, et lihtsalt jooksma buggy3 andke mulle selle asemel käivitada programm GDB, ja ma räägin seda käivitada buggy3, ja ma lähen lisada käsurea argument,-tui, ja me paneme selle tulevikus probleeme spec meelde. Ja nüüd on see must ja valge liides hüppasid üles, et jälle on veidi valdav esimesel, sest seal on kõik see teave garantiitingimuste siia alla, aga vähemalt midagigi tuttav. Ülemises aknas on minu tegelik kood, ja kui ma liikuge üles siin las ma kerin et väga peale minu faili ja tõepoolest, seal on buggy3.c, ja teate allosas see aken Mul on see GDB kiire. See ei ole sama, mis minu tavaline John Harvard kiire. See on kiire, et läheb lubage mul juhtida GDB. GDB on silur. Silur on programm, mis võimaldab teil kõndida läbi täitmine oma programmi rida-realt, mööda teed tee midagi soovite programmi isegi helistaja funktsioone või vaatavad, mis veelgi tähtsam, erinevatel muutuja väärtusi. Lähme edasi ja tee seda. Ma lähen edasi minna ja sisestada töötamises GDB on kiire, nii märkate allosas vasakul ekraani Olen trükitud joosta, ja ma olen Enter, ja mida see veel teha? Ta sõna otseses mõttes jooksin oma programmi, kuid tegelikult ma ei vaata palju minna siin sest ma ei ole tegelikult rääkinud siluri peatamiseks mingil kindlal ajahetkel. Lihtsalt kirjutades run käivitab programmi. Ma tegelikult ei näe midagi. Ma ei saa manipuleerida seda. Selle asemel lubage mul seda teha. Sel GDB kiire andke mulle selle asemel kirjuta pausi, siseneda. See pole see, mida ma mõtlesin kirjutada. Olgem selle asemel kirjuta pausi peamine. Teisisõnu, ma tahan luua midagi, mida nimetatakse murdepunkti, mis on tabavalt nimetatud, sest see murdub või pausi täitmine oma programmi selle konkreetse koha. Peamised on nimi minu ülesanne. Pange tähele, et GDB on päris tark. See arvasin, et peamine juhtub alustada umbes real 18 kohta buggy3.c ning märkate, siin üleval vasakul b + on õige kõrval realt 18. See on meenutas mulle, et ma olen pannud murdepunkti real 18. See aeg, kui ma tüüpi perspektiivis ma saan oma programmi kuni see tabab, et murdepunkt, et programm paus minu jaoks eelarverea 18. Hakkab pihta, jooksed. Midagi on ilmselt juhtunud, kuid teate all vasakul alustades programmi buggy3, murdepunkti 1 põhitähelepanu buggy3.c realt 18. Mida ma nüüd teen? Teade Ma ei hakka kirjutama asju nagu print, ei printf, print x, ja nüüd, et on kummaline. $ 1 on lihtsalt uudishimu, nagu me näha iga kord, kui prindite midagi saate uue $ väärtus. See on nii, et saate naasta eelmised väärtused igaks juhuks, kuid nüüd, mida prindi räägib mulle, et x väärtus selles punktis lugu Ilmselt on 134514032. Mida? Kust see isegi tulevad? [Kuuldamatu-õpilane] Tõepoolest, see on see, mida me nimetame prügi väärtus, ja me pole sellest rääkinud veel, kuid põhjus, et te initsialiseerida muutujad On selge, et neil oleks mingi väärtus, et sa tahad neid on. Aga saak on meelde tuletada, et saate tuvastada muutujad nagu ma tegin hetk tagasi minu sigma näiteks ilma tegelikult neile väärtust. Meenuta, mida ma tegin üle siin sigma. Ma kuulutatud n, kuid mis väärtus ma anda? Puudub, sest ma teadsin, et järgmise paari rida GetInt oleks hoolitseda probleem panna raha sees n. Aga siinkohal lugu line 11 ja rida 12 ja rida 13 ja rida 14 kogu nende mitu rida, mis on n väärtus? C sa lihtsalt ei tea. See on tavaliselt mõned prügi väärtus, mõned täiesti juhuslik arv mis on jäänud üle sisuliselt mõnest eelmise funktsiooni ning läbinud, et teie programm töötab meelde tuletada, et funktsiooni saab funktsioon, funktsioon, funktsioon. Kõik need raamid saavad panna mälu ja seejärel neid funktsioone Vastutasuks ja nagu Tegin koos kustutuskumm oma mälu lõpuks uuesti kasutada. Noh, see lihtsalt nii juhtub, et see muutuja x selles programmis tundub, et on esitatud mõned prügi väärtus nagu 134514032 mõnest eelmise funktsiooni, mitte üks, mille ma kirjutasin. See võiks olla midagi, mis on tegelikult operatsioonisüsteemi, mõned funktsiooni all kapuuts. Okei, see on hea, kuid olgem nüüd edasi järgmisele reale. Kui ma tüüpi "Next" minu GDB kiire ja ma tabanud siseneda, märgata, et esile liigub allapoole rida 19, aga loogiline jätk on see, et eelarverea 18 on nüüd lõppenud täidesaatva, nii et kui ma uuesti tippida "print x" Ma peaks nüüd näha 1 ja tõepoolest, ma teen. Jällegi $ värk on viis GDB teile meelde Mis ajaloos pildid on mis sa teinud oled. Nüüd lubage mul minna ja välja printida y, ja tõepoolest, y on mõned hull väärtus samuti, aga pole hullu, sest rida 19 me parasjagu määrata selle väärtus 2, seega lubage mul kirjutada "Next" uuesti. Ja nüüd oleme printf rida. Las ma teen print x. Las ma teen print y. Ausalt, ma saan natuke väsinud trükkimiseks. Lubage mul selle asemel kirjuta "ekraan x" ja "ekraani y" ja nüüd iga kord kui ma anna käsk tulevikus Ma meenutada, mis on x ja y, mis on x ja y, mis on x ja y. Võin ka, kui kõrvale, kirjuta "info kohalikega." Info on spetsiaalne käsk. Kohalikud tähendab see näitab mulle lokaalsed muutujad. Igaks juhuks ma unustan või see on hull, keeruline funktsioon et mina või keegi teine ​​kirjutas infot kohalikega ütlen teile millised on kõik kohalikud muutujad sees kohalik funktsioon et sa võiksid hooli, kui sa tahad tuhnima. Nüüd printf on umbes täita, seega lubage mul minna ja lihtsalt tüüp "kõrval." Sest me oleme selles keskkonnas me tegelikult ei näe seda täita siin all, kuid märgata Läheb veidi moonutatud siin. Aga märka seda kõige tähtsam ekraan seal nii see ei ole täiuslik programm siin, aga pole hullu, sest ma alati tuhnima kasutades prindi, kui ma tahan. Las ma kirjuta järgmine kord, ja nüüd siin on huvitav osa. Sel hetkel lugu y on 2 ja x on 1, nagu siin soovitati, ja jälle, Põhjus, miks see automaatselt väljapanek nüüd on, sest ma kasutasin käsk Näita X ja ekraani y, nii praegu ma tüüpi kõrval teoreetiliselt x ja y peaks saama vahetada. Nüüd me juba teame, et ei kavatse olla, kuid eks me näeme ühel hetkel kuidas sukelduda sügavamale aru saada, miks see on tõsi. Järgmine ja kahjuks y on veel 2 ja x on ikka 1, ning võin kinnitada, nii palju. Prindi x-, trüki y. Tõepoolest, ei ole Vahetatakse on tegelikult juhtus nii, alustame selle üle. Ilmselgelt swap on katki. Olgem selle asemel kirjuta "run" uuesti. Lubage mul öelda jah, ma tahan seda uuesti käivitada algusest peale, enter. Nüüd ma olen tagasi üles real 18. Nüüd pane tähele, x ja y on prügi väärtused uuesti. Järgmine, järgmine, järgmine, järgmine. Kui ma igavleda võin ka lihtsalt kirjutada n järgmisel. Võite lühendada seda võimalikult lühikese märgijada. Vaheta nüüd katki. Olgem sukelduda, nii kirjutamise asemel kõrval, nüüd ma lähen kirjuta samm nii et ma samm sees seda funktsiooni nii et võin kõndida läbi see, et ma tabanud sammu ja siis enter. Pange tähele, et esile hüppab alla madalam minu programmi rida 36. Nüüd siis millised on kohalikud muutujad? Info kohalikega. Miski lihtsalt veel, sest me pole saanud seda liini, nii lähme edasi ja öelda "Next". Nüüd tundub, et on tmp, trüki tmp. Prügi väärtust, eks? Ma arvan küll. Kuidas printida, printimine b, 1 ja 2? Selleks hetkeks, niipea kui ma tüüpi järgmisel jälle tmp läheb võtma väärtus 1, loodetavasti sest tmp saab olema määratud väärtus. Nüüd teeme printida, trüki b, kuid nüüd printida tmp, ja see on tõesti 1. Lubage mul teha järgmisena. Lubage mul teha järgmisena. Olen lõpetanud swap funktsiooni. Ma olen ikka sees on kooskõlas 40, nii et andke mulle printida, prindi b, ja ma ei hooli, mida tmp on. Tundub, swap on õige, kui tegemist on vahetada ja b. Aga kui ma nüüd kirjuta järgmine, ma hüppan tagasi real 25 ja muidugi, kui ma kirjuta x ja prindi y nad on ikka muutumatuks, nii et me ei ole fikseeritud probleem. Aga diagnostiliselt nüüd võibolla see GDB programmi oleme vähemalt saanud üks samm lähemale mõistmisele mis toimub vale ilma pesakond meie koodi pannes printf siin, printf siin printf siin ja siis töötab ta ikka ja jälle püüab välja selgitada, millised on valesti. Ma lähen edasi minna ja loobuda sellest üldse koos lõpetan. See saab siis öelda: "väljuda?" Jah. Nüüd olen ma tagasi minu tavaline kiire, ja ma olen teinud kasutades GDB. Nagu kõrvale, sa ei pea kasutama seda-tui lipp. Tegelikult, kui jätate selle saad sisuliselt põhja pool ekraani. Kui ma tippige pausi peamine ja seejärel käivitage Ma ei saa ikka saan oma programmi, kuid mida ta teeb on rohkem tekstina lihtsalt näita mulle mingi rida ühe korraga. -Tui, tekstiline kasutajaliides, lihtsalt näitab teile, mitu programmi korraga, mis on ilmselt natuke kontseptuaalselt lihtsamaks. Aga tõesti, ma ei saa lihtsalt teha järgmisena kõrval kõrval, ja ma lähen vaata üks rida korraga, ja kui ma tõesti tahan näha, mis toimub Ma ei kirjuta nimekiri ja vaata, kogu kari naaber read. Seal on video, et me oleme palunud, et sa vaatad jaoks probleem Komplektid 3 kus Nate hõlmab mõned Hienoudet GDB, ja see on üks nendest asjadest, ausalt, kus mõned mitte-triviaalne protsent te kunagi puudutage GDB, ja see on halb asi sest sõna otseses mõttes siis lõpuks kulutusi rohkem aega hiljem see semester death ette vigu siis oleks, kui paned, et poole tunni / tunni käesoleval ja järgmisel nädalal õppe saada rahul GDB. Printf oli sinu sõber. GDB peaks nüüd olema sinu sõber. Iga küsimustele GDB? Ja siin on kiire nimekirja mõned kõige võimsam ja kasulikke käske. Jah. >> Kas teil on vaja printida string? Kas teil on vaja printida string? Absoluutselt. See ei pea just olema täisarvud. Kui muutuja s on string lihtsalt kirjuta prindi s. See näitab teile, mida see string muutuja. [Kuuldamatu-õpilane] See annab teile aadress ja nöör ise. See näitab teile mõlemale. Ja viimane asi, lihtsalt sellepärast, et need on hea teada ka. Tagasijälitus ja raam, lubage mul sukelduda sellesse viimast korda, sama täpne programm koos GDB. Lubage mul minna ja joosta tekstiline kasutajaliides versioon, murda peamine. Lubage mul minna ja uuesti avada. Siin ma olen. Nüüd ma lähen järgmisel kõrval kõrval, kõrval kõrval, samm, siseneda. Ja nüüd arvan, et ma olen nüüd swap tahtlikult, aga ma olen nagu "Kurat, milline oli x väärtus?" Ma ei saa x enam. Ma ei saa y sest nad ei ole oma ulatuselt. Nad ei ole kontekstis, kuid mingit probleemi. Ma ei kirjuta tagasijälitust. See näitab mulle kõik funktsioonid, mis on teostatud kuni ajahetkel. Pange tähele, et üks all, peamine, ridade järele peamine on põhjas meie pilti siit. Asjaolu, et swap on eespool see ridade järele swap on eespool see mälu siin, ja kui ma tahan saada tagasi peamine ajutiselt võin öelda "raamiga." Mis number? Peamine on raam # 1. Ma lähen edasi minna ja öelda "korpus 1". Nüüd ma olen tagasi peamine, ja ma võin printida x, ja võin printida y, aga ma ei saa trükkida või b. Aga ma ei saa, kui ma ütlen: "Okei, oota natuke. Kuhu jäi swap?" Lubage mul minna ja öelda "kaadri 0". Nüüd ma olen tagasi, kus ma tahan olla, ja kui kõrvale, seal on teised käsud liiga, nagu kui sa oled tõesti Igavuse kirjutades kõrval kõrval, kõrval kõrval, saate tavaliselt öelda asju nagu "Järgmise 10," ja et astub läbi järgmise 10 rida. Võite ka kirjutada "Jätka", kui sa tõesti kõrini astudes läbi. Jätka kestab teie programm katkematult kuni see tabab teine ​​murdepunkti, kas tsüklina või madalamal oma programmi. Sel juhul jätkasime lõpuni, ja programm lahkus tavaliselt. See on fancy viis, halvem protsess. Lihtsalt oma programmi lahkus tavaliselt. Rohkem, et video ja silumine istungid tulla. See oli palju. Võtame meie 5-minutilise pausi siin, ja me tagasi koos structs ja faile. Kui olete sukeldunud nädala pset juba tead, et me kasutame jagamise kood, lähtekoodi, et pakume teile lähtepunkt, mõned uued tehnoloogiad. Eelkõige võtsime kasutusele uue märksõna nimetatakse struct, ehitise, nii et me saame luua kohandatud muutujate kehvasti. Meil on ka kasutusele mõiste Faili I / O, faili sisend ja väljund, ja see on nii, et saame säästa riik oma rüselus pardal fail kettal nii et õpetamise stipendiaatide, samuti saan aru mis toimub sees oma programmi ilma käsitsi mängida kümneid mängud rüselus. Me saame seda teha rohkem automatedly. See idee struct lahendab üsna kaalukaid probleem. Oletame, et me tahame rakendada mõne programmi et kuidagi peab arvet teavet õpilased, ja õpilased võivad olla näiteks ID nimi ja maja kohas nagu Harvard, mistõttu need 3 tükki teave me tahame hoida umbes, seega lubage mul minna ja hakake väike programm siin, sisaldavad stdio.h. Las ma teen sisaldavad cs50.h. Ja siis hakkan oma põhifunktsiooni. Ma ei viitsinud mingeid käsurea argumente, ja siin ma tahan olla üliõpilane, nii et ma lähen öelda Üliõpilasel on nimi, nii et ma ütlen "string nimi." Siis ma lähen ütlen üliõpilane on ka ID, nii int id, ja õpilane on maja, nii et ma ka ei ütle "string maja." Siis ma, et need veidi puhtamalt niimoodi. Okei, nüüd mul on 3 muutujaid, mis hakkab esindama õpilane, et "õpilane". Ja nüüd ma tahan, et asustada neid väärtusi, seega lubage mul minna ja öelda midagi sellist "Id = 123". Nimi ei hakka David. Oletame, et maja ei hakka Mather, ja siis ma teen midagi omavoliliselt nagu printf ("% s, kelle ID on% d, elab% s. Ja nüüd, mida ma tahan ühendada siin, üksteise järel? Nime, ID, maja; return 0. Okei, kui ma silmamunad kuskil siin Ma arvan, et meil on päris hea programm, mis salvestab üks õpilane. Muidugi, see ei ole nii huvitav. Mida teha, kui ma tahan 2 õpilast? See pole suur asi. Toetan 2 inimest. Lubage mul minna ja rõhutada seda ja minna siin, ja võin öelda, "id = 456" keegi nagu Rob, kes elab Kirkland. Okei, oota, kuid ma ei saa kutsume neid sama asi, ja tundub, et ma lähen on kopeerida see, seega lubage mul öelda, et need on Taaveti muutujad, ja las ma saaksin koopiaid nendest Rob. Me kutsume neid Rob kuid see ei hakka tööle nüüd sest ma olen-oot, olgem muuta mind id1, NAME1 ja house1. Rob on 2, 2. Ma pean seda muuta siin, siin, siin, siin, siin, siin. Oota, mis Tommy? Teeme seda uuesti. Loomulikult, kui sa ikka arvan, et see on hea viis seda teha, see ei ole, nii copy / paste halb. Aga me lahendasime selle paar päeva tagasi. Milline oli meie lahendus, kui me tahtnud Rohkete sama andmetüüp? [Õpilased] massiivi. Massiiv, nii et lubage mul proovida puhastada see üles. Lubage mul teha mõned ruumi ennast üleval, ja andke mulle selle asemel tee seda siin. Me kutsume neid inimesi, ja selle asemel ma lähen ütlen "int sümbolid," ja ma lähen toetada 3 meist nüüd. Ma ütlen "string nimed," ja ma toetan 3 meist, ja siis ma lähen ütlen "string majad," ja ma toetan 3 meist. Nüüd siin Taaveti asemel saada oma kohalike muutujate saame lahti neist. See on hea tunne, et me puhastamine selle üles. Võin siis öelda David saab olema [0] ja nimed [0] ja majad [0]. Ja röövida saame samamoodi salvestada see. Paneme selle siia alla, nii ta läheb omavoliliselt olema IDS [1]. Ta saab olema nimed, [1] ja siis lõpuks, majad [1]. Ikka natuke tüütu, ja nüüd on mul sellest sotti, nii ütleme "nimed [0], id [0], majad [0] ja olgem pluralize seda. IDS, ID, ID-d. Ja jälle, ma teen seda, nii et jälle, ma juba pöörduvad copy / paste uuesti, nii koefitsiendid on seal on teine ​​lahendus siin. Võin ilmselt puhastada see üles veelgi kliendiliinile või midagi sellist, nii lühike, see on veidi parem, kuid siiski tundub Ma pöörduvad copy / paste, kuid isegi see, Väidan, ei ole tõesti põhimõtteliselt õige lahendus, sest Mida teha, kui millalgi me otsustame tead mida? Me tõesti oleks pidanud ladustamiseks e-posti aadresse David ja Rob ja kõik teised selles programmis. Me peaksime ka salvestada telefoninumbreid. Me peaksime ka salvestada hädaabi numbreid. Meil on kõik need tükid andmed, et me tahame säilitada, Niisiis, kuidas sa minna seda teed? Sa deklareerida teise massiivi tipus, ja siis käsitsi lisada e-posti aadress [0], e-posti aadress [1] David ja Rob ja nii edasi. Aga seal on tõesti ainult eeldusega see disain et ma kasutan au süsteem teada, et [I] Iga mitu massiivid just nii juhtub viitavad samale isikule, nii [0] IDS on number 123, ja ma lähen eeldada, et nimed [0] on sama isiku nimi ja maja [0] on sama isiku maja ja nii edasi kõigi erinevate massiivide et ma loon. Aga teate, et seal on mingit põhimõttelist seost nende hulgas 3 tükki teavet, id, nimi ja maja, kuigi üksuse me üritame mudel selles programmis ei ole massiivid. Massiivid on lihtsalt sellises programmilises viis seda teha. Mida me tõesti tahame mudel meie programm on inimene nagu David, inimene nagu Rob mille sees või kapseldamist on nimi ja ID ja maja. Kas me kuidagi väljendada seda mõtet kapseldus millega isik on ID, nimi ja maja ja mitte kasutama tõesti seda häkkida, mille me lihtsalt usun, et sulg midagi viitab samale inimeste üksus kõik need erinevad massiivid? Me ei saa tegelikult seda teha. Laske mul minna üle peamised nüüd, ja las ma luua oma andmete tüüp jaoks tõesti esimest korda. Me kasutasime seda tehnikat rüselus, kuid siin ma lähen edasi minna ja luua andmete tüüp, ja tead mida, ma lähen kutsun seda õpilane või isik, ja ma lähen kasutada typedef jaoks määratleda tüüp. Ma ütlen, et see on struktuur, ja siis see struktuur saab olema tüüpi õpilane, me ütleme, kuigi see on veidi dateeritud nüüd minu jaoks. Me ütleme "int id." Me ütleme "string nimi." Siis me ütleme "string maja," nii et nüüd lõpuks need paar rida koodi Olen just õpetanud rõkkama, et on olemas andmetüüp peale ints lisaks stringid, lisaks kahekordistab kõrval hõljub. Nagu käesoleva ajahetkel line 11 on nüüd uus andmetüüp kutsus üliõpilasi, ja nüüd ma ei deklareerima õpilane muutuja kuskil ma tahan, las ma keri siin inimesi. Nüüd ma saan lahti sellest ja ma ei saa minna tagasi alla David siin, ja Taavet ma ei saa tegelikult öelda, et David, saame sõna otseses mõttes nimetada muutuja pärast ise, saab olema tüüpi õpilane. See võib tunduda natuke imelik, kuid see pole veel kõik, et erinevad kuulutamast midagi nii int või string või sularahaga. See lihtsalt nii juhtub olema kutsutud õpilane nüüd, ja kui ma tahan panna midagi sees selle struktuuri Mul on nüüd kasutada uus tükk süntaks, kuid see on üsna lihtne, david.id = 123, david.name = "David" kapitali D ja david.house = "Ema," ja nüüd ma saan lahti see värk siin. TEADE Me oleme nüüd ümber meie programm tõesti palju parem aastal, et nüüd meie programmi peegeldab reaalse maailma. Seal on reaalse maailma mõiste isik või õpilane. Siin on meil nüüd C versiooni isik või täpsemalt üliõpilane. Toas on selle isiku on need olulised tunnused, ID nimi ja maja, nii Rob sisuliselt muutub sama asi siin, nii õpilane Rob, ja nüüd rob.id = 456, rob.name = "Rob". Asjaolu, et muutuja nimega Rob on omamoodi mõtte. Me võinuks see x või y või z. Me lihtsalt nimeks Rob olema semantiliselt järjekindel, aga tõesti nimi on sees, et välja ennast, nii et nüüd mul on see. Ka see ei tundu parima disaini, et ma olen kõva kodeeritud David. Olen kõva kodeeritud Rob. Ja mul on veel kasutama mõned kopeeri ja kleebi iga kord ma tahan uusi muutujaid. Lisaks pean ilmselt andma kõik need muutujad nimi, kuigi ma parema meelega kirjeldada nende muutujate  rohkem üldnimetusega õpilased. Nüüd saame ühendada ideid, mis on töötanud hästi meie jaoks ja selle asemel öelda: "Tead mis, anna mulle muutuja nimega õpilased, ja ajame asja olema suurus 3, "nii et nüüd võin täpsustada seda edasi vabaneda käsitsi deklareeritud David, ja võin selle asemel öelda midagi sellist õpilast [0] siin. Võin siis öelda õpilastele [0] siin, üliõpilased [0] siin, ja nii edasi, ja ma ei saa minna ümber ja puhastage see üles Rob. Ma võiks ka minna nüüd äkki lisades loop ja kasutades getString ja GetInt tegelikult saada neid väärtusi kasutaja. Ma võiks minna umbes lisades pidev, sest see on üldiselt halb tava kõva kood suvalise arvu nagu 3 siinsamas ja siis lihtsalt meeles pidada, et sa peaksid tegema enam kui 3 õpilast ta. Ilmselt oleks parem kasutada # define ülaosas minu fail ja tegur, mis läbi, nii et tõepoolest, andke minna ja üldistada seda. Lubage mul avada näiteks see vahel tänapäeva näited ette, structs1. See on täiuslikum programm, mis kasutab # define siin ja ütleb, et me lähed on 3. klassi õpilased vaikimisi. Siin ma olen, mis kuulutab klassi väärt õpilaste, nii klassiruumis õpilaste ja nüüd ma kasutan silmus lihtsalt teha kood veidi rohkem elegantne, asustada klass koos kasutaja sisend, nii itereerima alates i = 0 kuni õpilased, mis on 3. Ja siis ma ajendab kasutaja selles versioonis  Mis on õpilase ID ja ma saan seda koos GetInt. Mis on õpilase nimi, ja siis ma saan seda koos getString. Mis üliõpilane maja? Ma saan seda getString. Ja siis allosas siin ma lihtsalt otsustasin muuta kuidas ma printida need välja ja tegelikult kasutada tsüklina Ja kes ma olen trükkimine? Vastavalt kommentaar Ma trükkimine keegi Mather, ja ongi nii Rob ja Tommy ja nii edasi-tegelikult Tommy on Mather. Tommy ja David oleks trükitud sel juhul, kuid kuidas see töötab? Me ei ole näinud seda funktsiooni enne, kuid võtta oletada, milline see teeb. Võrdleb stringid. See on veidi vähem selge, kuidas ta võrdleb stringe, sest tuleb välja, kui ta tagastab 0, mis tähendab, stringid on võrdsed. Kui ta naaseb -1, mis tähendab, üks tuleb tähestikuliselt enne teisi, ja kui ta naaseb 1, mis tähendab muu sõna pärineb tähestikuliselt enne teisi, ja saate vaadata online või mees lehekülg täpselt näha, mis suunas on mis, aga see kõik on nüüd teeme, on see ütlus kui [i]. Maja on võrdne "Ema" siis edasi minna ja välja printida nii ja nii on Mather. Aga siin on midagi, mida me ei ole varem näinud, ja me tuleme selle juurde tagasi. Ma ei mäleta kunagi seda teha kõik minu programmid. Tasuta on ilmselt viidates mälu, vabastades mälu, aga mis mälu ma ilmselt vabastades selle silmuse allosas selle programmiga? Tundub, et ma olen vabastades isiku nimi ja inimese maja, kuid miks see nii on? Tuleb välja, kõik need nädalat, et olete kasutanud getString oleme omamoodi on kasutusele bug arvesse iga ühe oma programmides. GetString mille konstruktsioon eraldab mälu, et ta saaks tagasi teie stringi, nagu David või Rob, ja saate seejärel teha mida iganes sa tahad selle stringi oma programmi, sest me oleme reserveeritud mälu teile. Probleem on kõik see aeg iga kord, kui helistada getString me, autorid getString, on küsinud operatsioonisüsteemi anda meile natuke RAM selle stringi. Anna meile natuke RAM selle kõrval string. Anna meile rohkem RAM selle kõrval string. Mida sa, programmeerija, pole kunagi teinud annab meile, et mälu tagasi, nii need mitu nädalat kõik programmid olete kirjutanud on olnud see, mida nimetatakse mälu hüpe, mille nad hoiavad kasutades rohkem ja rohkem mälu iga kord, kui helistada getString, ja see on hea. Me sihilikult teha, et esimestel nädalatel, sest see ei ole nii huvitav et ei pea muretsema, kui string on pärit. Kõik soovid on sõna Rob tagasi tulla, kui kasutaja tipib see sisse Aga liigub edasi me nüüd peame hakkama saada keerukamaid sellest. Iga kord, kui me mälu eraldada me parem lõpuks viige see tagasi. Vastasel reaalses maailmas Mac või PC võib teil olla vahetevahel kogenud sümptomeid, kus arvuti on seiskumist lõpuks või loll ketramine rannas palli lihtsalt istuvad arvuti kogu tähelepanu ja sa ei saa midagi teha. See võib seletada ükskõik arvu vigu, kuid nende seas võimalik vead on asju nimetatakse mälu lekked, mille keegi, kes kirjutas, et tükk tarkvara sa kasutad ei mäleta mälu vabastamiseks et ta palus operatsioonisüsteemi, ei kasuta getString, sest see on CS50 asi, kuid kasutades samalaadsete ülesannetega et küsida operatsioonisüsteemi mällu. Kui teie või nad kägardama ja tegelikult kunagi naasta, et mälu sümptom, mis võib olla, et programm aeglustub ja aeglustub ja aeglustub kui sa mäletad, et helistada tasuta. Me tuleme tagasi, millal ja miks sa kutsuksin tasuta, aga lähme edasi lihtsalt hea meede ja proovige käivitada selle konkreetse programmi. Seda kutsuti structs1, siseneda. Lubage mul minna ja joosta structs1, 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather, ja me näeme Davidi aastal Ema, Tommy sisse Mather. See on natuke meelerahu kontrolli, et programm töötab. Nüüd kahjuks see programm on natuke masendav, et Ma tegin kõik, et töö, ma kirjutada 9 erinevat stringid, Enter, öeldi kes oli Ema, veel muidugi ma teadsin, kes oli Ema juba sellepärast ma kirjutada seda. Oleks vähemalt tore, kui see programm on rohkem nagu andmebaas ja see tegelikult mäletab, mida ma olen sisestatud nii et ma enam kunagi sisend need üliõpilane arvestust. Võib-olla see on nagu registrarial süsteem. Me saame seda teha kasutades seda tehnikat tuntakse Faili I / O, faili sisend ja väljund, väga üldine viis öelda igal ajal soovite lugeda faile või kirjutage failid seda saab teha teatud hulk funktsioone. Lubage mul minna ja avada see näiteks structs2.c, mis on peaaegu sama, aga vaatame, mis see nüüd teeb. Ülaosas faili Kinnitan klassi õpilased. Ma siis asustada klassi kasutaja sisend, nii need rida koodi on täpselt nagu enne. Siis kui ma keri siin ma printida kõik, kes on Mather meelevaldselt nagu enne, kuid see on huvitav uus funktsioon. Need rida koodi on uus, ja nad tutvustada siin midagi, FAIL, kõik mütsid, ja see on * on ka siin. Lubage mul seda liigutada siia, * üle ka siin. See funktsioon ei ole me näinud, fopen, kuid see tähendab fail avatud, niiet Lukaista need, ja see on midagi, me tuleme tagasi tulevikus psets, kuid seda joont siin sisuliselt avab faili nimega andmebaas ja see konkreetselt avab ta nii, et ta saab teha, mida see? [Kuuldamatu-õpilane] Õige, nii "w" tähendab lihtsalt seda räägib operatsioonisüsteemi seda faili avada nii, et võin kirjutada. Ma ei taha seda lugeda. Ma ei taha lihtsalt seda vaadata. Ma tahan seda muuta ja lisada asju potentsiaalselt sellele ja fail saab nimeks andmebaasi. Seda võiks nimetada midagi. See võiks olla database.txt. See võiks olla. Db. See võiks olla sõna nagu suva, aga ma otsustanud meelevaldselt nimi faili andmebaasi. See on natuke meelerahu kontrolli, et me tuleme tagasi väga üksikasjalikult aja jooksul, Kui FP jaoks faili viitaja, ei võrdu NULL, mis tähendab, et kõik on hästi. Pikk lugu lühike, funktsioone nagu fopen mõnikord ebaõnnestuda. Ehk faili ei ole olemas. Võibolla sa oled välja kettaruumi. Võibolla sa ei ole luba selle kausta, nii et kui fopen tagastab null midagi halba juhtunud. Vastupidisel juhul, kui fopen ei tagasta null kõik on hästi ja ma ei hakake sellele failile. Siin on uus trikk. See on loop, mis on itereerimise üle iga minu õpilased, ja see tundub nii sarnane sellega, mida me oleme teinud enne, kuid see funktsioon on nõbu printf nimetatakse fprintf faili jaoks printf, ja märkate, et see on erinev, ainult 2 võimalust. Üks, see algab f asemel p, kuid siis tema esimene argument on ilmselt mida? [Õpilased] Fail. >> See fail. See asi nimega fp, mis me lõpuks tease peale mida faili viitaja on, kuid nüüd fp lihtsalt esindab faili, et ma olen avatud, nii fprintf siin ütleb trükkida selle kasutaja ID toimikule, mitte ekraanil. Trüki kasutaja nimi faili nime, ei kuvatud, maja toimikule, mitte ekraani ja siis siia alla ilmselgelt sulgege fail ja seejärel siia alla tasuta mälu. Ainus erinevus selles versioonis 2 ja versioon 1 on kasutusele fopen ja selle faili * ja see mõiste fprintf, nii vaatame, mis lõpptulemus on. Lubage mul minna minu terminaliakent. Ma jooksen structs2, siseneda. Paistab, et kõik on hästi. Teeme uuesti, structs2. 123, David Ema, 456, Rob Kirkland, 789, Tommy Ema, siseneda. Paistab, et see toimis sama, aga kui ma nüüd tegema LS teate, mis fail on siin kõigi minu kood, andmebaas, Niisiis on see, gedit andmebaasi, ja vaata seda. See ei ole seksikaim failivorminguid. See on tõesti üks tükk andmete rida rea ​​rea ​​peale, aga neile, kes kasutavad Excel või CSV faili, komaga eraldatud väärtused, Ma oleks kindlasti võinud kasutada fprintf selle asemel võibolla midagi sellist teha nii et ma oleks tegelikult võinud luua samaväärne Exceli faili eraldades asjad komadega, mitte ainult uusi liine. Sel juhul, kui ma oleksin selle asemel kasutada komadega asemel uued liinid Võiksin sõnalt avada andmebaasi faili Excelis, kui ma selle asemel tegi ta näeb välja selline. Ühesõnaga, nüüd, et meil on õigus kirjutada faili saame nüüd hakata püsivaid andmeid, hoides seda ringi ketas nii et saame hoida teavet ümber ja jälle. Teade paar muud asjad, mis on nüüd natuke rohkem tuttav. Ülaosas seda C fail on meil typedef sest me tahtsime luua andmetüüp, mis tähistab sõna, nii et see tüüp on nn sõna, ja sees selle struktuuri see on natuke Kasvataja nüüd. Miks on sõna, mis koosneb ilmselt massiivi? Mis on sõna lihtsalt intuitiivselt? See on array tähemärki. See on märgijada tagasi tagasi tagasi. Tähed kõik mütsid juhtub olema me suvaliselt öelda maksimaalne pikkus mis tahes sõna sõnastikku, mida me kasutame jaoks rüselus. Miks ma pean +1? Null iseloomu. Meenuta, kui me tegime Bananagrams Näiteks meil oli vaja erilist väärtust aasta lõpus sõna, et jälgida kus sõnad tegelikult lõppes, ja kui probleem komplekt spetsifikatsioon ütleb siin me ühendavate antud sõna tõeväärtuse, lipp, nii-öelda õige või vale. Kas olete leidnud seda sõna juba, sest me mõistame meil on tõesti vaja nii mäletamise mitte ainult see, mida sõna on rüselus aga kas sa ei, inimese, on leidnud nii et kui sa ei leia sõna "" sa ei saa lihtsalt kirjutada, andmeid sisestada, sisestada, sisestage ja saada 3 punkti, 3 punkti, 3 punkti, 3 punkti. Me tahame olla võimelised Musta Nimekirja et sõna seades bool true, kui olete juba leitud, ja nii see on, miks me kapseldatud ta selle struktuuri. Nüüd, siin all on rüselus seal on see teine ​​struct nimetatakse sõnaraamat. Puudub siin on sõna typedef sest sel juhul meil oli vaja kapseldada idee sõnastik ja sõnastik sisaldab terve hunnik sõnu, Nagu võib järeldada seda massiivi ja kui palju need sõnad on olemas? Noh, mis iganes see muutuja nimega suurus ütleb. Aga meil on vaja ainult üks sõnastik. Meil ei ole vaja andmete tüüp kutsus sõnaraamat. Meil on vaja ainult üks neist, nii selgub C et kui sa ei ütle typedef, sa ütlesid struct, siis sees looksulg paned oma muutujaid, siis paned nime. Seda kuulutatakse üks muutuja nimega sõnaraamat mis näeb välja selline. Seevastu need read on luua korduvkasutatavaid andmestruktuur nimetatakse sõna et saate luua mitu koopiat, nagu me loodud mitu koopiat õpilased. Mida see lõppkokkuvõttes võimaldab meil teha? Lubage mul minna tagasi, ütleme, lihtsam näide lihtsam korda ja andke mulle avada, oletame, compare1.c. Probleem on siin käepärast on tegelikult koor tagasi kiht nööri ja alustada õhkutõusmise need abirattad sest selgub, et string kogu aeg on meil lubanud 1. nädalal tõesti lihtsalt hüüdnimi, sünonüüm alates CS50 raamatukogu midagi, mis näeb välja veidi segasena, char *, ja me oleme näinud seda täht enne. Me nägime seda seoses faile. Lähme nüüd aru, miks oleme olnud peidus see detail juba mõnda aega. Siin on fail nimega compare1.c, ja see ilmselt küsib kasutajalt 2 stringid, s ja t, ja siis ta püüab võrrelda neid stringe võrdõiguslikkuse rida 26, ja kui nad võrdsed ta ütleb: "Sa kirjutasid sama asja," ja kui nad ei ole võrdsed ta ütleb: "Sa kirjutasid erinevaid asju." Lubage mul minna ja käivitada programm. Lubage mul minna minu allikas kataloog, teha compare1. See koostatud okei. Ma jooksen compare1. Ma suumimiseks siseneda. Ütle midagi. Tere. Ma ütlen midagi uuesti. Tere. Ma kindlasti ei kirjuta erinevaid asju. Las ma proovin seda uuesti. Bye Bye. Kindlasti ei erine, nii et mida siin toimub? Noh, mis tegelikult on võrreldes vastavalt 26? [Kuuldamatu-õpilane] Jah, nii selgub, et string, andmete tüüp, on selline hädavale. String on char *, kuid mida on char *? Char *, nagu nad ütlevad, on pointer, ja osuti on tõhusalt aadress, summa asukohta mälus, ja kui juhtub, et on sisestatud sõna nagu HELLO, meenutada mineviku arutelusid stringid see on nagu sõna HELLO. Pea meeles, et sõna nagu HELLO saab esindajad massiivina tegelasi nagu see ja siis spetsiaalse märgi lõpus kutsus null iseloomu, nagu \ tähistab. Mis on tegelikult string? Pange tähele, et see on mitu mäluhulka, ja tegelikult lõpuks on teada ainult üks kord vaatate läbi terve rea otsin eriline null iseloomu. Aga kui see on patakas mälu minu arvuti mälu, olgem suvaliselt öelda, et see jada lihtsalt vedas, ja ta sai paigutatud alguses minu arvuti RAM. See on bait 0, 1, 2, 3, 4, 5, 6 ... Kui ma ütlen midagi getString ja ma teen string s = getString Mis tegelikult tagastatakse? Need viimased mitu nädalat, mis tegelikult salvestatakse s ei ole see string iseenesest, kuid sel juhul mis siin hoitakse on arvu 0, sest mida getString tegelikult teeb on see ei füüsiliselt tagasi string. See isegi ei tõesti kontseptuaalses mõttes. Mis see tulu on number. See arv on aadress HELLO mälu, ja string s siis, kui me koor tagasi see kiht, nöör ei ole tegelikult olemas. See on ainult lihtsustamise CS50 raamatukogu. See on tõesti midagi, mida nimetatakse char *. Char on mõistlik, sest mis see sõna, nagu Halloo? Noh, see on mitmeid sümboleid seeria tähemärki. Char * tähendab, aadress iseloomu, nii et mida see tähendab tagasi string? Kena, lihtne viis tagastamise string on mitte proovida aru saada, kuidas ma tagasi 5 või 6 erinevat baiti lase mind tagasi mille aadressi bait? Esimene. Teisisõnu, lubage mul anda teile aadress märk mälu. Seda char * tähistab, aadress ühe märgi mälu. Helista et muutuja s. Hoida s, et eelkõige aadress, mis ma omavoliliselt ütles on 0, lihtsalt hoida asjad lihtsad, kuid tegelikkuses on see tavaliselt suurem number. Oota üks hetk. Kui sa vaid annad mulle aadressi esimene märk, kuidas ma tean, milline aadress on teise iseloomu, kolmanda, neljanda ja viienda? [Kuuldamatu-õpilane] Sa ainult ei tea kus stringi lõpuni on teel seda mugav trikk, Nii et kui te kasutate midagi printf, mida printf sõna otseses mõttes nagu tema argumendi, meelde tuletada, et me kasutame seda% s kohatäide, ja siis viiakse muutuja, mis on ladustamiseks string. Mida sa tegelikult kulgeb on aadress esimene märk, et string. Printf siis kasutab jaoks silmus või samas silmus saamisel, et aadress, Näiteks, 0, seega lubage mul seda teha nüüd, printf ("% s \ n", s); Kui ma kutsun printf ("% s \ n", s); mida ma tõesti pakkuda printf koos on aadress esimene märk on, mis selles meelevaldne juhul on H. Kuidas printf tea, mida täpselt näidata ekraanil? Isik, kes ellu printf rakendada samas loop või loop mis ütleb, et ei see märk võrdne erilist null iseloomu? Kui ei, siis printida. Kuidas oleks sellega? Kui ei prindi see, printida, printida, printida. Oh, see üks on eriline. Peatage printimine ja naasta kasutaja. Ja see on sõna otseses mõttes kõik, mis on juhtunud all kapuuts, ja see on palju seedida aastal esimesel päeval klassi, kuid nüüd on tõesti ehituskivi mõista kõike mis on kestnud juba sees meie arvuti mälu, ja lõpuks me tease see peale on vähe abi üks meie sõbrad Stanfordi. Professor Nick Parlante Stanfordi teinud selle imelise video jada alates igasuguseid erinevaid keeli, mis tutvustas see väike claymation iseloomu Binky. Hääl sa parasjagu kuulda vaid paar 2. vargsi eelvaade on see, et Stanfordi professor, ja te saate ainult 5 või 6 sekundit selle kohe, kuid see on märkus, mis me sõlmida täna ja algab kolmapäeval. Ma annan sulle Pointer Fun Binky, eelvaate. [♪ Music ♪] [professor Parlante] Hei, Binky. Ärka üles. On aeg osuti lõbus. [Binky] Mis see on? Lugege vihjeid? Oi kui tore! Me näeme teid kolmapäeval. [CS50.TV]