[Powered by Google Translate] [Teden 4] [David J. Malan] [Harvard University] [To je CS50.] [CS50.TV] V redu, to je CS50, in to je začetek tedna 4, in to je eden od najpočasnejših možnih algoritmov. Katera je bilo, da smo samo gledal tam? To je bilo nekako mehurček, da velik O (n ^ 2) + vsota, in res nismo edini na tem svetu, da ne ve kaj bubble sort je ali njen čas delovanja. Pravzaprav, to je bil intervju z Eric Schmidt iz Googla in nekdanji senator Barack Obama je le nekaj let nazaj. Zdaj, senator, da ste tukaj na Googlu in mi je všeč, da razmišljajo o predsedovanju kot razgovor za službo. Zdaj je težko dobiti službo kot predsednik, in greste skozi mrzlica zdaj. Prav tako je težko dobiti službo pri Googlu. Imamo vprašanja, zato vas prosimo naših kandidatov na vprašanja, in ta je od Larry Schwimmer. Mislita, da sem hecaš? Prav tukaj. Kaj je najbolj učinkovit način za razvrščanje milijon 32-bitnih celih števil? [Smeh] Dobro Žal mi je. >> Ne, ne, ne, ne. Mislim, da je mehurček vrsta bi bila napačna pot. Daj no, kdo mu povedal to? Prejšnji teden smo se spomnim odmor od kode, vsaj za en dan, in začeli s poudarkom na nekaterih višjih ravni idej in reševanje problemov na splošno v okviru iskanja in razvrščanje in uvedli nekaj, kar nismo slap to ime v zadnjem tednu ampak asimptotični zapis, Big O, Big Omega, in včasih Big Theta zapis, in ti so bili le načini opiše čas delovanja algoritmov, koliko časa je potrebno, da algoritmom za vožnjo. In morda se spomnite, da ste govorili o trenutnim časom glede na velikost vložka, ki smo ga na splošno imenujemo n, kar je težava lahko, kjer je n število oseb v sobi, število strani v imenik, in smo začeli pisati stvari kot O (n ^ 2) ali O (n) ali O (n log n) in tudi če matematika ni povsem izšlo tako popolno in je bil n ² - n / 2 ali kaj podobnega pa bi namesto tega preprosto vrgel proč nekaj manjših naročil pogoji, in motivacija je, da res želimo nekakšen objektiven način ocenjevanja izvedbo programov, izvedba algoritmov da ob koncu dneva, nima veze, na primer, s hitrostjo računalnika danes. Na primer, če izvajajo mehurček vrste, ali pa izvaja z zlivanjem ali izbira vrste na računalniku današnjem 2 GHz računalnik in ga zaženete, in traja nekaj sekund več, naslednje leto pa je 3 GHz ali bi lahko 4 GHz računalnik in nato trdijo, da "Vau, moj algoritem Zdaj je dvakrat tako hitro, "čeprav v resnici to očitno ne drži. To je samo has gotten strojne hitreje, vendar računalnik ni, zato si resnično želimo, da mečejo stvari, kot so večkratniki 2 ali večkratniki števila 3, ko gre za opisovanje kako hitro ali kako počasi algoritem in res samo osredotočiti na n ali kak dejavnik Pogodbe, nekateri njihovi moči, kot v primeru vrst iz prejšnjega tedna. In spomni, da je s pomočjo vrste spajanja nam je uspelo narediti tako veliko bolje kot neke mehurčke in izbire razvrstite in celo vstavljanje vrste. Imamo do n log n, in spet, spomnimo, da log n splošno se nanaša na nekaj, kar raste počasneje in nato n, tako da n log n doslej je bila dobra ker je bilo manj kot ² n. Toda, da bi n log n z neke spajanja kaj je bil osnovni kalčkov z idejo, da moramo vzvod da smo tudi vzvod nazaj v tednu 0? Kako smo rešiti problem razvrščanja spretno z neke spajanja? Kaj je bil ključ vpogled, morda? Kdorkoli. Ok, gremo korak nazaj. Opišite zlivanjem s svojimi besedami. Kako pa to deluje? Ok, bomo vrstico nazaj na teden 0. Prav, ja. [Neslišno-student] Dobro, dobro, zato smo razdelili niz številk v 2 kosov. Mi razporejene vsako od teh kosov, nato pa smo jih združili, in smo videli to idejo pred sprejemanja problem, ki je tako velik in ga sekljanje up na problem, ki je tako velik ali tako velika. Spomnimo primer telefonski imenik. Spomnimo se samo-štetja algoritem iz tedni Tako nekako združiti povzelo to psevdokod tukaj. Ko ste glede n elementov, prvič, da je duševno zdravje preveriti. Če je n <2, potem ne storiti ničesar na vse ker če n <2, potem je n očitno 0 ali 1, in tako, če je 0 ali 1 ni ničesar rešiti. Končali ste. Vaš seznam je že površno razvrščeni. Sicer pa, če imaš 2 ali več elementov, da gredo naprej in jih razdeliti v 2 polovici, levo in desno. Razvrščanje vsako od teh polovic in nato spojite razvrščeni polovic. Toda težava je, da na prvi pogled zdi, kot da smo punting. To je krožna definicija v tem, da če sem te prosil za razvrščanje teh n elementov in ti si mi pravi "V redu, v redu, bomo razvrstite tiste n / 2 in tiste, n / 2 elementov" potem moje naslednje vprašanje, se bo »Prav, kako razvrstiti N / 2 elementov?" Toda zaradi strukture tega programa, ker je ta osnovna, tako rekoč, Ta poseben primer, ki pravi, da če je n > Sara, vse v redu. Kelly. >> Kelly in? Willy. >> Willy, Sara, Kelly, in Willy. Zdaj so me vprašal vprašanje za nekoga, koliko ljudi je na tej stopnji, in nimam pojma. To je res dolg seznam, in tako namesto da bom naredil ta trik. Bom vprašal osebo, poleg mene opraviti večino dela, in ko je ona naredila počne večina dela Jaz bom naredil najmanjšo količino dela mogoče in preprosto dodajte 1 da ne glede na njen odgovor je, da gremo. Bila sem vprašal, koliko ljudi na odru. Koliko ljudi je na odru na levi strani vas? Levo od mene? >> Ok, ampak ne varam. To je dobro, to je res, vendar če želimo nadaljevati s to logiko predpostavimo, da si podobno želi punt ta problem na levi vas, Tako kot odgovor neposredno iti naprej in samo mimo denar. Oh, koliko ljudi je na levi strani meni? Koliko ljudi je na levi strani? 1. [Smeh] Ok, 0, kaj storiti zdaj je Willy se ste vrnili vaš odgovor v to smer pravi, 0. Torej, kaj storiti? >> 1. Ok, tako da ste 1, tako da boste rekli: "V redu, bom dodati 1 da ne glede na število Willy je bil, "da 1 + 0. Zdaj ste 1 do vaš odgovor na desni je zdaj- 1. Bi >> In moj je 2. Dobro, da ste ob prejšnji odgovor 1, doda minimalno količino dela, ki ga želite storiti, kar je +1. Zdaj imate 2, in jo nato z roko me kateri vrednost? 3, mislim, oprosti, 2. Dobro. No, smo imeli 0 na levo. Potem smo imeli 1 in nato dodamo 2, in zdaj ste se predaja mi številko 2, in tako sem rekel, v redu, 1, 3. Tam je res 3 ljudi stoji zraven mene na tej stopnji, tako da bi jih lahko storili očitno to zelo linearno, zelo v modi očitno, ampak kaj smo res? Mi je problem velikosti 3 na začetku. Nato smo ga pokvaril v težave, velikosti 2, potem problem velikosti 1 in nato končno osnovna Res je, oh, nikogar ni tam, Takrat Willy vrnil dejansko težko kodirane odgovor nekajkrat in je bila druga pa vrela, vrela, vrela, in potem z dodajanjem v tem dodatnem 1 1 smo izvajali to osnovno idejo rekurzije. Zdaj, v tem primeru to ni res rešitev problema vse bolj učinkovito potem smo videli doslej. Ampak pomislite algoritmov, ki smo jih storili na odru doslej. Imeli smo 8 listov na tablo, na video, ko je Sean iskal številko 7, in kaj je res? No, on ni storil kakršnokoli deli in vladaj. On ni storil kakršnokoli rekurzije. Namesto pravkar storil to linearni algoritem. Toda, ko smo uvedli idejo razvrščenih številk na odru v živo prejšnji teden Nato smo imeli ta nagon, da bi šel na sredino, Takrat smo imeli manjšo seznam velikosti 4 ali drugega seznama velikosti 4, in potem smo imeli točno isti problem, zato smo se ponovi večkrat, ponoviti. Z drugimi besedami, recursed. Najlepša hvala za naše 3 prostovoljcev tukaj za prikaz rekurzijo z nami. Poglejmo, če ne moremo narediti to sedaj malo bolj konkretnega, problemom, ki ga še lahko naredimo zelo enostavno, ampak ga bomo uporabili kot odskočno desko za izvajanje tega osnovnega pojma. Če hočem izračunati seštevanja kup številk, na primer, če se boste peljali po številu 3, Želim vam vrednosti sigma 3, tako da vsota 3 + 2 + 1 + 0. Želim, da bi dobili nazaj odgovor 6, tako da bomo izvajanje tega sigma funkcijo, ta vsota funkcije da, še enkrat, se na vhodu, in nato vrne seštevanja te številke pa vse do 0. Mi lahko to zelo preprosto, kajne? Mi lahko to storite z nekakšno zanka strukture, zato naj gredo naprej in se je to začelo. Vključi stdio.h. Dovolite mi, da se v glavnem delati tukaj. Rešimo to kot sigma.c. Potem bom šel noter, jaz pa bom razglasi int n, in jaz bom naredil naslednje, medtem ko uporabnik ne sodeluje. Medtem ko uporabnik ni dal pozitivno število Naj gredo naprej in jih prosil za GetInt n =, in mi jim nekaj napotkov o tem, kaj storiti, Tako printf ("pozitivno celo naš"). Samo nekaj dokaj preprost, kot je ta, da do takrat, ko smo zadeli linijo 14 zdaj imamo pozitivno celo predvidoma v n. Zdaj pa si poglejmo nekaj storiti z njim. Naj gredo naprej in izračun seštevanja, tako int vsota = sigma (n). Sigma je samo vsota, tako da sem samo pisal v Ljubitelj način. Enostavno bomo rekli sigma tam. To je vsota, in zdaj bom izpisal rezultat, printf ("Vsota je% d \ n", vsota). In potem se bom vrnil 0 za dobro mero. Naredili smo vse, kar ta program zahteva, razen zanimive strani ki je dejansko izvajanje sigma funkcijo. Naj grem dol do dna, in mi izjavi funkcije sigma. Ima naj spremenljivko, ki je za celo vrsto in kaj tip podatkov ne želim predvidoma vrnil iz sigma? Int, ker želim, da bi se ujemala z mojimi pričakovanji na spletu 15. Tukaj me spusti naprej in izvajanje tega na zelo enostaven način. Gremo naprej in rekli int vsota = 0, in zdaj bom šel imeti malo za zanke tukaj , ki je hotel reči kaj takega, for (int i = 0; i <= številka; i + +) vsota + = i. In potem se bom vrnil znesek. Lahko bi to izvaja v vsakem več načinov. Lahko bi uporabil while zanko. Lahko bi preskočila uporabo kilometrov spremenljivko, če sem si želela, ampak na kratko, imamo samo funkcijo, da če nisem Pepe izjavlja vsota je 0. Potem pa ponovi od 0 gor po številu, in na vsaki ponovitvi dodaja, da je sedanja vrednost seštevka in se nato vrne vsoto. No, tam je rahlo optimizacija tukaj. To je verjetno izgubljen korak, ampak tako je bilo. To je v redu za zdaj. Smo pa vsaj temeljito in gredo 0 vso pot gor. Ni zelo težko in zelo enostavno, vendar se izkaže, da je s funkcijo sigma imamo enake možnosti kot smo tu na odru. Na odru smo samo prešteti, koliko ljudi je bilo poleg mene, , ampak če bomo želeli prešteti 3 + 2 + 1 za navzdol, da bi se podobno 0 punt funkcijo da bom namesto tega opisujejo kot rekurzivno. Tukaj naredimo hitro sanity preverite in se prepričajte, da nisem Pepe. Vem, da je vsaj ena stvar v tem programu, da nisem naredil narobe. Ko sem zadeti nastopiti bom dobil kakršno koli kričiš name? Kaj bom, da bo vpil na okoli? Ja, pozabil sem prototip, tako da sem s funkcijo, imenovano sigma na liniji 15, vendar se ni prijavil do linije 22, tako da sem najboljši proaktivno šel gor in ugotovi, prototip, in bom rekel int sigma (int število), in to je to. To se izvaja na dnu. Ali pa še en način, da bi lahko rešili tako, Lahko sem premakniti gor, kar ni slabo, ampak vsaj ko se programi začeli, da bi dobili dolgo, odkrito povedano, Mislim, da je nekaj vrednosti v vedno ob glavnem na vrhu tako da lahko v bralcu odpreti datoteko in nato takoj videli kaj program počne, ne da iskati po njem iščem to glavno funkcijo. Pojdimo v mojo terminalsko okno tukaj, poskusite tako, da sigma sigma, in sem zajebal tukaj. Implicitno izjava GetInt funkcije pomeni, da sem pozabil narediti še kaj? [Neslišno-student] Dobro, tako da očitno običajna napaka, tako da je dal to gor, cs50.h, zdaj pa se vrnimo k mojim terminalskem oknu. Jaz bom počistite zaslon, in bom lahko ponovi sigma. Zdi se, da so pripravljeni. Naj sedaj vodi sigma. Jaz bom vnesite številko 3, in nisem dobil 6, tako da ni strog pregled, ampak vsaj tako se zdi, da se dela na prvi pogled, sedaj pa dajmo raztrgati, in kaj je dejansko vzvod idejo rekurzija, še enkrat, na zelo preprost kontekstu, zato da čez nekaj tednov ko smo začeli raziskovati imenitnejše podatkovne strukture, kot nizi imamo še eno orodje v kompletu, s katerim bi manipulirajo te podatkovne strukture, kot bomo videli. To je iterativni pristop, zanka temelječ pristop. Dovolite mi, namesto da bi zdaj to. Dovolite mi, namesto da bi rekli, da je vsota števila dol na 0, je res ista stvar kot številka + sigma (številka - 1). Z drugimi besedami, tako kot na odru sem punted za vsako od naslednjih oseb z mano, in jih nato hrani punting, dokler ne bomo na koncu dno na Willy, ki je moral vrniti težko kodirane kot odgovor 0. Tukaj zdaj smo podobno punting za sigma isto funkcijo kot je bilo prvotno imenovan, vendar je ključni vpogled tukaj je, da bomo brez dvoma sigma enako. Mi ne gre v n. Mi smo očitno poteka v številu - 1, tako nekoliko manjši problem, nekoliko manjši problem. Na žalost, to ni čisto rešitev še ni, in preden bomo rešili Kaj bi lahko skakali kot očitno na nekatere od vas Naj gredo naprej in znova uspelo. Zdi se pripravijo v redu. Naj ponovitev sigma s 6. Ops, naj ponovi sigma s 6. Videli smo že prej, pa čeprav nehote zadnjem času pa tudi. Zakaj sem dobil to napako Grobni segmentacije? Ja. [Neslišno-student] Ni osnovna, in še posebej, kar se je verjetno zgodilo? To je simptom, kaj vedenje? Reci malo glasnejši. [Neslišno-student] To je neskončna zanka učinkovito in težave z neskončnimi zankami ko gre za rekurzijo v tem primeru funkcijo klical samega sebe, kaj se zgodi vsakič, ko pokličete funkcijo? No, mislim nazaj na kako določeno količino pomnilnika v računalniku. Rekli smo, da je ta kos pomnilnika se imenuje sklad, ki je na dnu, in dobi naj vsakič, ko se klic funkcije malo več pomnilnika na tej tako imenovani sveženj, ki vsebuje to funkcijo opravlja v lokalnih spremenljivk ali parametrov, tako da, če sigma poziva sigma klice sigma poziva sigma  poziva sigma kje se ta zgodba konča? No, sčasoma prekoračitve skupni znesek pomnilnika, da imate na voljo za vaš računalnik. Si prekoračil segment, ki vas naj bi ostali v okviru, in dobite to napako segmentacije, jedro po dampinških cenah, in kaj pomeni jedro po dampinških cenah, je, da sem zdaj datoteko, imenovano jedro ki je datoteka, ki vsebuje ničel in enic , ki bo dejansko v prihodnje diagnostično uporaben. Če ni jasno, za vas, če je vaš hrošč lahko dejansko narediti nekaj forenzično analizo, tako rekoč, o tej zadevi jedro smetišče, ki je, še enkrat, je samo cel kup ničel in enic , ki v bistvu predstavlja stanje vašega programa v pomnilniku Trenutek je strmoglavil na ta način. Pritrditi tukaj je, da ne moremo kar slepo vrniti sigma, število + sigma za nekoliko manjši problem. Moramo imeti neke vrste primerjavi z osnovnim tukaj in kakšna naj bi bila osnovna verjetno? [Neslišno-student] Ok, tako dolgo, kot je število pozitivnih moramo pravzaprav vrniti to, ali povedano drugače, če je število, recimo, <= na 0 Veš kaj, jaz grem naprej in se vrniti 0, tako kot Willy storil, in sicer, da bom s tem nadaljevala in se vrniti to, da to ni tako veliko krajši kot iterativni različici, ki smo stepeno se najprej uporabi za zanke, ampak obvestilo, da je to neke vrste elegance z njo. Namesto da bi vrnil nekaj več in izvajanju vseh teh matematike in dodal stvari z lokalnimi spremenljivkami ste namesto rekel: "V redu, če je to super enostavno problem, kot je število <0, naj se takoj vrne 0 ". Ne bomo se trudim, podporo negativne številke, tako da bom trdo oznako vrednosti 0. Sicer pa, za izvajanje te ideje seštevek Vse te številke skupaj lahko učinkovito sprejmejo majhen ugriz iz tega problema, tako kot smo tukaj na odru, potem punt preostali del problema na naslednjo osebo, vendar v tem primeru naslednja oseba si. To je enako ime funkcije. Samo mimo je manjši in manjši in manjši težavo, vsakič, in čeprav še nismo povsem formalizirane stvari v kodo tukaj To je točno to, kar se je dogajalo v tednu 0 s imeniku. To je točno to, kar se je dogajalo v zadnjih tednih s Seanom in z našimi demonstracij iskanju številk. To je ob problem in ga tako spet in spet. Z drugimi besedami, tam je pot sedaj prevajanja to resničen svet konstrukt, to višjo raven konstrukt z deli in vladaj in delaš nekaj znova in znova v kodi, tako da je to nekaj, kar bomo spet videli čez čas. Zdaj, ko razveljavi, če ste novi na rekurzije bi si vsaj zdaj razumeš zakaj je to smešno. Jaz grem na google.com, in bom poiskal nekaj nasvetov in trikov rekurzija, vnesite. Povejte osebi poleg vas, če bi se ne smejim šele zdaj. Ali ste mislili rekurzijo? Ste mislili, ah, pa gremo. Ok, zdaj, da je ostalo vse. Malo Pirh vgrajeni tam nekje pri Googlu. Kot prahi, eden od členov nanesemo na spletni strani seveda je Za danes je le ta mreža različnih algoritmov razvrščanja, od katerih smo si ogledali prejšnji teden, ampak kaj je lepo o tem vizualizacijo kot ste poskušali zaviti vaš um okoli različnih stvari, povezane z algoritmi vem, da lahko zelo enostavno zdaj začeti z različnimi vrstami surovin. Vhodi vse obrnilo, vložki večinoma razvrščeni, vložki naključno in tako naprej. Kar poskusite, še enkrat, razlikovati te stvari v glavi zavedati, da ta naslov URL, na spletni strani je seveda na predavanjih strani Morda vam lahko pomaga razlog skozi nekatere od teh. Danes smo končno prišli do rešitev tega problema z nekaj časa nazaj, ki je bil, da je to swap funkcija preprosto ni delovalo, in kakšen je bil temeljni problem s to funkcijo zamenjave, katere cilj je bil, še enkrat, da si izmenjujejo vrednost tukaj in tukaj tako, da se to zgodi? To ni dejansko delajo. Zakaj? Ja. [Neslišno-student] Točno, razlaga za to bugginess preprosto zato, ker je bil, ko pokličete funkcije v C in te funkcije sprejme argumente, kot tu in b, ste mimo v kopijah koli vrednost si zagotoviti, da bi to funkcijo. Vi ne zagotavljajo prvotne vrednosti same, Tako smo videli, je to v okviru buggyc, buggy3.c, ki je pogledal malo kaj takega. Spomnimo se, da smo imeli x in y initialized za 1 in 2, v tem zaporedju. Potem smo natisniti, kaj so. Nato sem trdil, da sem jih zamenjala s pozivom swap x, y. Ampak problem je bil, da zamenjavam delal, vendar le v obsegu zamenjave sam deloval. Takoj, ko bomo zadeli linijo 40 zamenjala navedenim vrednot vrgli stran, tako da ni nič v prvotni funkciji je bil glavni dejansko spremenili na vse, tako da, če menite, da je takrat, kaj to izgleda v smislu našega spomina če je to leva stran uprave predstavlja- in bom naredil moj najboljši za vse, da se to, če je to leva stran uprave pomeni, recimo, RAM in sklad bo rasla gor ta način, in pokličemo funkcijo kot glavni, glavni in ima 2 lokalnih spremenljivk x in y, kaj je opisati takšne, kot so x tukaj in kaj je to opisati kot y tukaj, in kaj je dal v vrednosti 1 in 2, tako da je to tukaj glavni, in ko glavna zahteva swap funkcija operacijskega sistema izreka te zamenjave svojo funkcijo plasti spomina na sklad, svoj posnetek na kup, da se tako izrazim. Prav tako namenja 32 bitov za te ints. To se zgodi, da jih pokličete in b, ampak to je povsem samovoljno. Lahko bi jih imenoval karkoli hoče, ampak kaj se zgodi, ko glavni poziva k zamenjavi je ob tej 1, postavi kopijo tam, postavi kopijo tam. Tu je 1 druga lokalna spremenljivka v zamenjavo, čeprav imenovan kaj? >> NTU. Tmp, zato naj dam še 32 bitov tukaj, in kaj sem naredil v tej funkciji? Rekel sem, int tmp dobi, tako da je 1, tako da sem to storil, ko smo nazadnje igrali s to npr. Potem pride b, tako da je b 2, tako da zdaj to postane 2, in sedaj b dobi temperature, zato je temperatura 1, sedaj ko je to b. To je super. Delovalo je. Potem pa takoj, ko se vrne swap pomnilnik dejansko izgine, tako da se lahko ponovno je s kakšno drugo funkcijo v prihodnosti, in glavni je seveda popolnoma nespremenjena. Moramo priti v osnovi reševanja tega problema, in danes bomo končno imeli način, kako to, s katerim lahko uvede nekaj, kar ti kazalec. Izkaže se, da bomo lahko rešili ta problem ne pa gre v kopijah x in y temveč s posredovanjem, v čem, menite, da swap funkcijo? Ja, kaj je naslov? Nismo zares govorili o naslovih v veliko podrobnosti, če pa je ta tabla predstavlja mojega računalnika pomnilnika Lahko bi vsekakor začeti številčenje bajtov v mojem RAM in pravijo, je to Bajt # 1, to je bajta # 2, # 3 Bajt, Bajt # 4, bajt # ... 2 milijard EUR, če imam 2 GB RAM-a, tako da bi lahko zagotovo prišli do neke poljubno shemo številčnega za vse posamezne bajtov v pomnilniku mojega računalnika. Kaj če bi namesto, ko sem poklical swap kot geslo v kopijah x in y Zakaj ne bi namesto tega poslati v naslovu x tukaj, naslov y tu, v bistvu poštni naslov x in y, ker potem zamenjajte, če je sporočil, da naslova v spomin na x in y, nato zamenjali, če smo usposobljeni mu malo, da bi lahko vozite na ta naslov, če se tako izrazim, x in spremenite številko tam, nato vožnja na naslov y, spreminjanje števila tam, tudi ko ne dejansko dobili kopije teh vrednot sam, tako, čeprav smo se pogovarjali o tem, kot da je glavni pomnilnik in to, kot da swap pomnilnik močan in nevaren del C je, da lahko vsak dotik funkcija spomina kjerkoli v računalniku, in to je močna v tem, da lahko narediš zelo fancy stvari z računalniškimi programi v C. To je nevarno, ker lahko tudi zajebal zelo enostavno. Dejstvo je, da je eden od najpogostejših načinov za programe, ki v teh dneh je treba izkoristiti Še vedno je za programer ne zavedaš da je on ali ona je kar s podatki mora biti napisana v mesto v pomnilniku, ki ni bilo namenjeno. Na primer, on ali ona izjavi paleto velikosti 10 potem pa se po nesreči poskuša postaviti 11 bajtov v to vrsto pomnilnika, in začnete dotika delov pomnilnika, ki niso več veljavni. Samo na sobesedilo to, da nekateri izmed vas ve, da Programska oprema se bo od vas zahteval serijskih številk ali registrskih ključev, Photoshop in Word in programi, kot je ta. Obstajajo razpoke, kot nekateri že veste, na spletu, kjer lahko zaženete malo program, in voila, ni več prošnja za serijsko številko. Kako se to dela? V mnogih primerih se te stvari so enostavno najti na računalnikih besedilo odseki v dejanskih računalnika ničel in enic če je ta funkcija, kjer se zahteva serijska številka, in si prepisati, da je prostor, ali pa program teče lahko ugotovimo, kje je ključ dejansko skladiščena z nekaj imenuje razhroščevalnik, in lahko tresk programske opreme na ta način. To pa ne pomeni, da je to naš cilj za naslednjih nekaj dni, vendar je prav v realnem svetu posledice. To je ena zgodi, da za krajo programske opreme, vendar pa je tudi kompromis celih naprav. V bistvu, ko spletne strani izkoriščajo te dni in ogrožena in podatki ušli in gesla, ukradeno to je zelo pogosto povezano s slabim upravljanjem lastnega spomina, ali, v primeru baz podatkov, pomanjkljivo predvidevanje kontradiktoren vhod, tako da več o tem v prihodnjih tednih, vendar za zdaj le skrivaj predogled vrste škode, ki jo lahko naredite z ne povsem razumeti, kako stvari delujejo pod pokrovom. Pojdimo o razumevanju, zakaj je pokvarjen ta z orodjem, da bo postala bolj in bolj uporaben kot naši programi dobili bolj zapleten. Do sedaj, ko ste imeli hrošča v programu kako ste šli pa je odpravljanje napak? Kakšne so vaše tehnike je sedaj to, ali jih poučuje svojo TF ali pa samouk? [Študent] printf. Printf, da je printf najbrž tvoj prijatelj v tem, da če si želite ogledati kaj se dogaja v notranjosti vašega programa ste pravkar postavili printf tukaj printf tukaj printf tukaj. Potem ga zaženete, in dobiš cel kup stvari na zaslonu ki jih lahko uporabite, da potem sklepati, kaj se dejansko dogaja narobe v programu. Printf zna biti zelo močna stvar, ampak to je zelo ročni postopek. Moraš dati printf tukaj, tukaj printf, in če ste jo dali v notranjosti zanke bi lahko dobil 100 vrstic proizvodnje, ki jo potem morali odbirati skozi. To ni zelo uporabniku prijazen ali interaktivne mehanizem za razhroščevanje programov, ampak na srečo obstaja alternative. Obstaja program, na primer, ki se imenuje GDB, GNU Debugger, kar je nekoliko starinski v tem, kako ga uporabljate. To je nekoliko zapletena, vendar odkrito povedano, To je ena od tistih stvari, kjer, če si dal v ta teden in naslednji dodatna ura razumeti kaj takega gdb vam bo prihranilo verjetno deset ur na dolgi rok, tako s tem, da ti dam teaser o tem, kako ta stvar deluje. Jaz sem v terminalskem oknu. Naj gredo naprej in zbira ta program, buggy3. To je že do datuma. Naj deluje kot sva nekaj časa nazaj, in res, je pokvarjen. Ampak zakaj je to? Mogoče sem zasral swap funkcijo. Mogoče je, in b. Nisem povsem njihovo premikanje pravilno. Naj gredo naprej in to je to. Namesto, da samo teče buggy3 mi namesto zagon tega programa GDB, in jaz jo bom povedal, da delujejo buggy3, in bom vključiti argument v ukazni vrstici, Tui-, mi pa bomo dal to v prihodnje težave pri določilu, da spominjajo. In sedaj je ta črni in beli vmesnik izstrelil, da ponovno je malo veliko sprva zato, ker je vse to informacije o garanciji tukaj, ampak vsaj nekaj je znano. Na vrhu okna je moja dejanska koda in če sem se pomaknete gor Naj se pomaknite na sam vrh mojega spisa, in seveda, tam je buggy3.c in obvestilo na dnu tega okna Imam GDB uren. To ni isto kot moj običajni John Harvard uren. To je poziv, da se dogaja, da mi dovolite, da nadzor GDB. GDB je razhroščevalnik. Razbubnik je program, ki vam omogoča, da sprehod skozi izvajanje svojega programa, skladno s po vrsticah, vzdolž način, da bi kakor koli želite v program, celo kliče funkcije, ali pa si še pomembneje, V različnih vrednostih spremenljivke. Pojdimo naprej in to je to. Grem naprej in vnesite v teku na poziv GDB je, tako opazili v spodnjem levem kotu zaslona sem tipkal teči, in sem zadeti nastopiti, in kaj se je to naredil? To dobesedno tekel svoj program, vendar nisem dejansko videl veliko iti tukaj ker sem dejansko ni povedal razhroščevalnika Za premor v določenem trenutku. Vtipkate tek zažene program. Jaz dejansko ne vidim ničesar. Ne morem vplivati. Namesto tega naj to storijo. Na tej GDB poziv naj namesto tega vnesite prelom, vnesite. To ni tisto, kar sem mislil, da tip. Naj namesto tega vnesite prelom glavni. Z drugimi besedami, Rad bi postavil nekaj, kar ti prelomnih točk, ki je aptly imenovan, ker bo prekinil ali začasno ustaviti izvajanje svojega programa, na tem mestu. Glavna je ime mojega delovanja. Obvestilo, da je GDB zelo pameten. To je ugotovil, da je glavni zgodi, da grobo začeti na liniji 18 za buggy3.c, nato pa opazil tukaj na levem b + je tik ob liniji 18. To me spominja, da sem nastavite prekinitveno točko na liniji 18. Ta čas, ko sem tipa teči, grem teči svoj program do zadene, da prelomne točke, Tako bo program premor me na liniji 18. Pa gremo, teci. Nič se zdi, da se je zgodilo, vendar je oznaka na spodnjem levem začetni program, buggy3, prekinitvena točka 1 v glavnem v skladu buggy3.c 18. Kaj lahko storim sedaj? Obvestilo lahko začnem tipkati stvari, kot so tisk, Ne printf, tiskanje x, in zdaj, da je čudno. $ 1 je le radovednost, kot bomo videli vsakič, ko natisnete nekaj dobiš nov $ vrednost. To je, tako da lahko vrne na prejšnje vrednosti samo v primeru, vendar za zdaj, kaj print so mi povedali, da je vrednost x v tem trenutku v zgodbi očitno 134514032. Kaj? Kje si, da je tudi prišel? [Neslišno-student] Pravzaprav, to je tisto, kar imenujemo smeti vrednost, in smo govorili o tem, ne še, ampak razlog, da si inicializacijo spremenljivk Očitno je, da imajo neko vrednost, ki jo želite, da imajo. Ampak ulov je opozoriti, da se lahko ugotovi, spremenljivke kot sem pred nekaj trenutki v mojem primeru sigma ne da bi dejansko jim vrednost. Spomnimo se, kaj sem storil sem v sigma. Sem izjavil n, ampak kaj vrednostne sem jo dal? Jih ni, ker sem vedel, da bo v naslednjih nekaj vrstic GetInt bi poskrbel za problem dajanja vrednosti znotraj n. Toda na tej točki v zgodbo vrstico 11 in linijo 12 in linijo 13 in linijo 14 po teh nekaj vrstic, kaj je vrednost n? V C preprosto ne vem. To je na splošno nekaj smeti vrednost, nekaj povsem naključno število , ki je ostala v bistvu iz neke prejšnje funkcije bilo teči, tako kot vaš program teče opozoriti, da je funkcija dobi funkcijo, funkcijo, funkcijo. Vsi ti okvirji se dajo na pomnilnik, nato pa vrnitev teh funkcij, in tako kot sem predlagal, z radirko njihov spomin je sčasoma ponovno uporabiti. No, prav tako se zgodi, da je ta spremenljivka x v tem programu Zdi se, da so se zadrževali nekaj smeti vrednost kot 134514032 iz neke prejšnje funkcije, ne tisti, ki sem jih napisal. To je lahko nekaj, kar prihaja učinkovito z operacijskim sistemom, nekatere funkcije pod pokrovom. Ok, to je v redu, ampak kaj je zdaj napreduje v naslednji vrstici. Če sem tipa "Next" na moj poziv GDB in sem zadeti nastopiti, opazili, da poudarjanje poteze navzdol do vrstice 19, vendar logično izhajalo, da se vrstica 18 se je zdaj končal izvedbo, tako da če še enkrat vtipkajte "print x" Jaz Zdaj bi morali videti 1, in seveda jaz. Spet $ stvari je način GDB vas opomnijo Kaj je zgodovina odtisov, ki ste jih storili. Zdaj pa mi daj in tiskanje y, in res, y je vrednost nekaterih nor, kot tudi, vendar pa ni nič hudega, saj v vrstici 19 smo na tem, da jih dodeli vrednost 2, da mi tip "Next" znova. In zdaj smo na liniji printf. Naj jaz tiskanja x. Naj jaz tiska y. Odkrito povedano, sem že malo utrujen tiskanja tega. Naj namesto tega vnesite "x" in "prikazni zaslon," y in zdaj vsakič, ko sem vnesite ukaz v prihodnosti Sem se spomnil, kaj je x in y, kaj je x in y, kaj je x in y. Ne morem tako, kot praho, tipa "info domačini." Info je poseben ukaz. Domačini pomeni, da mi pokaže lokalne spremenljivke. Samo v primeru, sem pozabil, ali je to noro, zapletena naloga da sem ali kdo drug napisal info domačini vam bo povedal, Kaj so vse lokalne spremenljivke znotraj te lokalne funkcije da bi vas skrbi, če želite, da okoli zbosti. Zdaj printf gre za izvrševanje, zato naj gredo naprej in samo tip "Next". Ker smo v tem okolju ne bomo dejansko videli izvršitev dol, ampak obvestilo, da je že malo pokvarjenimi tukaj. Ampak opazite, da je nujni zaslon tam, tako da ni popoln program tukaj, ampak to je v redu, ker sem lahko vedno suniti okrog pomočjo tiska, če hočem. Naj Type Naslednja enkrat, in zdaj tukaj je zanimivo. Na tej točki v zgodbo y 2 in x je 1, kot je bilo predlagano tu in tam, Razlog je ta samodejno prikazovanje zdaj, ker sem uporabil ukaz Prikaz x in y zaslon, tako da ko sem Type Naslednja V teoriji x in y mora postati zamenjali. Zdaj že vemo, da se to ne bo tako, ampak bomo videli v trenutku, kako se lahko potopite globlje bomo ugotoviti, zakaj je to res. Naprej, na žalost, še vedno y 2 x in je še vedno 1, in lahko potrdim toliko. Tiskanje x, y print. V resnici je ni zamenjala se je dejansko zgodilo, zato začnimo tole. Jasno je pokvarjen swap. Naj namesto tipa "Run" znova. Naj povem, da želim ponovno zagnati od začetka, začne. Zdaj sem nazaj na liniji 18. Zdaj opazite x in y vrednosti smeti znova. Naprej, Naprej, Naprej, naprej. Če dobim dolgčas, sem lahko samo tip n za zraven. Lahko ga skrči na najkrajši zaporedje znakov. Zamenjava je zdaj prekinjena. Naj se potopite v, tako da namesto tipkanja naslednji, Zdaj se bom s tipom korak, tako da sem notri okrepitev te funkcije tako da lahko hodim po njej, tako da sem zadel korak in vnesite. Obvestilo, da s poudarjanjem skoči dol nižje v mojem programu za linijo 36. Zdaj, kaj so lokalne spremenljivke? Info domačini. Nič samo še zato, ker smo ni prišel do te črte, tako da gremo naprej in rekli "Naprej." Zdaj se zdi, da imajo tmp, tiskanje tmp. Garbage vrednost, kajne? Mislim, da. Kaj pa tiskanje, tiskanje B, 1 in 2? V trenutku, takoj ko sem tipa enkrat Naprej tmp se dogaja, da se na vrednost 1, upajmo, ker tmp se bo določena z vrednostjo. Zdaj pa dajmo tiskanje, tiskanje b, zdaj pa natisnite tmp, in to je res 1. Bom jaz naslednji. Bom jaz naslednji. Sem končal swap funkcijo. Še vedno sem v notranjosti pa v skladu 40, tako da naj tiska, print b, in ne zanima me, kaj je tmp. Izgleda, da zamenjava prav, ko gre za zamenjavo a in b. Ampak, če sem zdaj vnesite naslednjo, sem skočil nazaj na linijo 25, in seveda, če sem tip v x in y tiskanja oni so še vedno nespremenjena, zato nismo odpravili. Ampak diagnostično zdaj morda s tem programom GDB smo vsaj dobil en korak bližje k razumevanju kaj je narobe, ne da bi legla našo kodo z uvedbo printf tukaj, printf tukaj, tukaj in printf ga izvaja znova in znova poskuša ugotoviti, kaj je šlo narobe. Grem, da gredo naprej in nehal od tega skupaj s nehal. To se dogaja, potem pa rekel, "Vseeno končam?" Da. Zdaj sem nazaj na moj poziv normalno, in sem naredil z GDB. Naj omenim, da vam ni treba uporabljati to-TUI zastavo. V bistvu, če ga izpustite boste dobili v bistvu spodnjo polovico zaslona. Če sem vnesite prelom glavni in nato zaženite Še vedno lahko vodijo moj program, ampak kaj bo naredil, je bolj besedilom Samo pokaži mi trenutno ena vrstica naenkrat. -Tui, tekstovno uporabniški vmesnik, samo kaže, da več programa naenkrat, kar je verjetno nekoliko conceptually lažje. Toda v resnici, lahko sem naredil naslednji, naslednji, naslednji, in bom videl eno vrstico naenkrat, in če bi res rad videl, kaj se dogaja Lahko vnesete seznam in videli cel kup sosednjih linij. Tukaj je video, ki smo jih prosil, da gledate na problem postavlja 3 v kateri Nate zajema nekatere zapletenosti gdb, in to je ena od tistih stvari, po pravici povedano, če nekaj ne-trivialen odstotek vas Nikoli ne bo dotaknil GDB in da bo slabo ker dobesedno boste na koncu porabi več časa kasneje ta semester loviš določitvi bugs potem bi si, če si dal v tej pol ure / uro Ta teden in naslednji učenje, da bi dobili udobno z gdb. Printf je bil tvoj prijatelj. GDB bi zdaj moral biti vaš prijatelj. Vsa vprašanja o gdb? In tukaj je kratek seznam nekaterih od najbolj močnih in uporabnih ukazov. Ja. >> Lahko natisnete niz? Lahko natisnete niz? Absolutno. Ni nujno, da se samo cela števila. Če spremenljivka y je niz vtipkaj vs tiskanja. To vam bo pokazal, kaj je niz spremenljivka. [Neslišno-student] To vam bo dala naslov in godalnega sam. To vam bo pokazal oba. In zadnja stvar, samo zato, ker so preveč dobro, da bi vedel. Povratno sledenje in okvir, naj se potopite v to, tokrat zadnjič, Enako Natančen program z gdb. Naj gredo naprej in zagon tekstovno različico uporabniškega vmesnika, Glavni odmor. Naj gredo naprej in ponovno zaženete. Tukaj sem. Zdaj pa grem naslednji, naslednji, naslednji, naslednji, naslednji, korak, vnesite. In zdaj, da sem jaz zdaj v zamenjavo namerno, ampak sem kot "Prekleto, kaj je vrednost x?" Ne morem x več. Tega ne morem storiti, y, ker oni ne po obsegu. Oni ne v smislu, ampak ni problema. Lahko vnesete povratno sledenje. To mi pokaže vse funkcije, ki so izvedene do tega trenutka. Obvestilo, da je ena na dnu, glavni, poravna z glavno da je na dnu naše slike tukaj. Dejstvo, da je zamenjava nad njim vrstic z zamenjavo je nad njo v spomin tukaj in če želim priti nazaj na glavno začasno lahko rečem "okvir". Katera številka? Glavni okvir je # 1. Grem, da gredo naprej in reči "okvir 1". Zdaj sem se vrnil v glavnem, jaz lahko natisnete x in sem lahko natisnete y, ampak ne morem natisniti ali b. Lahko pa, če rečem: "V redu, samo trenutek. Kje je bila zamenjava?" Naj gredo naprej in rekli "frame 0". Zdaj sem spet tam, kjer želim biti, in kot prahi, tam je tudi drugi ukazi, kot če ste res dolgčas tipkanje Naprej, Naprej, Naprej, Naprej, lahko na splošno povedati stvari, kot so "Naslednjih 10", in da bo korak skozi naslednjih 10 progah. Napišete lahko tudi "še", ko se res naveličani pospešitvi skozi to. Še naprej se bo izvajal svoj program brez prekinitve, dokler se ne dotakne drugega odmerka, ali v zanki ali spustiti v programu. V tem primeru smo nadaljevali do konca, in program izstopilo običajno. To je fancy način, slabše proces. Samo vaš program izstopilo običajno. Več o tem v videu in razhroščevanje seje, ki prihajajo. To je bilo veliko. Vzemimo našo 5-minutni odmor tukaj, pa bomo vrnili s konstrukti in datotek. Če ste vrgli v pset ta teden že boste vedeli, da bomo uporabili v distribucijskem kodo, izvorne kode, ki jih ponujamo kot izhodišče, nekaj novih tehnik. Še posebej smo uvedli novo ključno besedo imenovano struct za konstrukcijo, tako da lahko oblikujemo po meri spremenljivke vrst. Uvedli smo tudi pojem datoteke, vhod / I, datoteke in izhod, in to je, da lahko rešimo državo vašega Izokrenuti sveta v datoteko na disku tako da lahko poučevanje tovariši in jaz razumem kaj se dogaja znotraj svojega programa, ne da bi sami igrali na ducate iger Scramble. Mi to zmoremo več automatedly. Ta ideja struct rešuje dokaj prepričljiv problem. Recimo, da želimo izvajati nek program da nekako beleži podatke o študentih, in morda imajo učenci, na primer ID, ime in hiša v mestu, kot je Harvard, tako da so 3 kosi informacij želimo ohraniti okoli, zato naj gredo naprej in začnite pisati malo program tukaj, vključiti stdio.h. Naj ne vključujejo cs50.h. In potem začnem glavno funkcijo. Ne bom se ukvarjati z vsemi argumenti v ukazni vrstici, in tu želim imeti študent, tako da bom povedal Študent ima ime, tako da bom rekel "niza ime." Potem bom rekel študent ima tudi ID, tako int id, in študent ima hišo, tako da sem tudi hotel reči "niz hišo." Potem bom naročiš ta malo bolj čisto, kot je ta. Ok, zdaj imam 3 spremenljivke, s katerimi se predstavljajo študenta, tako da "študent". In zdaj hočem, da zapolnijo te vrednosti, zato naj gredo naprej in rekel nekaj podobnega "Id = 123". Ime bo dobil Davida. Recimo hiša bo dobil Mather, in potem bom naredil nekaj samovoljno kot printf ("% s , katerega številka je% d, živi v% s. In zdaj, kaj hočem, da bi zapolnili tukaj, enega za drugim? Ime, id, hiša; return 0. V redu, če sem zasral tu nekje Mislim, da imamo zelo dober program, ki shranjuje 1 študenta. Seveda pa to ni vse, kar zanimivo. Kaj pa, če želim imeti 2 študente? To ni nič takega. Ne morem podpreti 2 osebi. Naj gredo naprej in označite to in pojdi tja, in lahko rečem, "id = 456", za nekoga, kot Rob, ki živi v Kirkland. Ok, počakaj, pa ne morem poklicati to isto stvar, in izgleda, da bom moral to kopirati, zato naj povem, da bo to spremenljivke Davidove, in kaj mi nekaj izvodov te za rob. Poklicali bomo ti Rob, vendar se to ne bo delovalo zdaj ker sem, čakaj, kaj je me spremeni v ID1 name1 in house1. Rob bo 2, 2. Imam to spremeniti, tukaj, tukaj, tukaj, tukaj, tukaj, tukaj. Čakaj, kaj je Tommy? Naredimo to še enkrat. Seveda, če še vedno misliš, da je to dober način za to, da to ni, tako copy / paste slabo. Ampak smo rešili ta teden. Kakšna je bila naša rešitev, če želimo imeti več primerkov iste vrste podatkov? [Dijaki] matrika. Matrika, zato naj ne poskušajte očistiti tega. Dovolite mi, da nekaj prostora zase na vrhu, in mi namesto tega tukaj. Poklicali bomo te ljudi, namesto tega pa bom rekel "int ids" in bom podprla 3 od nas za zdaj. Jaz bom rekel "niz imen," in jaz bom podprla 3 od nas, in potem bom rekel "niz hiš," in jaz bom podprla 3 od nas. Sedaj sem namesto Davida dobili svoje lokalne spremenljivke moremo znebiti teh. To je dober občutek, da smo za čiščenje to gor. Ne morem reči, potem David se bo [0] in imena [0] in hiše [0]. In potem Rob lahko prav tako shranite na to. Dajmo to tukaj, da mu bo samovoljno biti ids [1]. On bo imena [1] in potem končno, hiše [1]. Še malo dolgočasno, zdaj pa moram, da to ugotovite, Tako recimo "imena [0] id [0], hiše [0] in kaj je pluralize to. IDS, IDS, IDS. In spet, to počnem, tako da še enkrat, sem se že zateka k copy / paste spet tako da so možnosti, da je še ena rešitev tukaj. Jaz verjetno lahko očistite tako nadaljeval še z zanko ali kaj podobnega, Tako na kratko, da je malo bolje, vendar še vedno počuti kot Jaz sem se zatečejo k copy / paste, ampak tudi to, Trdim, v resnici ni bistveno prava rešitev, saj Kaj pa, če se odločimo, kdaj veš kaj? Mi bi res bilo shranjevanje e-poštnih naslovov za Davida in Rob in vsi ostali v tem programu. Prav tako je treba shranjevanje telefonskih številk. Prav tako bi morali hraniti kontaktne številke za klic v sili. Imamo vse te koščke podatkov, ki jih želimo shraniti, Torej, kako si šel o tem? Če ugotovi, drugi niz na vrhu, nato pa dodate ročno E-poštni naslov [0], e-mail [1] Za Davida in Rob in tako naprej. Vendar pa je res samo predpostavka tega modela da sem z uporabo častno sistem, da vedo, da [I] v vsaki izmed številnih nizi Samo tako se zgodi, da se nanašajo na isto osebo, tako [0] v ids je številka 123, in jaz bom prevzela, da so imena [0] je ista oseba ime in hiše [0] je ista oseba hišo in tako naprej za vse različne nizi, ki sem ustvarjajo. Toda opazil, da ni bistvena povezava med temi 3 kosi informacij, id, ime in hiše, čeprav podjetje poskušamo modelom v tem programu, ni polja. Polja so le ta programski način za to. Kaj res želimo modelirati v našem programu je oseba kot David, osebo, kot je Rob znotraj katerega in vključujejo je ime in ID in hiša. Lahko smo nekako izraziti to idejo kapsuliranje pri čemer oseba, ki ima ID, ime in hišo in ne zatekajo k res to hack, s katerim smo pravkar zaupam, da je nosilec nekaj se sklicuje na isto človeško podjetja v vsakem od teh neskladnih nizi? Mi lahko dejansko narediti. Naj gredo nad glavno za zdaj, in mi ustvariti svoj lasten vrste podatkov za zelo prvič. Uporabili smo to tehniko v Scramble, ampak tukaj bom, da gredo naprej in ustvariti vrsto podatkov, In veš kaj, bom poklical, da študent ali oseba, in bom uporabila typedef za opredelitev vrste. Jaz bom rekel, da je to struktura, in potem je ta struktura bo študenta vrsti, bomo rekli, čeprav je malo zastarelo za mene. Bomo rekli "int id". Bomo rekli "niza ime." Potem bomo rekli "niz hišo," tako da zdaj do konca teh nekaj vrstic kode Pravkar sem učil Jek, da obstaja Podatkovni tip poleg ints, poleg nizov, poleg podvoji, poleg plovcev. Od tega trenutka v časovnem zaporedju 11, je zdaj nova vrsta podatkov pozval študente, zdaj pa izjavljam, študentsko spremenljivke kjerkoli želim, zato naj se pomaknite dol, da bi ljudi. Zdaj se lahko znebim tega, in sem lahko šel nazaj dol Davidu tukaj, in za Davida lahko dejansko rečemo, da David, lahko dobesedno ime spremenljivke po sebi, se bo študenta tipa. To lahko izgleda malo čudno, vendar to še ni vse, da je drugačna razglasi nekaj tako notr ali niz ali lopatico. Samo tako se zgodi, da se imenuje študent zdaj, in če želim dati nekaj znotraj te strukture Zdaj imam uporabiti nov del skladnje, vendar je zelo enostavno, david.id = 123, david.name = "David" v prestolnici D in david.house = "Mather" in sedaj ne morem znebiti te stvari tukaj. Obvestilo smo zdaj preoblikovali naš program res veliko boljši način v tem, da zdaj naš program, odraža resničnega sveta. Tam je v realnem svetu pojem osebe ali študenta. Tu imamo zdaj različice C osebe ali natančneje študenta. Znotraj te osebe so te značilnosti, ID, ime in hiše, tako da v bistvu Rob postane ista stvar tukaj, Tako študent rob, in zdaj rob.id = 456, rob.name = "Rob". Dejstvo, da je spremenljivka imenovan Rob je nekako nesmiselno. Lahko bi ga imenovali x ali y ali z. Pravkar smo ga poimenovali Rob, da je semantično dosledno, ampak res je ime notranjosti tem področju sama, tako da zdaj imam to. Tudi to ne zanima najboljši dizajn v tem, da sem težko kodirane Davida. Trdo sem kodirani Rob. In še vedno zateče k neki kopiraj in prilepi vsakič, ko hočem nove spremenljivke. Poleg tega moram očitno daje vsako od teh spremenljivk ime, čeprav sem veliko raje opisujejo te spremenljivke  Več kot generično študentov. Sedaj lahko združila ideje, ki so bili dobro delajo za nas in namesto tega rekel: "Veš kaj, daj mi spremenljivko z imenom študentov, in naj bi bilo po velikosti 3 ", tako da zdaj lahko izboljšate to še dodatno, znebiti ročno prijavljenih Davidu in sem lahko rekla kaj takega, namesto študentov [0] tukaj. Ne morem reči, potem študente [0] tukaj študenti [0] tukaj, in tako naprej, in sem lahko šel okrog in čiščenje, da se na robu. Jaz bi tudi šel pa zdaj morda dodal zanko in uporabo GetString in GetInt dejansko dobil te vrednote od uporabnika. Lahko bi šla o dodajanju konstantna, saj je to na splošno slaba praksa na trdi oznako nekaj poljubnega števila kot 3 tukaj in potem samo ne pozabite, da morate dati največ 3 študentov v njem. Verjetno bi bilo bolje uporabiti # define na vrhu moje datoteke in dejavnik, ki ven, tako da res, mi gredo naprej in to posploševati. Naj odprejo primer, ki je med današnjo Primeri vnaprej, structs1. To je bolj celovit program, ki uporablja # define tukaj in pravi, da bomo imeli 3 študente privzeto. Tukaj sem razglasitvi razreda vredno študentov, Tako učilnica študentov, in zdaj sem z zanko samo, da je koda malo bolj elegantno, zapolnijo razred z močjo uporabnika, tako da izbirate od i = 0 na do študentov, kar je za 3. In potem sem pozval, si v tej različici  kaj študenta ID, in sem jo dobil z GetInt. Kaj je ime študenta, potem pa sem dobil z GetString. Kako je študentsko hišo? Razumem z GetString. In potem na dnu tukaj sem se odločil zamenjati kako sem ti tiskanje, in dejansko uporabo zanke, In kdo sem jaz tisk? Glede na pripombo bom tiskanje koga v Mather, in da je tako Rob in Tommy in tako naprej, dejansko Tommy je v Mather. Tommy in David bodo natisnjeni v tem primeru, ampak kako se to dela? Nismo videli to funkcijo prej, vendar pa si ugibati, kaj to počne. Primerja niza. To je malo ni jasno, kako se primerja nize, saj se je izkazalo, če se vrne 0, ki pomeni niza sta enaka. Če se vrne -1, ki pomeni enega pride po abecedi pred drugim, in če se vrne 1, ki pomeni drugo besedo prihaja po abecedi pred drugo, si lahko ogledate na spletu ali na stran man natančno vidijo, kako je kateri, ampak vse to se počne sedaj je to govori če je [i]. hiša je enako "Mather" potem pojdi naprej in izpisal tako in tako je v Mather. Ampak tukaj je nekaj, kar še nismo videli, mi pa vam bomo vrnili k temu. Ne spomnim se, kdaj to storiti v kateri koli od mojih programov. Brezplačno se očitno nanaša na spomin, sprostitev pomnilnika, ampak kaj pomnilniško sem očitno sprostitev v to zanko na dnu tega programa? Izgleda, da sem sprostila ime osebe in za osebo, hiše, ampak zakaj je to? Izkazalo se je, vseh teh tednih, ki ste ga uporabljali GetString smo nekako uvajamo napako v vsakem od vaših programov. GetString za oblikovanje spomina razporedi tako, da se lahko vrne na vaš niza, tako kot David, ali Rob, potem pa lahko naredite kar hočeš s tem niza v programu, ker smo rezerviran pomnilnik za vas. Problem je ves ta čas vsakič, ko pokličete GetString smo avtorji GetString so bili sprašuje operacijski sistem da nam malo RAM-a za ta niz. Daj nam malo RAM-a za to naslednji niz. Dajte nam nekaj več RAM-a za to naslednji niz. Kaj pa, programer, nikoli počel Daje nam, da spomin nazaj, tako da teh nekaj tednov vse programe ste napisali imeli kaj se ti spomin preskok, pri čemer so še naprej uporabljate več pomnilnika vsakič, ko pokličeš GetString, in to je v redu. Namenoma smo storili v prvih tednih, saj to ni tako zanimivo morali skrbeti, če je niz prihaja. Vse kar želim je beseda Rob, da pridejo nazaj, ko uporabnik tipi palcev Toda napredek moramo zdaj začeti pridobivanje bolj prefinjene o tem. Vsak čas bomo dodeliti pomnilnika bolje sčasoma vrniti. V nasprotnem primeru v realnem svetu na vaš PC ali Mac boste morda morali občasno izkušen Simptomi, kjer je računalnik zaustavitev na koncu ali neumen, predenje žogo plaža je le zasedajo računalnika Celoten pozornosti in ne morete narediti stvari. To je mogoče pojasniti s poljubnim številom napak, vendar se v teh možnih napak so stvari, ki se imenuje spomin pušča, s katerim je nekdo, ki je napisal, da je kos programske opreme ga uporabljate, ni spomnil, da sprostite pomnilnik da je on ali ona vprašal operacijski sistem, ne uporabljate GetString, ker je to stvar CS50, vendar z uporabo podobne funkcije ki zaprosi za operacijski sistem za spomin. Če ste ali pa zajebal in dejansko ni nikoli vrnil, da je spomin simptom, ki se lahko, da program upočasni in zavira in upočasnjuje če se spomnite, da pokličete brezplačno. Vrnila se bova kdaj in zakaj bi vi imenovali brezplačno, pa pojdimo naprej samo za dober ukrep, in poskusite z izvajanjem tega posebnega programa. To je bil imenovan structs1, vnesite. Naj gredo naprej in zagon structs1, 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather in vidimo Davida v Mather, Tommy je v Mather. To je le malo sanity pregled, da program deluje. No, na žalost, ta program je malo neprijetno, ker Naredil sem vse, da se delo, sem tipkal v 9 različnih nizih, zadeti nastopiti, je povedal, kdo je bil v Mather, a očitno sem vedel, kdo je bil v Mather že zato, ker sem jo vnesli. Bilo bi lepo, če bi vsaj ta program je bolj kot baze podatkov in dejansko spomni, kaj sem tipkal v tako da ne bo nikoli več treba vnos teh študentov zapisov. Mogoče je kot registrarial sistema. To lahko storimo z uporabo te tehnike, znano kot vhodni datoteki / I, datoteke in izhod, zelo splošen način rekel, kadarkoli želite prebrati, ali pisati datoteke lahko to storite z določenim naborom funkcij. Naj gredo naprej in odpreti ta primer structs2.c, , ki je skoraj enaka, vendar pa poglejmo, kaj zdaj počne. Na vrhu datoteke Izjavljam razred učencev. Nato sem zapolnijo razred z močjo uporabnika, Tako ti vrstic kode so natančno kot prej. Potem, če sem se pomaknite navzdol, tukaj sem natisniti vsak, ki je v Mather samovoljno kot prej, ampak to je zanimiva novost. Te vrstice kode so novi in ​​uvajajo nekaj tukaj, Datoteko, vsi pokrovčki, in je * tukaj kot dobro. Naj prestavili sem, a * tukaj kot dobro. Ta funkcija še nismo videli, fopen, vendar to pomeni datoteko, odprto, tako da je posneto z njimi, in to je nekaj, kar bomo vrnili v prihodnjih psets, vendar ta postavka tu v bistvu odpre datoteko z imenom baze podatkov, in je to posebej odpre tako, da lahko delajo, kar do njega? [Neslišno-student] V redu, torej "w" samo pomeni, da govori operacijski sistem odpreti datoteke, tako da lahko pišem z njim. Ne želim, da ga preberete. Ne želim, da samo gledaš. Rad bi jo spremenili in dodali stvari, potencialno pa tudi za to, in datoteka se bo imenujemo baze. To bi lahko imenovali ničesar. To bi lahko database.txt. To bi lahko bilo. Db. To bi lahko bila beseda kot foo, vendar sem samovoljno odločil, da ime datoteke zbirke podatkov. To je malo sanity preverjanje, da se bomo vrnili v zelo podrobno daljšem časovnem obdobju, če fp za kazalec datoteke ni enaka NULL pomeni, da je vse v redu. Skratka, deluje kot fopen včasih ne uspe. Morda datoteka ne obstaja. Morda ste iz prostora na disku. Morda nimate dovoljenja za to mapo, tako da, če fopen vrne null nekaj slabega zgodilo. Nasprotno, če fopen ne vrne null vse dobro in lahko začnem pisati v to datoteko. Tukaj je nov trik. To je za zanko, ki je nad vsakim ponavljanjem mojih študentov, in to izgleda tako podobni, kar smo počeli, vendar je ta funkcija bratranec printf pozval ovrednotenj za datoteke printf, in opazili, da je drugačen v samo 2 načina. Ena, se začne z f namesto p, nato pa svoj prvi argument je očitno, kaj? [Dijaki] datotek. >> To je datoteka. Ta stvar se imenuje fp, ki jih bomo na koncu draži narazen, kaj datoteka kazalec, vendar za zdaj fp preprosto pomeni datoteko, ki sem jo odprli, Tako ovrednotenj tukaj pravi tiskanje ID tega uporabnika do spisa, ne na zaslonu. Tiskanje ime uporabnika do spisa, ni na zaslonu, Hiša na datoteko, ne na zaslonu, nato pa sem, seveda, zapre datoteko, nato pa dol brez spomina. Edina razlika med to različico in različico 1 2 je uvedba fopen in to datoteko z * in ta pojem ovrednotenj, tako da vidimo, kaj je končni rezultat. Naj grem v mojo terminalskem oknu. Naj teče structs2, vnesite. Izgleda, da je vse v redu. Naj ponovitev structs2. 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather, vnesite. Izgleda, da je ravnala enako, če pa sem zdaj naredil ls opažati datoteka je tukaj med vso svojo kodo, podatkovne baze, tako da je odpreti to, gedit baze podatkov, in pogled na to. To ni najbolj seksi formatov. Res je en del črte podatkov na vrstico na linijo, ampak tiste, ki uporabljajo Excel ali CSV datotek, ločene z vejico vrednosti, Jaz bi vsekakor uporabiti ovrednotenj, namesto morda kaj takega tako da sem lahko dejansko ustvarijo enakovredno Excelove datoteke z ločitvijo stvari z vejicami, ne le novih linij. V tem primeru, če bi jaz namesto tega uporabljajo vejice namesto nove proge Jaz bi dobesedno odpreti to datoteko zbirke podatkov v Excelu, če bi namesto tega je bilo videti takole. Skratka, zdaj, ko imamo moč pisati datoteke lahko zdaj začnete trajnih podatkov, ohranjanje približno na disku tako da lahko hranimo podatke, okoli spet in spet. Obvestilo nekaj drugih stvari, ki so zdaj nekoliko bolj seznanjeni. Na vrhu te datoteke C imamo typedef ker smo želeli ustvariti vrsto podatkov, ki predstavlja besedo, tako da je ta vrsta se imenuje Beseda, znotraj te strukture to je malo Ljubitelj zdaj. Zakaj je beseda sestavljena iz navidez matrike? Kaj je beseda samo intuitivno? To je niz znakov. To je zaporedje znakov, back to back to back. Črke v vseh kape zgodi, da se bomo poljubno rekli največja dolžina vsake besede v slovarju, ki ga uporabljamo za Scramble. Zakaj imam 1? Null značaj. Spomnimo se, ko sva primer Bananagrams smo potrebovali posebno vrednost na koncu besede, da bi spremljali o tem, kje je dejansko končalo besede, in kot problem niz specifikacij pravi Tukaj smo povezuje z dano besedo boolean vrednost, zastave, če se tako izrazim, resnična ali neresnična. Ali ste našli to besedo že, saj se zavedamo res potrebujemo način spomina ne samo, kaj beseda v Scramble ampak, ali ti, človek, so ga našli tako da če se najde besedo "je" ne moreš kar vnesite vnesite je, vstopiti, vnesite in dobili 3 točke, 3 točke, 3 točke, 3 točke. Želimo, da bi lahko na črno te besede, ki jih določa bool se pravi, če je že našel, in da je zato ga vnesli v tej strukturi. Zdaj, tukaj v Scramble tam je ta druga struct imenuje slovar. Odsotni tukaj je beseda typedef ker v tem primeru smo morali zaobjeti idejo slovarju, in slovar vsebuje cel kup besed, kot je vsebovano v tem polju, in koliko od teh besed obstajajo? No, karkoli že to imenujemo spremenljivka velikost pravi. Vendar pa moramo samo 1 zbirko. Ne potrebujemo vrsto podatkov, imenovano slovar. Potrebujemo samo eno od njih, da se izkaže v C da če ne boste rekli typedef, si rekel struct, nato pa znotraj zavitih oklepajih daste spremenljivke, nato pa si dal ime. To je razglasila 1 spremenljivko z imenom zbirko ki je videti takole. Nasprotno, te linije ustvarjajo enkratno podatkovno strukturo, imenovano beseda da lahko ustvarite več kopij, tako kot smo ustvarili več kopij študentov. Kaj to končno omogočilo, da storimo? Naj grem nazaj v, recimo, enostavnejši primer iz preprostejših časih, in mi odpre, recimo, compare1.c. Problem pri roki, je dejansko lupine nazaj plast niz in začeti vzleta te vrste usposabljanja kolesa ker se je izkazalo, da je niz ves ta čas je, kot smo obljubili v 1 tednu res samo vzdevek, sopomenka od CS50 knjižnico za nekaj, kar je malo več skrivnosten, char *, in to smo videli zvezdo doslej. To smo videli v kontekstu datotek. Poglejmo zdaj vidite, zakaj smo se skrivali to podrobnost, že nekaj časa. Tukaj je datoteka z imenom compare1.c, in je očitno vpraša uporabnika za 2 nizih, s in t, in potem poskuša primerjavo teh nizov za enakost v skladu 26, in če si enaka pravi: "Vnesli ste isto stvar," in če niso enaka pravi: "Ti vnesli različne stvari." Naj gredo naprej in zagon programa. Naj grem v mojo izvornega imenika, si compare1. To zbrati v redu. Naj teče compare1. Bom povečavo, vnesite. Reci nekaj. Pozdravljeni. Jaz bom povedal nekaj več. Pozdravljeni. Jaz definitivno nisem tip različne stvari. Naj poskusim še enkrat. Adijo. Zagotovo ne razlikujejo, kaj se dogaja tukaj? No, kaj v resnici se primerjajo v skladu 26? [Neslišno-student] Da, tako se je izkazalo, da je niz, vrsto podatkov, je malo belo laž. Niz je char *, ampak kaj je char *? Char *, kot pravijo, je kazalec, in kazalec učinkovito naslov, Vsota mesto v pomnilniku, in če se zgodi, da so vnesli v besedo, kot HALO, spomnite iz prejšnjih razpravah godala To je tako kot beseda Pozdravljeni. Ne pozabite, da lahko zastopa beseda kot Pozdravljeni kot niz znakov, kot je ta, in nato še s posebnim znakom na koncu imenovana null značaj, kot denotacije \. Kaj je pravzaprav niz? Vedite, da je to več kose pomnilnika in v resnici, je konec vsega šele, ko pogledaš skozi celoten niz išče zaradi posebnega značaja null. Ampak, če je to kos pomnilnika iz spomina mojega računalnika, kaj je samovoljno pravijo, da ta niz samo srečo, in je dobil v samem začetku RAM mojega računalnika. To je bajt 0, 1, 2, 3, 4, 5, 6 ... Ko sem rekel kaj takega GetString in jaz String s = GetString kaj je bilo res vrnil? V teh zadnjih nekaj tednih, je tisto, kar zares shranjeni v ih Ni ta niz po sebi, ampak v tem primeru, kaj je bilo shranjeno, je številka 0, ker tisto, kar v resnici počne GetString se fizično ne vrne niz. To sploh ni res, da konceptualno smiselna. Kaj pa vrnitev številka. Ta številka je naslov Pozdravljeni v spominu, in niz je nato, če se lupine nazaj ta sloj, niz v resnici ne obstaja. To je le poenostavitev v CS50 knjižnici. To je res nekaj, kar ti char *. Char smiselno, ker tisto, kar je beseda, kot HELLO? No, to je niz znakov, niz znakov. Char * pomeni naslov značaja, kaj to pomeni, da vrne niz? Lepo, enostaven način vračanja niz je namesto poskušali ugotoviti, kako se vrniti na 5 ali 6 različnih bajtov Naj se vrnem na naslov, ki bajt? Prvi. Z drugimi besedami, naj ti dam naslov znak v spomin. To je tisto, char * pomeni, naslov enega samega znaka v pomnilniku. Pokličite, da se variabilni s. Shranjujte v ih, ki je predvsem naslov, ki sem ga samovoljno dejal 0, samo, da se stvari preprosto, v resnici pa je na splošno večje število. Čakaj malo. Če ste le mi dali naslov prvega znaka, kako naj vem, kaj je naslov v drugem, tretjem, četrtem in petem? [Neslišno-student] Vi samo vedeti, kje je konec niza je prek tega priročen trik, tako da, ko boste uporabili nekaj podobnega printf, kaj printf dobesedno vzame za svoje trditve, opozarjajo, da bomo uporabili to% s ogrado, nato pa preide v spremenljivka, ki se skladiščijo niz. Kaj ste res mimo, je naslov prvega značaj tega niza. Printf nato uporabi za zanke ali while zanko po prejemu tega naslova, na primer, 0, tako da mi to zdaj, printf ("% s \ n", i); Ko sem poklical printf ("% s \ n", i), kaj sem res zagotavlja printf s je naslov prvega znaka v oklepajih, ki v tem primeru je samovoljno H. Kako printf vem, kaj točno želite prikazati na zaslonu? Oseba, ki izvaja printf izvaja while zanko ali za zanko ki pravi, da se ta znak enak poseben značaj null? Če ne, ga natisnete. Kaj pa tole? Če ne natisniti, jo natisnite, jo natisnite, ga natisnete. Oh, to je nekaj posebnega. Prekinite tiskanje in se vrniti na uporabnika. In to dobesedno vse, kar se dogaja pod pokrovom motorja, in to je veliko za prebavo v prvi dan v razredu, ampak za zdaj je res gradnik vsega razumevanja da se je dogajalo na notranji pomnilnik našega računalnika, in na koncu bomo to draži narazen z malo pomoči eno od naših prijateljev v Stanfordu. Profesor Nick Parlante na Stanfordu je naredil to čudovito video zaporedje iz vseh vrst različnih jezikih, ki so uvedle ta mali Claymation znak Binky. Glas boste kmalu slišali v samo nekaj Prikradati predogled 2. je, da je za Stanford profesor, in ste dobili Samo 5 ali 6 sekund tem zdaj, ampak to je opomba, na katerem bomo danes sklepajo in začel v sredo. Dam kazalca Zabava z Binky, predogled. [♪ ♪ Glasba] [Profesor Parlante] Hej, Binky. Zbudi se. Čas je za zabavo kazalca. [Binky] Kaj je to? Več o kazalci? Oh, vrlina! Mi vas bo v sredo. [CS50.TV]