[Powered by Google Translate] [Hét 4] [David J. Malan] [Harvard Egyetem] [Ez a CS50.] [CS50.TV] Rendben, itt CS50, és ez a kezdete 4. héten, és ez az egyik a leglassabb lehetséges rendező algoritmus. Melyik volt az, hogy mi csak néztem oda? Ez volt buborék rendezés érdekében nagy O (n ^ 2) + összeget, és valóban nem mi vagyunk az egyetlenek, akik ebben a világban, hogy úgy tűnik, hogy tudni mi buborék rendezés, illetve a működési idő. Valóban, ez egy interjú Eric Schmidt a Google és a korábbi szenátor Barack Obama néhány évvel ezelőtt. Nos, szenátor, te itt a Google-nál, és azt szeretném tudni, hogy az elnökség, mint egy állásinterjú. Nos, nehéz munkát találni, mint elnök, és megy keresztül a borzongás most. Ez is nehéz munkát találni a Google-nál. Van kérdése, és kéri, hogy jelöltek kérdéseket, és ez az egyik a Larry Schwimmer. Azt hiszitek, viccelek? Ez itt van. Mi a leghatékonyabb módja annak, hogy rendezni egy millió 32-bites egész? [Nevetés] Well- Sajnálom. >> Nem, nem, nem, nem. Azt hiszem, a buborék rendezés lenne a rossz út. Gyerünk, ki mondta ezt neki? Múlt héten emlékeztetni vettünk egy kis szünetet a kódot, legalább egy nap, és elkezdtem összpontosítva valamilyen magasabb szinten ötletek és problémamegoldás általában keretében a keresés és válogatás, és azt be valamit, amit mi nem pofon ez a név a múlt héten, de aszimptotikus jelölések, a Big O, a Big Omega, és néha a nagy Theta jelölés, és ezek csupán módokon hogy leírja a futási ideje algoritmusok, mennyi időt vesz igénybe egy algoritmus futtatásához. És akkor emlékszem, hogy beszélt a futási idő szempontjából a méret a bemeneti, amit általában véve n, függetlenül a probléma lehet, ahol n az emberek száma a szobában, az oldalak számát a telefonkönyvben, és elkezdtük írni a dolgokat mint O (n ^ 2) vagy O (n) vagy O (n log n), és még ha a matek nem igazán dolgoznak ki, így tökéletesen és ez n ² - n / 2, vagy valami ilyesmi mi lenne inkább csak dobja néhány alacsonyabb rendű feltételeket, és a motiváció is van, hogy valóban szeretnénk fajta objektív módon értékelésére teljesítménye programok vagy teljesítményének algoritmusok , hogy a végén a nap semmi köze, például, A sebesség a számítógép ma. Például, ha a végre buborék rendezés, vagy végre egyesítése rendezés vagy kiválasztás sort a mai számítógép, A 2 GHz-es számítógépet, és futtatja azt, és némi másodpercek száma, a következő évben van egy 3 GHz vagy a 4 GHz-es számítógépet, és lehet, hogy majd azt állítják, hogy "Wow, én algoritmus most kétszer olyan gyors, "amikor a valóságban ez nyilvánvalóan nem ez a helyzet. Ez csak a hardver ütött gyorsabb, de a számítógép nem, és ezért szeretné, hogy dobja el a dolgokat, mint a többszörösei 2 vagy többszöröse 3, amikor a leíró , hogy milyen gyorsan vagy milyen lassú az algoritmus, és tényleg csak összpontosítani n vagy néhány tényező annak Egyes annak erejét, mint abban az esetben, a fajta a múlt héten. És emlékeztetni arra, hogy segítségével a merge sort tudtuk, hogy ezt sokkal jobb, mint buborék rendezés és kiválasztás sort és még beillesztés sort. Kaptunk le n log n, és újra, Emlékeztetek arra, hogy log n általában az valamit, hogy nő lassabban akkor n, így n log n eddig jó volt mivel az kevésbé mint n ². De elérése n log n a merge sort mi volt az az alap, csírája egy ötlet, hogy mi volt, hogy felerősítse a hogy mi is megmutatta, vissza a 0. héten? Hogyan kezeljük a rendezési probléma ügyesen a merge sort? Mi volt a legfontosabb betekintést, talán? Bárki, aki egyáltalán. Oké, egy lépést hátra. Ismertesse merge sort a saját szavaival. Hogyan működik? Oké, evezni vissza 0. héten. Oké, igen. [Hallhatatlan-diák] Oké, jó, szóval megosztotta a tömb számokat 2 db. Mi sorrendje minden egyes ilyen darab, aztán egyesült őket, és láttuk ezt az ötletet, mielőtt figyelembe a probléma, hogy ez a nagy és darabolás fel egy probléma, hogy ez a nagy, vagy a nagy. Hívja a telefonkönyv példa. Emlékezzünk az ön-számlálás algoritmust héttel ezelőtt, így merge sort foglalta össze ezt a pszeudokód ide. Amikor adott n elemű, első volt józanság megtekintéséhez. Ha n <2, akkor nem csinál semmit mert ha n <2, akkor n értéke 0 vagy 1 nyilvánvalóan, és így, ha ez 0 vagy 1 semmi rendezni. Te kész. A lista már triviálisan rendezve. De egyébként ha van 2 vagy több elem megy előre, és az őket elválasztó a 2 fél, balra és jobbra. Rendezése minden említett fél, majd egyesíteni a rendezett felét. De a probléma az, hogy első látásra ez az érzés vagyunk punting. Ez körkörös meghatározás, hogy ha én kértem, hogy rendezni ezeket n elemek , és azt mondod: "Oké, rendben, akkor rendezni e n / 2 és az n / 2 elem" akkor a következő kérdés az lesz, hogy "Rendben, hogyan rendezheti a n / 2 elem?" Hanem azért, mert a szerkezete ennek a programnak, mert ez az alapeset, hogy úgy mondjam, Ebben a speciális esetben, hogy azt mondja, ha n > Sara, rendben. Kelly. >> Kelly és? Willy. >> Willy, Sara, Kelly és Willy. Most Én már feltette a kérdést valaki hány ember fel ebben a szakaszban, és fogalmam sincs. Ez egy nagyon hosszú lista, és így ahelyett, hogy fogom csinálni ezt a trükköt. Meg fogom kérni a személy mellett, hogy tegyek a munka nagy részét, és ha ő kész csinál a munka nagy részét Fogok csinálni a legkevesebb munka lehetséges, és csak adjunk hozzá 1 hogy bármilyen rá válasz, hogy itt vagyunk. Már kérték, hány ember van a színpadon. Hány ember van a színpadon, a bal oldalon van? A bal rám? >> Oké, de nem csalnak. Ez jó, ez igaz, de ha azt akarjuk, hogy továbbra is ezt a logikát tegyük fel, hogy hasonlóan szeretné punt ezt a problémát, hogy a bal oldalán van, így ahelyett answer közvetlenül megy előre, és add meg a pénzükért. Ó, milyen sokan balra engem? Hányan vannak a bal oldalon? 1. [Nevetés] Oké, tehát 0, akkor mi most Willy tett van már vissza a válasz ebben az irányban mondván 0. Most mit tegyünk? >> 1. Oké, te vagy az 1, tehát azt mondod: "Rendben van, megyek hozzá 1 hogy bármilyen Willy gróf ", így 1 + 0. Te most 1, így a választ a jobb most, 1. >> És az enyém lenne a 2. Jó, így szedi az előző választ 1, hozzáadták a minimális mennyiségű munkát akarsz csinálni, ami +1. Most van 2, és akkor majd adja meg, amely érték? 3, Úgy értem, sajnálom, 2. Jó. Nos, mi volt 0-balra. Aztán volt 1, majd adunk hozzá 2, és most átadta nekem a 2-es szám, és ezért mondom, oké, +1, 3. Van ugyanis 3 ember mellett állva rám ezen a színpadon, így volna nyilvánvalóan tette ezt nagyon lineárisan, nagyon is nyilvánvaló módon, de mit igazán csinálni? Mi volt a probléma méretű, 3 kezdetben. Ezután tört le egy probléma a 2-es méret, akkor a probléma az 1-es méret, és majd végül az alapeset valóban, oh, nincs ott senki, ekkor Willy visszatért hatékonyan a kódolt választ egy pár alkalommal, , a második pedig ezután buborékoltatunk fel, buborékoltatunk fel, buborékoltattunk fel, és azután hozzáadásával ebben az egy további 1 most már végre ezt alapgondolata rekurzió. Most, ebben az esetben nem igazán egy probléma megoldásához bármely hatékonyabban, akkor láttunk eddig. De gondolj az algoritmusok tettünk a színpadon eddig. Mi volt 8 darab papír a táblára, a videó, amikor Sean kereste a 7-es, és mit mondott valójában csinálni? Nos, ő nem tett semmilyen oszd meg és uralkodj. Ő nem tett semmilyen rekurzió. Inkább ő csak tette a lineáris algoritmus. De amikor bevezette azt az elképzelést, rendezett számok színpadon élő múlt héten akkor mi volt ennek az ösztönnek az lesz a középső, ekkor volt egy kisebb lista mérete 4 vagy másik lista 4-es méretű, és akkor volt, pontosan ugyanaz a probléma, ezért ismételt, többszöri, ismételt. Más szóval, mi recursed. Köszönjük, hogy a 3 önkéntesek itt bizonyításának rekurzió velünk. Lássuk, ha nem tudjuk, hogy ez most egy kicsit konkrétabb, egy probléma megoldására, hogy ismét tudtunk csinálni elég könnyen, de mi fogjuk használni, mint egy lépcsőfok, hogy végrehajtja ezt az alapvető elképzelést. Ha azt akarom, hogy kiszámolja az összegzése egy csomó számok, például, ha át a 3-as szám, Azt akarom, hogy ön a szigma értéke 3, így az összege 3 + 2 + 1 + 0. Azt akarom, hogy menj vissza a választ 6, úgyhogy végrehajtásához sigma funkciót, ez a funkció összegzés arra, hogy ismét vesz bemenet, majd visszaadja az összegzési E szám egészen 0-ra. Megtehetjük ezt elég egyszerű, ugye? Mi is ezt valamilyen looping szerkezet, hadd menjen előre, és kap ez elkezdődött. Beleértve stdio.h. Hadd magam fő dolgozni itt. Nézzük Mentés sigma.c. Aztán megyek itt, és én fogom állapítsa int n, és fogok csinálni a következő, amíg a felhasználó nem működik együtt. Amíg a felhasználó nem adott nekem egy pozitív szám hadd menjen előre, és kéri őket, n = getInt, és hadd adjon nekik néhány utasítást, hogy mit kell csinálni, így printf ("Pozitív egész kérem"). Csak valami viszonylag egyszerű, mint ez, hogy mire elérjük a 14 vezetéken most már van egy pozitív egész feltehetően n. Most valamit csinálni vele. Hadd menjek előre, és kiszámítja az összegzése, ezért int összeg = sigma (n). Sigma csak összegzése, úgyhogy én csak írni azt a szakértő módon. Majd csak hívni szigma ott. Ez az összeg, és most megyek, hogy nyomtassa ki az eredményt, printf ("Az összeg% d \ n", összeg). És aztán vissza 0 a jó intézkedés. Már mindent megtett, hogy ez a program előírja, kivéve az érdekes rész, amely a ténylegesen alkalmazni a szigma funkciót. Hadd menjek le ide, hogy az aljára, és hadd állapítsa funkció sigma. Úgy van, hogy olyan változó, hogy ez a típusú egész szám, és milyen adattípus akarok visszatérni feltehetően a Sigma? Int, mert azt akarom, hogy megfeleljen az elvárásaimnak on line 15. Az itt hadd menjen előre, és végrehajtják ezt Egy nagyon egyszerű módon. Menjünk előre, és azt mondják, int összeg = 0, és most megyek egy kicsit a hurok itt hogy fog mondani valamit, mint ez, for (int i = 0; I <= szám; i + +) összeg + = i. Aztán megyek vissza az összeget. Tudtam volna végre ezt a tetszőleges számú módon. Én is használtam egy darabig hurok. Tudtam volna kihagyja a változó összeg, ha tényleg akartam, de a rövid, már csak egy függvény, hogy ha nem hülye nyilatkozik összeg 0. Ezután megismétli 0-tól akár a száma, és minden iteráció hozzáteszi, hogy a jelenlegi értéket összeg, majd visszatér összeget. Nos, van egy kis optimalizálás itt. Ez valószínűleg egy elvesztegetett lépés, de hát legyen. Ez rendben van most. Vagyunk, legalább, hogy alapos és megy 0 egészen akár. Nem nagyon kemény és nagyon egyszerű, de kiderül, hogy a szigma funkcióval van az ugyanezt a lehetőséget mint mi itt a színpadon. A színpadon már csak számolni, hogy hány ember volt mellettem, hanem ha azt akartuk, hogy számolja meg a 3 + 2 + 1 le 0-ra tudtunk hasonlóan punt egy függvény hogy én inkább írni, hogy a rekurzív. Itt csináljuk gyors józanság ellenőrizze és győződjön meg róla, én nem hülye. Tudom, hogy van legalább egy dolog ez a program, hogy én csináltam rosszul. Amikor hit lép fogok kapni bármilyen kiabál rám? Mit fogok, hogy kiabált szó? Ja, elfelejtettem a prototípus, úgyhogy függvény segítségével úgynevezett szigma on line 15, de ez nem nyilvánított ig a 22, úgyhogy a legjobb proaktív menni ide és állapítsa meg a prototípus, és azt mondom int sigma (int szám), és ennyi. Ez végre az alján. Vagy egy másik módja, hogy oldja meg ezt, Tudtam mozgatni a funkció ott, ami nem rossz, de legalább, ha a programok kezdenek hosszú, őszintén szólva, Azt hiszem, van néhány érték, amely mindig a legfontosabb a csúcson úgy, hogy az olvasó tudja nyitni a fájlt, majd azonnal látni mit csinál a program anélkül, hogy keressük rajta keres, hogy a fő funkciója. Menjünk le a terminál ablak van, próbálja sigma tenni szigma, és elcsesztem itt is. Implicit nyilatkozatot funkció getInt jelenti elfelejtettem csinálni mi mást? [Hallhatatlan-diák] Jó, így nyilvánvalóan a gyakori hiba, úgyhogy tegyük ezt itt, cs50.h, és most menjünk vissza a terminál ablakot. Majd törölje a képernyőt, és én, hogy futtassa újra sigma. Úgy tűnik, hogy összeállítani. Hadd futni sigma. Majd írja be a 3-as szám, és nem kap 6, tehát nem a szigorú ellenőrzést, de legalább úgy tűnik, hogy működik az első pillantásra, de most hadd rip szét, és hagyja, hogy a valóban kihasználhatják azt az elképzelést, rekurzió, újra, Egy nagyon egyszerű kontextus úgyhogy néhány hét múlva amikor elkezdjük felfedezni galambász adatszerkezetek, mint a tömbök van egy másik eszköz az eszköztár, amellyel manipulálják ezeket adatstruktúrák mint látni fogjuk. Ez az iteratív megközelítés, a loop-alapú megközelítés. Hadd ehelyett most ezt. Hadd inkább azt mondják, hogy az összegzése a szám le 0-ra valóban ugyanaz, mint a száma + sigma (száma - 1). Más szóval, ahogy a színpadon I punted az egyes emberek mellém, és viszont punting tartott, amíg végül el mélypontját a Willy, aki vissza a kódolt választ, mint a 0-ra. Itt most mi hasonlóan punting a szigma ugyanazt a funkciót, mint eredetileg nevezett, de a legfontosabb betekintést itt az, hogy mi nem hív szigma azonosan. Mi nem halad n. Mi jól halad száma - 1, így egy valamivel kisebb probléma, valamivel kisebb probléma. Sajnos, ez nem egészen megoldás még, és mielőtt rögzítjük milyen lehet ugrott ki, mint nyilvánvaló, néhányan hadd menjen előre, és futtassa újra tenni. Úgy tűnik, hogy rendben összeállításához. Hadd futtasd Sigma, 6. Hoppá, hadd futtassa újra Sigma, 6. Már láttam ilyet, de véletlenül utoljára is. Miért kaptam ezt a rejtélyes szegmentálási hiba? Igen. [Hallhatatlan-diák] Nincs az alapeset, pontosabban, mi valószínűleg történt? Ez a tünet milyen viselkedés? Mondja, hogy egy kicsit hangosabban. [Hallhatatlan-diák] Ez egy végtelen ciklus hatékonyan, és a probléma a végtelen hurkok amikor az együtt jár a rekurziót ebben az esetben, egy függvény nevezte magát, mi történik, minden alkalommal, amikor hívja a funkciót? Nos, gondolom, vissza hogyan lefektetett a memória a számítógép. Azt mondta, hogy itt van ez a darab a memória az úgynevezett stack, ami az alján, és minden alkalommal, amikor hív egy függvényt egy kicsit több memóriát kap valósult Ezen az úgynevezett stack tartalmazó függvény helyi változók vagy paraméterek így ha sigma felhívja sigma felhívja szigma felhívja szigma  felhívja sigma amennyiben nem ez a történet vége? Nos, ez végül túllépése a teljes összeget memóriát, hogy van elérhető a számítógéphez. Te túllépés a szegmens, amit kéne maradnia, és megkapod ezt a szegmentációs hiba, core dump, és milyen core dump jelenti, hogy most van egy nevű fájlt core amely egy fájl, amely nullákkal és egyesekkel hogy valóban a jövőben lesz diagnosztikailag hasznos. Ha ez nem egyértelmű, hogy hol a hiba a akkor valóban egy kicsit a kriminalisztika, hogy úgy mondjam, ezen a core dump fájlt, ami ismét csak egy csomó nullákkal és egyesekkel jelenti, hogy lényegében az állam a program a memóriában a pillanatban, amikor összeomlott így. A javítás az, hogy nem tudunk vakon vissza szigma, a száma + szigma egy valamivel kisebb probléma. Szükségünk van valamilyen alap esetben is, és mi legyen a bázis esetében valószínűleg? [Hallhatatlan-diák] Rendben, amíg a szám pozitív kellene tulajdonképpen vissza ezt, vagy másképpen fogalmazva, ha a szám, mondjuk, <= 0-ra Tudod mit, én megyek előre és vissza 0, ugyanúgy, mint Willy volt, és mást, megyek, hogy menjen előre és vissza ezt, így ez nem olyan sokkal rövidebb mint az iteratív változata, amit felvert fel először egy for ciklus, azonban észre, hogy itt van ez a fajta elegancia hozzá. Ahelyett, hogy az adatszolgáltató egyes szám és előadó mindezt matematikai és hozzá a dolgokat a helyi változók ön helyett azt mondja: "Jól van, ha ez egy szuper könnyű probléma, mint a szám <0, hadd azonnal vissza 0-ra. " Nem fogunk zavarni támogató negatív számokat, így fogok keményen kódot a 0 értéket. De egyébként, hogy végrehajtsák ezt a gondolatot az összegező Mindezen számok együttesen lehet hatékonyan, hogy egy kis falatot ki a probléma, ugyanúgy, mint tettük itt a színpadon, akkor punt a többi probléma a következő személyt, de ebben az esetben a következő személy magad. Ez egy azonos nevű funkciót. Csak add meg, hogy egy kisebb és kisebb és kisebb problémát minden egyes alkalommal, és bár mi nem igazán hivatalossá dolgokat ide a kódot ez pontosan mi is folyik a 0. héten, a telefonkönyvben. Pontosan ez az, hogy mi történik az elmúlt hét Sean és a mi bemutatók keres számok. Ez vesz egy problémát, és elosztjuk meg újra és újra. Más szóval, van egy módja már fordításának ez a valós konstrukciót, ez a magasabb szintű konstrukció Az oszd meg és uralkodj, és csinál valamit újra és újra kódot, így ez az, amit látni fogjuk, újra az idő múlásával. Most, mint egy félre, ha új rekurzió akkor legalább megérteni, hogy ez miért vicces. Fogok menni google.com, és megyek keresni néhány tippet és trükköt rekurzió írja. Mondd meg az a személy, Ön mellett, ha nem nevetnek most. Gondolt rekurzió? Did you mean-ah, ott vagyunk. Oké, most, hogy ez a többi mindenkinek. Egy kis húsvéti tojás beágyazott valahol ott a Google. Mint félre, egyet a linkeket tesszük a pályán honlapján mára csak ez a rács a különböző válogatás algoritmusok, amelyek közül néhány néztük múlt héten, de mi a jó ebben megjelenítés ahogy próbálja tekerje elméd köré különböző dolgokat kapcsolódó algoritmusok tudom, hogy nagyon könnyen nekiláthatnak különböző típusú bemenet. A bemenetek minden megfordult, a bemenetek többnyire rendezve, a bemenetek véletlen és így tovább. Ahogy próbálja újra, megkülönbözteti ezeket a dolgokat a fejedben észre, hogy ezt az URL a kurzus honlapján a Lectures oldalon segíthet miatt át néhány ilyen. Ma végre kap, hogy megoldja ezt a problémát egy kicsit vissza, ami az volt, hogy ez a csere a funkció nem működött, és mi volt az alapvető probléma ezzel a funkcióval swap, a cél az volt, ismét cseréljenek értéket itt és itt oly módon, hogy ez történik? Ez valójában nem működik. Miért? Igen. [Hallhatatlan-diák] Pontosan, a magyarázat erre a bugginess Egyszerűen azért, mert ha hívja funkciók C és ezeket a funkciókat vesz érvek, mint a és b itt, Ön halad példányban bármilyen érték, amit nyújt, hogy ezt a funkciót. Ön nem biztosítja az eredeti értékek maguk így látta ezt keretében buggyc, buggy3.c, ami úgy nézett egy kicsit valami ilyesmi. Emlékezzünk arra, hogy mi volt az x és y inicializálódik az 1. és 2., illetve. Ezután kinyomtatható mik voltak azok. Aztán azt állította, hogy én swapping őket hívja swap x, y. De a probléma az volt, hogy a csere működött, de csak a hatálya alá a swap funkció is. Amint elérjük a 40 vezetéken ezeket cserélték értékek dobtak el, és így semmi Az eredeti funkció fő ténylegesen változott, így ha úgy gondolja, majd vissza, hogy ez mit néz szempontjából emlékezetünk ha ez a bal oldali a fórumon jelentése- és én minden tőlem telhetőt, hogy mindenki lássa, ha a bal oldalán a fórumon jelentése, mondjuk, a RAM és a verem fog növekedni fel ilyen módon, és hívjuk a függvényt, mint a fő-, és fontosabb a 2 helyi változók, x és y, menjünk le ezeket, mint x itt, és menjünk le ezeket y itt, és tegyük az értékek 1 és 2, így ez itt a fő, és amikor fő felhívja a swap függvény az operációs rendszer meghozta a swap függvény saját rend a memória a verem, saját keret a verem, hogy úgy mondjam. Azt is lefoglal 32 bit ezen ints. Ez történik hívni őket és b, de ez teljesen önkényes. Lehetett nevezték őket, amit akar, de mi történik, ha a fő felhívja swap tart ez 1, tesz egy példányt ott tesz egy példányt ott. Jelenleg 1 más helyi változó csere, bár az úgynevezett mi? >> Tmp. Tmp, úgyhogy hadd adjak magamnak még egy 32 bit itt, és mit tegyek ez a funkció? Azt mondtam, int tmp kap, így van 1, ezért tettem ezt, amikor utoljára játszottunk ezt a példát. Aztán lesz b, tehát b értéke 2, így most ez lesz 2, és most b kap temp, így a temp 1, így most b válik ez. Ez nagyszerű. Ez működött. De aztán, amint a függvény csere memóriájában ténylegesen eltűnik oly módon, hogy újra fel lehet használni valamilyen más funkciót a jövőben, és a fő nyilvánvalóan teljesen változatlan. Szükségünk van egy módja annak, alapvetően ezen probléma megoldásához, és ma mi végre van egy ezt a módszert, amellyel tudjuk be egy úgynevezett mutató. Kiderül, hogy meg tudjuk oldani ezt a problémát nem vezetjük példány x és y hanem átadásával, amit, mit gondol, hogy a swap funkció? Ja, és mi van a cím? Mi nem igazán beszéltünk címeket sok részlet, de ha ez a tábla mutatja a számítógép memóriájában tudtuk biztosan kezdeni a számozást byte az én RAM és azt mondják, ez a bájt # 1, ez a bájt # 2, # 3 bájt, # 4 bájt, bájt # ... 2000000000 ha van 2 GB RAM, így minden bizonnyal jönni néhány önkényes számozási rendszer minden egyes bájt a számítógép memóriájában. Mi van, ha ehelyett, amikor hívásváltás ahelyett igazolványt példányban x és y miért nem inkább át a címét x itt, címe y itt lényegében a postacím Az x és y, mert akkor csere, ha ő tájékoztatta A cím a memóriában az x és y, akkor csere, ha képzett neki egy kicsit, tudott potenciálisan vezetni arra a címre, hogy úgy mondjam, x, és módosítsa a számot ott, majd a meghajtó a címét y, számának módosításához ott, miközben valójában nem kapok másolatát ezeket az értékeket magát, így még akkor is beszéltünk erről, hogy a fő memóriájába és ez az, hogy a swap-memóriája az erős és a veszélyes rész a C , hogy minden funkció megérinteni memóriát bárhol a számítógép, és ez az erős, hogy meg tudod csinálni nagyon divatos dolgokat számítógépes programok C. Ez veszélyes, mert akkor is csavarja ki nagyon könnyen. Sőt, az egyik az a leggyakoribb módja a programok manapság kiaknázandó még mindig a programozó nem felismerni hogy ő, amely lehetővé teszi az adat írandó olyan helyen a memória nem erre tervezték. Például ő nyilatkozik egy sor 10-es méret de aztán véletlenül megpróbál tenni 11 byte-ba, hogy a tömb memória, és elkezdi megható részei memória már nem érvényesek. Csak kontextuális ezt néhány talán tudja, hogy szoftver gyakran kér sorozatszámot vagy regisztrációs kulcs, Photoshop és a Word és programok, mint ez. Léteznek repedések, mivel néhány tudjátok, online hol lehet futtatni egy kis program, és íme, nincs több kérelem egy sorszám. Milyen az, hogy működik? Sok esetben ezek a dolgok egyszerűen csak megtalálni a számítógépek text szegmensek a számítógép aktuális nullákkal és egyesekkel hol van ez a funkció, ha a sorozatszám kérik, és felülírja ezt a helyet, vagy miközben a program fut tudod kitalálni, hol a kulcs ténylegesen tárolt segítségével egy úgynevezett debugger, és akkor kiváló szoftver módon. Ez nem azt jelenti, hogy ez a célunk a következő pár napban, de nagyon valós következményei. Ez az egyetlen történik vonja lopás szoftver, de ott is kompromisszum a teljes gép. Valójában, amikor weboldalak ezekben a napokban kizsákmányolás és a sérült és az adatok szivárgott és jelszavakat lopott ez nagyon gyakran kapcsolódik a rossz gazdálkodás egyik memóriájában, vagy, abban az esetben az adatbázisok, elmulasztása előre kontradiktórius bemenet, így több az, hogy az elkövetkezendő hetek során, de most csak egy settenkedik sajtóbemutató a fajta kár, hogy meg tudod csinálni azzal, hogy nem egészen megértése hogyan működnek a dolgok a motorháztető alatt. Menjünk megértéséről szól, hogy miért ez hibás -vel egy olyan eszköz, amely egyre inkább hasznos mint a mi programok kap bonyolultabb. Eddig, ha már volt egy hiba a programban hogy elment az erről hibakeresés ez? Mit a technikák voltak eddig, hogy tanítják a TF vagy csak autodidakta? [Student] printf. Printf, így a printf valószínűleg már a barátod, ha meg akarja nézni mi folyik belül a program Ön az imént printf ide, printf itt printf itt. Akkor fuss ez, és kapsz egy csomó dolog a képernyőn hogy tudod használni, hogy aztán levezetni, ami valójában rosszul a programban. Printf hajlamos arra, hogy egy nagyon erős dolog, de ez egy nagyon manuális folyamat. Van, hogy egy printf itt, egy printf itt, és ha tedd belsejében egy hurkot akkor lehet, hogy 100 sor kibocsátás, amit majd meg kell rostálni keresztül. Ez nem egy nagyon felhasználóbarát vagy interaktív mechanizmus hibakereső programok de szerencsére létezik alternatíva. Van egy program, például az úgynevezett GDB, a GNU Debugger, ami egy kicsit misztikus, hogyan használja azt. Ez egy kicsit bonyolult, de őszintén szólva, ez az egyik olyan dolog, ahol ha tesz ezen a héten és a jövő az extra órát, hogy megértsék ilyesmit GDB meg fog menteni valószínűleg tíz óra a hosszú távon, így van, hogy hadd adjak egy teaser, hogyan működik ez a dolog. Én vagyok az én terminál ablakban. Hadd menjek előre, és fordítani ezt a programot, buggy3. Ez már naprakész. Hadd futtatni, mint tettük egy kicsit vissza, és valóban, ez eltörött. De miért van ez? Lehet, hogy elszúrtam a swap funkciót. Talán ez az a és b. Én nem egészen mozgó őket körül helyesen. Hadd menjek előre, és ezt. Ahelyett, hogy csak fuss buggy3 hadd helyett futtatni ezt a programot GDB, és azt fogom mondani, hogy fuss buggy3, és megyek fel egy parancssori argumentum,-tui, és mi, hogy ezt a jövőben a problémákat, hogy emlékeztesse spec. És most ez a fekete-fehér felület bukkant fel, hogy újra, egy kicsit nyomasztó az első, mert ez az egész jótállási információk itt lent, de legalább van valami ismerős. Az ablak tetején az én tényleges kódot, és ha felfelé itt hadd lapozzunk a legtetején a fájl, és valóban, van buggy3.c és azt tapasztaljuk, alján ezen ablak Van ez a GDB gyors. Ez nem ugyanaz, mint a normális John Harvard gyors. Ez egy figyelmeztetés fog engedje meg, hogy ellenőrizzék GDB. GDB egy debugger. A hibakereső olyan program, amely lehetővé teszi, hogy séta végrehajtása a program soronként sorra, az út mentén, hogy bármit szeretnénk a programot, még hívásfunkciók, vagy keres, ami még fontosabb, különböző változó értékeit. Menjünk előre, és ezt. Én megyek előre, és írja be a GDB fut a parancssorba, így észre a bal alsó sarokban a képernyő, amit beírt fut, és én már nyomd meg az Entert, és mit, hogy tegyek? Szó futott a program, de valójában nem sokat látni tovább itt mert valójában nem azt mondta a debugger szünet egy adott pillanatban. Csak írja távon futtatja a programot. Igazából nem látok semmit. Nem tudok manipulálni. Ehelyett hadd tegye ezt. Ezen GDB parancsot hadd helyett írja törés, az enter billentyűt. Ez nem az, amit akartam beírni. Nézzük inkább írja szünet fő. Más szóval, azt akarom állítani egy úgynevezett töréspont, amely találóan elnevezett, mert eltörik vagy szünet végrehajtása a program, hogy az adott helyen. Fő a neve az én funkció. Figyeljük meg, hogy GDB elég okos. Ebből rájött, hogy fő történik kezdeni nagyjából 18 vezetéken A buggy3.c, majd észre, itt a bal felső sarokban b + közvetlen közelében 18 vezetéken. Ez eszembe juttatta, hogy meghatározta a töréspontot sorban 18. Ez az, amikor azt írja run, megyek futni a programot addig, amíg eléri, hogy a töréspont, így a program leáll nekem sorban 18. Itt vagyunk, fuss. Semmi sem úgy tűnik, hogy történt, de a felhívás a bal alsó sarokban kezdő program, buggy3, töréspont 1-fő at buggy3.c 18 vezetéken. Mit tehetek most? Figyeljük meg tudok kezdeni gépelni dolgokat, mint a nyomtatás, Nem printf, print x, és most, hogy furcsa. A $ 1 csak a kíváncsiság, mint látni fogjuk minden alkalommal, amikor nyomtat valamit, kapsz egy új $ értéket. Ez így utalja vissza az előző értékeket csak abban az esetben, de most mi print azt mondja nekem, hogy az x értéke ezen a ponton a történet látszólag 134514032. Mi az? Honnan, hogy még ide? [Hallhatatlan-diák] Valóban, ez az, amit hívom a szemét érték, és mi már nem beszéltünk még, de az ok, hogy Ön változók inicializálása nyilvánvalóan úgy, hogy van néhány érték, amely azt szeretné, hogy van. De a fogás felidézni, hogy akkor nyilvánítja változókat mint én egy perccel ezelőtt az én szigma példa anélkül, hogy azokat egy értéket. Emlékezzünk, mit tettem ide a szigma. Kijelentettem n, de mi értéke adtam meg? Nincs, mert tudtam, hogy a következő néhány sorban GetInt is gondoskodik a probléma üzembe értékű belsejében n. De ezen a ponton a történet line 11 és a 12-es vonal és a vonal 13 és 14. sor szerte a több vonalon mi az értéke az n? A C-ben, csak nem tudom. Ez általában valamilyen szemét érték, néhány teljesen véletlen számot ami megmaradt lényegében néhány korábbi funkció miután futni, így a program fut Emlékeztetek arra, hogy a funkció lesz a funkció, funkció, funkció. Mindezen keretek kap fektetni a memóriában, majd ezeket a funkciókat visszatérés, és mint azt javasoltam a radír a memória végül újra. Nos, ez csak azért történik, hogy ez a változó x ebben a programban Úgy tűnik, hogy néhány olyan értéket, mint a szemetet, 134514032 néhány korábbi funkcióját, és nem az egyik, hogy én írtam. Ez lehet valami, ami ténylegesen az operációs rendszer, Néhány funkció a motorháztető alatt. Oké, rendben, de hadd most tovább a következő sorra. Ha azt írja be a "next" én GDB azonnali és én nyomd meg az Entert, észre, hogy a kiemelése mozog lefelé a vonal 19, de a logikus következménye, hogy a 18. sor már befejezte a végrehajtó, így ha újra írja be a "print x" Azt kell most lásd 1, sőt, tudom. Ismét a $ cucc egy módja GDB emlékeztetve, mi a története nyomatok, amit tettél. Most hadd menjen előre, és nyomtassa ki y, és valóban, y néhány őrült érték is, de nem nagy ügy, mert a 19 vagyunk arról, hogy rendelje hozzá a 2 értéket, ezért hadd írja be a "next" újra. És most mi vagyunk a printf sorban. Hadd csináljam print x. Hadd csináljam print y. Őszintén szólva, én egy kicsit fáradt nyomtatási ezt. Hadd helyett írja "kijelző x" és "y kijelző," és most minden alkalommal, amikor írja be a parancsot a jövőben Én is emlékeztetik mi x és y, mi x és y, mi x és y. Én is, mint félretéve, írja be a "info helyiek." Info egy speciális parancs. A helyiek azt jelenti, hogy megmutatja nekem a lokális változók. Csak abban az esetben elfelejtem, vagy ez egy őrült, bonyolult függvény hogy én vagy valaki más írta info helyiek fogja mondani, hogy melyek az összes helyi változót ezen belül a helyi funkció hogy esetleg érdekel, ha azt szeretné, hogy piszkálni körül. Most printf körülbelül végrehajtani, úgyhogy hadd menjen előre, és csak a típus "next". Mert mi vagyunk ebben a környezetben mi valójában nem látta azt végre itt lent, de észre ez egy kicsit szétroncsolt itt. De észre, ez felülbírálja a képernyőn van, így ez nem egy tökéletes program itt, de ez rendben van, mert én mindig piszkálni körül használatával print, ha akarok. Hadd írja next újra, és most itt az érdekes rész. Ezen a ponton a történet y értéke 2, és x értéke 1, ahogy azt itt, és újra, az oka ez automatikusan megjeleníti most, mert használt a parancs kijelző x és y kijelző, így a pillanatban írja next elméletben x és y váljon cserélték. Most már tudjuk, hogy ez nem lesz a helyzet, de majd meglátjuk, egy pillanat, hogyan tudunk merülni mélyebbre, hogy kitaláljuk, hogy miért igaz. Tovább gombra, és sajnos még mindig y 2 és x még mindig 1, és tudom erősíteni annyira. Print x, print y. Valóban, nincs csere is történt, úgyhogy kezdjük ezt újra. Nyilvánvaló, csere van törve. Nézzük inkább írja be a "run" újra. Hadd mondjam el, igen, szeretnék újraindítani a kezdetektől, az enter billentyűt. Most én vagyok vissza sorban 18. Most észre x és y értékek szemét megint. Következő, next, next, next. Ha unatkozni Én is csak írja n a következő. Tudod rövidítéséhez azt a lehető legrövidebb karaktersorozat. Swap most elromlott. Nézzük merülés, így ahelyett, hogy gépelés következő, Most megyek, hogy írja lépést, így az én megerősítéséről belül ez a funkció annak érdekében, hogy tudok járni rajta, úgyhogy hit lépést, majd adja meg. Figyeljük meg, hogy a kiemelése ugrik lejjebb az én programban sor 36. Most mi vagyunk a lokális változók? Info helyiek. Semmi, csak még, mert mi már nem jutott, hogy ezt a vonalat, úgyhogy menjünk előre, és mondja ki a "next". Most úgy tűnik, hogy tmp, print tmp. Garbage érték, ugye? Azt hiszem, igen. Mit szólnál nyomtatása, print b, 1 és 2? Abban a pillanatban, amint írja next újra tmp fog tartani az értéke 1, remélhetőleg, mert tmp fog kell rendelni az értékét. Most nem nyomtat, print b, de most nyomtatni tmp, és ez valóban 1. Hadd csinálni. Hadd csinálni. Már kész a swap funkciót. Én még mindig a benne lévő sorban 40, úgyhogy hadd nyomtatni, print b, és nem érdekel, hogy mit tmp van. Úgy néz ki, csere helyes, amikor a csere a és b. De ha most írja a következő, én ugorj vissza a vonal 25, és persze, ha az I. típusú x és y print ők még mindig változatlan, tehát még nem rögzítették a problémát. De diagnosztikai Most talán ennek GDB programmal most már legalább ütött egy lépéssel közelebb a megértés mi baj, anélkül, hogy szemét a kódot azáltal, hogy a printf itt, printf itt printf ide, majd fut újra és újra hogy kitaláljam, mi baj. Én megyek előre, és lépjen ki ebből a teljesen kilép. Ez lesz majd mondani, hogy "kilép?" Igen. Most már itt vagyok én normális parancssorba, és én végezzük GDB. Mint félre, akkor nem kell használni ezt a tui-zászló. Sőt, ha nem adjuk meg azt kapsz lényegében az alsó felében a képernyőn. Ha majd írja szünet fő és futtassa Még mindig fut a program, de mit fog tenni több szövegesen csak mutasd meg nekem az aktuális sor egyesével. The-tui, szöveges felhasználói felület, csak azt mutatja, hogy több, a program egyszerre, ami talán egy kicsit fogalmilag könnyebb. De valóban, én is csak csináld next, next, next, és meg fogom látni, egy sort egy időben, és ha szeretné, hogy mi folyik itt Én típusú listát és látni egy csomó szomszédos vonalak. Van egy videó, hogy már kérte, hogy figyelje a probléma készletek 3 amely Nate kiterjed néhány bonyolult GDB, és ez az egyik olyan dolog, őszintén szólva, ahol néhány nem triviális százalékos Ön soha nem fog megérinteni GDB, és hogy lesz egy rossz dolog mert szó lesz a végén több időt töltenek majd ebben a félévben kergeti bugs akkor lenne, ha életbe, hogy fél óra / óra ezen a héten és a jövő tanulás kap kényelmes GDB. Printf volt a barátja. GDB kell most a barátod. Bármilyen kérdésre GDB? És itt egy rövid lista néhány a legerősebb és hasznos parancsokat. Aha. >> Tud nyomtatni egy string? Tud nyomtatni egy string? Abszolút. Nem kell, hogy csak egész számok. Ha egy változó s string csak típus print s. Ez megmutatja, hogy mi karakterlánc változó. [Hallhatatlan-diák] Ez megadja a cím és a szöveg is. Ez megmutatja, mindkettő. És egy utolsó dolog, csak azért, mert ezek jó tudni is. Visszakövetés és a keret, hadd merüljön ebbe még egyszer utoljára, pontosan ugyanazt program GDB. Hadd menjek előre, és futtassa a szöveges felhasználói felület változata, szünet fő. Hadd menjek előre, és futtassa újra. Itt vagyok. Most hadd menjek next, next, next, next, next, step, írja. És most tegyük fel, én vagyok most csere szándékosan, de olyan vagyok, mint: "A fenébe, mi volt az x értéke?" Nem tudom x többé. Nem tudom y, mert ők nem hatályát. Ők nem a kontextusban, de nem probléma. Én beírhatja backtrace. Ez azt mutatja meg az összes funkciót, hogy végre ezen a ponton az időben. Figyelje meg, hogy az egyik az alsó, a fő, vonalak fel a fő hogy az alján a kép itt. Az a tény, hogy a swap fölött vonalba swap fölötti a memóriában van, és ha akarom, hogy újra a fő ideiglenesen tudom mondani, hogy "keretet". Mi a száma? Main frame # 1. Én megyek előre, és mondja ki a "keret 1". Most itt vagyok a fő, és én is nyomtathat x, és tudok nyomtatni y, de nem tudok nyomtatni, vagy b. De ha azt mondom: "Oké, várj egy percet. Hol volt a csere?" Hadd menjek előre, és azt mondják: "frame 0". Most itt vagyok, ahol szeretnék lenni, és mint félre, van más parancs is, mint ha tényleg kezd unatkozni gépelés next, next, next, next, Ön általában mondani a dolgokat, mint a "következő 10", és hogy át lehet lépni a következő 10 vonalak. Azt is írja: "továbbra is", ha tényleg kap elege lépett át rajta. Tovább fog futni a program, megszakítás nélkül, amíg eléri egy töréspont, akár a hurok vagy lejjebb a programban. Ebben az esetben továbbra is a végén, és a program kilépett rendesen. Ez egy divatos módon alsóbbrendű folyamat. Csak a program kilépett rendesen. Bővebben az, hogy a videó és a hibakeresés üléseken, hogy jöjjön. Ez volt egy csomó. Nézzük mi 5-perces szünet van, és mi vissza a struktúrákat és fájlokat. Ha már lebukott e heti Pset már tudni fogja, hogy mi használja a forgalmazási kódot, a forráskódot, hogy mi az, hogy Ön, mint egy kiindulási pont, néhány új technikákat. Különösen azt be ezt az új kulcsszót hívott struct, a szerkezet, annak érdekében, hogy mi is létrehozhatunk egyéni változók fajta. Mi is bevezette a fogalmat fájl I / O, a fájl bemenet és kimenet, és ez az, hogy ki tudjuk menteni az állam a Scramble fórumon, hogy egy fájlt a lemezen úgy, hogy a tanítás ösztöndíjasok és megértem mi folyik belül a program anélkül, hogy kézzel játszani tucatnyi játékok Scramble. Meg tudjuk csinálni ezt jobban automatedly. Ez az elképzelés egy struct old meglehetősen impozáns probléma. Tegyük fel, hogy szeretnénk végrehajtani néhány program hogy valahogy nyomon követi információk diákok, és a diákok lehetnek, például egy azonosító, egy nevet és egy házat egy olyan helyen, mint a Harvard, így ezek a 3 információkat akarjuk tartani körül, hadd menjen előre, és kezdjük el beírni a kis program van, között stdio.h. Hadd tegyek közé cs50.h. És akkor kezdődik a fő funkciója. Én nem zavarja semmilyen parancssori argumentumok, és itt szeretnék egy diák, így fogom mondani a hallgató neve, így fogom mondani, hogy "string name". Akkor fogok mondani, egy diák is van azonosítója, ezért int id, és a hallgató egy házat, úgyhogy én is akartam mondani "string ház." Akkor megrendelni ezeket egy kicsit tisztábban, mint ez. Oké, most már 3 változókat, amelyek képviseletére a tanuló, így a "diák". És most szeretném feltölteni ezeket az értékeket, ezért hadd menjen előre, és mond valamit, mint a "Id = 123". Név fog kapni David. Tegyük fel, hogy házat fog kapni Mather, majd fogok csinálni valamit önkényesen hasonló printf ("% s, amelynek ID% d, él% s. És most, mit szeretnék, hogy csatlakoztassa itt, egyik a másik után? Név, id, house, return 0. Oké, ha elszúrtam valahol itt Azt hiszem, van egy nagyon jó program, amely tárolja az egyik diák. Persze, ez nem is olyan érdekes. Mit tegyek, ha akarom, hogy 2 diák? Ez nem nagy ügy. Tudom támogatni 2 fő részére. Hadd menjek előre, és jelölje ki ezt, és menj le ide, és azt mondhatja, hogy "id = 456" valaki, mint Rob, aki él Kirkland. Oké, várj, de én nem nevezném ezeket ugyanaz a dolog, , és úgy néz ki, megyek kell másolni ezt, ezért hadd mondjam, hogy ezek lesznek Dávid változók, és hadd kap néhány másolatot ezekről a Rob. Hívjuk ezeket Rob de ez nem fog menni most mert már-várj, változtassuk meg engem ID1, NAME1 és house1. Rob lesz 2, 2. Van ezen változtatni itt, itt, itt, itt, itt, itt. Várj, mi van Tommy? Csináljuk ezt újra. Nyilvánvaló, hogy ha még mindig úgy gondolja, hogy ez egy jó módja ennek, ez nem, így copy / paste rossz. De megoldotta ezt egy héttel ezelőtt. Mi volt a megoldás, ha azt akartuk, hogy a több példányban azonos adatokat típus? [Diákok] A tömb. Egy tömb, hadd próbálja megtisztítani ezt. Engedjék meg, hogy néhány helyet magamnak a tetején, és hadd helyette ezt itt. Hívjuk ezeket az embereket, és helyette fogok mondani, "int ids," és én fogom támogatni 3 of us most. Fogok mondani "string nevek", és én támogatni 3 of us, majd fogok mondani "string házak", és megyek, hogy támogassák 3 minket. Most itt van, nem David szerzés saját lokális változók tudunk megszabadulni e. Ez jó érzés, hogy mi Tisztítás fel. Én majd mondja Dávid lesz a [0] és nevek [0] és házak [0]. Aztán Rob tudunk hasonlóan menteni ezt. Nézzük, hogy ezt ide, így fog önkényesen lesz ids [1]. Ő lesz a nevek [1], majd végül házak [1]. Még egy kicsit unalmas, és most már, hogy kitaláljuk, így mondjuk: "names [0], id [0], házak [0] és menjünk pluralize ezt. IDS, ids, ids. És ismét, én csinálom, úgyhogy megint, én már folyamodik copy / paste újra így esély van egy másik megoldás van. Én valószínűleg tisztítani ezt fel tovább a hurok, vagy valami ilyesmi, így rövid, ez egy kicsit jobb, de még mindig úgy érzi, mint Én igénybe a copy / paste, de ez, azt állítják, nem igazán alapvetően jó megoldás, mert mi lenne, ha valamikor úgy döntünk, tudod mit? Tényleg kellett volna tárolni e-mail címét David és Rob és mindenki más ebben a programban. Azt is meg kell tárolni a telefonszámokat. Azt is meg kellene tárolni segélyhívó telefonszámokat. Mindannyian ezeket a darabokat az adatokat szeretnénk tárolni, igen, hogyan megy körülbelül csinálás ez? Ön kijelenti másik tömböt a tetején, és akkor kézzel hozzá E-mail cím [0], e-mail címe [1] David és Rob és így tovább. De tényleg csak egy feltételezés alapjául ez a design , hogy én vagyok a megtiszteltetés rendszer tudni, hogy [I] az egyes több tömböt csak azért történik, hogy utalja az ugyanaz a személy, így [0] ids a szám 123, és én fogom feltételezni, hogy a nevek [0] ugyanaz a személy nevét és házak [0] ugyanaz a személy házába, és így tovább az összes különböző tömbök, amit létre. De észre, hogy nincs alapvető kapcsolat közül 3 db információt, id, név és a ház, annak ellenére, hogy a gazdálkodó egység próbálunk modell ez a program nem tömbök. Tömbök csak ezt programozási módja ennek. Amit igazán akar, hogy a modellt a program egy személy mint Dávid, az a személy, mint Rob belsejében, amely vagy kapszulázó a neve és azonosítója, valamint egy házat. Lehet valahogy kifejezni ezt az ötletet a tokozás amelyben egy személy van egy azonosítója, egy nevet és egy házat és nem folyamodnak ahhoz, hogy valóban ez a hack, amellyel már csak bízom benne, hogy valami konzol utal az azonos emberi szervezet minden, ezeket a különálló tömbök? Tudjuk ténylegesen ezt. Hadd menjek a fenti fő most, hadd hozzon létre saját adattípust az igazán először. Úgy használta ezt a technikát Scramble, de itt én megyek előre, és hozzon létre egy adattípus, és tudod mit, én fogom hívni diák vagy személy, és én fogom használni typedef az határozza meg a típusát. Fogom mondani, hogy ez a struktúra, és akkor ez a szerkezet lesz típusú diák, akkor mondjuk, annak ellenére, hogy egy kicsit én kelt most nekem. Azt mondjuk "int id". Majd mondják, hogy "string name". Akkor mondjuk "string ház" így most a végére e néhány sornyi kódot Imént tanított csenget, hogy létezik Egy adattípus mellett ints mellett vonósok mellett páros mellett lebeg. Mivel e pillanatban line 11 van, most egy új adattípus nevű diák, és most kijelentem diák változót bárhol akarok, hadd Görgessen ide az emberek. Most már tudom hogy eltűnjön ez, és mehetek vissza David ide, és az I. Dávid valójában mondani, hogy David, akkor szó szerint megnevezni a változó után magam, lesz típusú diák. Ez tűnhet egy kicsit furcsa, de ez még nem minden, hogy a különböző a kijelentésen valami, mint egy int vagy egy string vagy egy úszó. Ez csak azért történik, hogy hívják diák most, és ha azt akarjuk, hogy valami belül ezt a szerkezetet Most kell használni egy új darab szintaxis, de ez elég egyértelmű, david.id = 123, david.name = "David" a tőke-D, és david.house = "Mather," és most hogy eltűnjön ez a cucc itt. Figyeljük meg mi már most átalakítottuk a programot tényleg sokkal jobb megoldás az, hogy most a programunk tükrözi a valós világban. Van egy valós világ fogalma egy személy vagy egy diák. Itt van már a C változat egy személy vagy pontosabban a hallgató. Belül az adott személy ezek fontos jellemzőit, ID, név és a ház, így a Rob lényegében válik ugyanaz itt lent, így diák rob, és most rob.id = 456, rob.name = "Rob". Az a tény, hogy a változó neve Rob egyfajta értelmetlen. Mi volna neveztük x vagy y vagy z. Csak nevezték el Rob hogy szemantikailag következetes, de valójában a név belsejében e területen is, így most van ez. Ez szintén nem érzi, mint a legjobb design, hogy már nehezen kódolt David. Már kemény kódolt Rob. És én még mindig kénytelen néhány példányt be minden alkalommal szeretnék új változókat. Sőt, azt kell, hogy minden látszólag e változók egy nevet, bár én sokkal inkább írni ezeket a változókat  Több általánosságban a diákok. Most már tudjuk egyesíteni az ötlet, hogy már jól működik nálunk és helyette azt mondja: "Tudod mit, adj egy változó nevezett hallgatók, és mondjuk meg, hogy legyen méretű, 3 ", így most tudom ezt tovább finomítani, megszabadulni a kézi bejelentett David, és én inkább mondani valamit, mint a diákok [0] itt. Tudok majd mondani, diákok [0] itt, diákok [0] itt, és így tovább, és én is menni körül és tisztítsa meg, hogy a fel Rob. Azt is megy a most talán hozzá egy hurok és használata, valamint getString getInt hogy ténylegesen kap ezeknek az értékeknek a felhasználó elől. Tudtam járni hozzá egy állandó, mert ez általában rossz gyakorlat kemény-kód bizonyos tetszőleges számú, mint 3 itt és aztán csak ne feledjük, hogy meg kell tenni legfeljebb 3 diák is. Ez valószínűleg jobb, hogy # define tetején az én fájl és a tényező, hogy ki, így valóban, hadd menjen előre, és általánosítani ezt. Hadd nyit egy példát, hogy ez napjaink példák előre, structs1. Ez egy komplett program, amely a # define ide és azt mondja, megyünk, hogy a 3 diák alapértelmezés szerint. Itt vagyok nyilvánító osztály értékű diákok, így egy osztályteremben a diákok, és most egy hurok csak azért, hogy a kódot egy kicsit elegáns, népességnövekedés az osztály a felhasználó bemenet, így navigálhat i = 0-tól akár a diákok, amely 3. Aztán megkérdezi a felhasználót ez a verzió  mi a hallgató azonosítóját, és kapok rá getInt. Mi a hallgató nevét, majd kapok azt getString. Mi a tanuló háza? Értem azt getString. És akkor az alján van csak úgy döntött, hogy módosítani mennyire vagyok nyomtatás ezeket, és hogy ténylegesen használni a hurok, és aki vagyok nyomtatás? Az kommentezni vagyok nyomtatás valaki Mather, és ez annyira Rob és Tommy, és így tovább, valójában Tommy a Mather. Tommy és David lenne kinyomtatni a jelen ügyben, de hogy van ez működik? Nem láttuk ezt a funkciót, de hogy a találgatás, hogy mi ez. Összehasonlítja a szálakat. Ez egy kicsit, nem nyilvánvaló, hogy hogyan viszonyul húrok, mert kiderült, hogy ha visszatér 0 azt jelenti, hogy a húrok egyenlő. Ha visszatér a -1 azt jelenti, hogy jön egy betűrendben a másik előtt, és ha visszatér 1 azt jelenti, hogy a többi szó a betűrendben még mielőtt a másik, és nézd online, vagy a férfi oldal pontosan lássák, milyen módon, amely de ez most csinál ez mondja ha a [i]. house egyenlő: "Mather" akkor megy előre, és nyomtassa ki így és így van Mather. De itt van valami, amit még nem látott, és mi jön vissza erre. Nem emlékszem, hogy valaha ezt minden az én programokat. Free nyilvánvalóan utal memória, memória felszabadítása, de mit memória én látszólag felszabadítja e hurok alján ez a program? Úgy néz ki, én vagyok szabadítva a személy nevét és az a személy házába, de miért van ez? Kiderült, hogy ezek a hetek, amit használ getString voltunk ilyen bemutatta egy bug-ba valamennyien a programokat. GetString by design Memóriát azért, hogy visszatérjen egy string, mint Dávid, vagy Rob, és akkor majd csinálsz, amit akarsz azzal a húr a programot, mert mi már fenn a memória az Ön számára. A probléma az egész idő alatt minden alkalommal, amikor szükséges getString mi, a szerzői getString, már kérte az operációs rendszer hogy nekünk egy kis RAM ezt a fonalat. Adj egy kis RAM ez a következő string. Adj nekünk néhány RAM ez a következő string. Amit a programozó, soha nem csinál ad nekünk, hogy memória vissza, így e több hétig az összes program, amit írt volt az úgynevezett memória ugrást, amelyben tartják a egyre több és több memóriát minden alkalommal, amikor hívás getString, és ez rendben van. Tudatosan ezt, hogy az első hetekben, mert ez nem olyan érdekes hogy nem kell aggódnia, ha a string jön. Minden, amit szeretnénk, az a szó, Rob, hogy jöjjön vissza, amikor a felhasználó a be! De előrelépés most el kell kezdeni, hogy a kifinomultabb erről. Minden alkalommal, amikor a memóriát, jobb, végül adja vissza. Ellenkező esetben a valós világban a Mac vagy PC lehet, hogy alkalmanként tapasztalt tünetek, ha a számítógép szűnnek meg végül vagy a hülye pörgő strandlabda éppen elfoglaló a számítógép teljes figyelmet, és nem tudsz csinálni a dolgokat. Ez azzal magyarázható, hogy tetszőleges számú hibát, de azok között az esetleges hibákat vannak dolgok, nevezzük memóriavesztés, amellyel valaki, aki azt írta, hogy a szoftver Ön használ nem emlékszem, hogy szabad memória , hogy ő kérte a operációs rendszer, nem használó getString, mert ez egy CS50 dolog, de a hasonló funkciókat hogy kérje az operációs rendszer a memória. Ha Ön vagy ők csavart, és valójában soha nem tér vissza, hogy a memória a tünete, ami lehet, hogy egy program lelassítja és lassítja, és lassítja ha emlékszel, hogy hívja ingyenes. Majd gyere vissza, mikor és miért neveznétek ingyen, de menjünk előre csak a jó intézkedés, és próbálja meg futtatni az adott programot. Ezt nevezték structs1 írja. Hadd menjek előre, és fuss structs1, 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather, és látjuk, Dávid a Mather, Tommy a Mather. Ez csak egy kis józanság ellenőrzése, hogy a program működik. Nos, sajnos, ez a program egy kicsit frusztráló, hogy Én minden munkát, nem adtam a 9 különböző vonósok, nyomd meg az Entert, azt mondták, aki a Mather, de természetesen tudtam, ki volt Mather már, mert nem adtam meg. Ez legalább jó, ha ez a program több, mint egy adatbázis és ez tényleg emlékszik, amit már beírt így soha többé nem kell ilyen input hallgatói nyilvántartások. Lehet, hogy olyan, mint egy registrarial rendszer. Meg tudjuk csinálni ezt a technikát nevezik fájl I / O, a fájl bemenet és kimenet, igen általános megfogalmazásban azt bármikor el szeretnénk olvasni fájlokat írni vagy fájlok meg tudod csinálni ezt egy bizonyos funkciók. Hadd menjek előre, és nyissa meg ezt a példát structs2.c, , amely majdnem azonos, de lássuk, mi most csinál. A tetején a fájl Kijelentem, egy osztály a hallgatók. Aztán népességnövekedés az osztályt a felhasználó bemenet, így azok sornyi kódot pontosan úgy, mint korábban. Akkor, ha én itt vagyok görgessen nyomtatni mindenkit, aki a Mather önkényesen, mint korábban, de ez egy érdekes újdonság. Ezek a vonalak kódot újak, és vezessen be valamit, FILE, nagybetűs, és azt * itt is. Hadd mozgatni ezt ide, a * ide is. Ez a funkció még nem látott, fopen, de ez azt jelenti fájl nyitva van, úgyhogy átlássa ezeket, és ez az, amit mi jön vissza a jövőben psets, de ez a vonal itt lényegében megnyit egy fájlt nevű adatbázist, és különösen megnyitja azt oly módon, hogy meg tudja csinálni, amit vele? [Hallhatatlan-diák] Igaz, így a "w" csak azt jelenti, hogy mondja az operációs rendszer megnyitni ezt a fájlt oly módon, hogy tudok írni. Nem akarom, hogy elolvassa. Nem akarom, hogy csak nézd meg. Azt akarom, hogy változtassa meg, és adjunk hozzá cucc esetlegesen rá, és a fájl fog hívni adatbázisba. Ezt nevezhetnénk semmit. Ez lehet database.txt. Ez lehet az. DB. Ez lehet egy szó, mint a foo, de önkényesen úgy döntött, hogy a fájl nevét adatbázisban. Ez egy kis józanság ellenőrzése, hogy mi jön vissza nagy részletességgel az idő múlásával, ha fp, a fájl pointer, nem egyenlő NULL azt jelenti, hogy minden rendben van. Hosszú történet rövid, funkciók, mint a fopen néha nem. Lehet, hogy a fájl nem létezik. Talán elfogyott a lemezterület. Lehet, hogy nincs engedélye az adott mappát, így ha fopen függvény null valami rossz történt. Ezzel szemben, ha fopen nem tér vissza null, minden rendben van és én írjuk ezt a fájlt. Itt egy új trükk. Ez a for ciklus, ami iterációjával az egyes tanítványom, és ez úgy néz ki, hasonló ahhoz, amit tettünk korábban, de ez a funkció egy unokatestvére printf hívott fprintf a fájl printf, , és vegyük észre, hogy ez különbözik csak 2 módon. Egyik, hogy kezdődik f helyett p, de aztán az első érv nyilvánvalóan mi? [Diákok] fájl. >> Ez egy fájlt. Ez a dolog az úgynevezett fp, amit majd végül kötekedik eltekintve, amit a fájl pointer van, de most fp egyszerűen képviseli a fájlt, amit megnyitott, így fprintf itt azt mondja, nyomtassa ki a felhasználói azonosítót a fájlt, hogy ne a képernyőt. Nyomtassa ki a felhasználó nevét a fájl, nem a képernyőn, a ház a fájlt, nem a képernyőn, majd ide, természetesen, zárja be a fájlt, majd itt lent szabad a memóriát. Az egyetlen különbség a 2-es verziója, és 1-es verzió a bevezetése fopen és ez a fájl a * és ez a fogalma fprintf, úgyhogy lássuk, mi a végeredmény. Hadd menjek be a terminál ablakot. Hadd futni structs2 írja. Úgy tűnik, minden rendben van. Nézzük ismételni structs2. 123, David Mather, 456, Rob Kirkland, 789, Tommy Mather, az enter billentyűt. Úgy viselkedett, mintha ugyanaz, de ha most nem ls észre, milyen fájl van az összes kódomat, adatbázis, úgyhogy nyitni, gedit adatbázis, és nézd meg ezt. Ez nem a legszexisebb fájl formátumokat. Ez tényleg egy adat sor soronként soronként, de azok, akik az Excel vagy CSV fájlokat, vesszővel elválasztott értékek, Tudtam biztosan használtam fprintf ehelyett talán ilyet így én ténylegesen létrehozni az egyenértékű egy Excel fájl elválasztva vesszővel dolgokat, nem csak az új vonalak. Ebben az esetben, ha én ehelyett vessző helyett új vonalak Tudtam szó megnyitni az adatbázis fájlt az Excel, ha helyette tette, hogy néz ki, mint ez. Röviden, most, hogy a hatalom, hogy írjon fájlokat most már kezdeni tartós adatok tartása körül lemezen annak érdekében, hogy tudjuk tartani információkat körül újra és újra. Értesítés egy pár más dolog, hogy most már egy kicsit ismerős. A tetején C fájl van egy typedef mert azt akartuk, hogy hozzon létre egy adattípus, amely egy szót, így ez a típus az úgynevezett szó, és ezen belül az e struktúra ez egy kicsit szakértő most. Miért egy szó alkotja látszólag egy tömb? Mi az a szó, csak ösztönösen? Ez egy sor karakter. Ez egy karaktersorozatot háttal hátra. LETTERS minden sapkák történik, hogy azt önkényesen mondjuk a maximális hosszt minden szót a szótárban, hogy mi használ Scramble. Miért van a +1? A null karakter. Emlékezzünk, amikor megcsináltuk a Bananagrams példában szükség különleges értéket végén a szó-ben annak érdekében, hogy követni hol szavak ténylegesen véget ért, és a probléma meg előírás szerint Itt vagyunk társítani egy adott szót a logikai érték, egy zászlót, hogy úgy mondjam, igaz vagy hamis. Találtál ezt a szót már, mert rájövünk, valóban szükségünk van egy módja annak, emlékezés nem csak egy szó, mi van a Scramble de függetlenül attól, hogy az emberi, megtaláltam így ha nem talál a szó ", a" nem lehet csak írja be, írja be, az adja meg, az adja meg és kap 3 pont, 3 pont, 3 pont, 3 pont. Azt akarjuk, hogy képes legyen feketelistára szó beállításával bool true ha már megtalálta, és így éppen ezért kiöntött azt ezt a struktúrát. Most, itt lent a tülekedés van ez a másik struct nevű szótárban. Hiányában itt a szó typedef mert ebben az esetben mi szükség van, hogy magukba az ötlet egy szótár, és egy szótár tartalmaz egy csomó szó, szerint közvetlenül ezt a tömböt, és hány ilyen szavak vannak? Nos, bármi ez a változó nevű Méret mondja. De csak kell egy szótár. Nem kell egy adattípust nevű szótárban. Csak kell egy közülük, így kiderül, a C hogy ha nem mondom typedef, struct mondod, majd belül a kapcsos zárójelek tegye a változókat, akkor tegye a nevet. Ez nyilvánító egy változót nevű szótár úgy néz ki, mint ez. Ezzel szemben, ezek a sorok létrehozása újrahasználható adatszerkezet nevezett Szó hozhat létre több példányt, mint hoztunk létre több példányban versenyző. Mit jelent ez végső soron lehetővé teszi számunkra, mit tegyek? Hadd menjek vissza, mondjuk, egy egyszerűbb példa egyszerűbb alkalommal, és hadd nyitni, mondjuk, compare1.c. A probléma itt kéznél van, hogy ténylegesen héjúak vissza a réteg egy string, és kezdje levette ezeket a képzési kerekek mert kiderül, hogy egy string egész idő olyan megígértük az 1. hét tényleg csak egy becenevet, szinonimájaként a CS50 könyvtár valamit, ami úgy néz ki, egy kicsit rejtélyes, char *, és láttuk ezt a csillag előtt. Láttuk azt az összefüggésben fájlokat. Nézzük most már értem, miért voltunk bujkál ezt a részletet egy ideje most. Itt van egy nevű fájlt compare1.c, és ez nyilvánvalóan felkéri a felhasználót a 2 szalagot, s és t, és akkor megpróbálja összehasonlítani a húrok egyenlőség sorban 26, és ha ők egyenlő azt mondja: "Te gépelt ugyanaz a dolog" és ha ők nem egyenlő azt mondja: "Te gépelt különböző dolog." Hadd menjek előre, és futtassa ezt a programot. Hadd menjek az én forrás könyvtárába, hogy a compare1. Az összeállított rendben. Hadd futni compare1. Én nagyítás, az enter billentyűt. Mondj valamit. HELLO. Azt mondom valami újra. HELLO. Én biztosan nem írja különböző dolog. Hadd próbáljam meg újra. BYE BYE. Határozottan nem a különböző, így mi folyik itt? Nos, mi is valójában az összehasonlított sorban 26? [Hallhatatlan-diák] Igen, így kiderül, hogy egy string, adattípus, egyfajta fehér hazugság. Egy karakterlánc egy char *, de mi egy char *? A char *, mint mondják, egy mutató, és a mutató ténylegesen a címet, összeg memóriabeli helyét, és ha történetesen beírt a szót, mint HELLO, visszahívja a korábbi viták húrok ez olyan, mint a szó HELLO. Ne feledje, hogy a szó, mint a HELLO leírható mint egy sor karakter, mint ez , majd egy különleges karakter a végén hívott a null karakter, mint a \ jelöli. Milyen valójában egy string? Vegyük észre, hogy ez a többszörös darabokat memória, és valóban, a vége csak ismertté, miután megnézi az egész szöveg keresi a különleges null karaktert. De ha ez egy darab memória a számítógép memóriájából, mondjuk önkényesen azt mondják, hogy ez a szöveg csak most szerencsés, És van elhelyezni a legelején a számítógép RAM. Ez bájt 0, 1, 2, 3, 4, 5, 6 ... Amikor azt mondom, valami ilyesmit getString és én húr s = getString mi valóban a vissza? Ezen az elmúlt néhány hét, mi valóban a tárolt s Nem ez a karakterlánc önmagában, de ebben az esetben mi is tárolják, a 0, mert mi getString valójában nem csinál A nem fizikailag vissza string. Ez még csak nem is igazán konceptuális értelemben. Mit csinál visszatérés egy szám. Ez a szám a címe HELLO a memóriában, és string s aztán, ha húzza vissza ezt a réteget, húr nem igazán létezik. Ez csak egy egyszerűsítés CS50 könyvtárban. Ez valóban egy úgynevezett char *. Char van értelme, mert mi az a szó, mint a HELLO! Nos, ez egy sor karakter, egy sor karakter. Char *: a címét egy karaktert, tehát mit is jelent, hogy visszatérjen egy string? Egy szép, egyszerű módot visszatérés egy string inkább, mint megpróbálja kitalálni, hogyan térjen vissza 5 vagy 6 különböző bytes hadd vissza a címet, amely byte? Az első. Más szóval, hadd adjak a címét egy karaktert a memóriában. Ez az, amit char * képviseli a címe egyetlen karaktert a memóriában. Hívja a változó s. Tárolja s az adott címet, amit én mondtam önkényesen 0, csak azért, hogy a dolgok egyszerű, de a valóságban ez általában egy nagyobb számot. Várj egy percet. Ha csak ad nekem a címét az első karakter, hogyan tudom, mi a címe A második karakter, a harmadik, a negyedik és az ötödik? [Hallhatatlan-diák] Csak tudja, hol a vége a húr útján ez a praktikus trükköt, így ha használja valami ilyesmit printf, milyen printf szó szerint veszi az érvet, emlékeztetni arra, hogy használja ezt a% s placeholder, majd adja át a változó, ami tárolja a string. Amit igazán halad a címe az első karakter, amely string. Printf akkor használ a hurok vagy a while ciklus, amikor megkapta ezt a címet, Például, 0, hadd tegye ezt most, printf ("% s \ n", s); Amikor hívom printf ("% s \ n", s), amit én igazán nyújt printf a cím első karaktere s, ami ebben az esetben tetszőleges H. Hogyan printf tudja, pontosan mi jelenik meg a képernyőn? Az a személy, aki végre printf végre egy while vagy for ciklus azt mondja ez karakter megegyezik a speciális null karakter? Ha nem, akkor nyomtassa ki. Mit szólsz ehhez? Ha nem nyomtassa ki, nyomtassa ki, nyomtassa ki, nyomtassa ki. Oh, ez egy különleges. Állítsa le a nyomtatást, és térjen vissza a felhasználónak. És ez szó szerint minden, ami történt a motorháztető alatt, és ez sokat megemészteni az első nap egy osztály, de most ez tényleg az építőköve minden megértés ez folyik belül a számítógép memóriájában, és végül mi kötekedik ezt leszámítva egy kis segítség az egyik barátunk a Stanford. Professor Nick Parlante Stanford tette ezt a csodálatos képsor mindenféle nyelven bevezetett ez a kis Claymation karaktert Muci. A hang fogsz hallani néhány 2. settenkedik sajtóbemutató az, hogy a Stanford professzora, és kapsz csak 5 vagy 6 másodperc e most, de ez a megjegyzés, amely fogunk kötni ma és kezdődik szerdán. Adok Pointer Fun Muci, az előnézet. [♪ ♪ Music] [Professor Parlante] Hey, Muci. Kelj fel. Itt az ideje a mutató fun. [Muci] Mi ez? Tudjon meg többet a mutatók? Oh, nagyszerű! Fogjuk látni szerdán. [CS50.TV]