[Powered by Google Translate] [4. szakasz - További Kényelmes] [Rob Bowden - Harvard University] [Ez CS50. - CS50.TV] Van egy kvíz holnap, abban az esetben, ha a srácok nem tudja, hogy. Ez alapvetően mindent, amit látott az osztályban, vagy kellett volna az osztályban. Ez magában foglalja a mutató, annak ellenére, hogy egy nagyon friss téma. Meg kell legalább megértetni a magas szintű őket. Bármi, ami eltűnt több osztályba meg kell értened a kvíz. Tehát, ha kérdése van rájuk, akkor kérje meg őket most. De ez lesz egy nagyon diákok által vezetett ülésen, ahol a srácok kérdéseket feltenni, így remélhetőleg az emberek kérdéseire. Van valakinek kérdése? Igen. >> [Hallgató] Tud megy át mutatókat újra? Odamegyek mutatók. Minden a változók szükségszerűen él a memóriában, de általában ne aggódj, és mondod x + 2 és y + 3 és a fordító fog kitalálni, ahol a dolgok élnek az Ön számára. Ha dolgunk mutató, most meg kifejezetten használ a memória címeket. Így egy egyetlen változó csak mindig élőben egyetlen cím bármely adott időben. Ha azt akarjuk, hogy állapítsa meg a mutató, ami a típus fog kinézni? Azt akarom, hogy állapítsa meg a mutató p. Mit jelent a típus néz ki? [Hallgató] int * p. >> Igen. Így int * p. És hogyan teszik mutatni x? >> [Hallgató] jelet. [Bowden] Szóval jelet szó szerint nevezik címét üzemeltető. Tehát amikor azt mondom & x ez egyre a memória címét a változó x. Így most már a mutató p, és bárhol kódomat tudom használni * p vagy én jönne x és ez lesz pontosan ugyanaz a dolog. (* P). Mit keres ez? Mit jelent, hogy a csillag jelent? [Hallgató] Ez azt jelenti, az érték ezen a ponton. >> Igen. Tehát, ha azt nézzük, akkor nagyon hasznos lehet, hogy dolgozzon ki a diagramok ha ez egy kis doboz memória x, ami történik, hogy az érték 4, akkor van egy kis doboz memória p, és így p pontok x, így felhívni egy nyilat p x. Tehát amikor azt mondjuk, * p mondunk megy a doboz, p. Star követi a nyilat, majd csinálsz, amit akarsz, hogy a dobozban ott. Így azt mondhatom, * p = 7, és hogy fog menni a dobozt, hogy az x és a változás, hogy a 7-re. Vagy azt is mondhatnám int z = * p * 2; ez zavaró, mert a csillag, star. Az egyik csillag dereferencing p, a másik csillag megszorozzuk 2-vel. Figyeljük meg tudtam volna éppúgy helyébe a * p az x. Használhatod őket ugyanúgy. Aztán később azt lehet p pont egy teljesen új dolog. Én csak azt mondom p = &z; Tehát most már nem p pontok x, ez mutat z. És minden alkalommal, amikor ezt * p, hogy ez ugyanaz, mint csinál z. Így a hasznos dolog ez egyszer elkezdünk bekerülni funkciókat. Elég haszontalan, hogy nyilvánítson egy mutató, amely rámutat arra, hogy valami és akkor még csak azt dereferencing ha volna használni az eredeti változót kezdeni. De ha bejutni funkciók - így mondjuk van néhány funkció, int foo, hogy vesz egy mutató, és csak nem * p = 6; Mint láttuk, mielőtt a csere, akkor nem hatékony swap és külön funkció mellett csak múló egész, mert minden a C mindig elhaladó értéket. Még ha éppen elhaladó pointers te elhaladó értéket. Ez csak azért történik, hogy ezek az értékek memória címeket. Tehát amikor azt mondom foo (p) Én halad a mutató a function ize majd a foo csinál * p = 6; Szóval belül ilyen funkciót, * p még mindig egyenértékű x, de én ezért nem használhatja x belsejébe, hogy a funkció, mert nem hatókörű belül funkciót. Szóval * p = 6 az egyetlen módja tudok hozzá egy helyi változót egy másik funkció. Vagy, nos, pointerek az egyetlen módja tudok hozzá egy helyi változót egy másik funkció. [Hallgató] Tegyük fel, hogy vissza akart térni a mutató. Pontosan hogyan csinálod ezt? [Bowden] vissza a mutatót, mint valami hasonlót int y = 3; visszatérés & y? >> [Hallgató] Igen. [Bowden] Oké. Soha ne tegye ezt. Ez rossz. Azt hiszem, láttam ilyen előadás diák elkezdte látni az egész diagram a memória ahol akár itt megvan memória cím 0 és itt lent van memóriacím 4 koncertek vagy a 2 a 32. Akkor neked néhány dolgot, és néhány dolgot, és akkor már a stack és megvan a halom, amit most kezdett tanulni, felnőni. [Hallgató] Nem a halom felett stack? Igen. A kupac tetején, nem igaz? >> [Hallgató] Nos, tette 0 a tetején. [Hallgató] Oh, tette 0 a tetején. >> [Hallgató] Ó, oké. Jogi nyilatkozat: bárhol CS50 fogod látni, hogy ezen a módon. >> [Hallgató] Oké. Csak arról van szó, amikor 1. látta halom, szeretném, ha úgy gondolja, egy rakás gondol egymásra dolgokat egymás tetejére. Ezért hajlamosak vagyunk a flip e körül, így a verem nő fel, mint egy halom a megszokott módon ahelyett, hogy a köteg lóg le. >> [Hallgató] Ne halmok műszakilag felnőni is, igaz? Ez attól függ, mit értesz felnőni. A stack és heap mindig nő ellentétes irányban. A stack mindig nő fel abban az értelemben, hogy ez felnövő a magasabb memória címek, és a kupac egyre lefelé az, hogy ez egyre nagyobb az alacsonyabb memória címeket. Így a felső értéke 0 és az alsó nagy memória címeket. Ők mind a növekvő, csak ellentétes irányban. [Hallgató] Én csak azt jelentette, hogy azért, mert azt mondta, hogy fel stack az alsó mert úgy tűnik, sokkal intuitívabb mert a köteget kezdeni a tetején egy halom, kupac van a tetején önmagában is, így ez - >> Igen. Azt is gondolom, a halom, mint nőnek fel, és nagyobb, de a verem inkább. Tehát a verem az, hogy mi a fajta akarjuk mutatni felnőni. De mindenhol nézel másként fog mutatni a 0 címet a tetején és a legmagasabb memória cím az alján, így ez a szokásos kilátás memória. Van kérdése? [Hallgató] Elmondanád bővebben a kupac? Igen. Majd kap, hogy egy második. Először is, hogy miért megy vissza visszatérő és y egy rossz dolog, A verem van egy csomó köteg kereteket, amelyek képviselik az összes funkció amelyeket hívott. Szóval, figyelmen kívül hagyva a korábbi dolgokat, a tetején a verem mindig lesz a fő funkciója mivel ez az első funkció ez, hogy hívják. És amikor hívod másik funkció, a verem fog nőni lefelé. Tehát, ha hívom néhány funkció, ize, és ez lesz a saját stack frame, akkor hívhatjuk néhány funkció, bár, ez lesz a saját stack frame. És bár lehet, rekurzív és ez lehet hívni magát, és hogy a második hívást, hogy bar fog kapni a saját stack frame. És így, mi folyik ezeken a stack frame mind a lokális változók és az összes a függvény érvek - Minden olyan dolog, ami helyileg hatókörű ezt a funkciót menni ezen stack kereteket. Tehát ez azt jelenti, amikor azt mondtam, valami hasonlót bár egy olyan funkció, Én csak úgy állapítsa egész, majd visszatér a mutatót, hogy az egészre. Szóval, ha nem y él? [Hallgató] y él bar. >> [Bowden] Igen. Valahol ebben a kis négyzet memória egy Littler négyzet, amely y benne. Amikor visszatér és y, én vissza a mutatót ez a kis blokk memória. De aztán, amikor egy függvény visszatér, a verem kocka bukkant ki a köteget. És ezért hívják verem. Ez olyan, mint a verem adatszerkezet, ha tudod, mi az. Vagy akár, mint egy köteg tálcák mindig a példában Fő fog menni az alsó, majd az első funkció hívás fog menni a tetején, hogy a és akkor nem kap vissza a főoldalra, amíg vissza nem tér az összes funkciót, amely már az úgynevezett hogy kerültek a tetején. [Hallgató] Szóval, ha te ezt vissza és y, ez az érték van kitéve értesítés nélkül változhatnak. Igen, ez - >> [hallgató] Ez lehet felülírni. >> Igen. Ez teljesen - Ha megpróbálja, és - Ez is egy int * bar mert ez visszatérő a mutató, így a visszatérési típusa int *. Ha megpróbálja használni a visszatérési értéke ez a funkció, ez nem definiált viselkedést mert ez a mutató rossz memória. >> [Hallgató] Oké. Szóval, mi lenne, ha, például, ha bejelentett int * y = malloc (sizeof (int))? Így már jobb. Igen. [Hallgató] Beszéltünk arról, hogy hogyan, mikor húzza a dolgokat a kukába ők valójában nem törlik, mi csak elveszítik a mutatók. Tehát ebben az esetben tudunk valójában az érték törléséhez, vagy ez még mindig ott van a memóriában? A legtöbb esetben, ez lesz, hogy még mindig ott van. De tegyük fel, hogy mi történik, hogy hívja néhány más funkció, BAZ. Baz fog kapni a saját stack frame itt. Ez lesz felülírja az összes ezt a cuccot, majd ha később megpróbálja használni a mutatót, hogy van korábban, ez nem lesz ugyanaz az értéke. Ez lesz változott csak azért, mert az úgynevezett funkciót BAZ. [Hallgató] De még mi nem, akkor még mindig kap 3? [Bowden] Minden valószínűség szerint, ha lenne. De nem hivatkozhat erre. C Csak mondja definiált viselkedést. [Hallgató] Ó, igen. Oké. Tehát, ha vissza akar térni a mutatót, ez az, ahol malloc jön használatban. Írok valójában csak vissza malloc (3 * sizeof (int)). Menjünk át malloc látna egy második, de az ötlet malloc minden a helyi változók mindig megy a verem. Bármi, ami malloced megy a kupac, és ez örökké, és mindig a heap amíg kifejezetten nem szabad azt. Tehát ez azt jelenti, hogy ha malloc valamit, hogy fog túlélni után a függvény. [Hallgató] Vajon túléli után a program leáll? No. >> Oké, így lesz, amíg a program végig kész fut. >> Igen. Mi megy át részleteket, hogy mi történik, amikor a program leáll. Lehet, hogy emlékeztessen, de ez egy külön dolog teljesen. [Hallgató] Szóval malloc létrehoz egy pointer? >> Igen. Malloc - >> [hallgató] Azt hiszem malloc kijelöl egy memória blokkot, hogy a mutató használható. [Bowden] Azt akarom, hogy a diagram újra. >> [Hallgató] Szóval ez a funkció működik, igaz? [Hallgató] Ja, malloc jelöl egy memóriablokkot, hogy tudod használni, majd visszatér a címe az első blokk, hogy a memória. [Bowden] Igen. Tehát, ha malloc, akkor megragadta néhány memóriablokkot ez jelenleg a kupac. Ha a heap túl kicsi, akkor a halom éppen fog nőni, és ez növekszik ebben az irányban. Tehát mondjuk a heap túl kicsi. Akkor ez hamarosan nőni egy kicsit, és térjen vissza a mutatót ebben a mondatban, hogy csak nőtt. Ha ingyenes cucc, te hogy több hely a halom, így aztán egy későbbi telefonáljon a malloc tudja használni, hogy a memóriát, amit korábban felszabadította. Az a fontos dolog malloc és free, hogy ad teljes ellenőrzése élettartama ezeknek memória blokkokat. A globális változók mindig életben van. A helyi változók él e rendelkezések hatálya alá. Amint megy az elmúlt egy kapcsos zárójel, a helyi változók halott. Malloced emlékezet életben van, ha azt szeretné, hogy életben majd szabadul, amikor mondja, hogy fel kell szabadítani. Ezek valójában csak 3 típusú memória, tényleg. Van automatikus memória kezelése, ami a verem. Dolgok történnek automatikusan. Amikor azt mondja, int x, memóriát int x. Ha x kimegy a hatálya, memória regenerált az x. Aztán ott van a dinamikus memória kezelése, ami pedig malloc van, ami, ha van ellenőrzés. Ön dönti el, mikor dinamikusan memóriát kell, és nem kell felosztani. És akkor ott van a statikus, ami éppen azt jelenti, hogy él örökké, ami pedig a globális változók. Ők csak mindig a memóriában. Kérdései vannak? [Hallgató] Tud meg a blokk éppen használatával kapcsos zárójelek azonban nem rendelkezik, hogy egy if vagy while, vagy ilyesmi? Megadhatunk egy blokk, mint egy funkció, de ennek kapcsos zárójelek is. [Hallgató] Szóval nem lehet csak úgy tekintette, mint egy véletlen pár kapcsos zárójel a kódban amelyek lokális változók? >> Igen, lehet. Belül int bár tudtuk, hogy {int y = 3;}. Ez kéne, hogy igaza van. De ez teljesen hatályát határozza meg int y. Utána a második göndör merevítő, y nem használható többé. Majdnem soha nem, hogy mégis. Visszatérve, hogy mi történik, ha a program véget ér, van egyfajta tévhit / half hazugságot, hogy adunk ahhoz, hogy csak megkönnyítené a dolgokat. Azt mondjuk nektek, hogy ha memóriát Ön elosztásának néhány darabja a RAM, hogy változó. De te nem igazán közvetlenül érintő RAM valaha a programokat. Ha belegondolok, hogy én rajzoltam - És valóban, ha átmegy a GDB látni fogod, ugyanaz a dolog. Függetlenül attól, hogy hányszor fut a program, illetve milyen programot futtat, a verem mindig fog kezdeni - te mindig fog látni változók körül címet oxbffff valamit. Ez általában valahol a régióban. De hogyan lehet 2 program esetleg van mutatókat azonos memória? [Hallgató] Van valami önkényes kijelölése, ahol oxbfff állítólag a RAM hogy is lehet különböző helyeken attól függően, hogy a funkció nevezték. Igen. A kifejezés a virtuális memória. Az elképzelés az, hogy minden egyes folyamat, minden egyes program, amely fut a számítógépen saját - tegyük fel, 32 bit - teljesen független címtartomány. Ez a címtartomány. Megvan a saját teljesen független 4 gigabájt használni. Tehát, ha futtatni 2 programot párhuzamosan, ez a program úgy látja, 4 gigabyte magának, ez a program úgy látja, 4 gigabyte magának, és lehetetlen, hogy e program dereference a mutatót és a végén a memória el ezt a programot. És mi a virtuális memória egy leképezés a folyamatok címtartomány tényleges dolgokat RAM. Tehát akár az operációs rendszer tudni, hogy Hé, mikor ez a fickó dereferences pointer oxbfff, hogy valójában azt jelenti, hogy ő akar RAM byte 1000, mivel ha ez a program dereferences oxbfff, hogy tényleg akar RAM byte 10000. Lehetnek tetszőlegesen távol egymástól. Ez még akkor is igaz, a dolgok egyetlen folyamatok címtartomány. Szóval, mint látja mind a 4 gigabyte magának, hanem mondjuk - [Hallgató] Vajon minden egyes folyamat - Tegyük fel, hogy van egy számítógép, csak 4 GB RAM-mal. Vajon minden egyes folyamat látni az egész 4 gigabyte? >> Igen. De a 4 gigabájt látja hazugság. Ez csak azt hiszi, hogy az összes ezt a memóriát, mert nem ismerek más eljárás létezik. Ez csak használni sok memóriát, mint amilyen valójában szüksége van. Az operációs rendszer nem fogja adni RAM ennek a folyamatnak ha ez nem használ semmilyen memória az egész régióban. Ez nem fog adni neki memóriát a régióban. De az ötlet, hogy - próbálok arra gondolni - nem tudok gondolni egy hasonlat. Analógiák nehéz. Az egyik kérdés a virtuális memória, vagy az egyik dolog, ez megoldás az, hogy a folyamatok teljesen tisztában egymást. És így írhatsz bármilyen program, hogy csak dereferences bármely mutató, mint csak írni egy programot, amely azt mondja, * (ox1234) és ez dereferencing memória cím 1234. De ez fel az operációs rendszert, majd lefordítani, amit 1234 jelent. Tehát, ha 1234 történik, hogy egy érvényes memóriacím ezt a folyamatot, mintha ez a verem, vagy valami, akkor ez vissza fog térni az értékét, hogy a memória cím amennyire a folyamat tudja. De ha 1234 nem egy érvényes címet, mint ez történik a partra néhány kis darab memória itt, hogy túl van a verem, és azon túl a heap , és még nem igazán használható, hogy akkor ez, ha kap ilyeneket segfaultol mert te megható memóriát, hogy nem kell érjen. Ez akkor is igaz - A 32-bites rendszer, 32 bit azt jelenti, hogy 32 bites, hogy meghatározzák a memória címet. Ez az, amiért pointers 8 bájt, mert 32 bit 8 bájt - vagy 4 bájt. Mutatók a 4 byte. Tehát, ha látsz egy mutatót, mint oxbfffff, azaz - Keretében adott programban, ha csak építeni tetszőleges mutató, bárhol ox0 az ökör 8 f's - ffffffff. [Hallgató] Nem azt mondtad, ők 4 byte? >> Igen. [Hallgató] Ezután minden byte lesz - >> [Bowden] Hexadecimális. Hexadecimális - 5, 6, 7, 8. Szóval pointers fogsz mindig látni hexadecimális. Csak hogyan osztályozzák mutatók. Minden 2 jegyű hexadecimális értéke 1 byte. Tehát ott lesz 8 hexadecimális számjegy, 4 bájt. Tehát minden egyes mutató a 32-bites rendszer lesz 4 byte, ami azt jelenti, hogy a folyamat lehet építeni önkényes 4 bájt és egy mutatót belőle, ami azt jelenti, hogy amennyire ez tudomása, akkor kezelni egy egész 2 a 32 bájt memóriát. Annak ellenére, hogy nem igazán férhet hozzá, hogy a még akkor is, ha a számítógép csak 512 megabájt, azt hiszi, hogy van, hogy mennyi memória. És az operációs rendszer elég okos ahhoz, hogy ez csak akkor nyújtanak amire valójában szüksége van. Ez nem csak menj, oh, egy új folyamat: 4 koncertek. Igen. >> [Hallgató] Mit jelent az ökör jelent? Miért írsz meg? Ez csak a szimbólum hexadecimális. Ha látsz egy számot kezdődik ökör, az egymást követő dolgok hexadecimális. [Hallgató] Maga elmagyarázza, hogy mi történik akkor, ha a program véget ér. >> Igen. Mi történik, ha a program véget ér az operációs rendszer csak törli a leképezések, hogy rendelkezik az ezeket a címeket, és ennyi. Az operációs rendszer már csak így, hogy a memória egy másik program használja. [Hallgató] Oké. Tehát, ha valami kiosztani a halom, vagy a kéményből vagy globális változók, vagy ilyesmi, ők minden csak eltűnik, amint a program vége mert az operációs rendszer most szabad adni, hogy a memória más folyamat. [Hallgató] Annak ellenére, hogy valószínűleg még értékeket írva? >> Igen. Az értékek valószínűleg még mindig ott van. Ez csak akkor lesz nehéz, hogy őket. Ez sokkal nehezebb, hogy őket, mint az, hogy egy törölt fájl mert a törölt fájl fajta ül ott egy hosszú idő, és a merevlemez-meghajtó sokkal nagyobb. Így fog felülírni különböző részein a memória előtt történik, hogy felülírja a darab memória, hogy a fájl alkalmazott lenni. De a fő memória, RAM, a ciklus egy sokkal gyorsabb, így fog nagyon gyorsan lehet felülírni. Kérdések az ezen vagy bármi mást? [Hallgató] Van kérdése van egy másik téma. >> Oké. Van valakinek kérdése ezzel kapcsolatban? Oké. Különböző téma. >> [Hallgató] Oké. Mentem keresztül néhány gyakorlati teszteket, és az egyik közülük, hogy beszélt a sizeof és az érték, hogy visszatér, vagy különböző változó típusok. >> Igen. És azt mondta, hogy mind a két int és a hosszú megtérülési 4, így mindketten 4 byte hosszú. Van-e különbség az int, és egy hosszú, vagy ez ugyanaz a dolog? Igen, van egy különbség. A C standard - Én valószínűleg meg is összezavar. A C szabvány, mint amit a C, a hivatalos dokumentáció C. Ez az, amit mond. Tehát a C szabvány, csak azt mondja, hogy a char örökre és mindig 1 byte. Minden, azután, hogy az - a rövid mindig csak a meghatározás szerint nagyobb, vagy egyenlő, mint egy kar. Erre akkor lehet szigorúan nagyobb, mint, de nem pozitív. Int éppen meghatározás szerint nagyobb, vagy egyenlő, mint egy rövid. És hosszú éppen meghatározás szerint nagyobb, vagy egyenlő, mint egy int. És egy hosszú, hosszú nagyobb vagy egyenlő, mint egy hosszú. Tehát az egyetlen dolog, amit a C szabvány meghatározza a relatív rendelni mindent. A tényleges memória, hogy a dolgok megkezdésének általában legfeljebb végrehajtását, de ez elég jól definiált ezen a ponton. >> [Hallgató] Oké. Tehát rövidnadrág szinte mindig lesz 2 bájt. Ints szinte mindig lesz 4 bájt. Long long szinte mindig lesz 8 bájt. És arra vágyik, hogy attól függ, hogy te egy 32-bites vagy 64-bites rendszer. Tehát egy hosszú fog megfelelnek a rendszer típusa. Ha használja a 32-bites rendszer, mint a gép, ez lesz 4 bájt. Ha használja a 64-bites, mint egy csomó a legutóbbi számítógépek, ez lesz 8 bájt. Ints szinte mindig 4 bájt ezen a ponton. Long long szinte mindig 8 bájt. A múltban, ints használt, hogy csak akkor 2 bájt. De észre, hogy ez teljes mértékben megfelel mindezen kapcsolatok nagyobb és egyenlő. Mindaddig, amíg tökéletesen megengedett, hogy az azonos méretű, mint egy egész szám, és ez is lehetővé tette, hogy az azonos méretű, mint egy hosszú, hosszú. És ez csak azért történik, hogy lehet, hogy a 99,999%-os rendszerek, ez lesz egyenlő vagy egy int, vagy egy hosszú, hosszú. Ez csak attól függ, hogy 32-bites vagy 64-bites. >> [Hallgató] Oké. Az úszók, hogyan tizedespont kijelölt szempontjából bit? Mint bináris? >> Igen. Önnek nem kell tudni, hogy a CS50. Még csak nem is tanulnak, hogy a 61. Nem tanulnak, hogy tényleg minden tanfolyamot. Ez csak egy képviseletet. Elfelejtettem a pontos bit veteményeskertek. Az az elképzelés, lebegőpontos, hogy te kiosztani egy bizonyos számú bitet, hogy képviselje - Alapvetően, minden tudományos jelöléssel. Szóval kiosztani egy bizonyos számú bitet, hogy képviselje a szám maga, mint 1,2345. Én soha nem képviselnek több számjegy 5-nél. Akkor is jelöl egy bizonyos számú bitet úgy, hogy inkább legyen, mint akkor csak megy egy bizonyos számot, mint például ez a legnagyobb kitevő akkor van, és akkor csak menj le egy bizonyos kitevő tetszik ez a legkisebb kitev lehetőség van. Nem emlékszem a pontos módját bit hozzárendelve az összes ezeket az értékeket de egy bizonyos számú bitet szentelt 1,2345, másik bizonyos számú bit elkötelezett a kitevő és ez csak akkor lehetséges, hogy képviselje exponens egy bizonyos méretet. [Hallgató] És egy kettős? Olyan, mint egy extra hosszú float? >> Igen. Ez ugyanaz, mint a float kivéve, most meg a 8 bájt helyett 4 byte. Most akkor hogy képes legyen használni 9 számjegy vagy 10 számjegy, és ez lesz képes menni akár 300 100 helyett. >> [Hallgató] Oké. És úszók is 4 byte. >> Igen. Nos, újra, valószínűleg attól átfogó általános végrehajtására, de úszók a 4 byte, kétágyas Jelenleg 8. Páros nevezzük dupla, mert dupla méretű úszók. [Hallgató] Oké. És ott vannak dupla páros? >> Nincsenek. Azt hiszem - >> [hallgató] Like hosszú long? >> Igen. Nem hiszem. Igen. [Hallgató] A tavalyi teszt volt egy kérdés, ami a fő funkciója tekintettel is részt vesz a programban. A válasz az volt, hogy nem kell részt venni a programban. Milyen helyzetben? Ez az, amit láttam. [Bowden] Úgy tűnik - >> [hallgató] Mi helyzet? Megvan a probléma? >> [Hallgató] Igen, én is határozottan húzza fel. Nem kell, technikailag, de alapvetően ez lesz. [Hallgató] láttam egyet egy másik év. Olyan volt, mint igaz vagy hamis: Egy érvényes - >> Oh, a. C fájlt? [Hallgató] Minden. C fájlban kell, hogy - [a két beszélő egyszerre - érthetetlen] Oké. Szóval ez külön. A. C fájl csak tartalmaznia kell funkciókat. Tudod összeállít egy fájlt gépi kód, bináris, bármi, anélkül, hogy futtatható még. Egy érvényes végrehajtható kell a fő funkciója. Írhat 100 funkciók 1 fájl, de nem fő majd fordítani, hogy le bináris, akkor írjunk egy fájlt, csak fő, de felhívja egy csomó ezeket a funkciókat e bináris fájl itt. És amikor így végrehajtható, ez az, amit a linker nem van az, egyesíti ezeket a 2 bináris fájlokat egy futtatható. Tehát a. C fájl nem kell, hogy a fő funkciója egyáltalán. És nagy-kód bázisok látni fogod, több ezer. C fájlok és 1 fő fájlt. További kérdések? [Hallgató] Volt egy másik kérdés. Azt mondta, hogy egy fordító. Igaz vagy hamis? És a válasz hamis volt, és megértettem, hogy miért nem olyan, mint csenget. De mit nevezünk, hogy ha ez nem? Győződjön meg alapvetően csak - Látom, mit nevez meg. De ez csak fut parancsokat. Győződjön meg. Tudom húzni ezt. Igen. Ó, igen. Győződjön meg is csinálja. Ez azt mondja, a célja a make segédprogram meghatározni automatikusan amely darab egy nagy program kell újrafordítani és kiadja a parancsokat újrafordítani őket. Tudod, hogy hogy a fájlok teljesen hatalmas. Érezd néz a időbélyegeket fájlok, és mint azt már korábban említettük, tudja fordítani az egyes fájlokat le, és ez nem, amíg nem kap a linker hogy ők össze egy futtatható. Tehát, ha 10 különböző fájlokat, és csinál változás 1 őket, akkor mi make fog tenni csak újrafordítás, hogy 1 fájl és utána átszerkeszthesse mindent együtt. De ez sokkal ostobább, mint ezt. Ez rajtad múlik, hogy teljesen meg, hogy ez mit kell tennie. Ez alapértelmezésben a képességét, hogy ismerje el ezt időbélyegző cucc, de akkor írj egy make fájlt semmit. Írhatsz egy make fájlt, így amikor begépeli hogy ez csak a CD egy másik könyvtárba. Kezdtem csalódott, mert mindent tack belsejében az én Appliance és aztán többet a PDF a Mac. Szóval megy Finder és én nem megy, Connect to Server, és a szerver I csatlakozni az én Appliance, aztán megnyitja a PDF hogy lesz összeállított LaTeX. De én egyre csalódott, mert minden egyes alkalommal, amikor szükség van, hogy frissítse a PDF, Kellett másolni egy adott könyvtárba lehetett elérni és azt egyre bosszantó. Tehát ahelyett, hogy írtam egy make fájlt, amelyben meg kell határozni, hogyan teszi a dolgokat. Hogyan csinál ebben a PDF LaTeX. Csakúgy, mint minden más gyártmányt fájlt, vagy - Azt hiszem, még nem látta a make fájlokat, de van a gép egy globális márka fájlt, hogy csak azt mondja, ha összeállításának C fájlt, használja csenget. És itt van az én make fájlban teszek mondom, ezt a fájlt fogsz kíván fordítani a PDF LaTeX. És ez így van a PDF LaTeX hogy csinál a fordítás. Győződjön meg nem összeállításánál. Ez csak futó ezeket a parancsokat a sorozatban I megadva. Így fut PDF LaTeX, akkor azt bemásolja a könyvtárat Azt akarom, hogy kell másolni, ez a cd a könyvtárba, és nem más dolog, de ez nem az elismerését, ha egy fájl megváltozik, és ha megváltoztatja, akkor fog futni a parancsokat, hogy kéne futtatni a fájl változásokat. >> [Hallgató] Oké. Nem tudom, hol a globális márka fájlok nekem, hogy nézd meg. Egyéb kérdés? Bármi korábbi vetélkedők? Minden mutató dolgokat? Vannak apró dolgok, mint a mutató - Én nem lesz képes megtalálni a kvíz kérdés, hogy - de csak, mint ez a fajta dolog. Győződjön meg arról, hogy érti, amikor azt mondom int * x * y - Ez nem éppen itt semmit, azt hiszem. De mint * x * y, azok 2 változó, amelyek a verem. Amikor azt mondom, x = malloc (sizeof (int)), x még mindig változó a stack, malloc van néhány mondat át a halom, és mi tekintettel x ponttól a kupac. Tehát valami a veremben pont a kupac. Amikor malloc valamit, akkor óhatatlanul tárolja belsejében egy mutató. Annak érdekében, hogy pointer van a verem, a malloced blokk van a kupac. Sokan összezavarodnak, és azt mondják int * x = malloc, x van a kupac. Ne. Mit x mutat van a kupac. x maga a verem, kivéve, ha valamilyen oknál fogva már x egy globális változó, ebben az esetben történik, hogy egy másik régióban memória. Így nyomon követése, ezek a doboz és a nyíl diagramok elég gyakori a kvíz. Vagy ha ez nem kvíz 0, akkor lesz a kvíz 1. Tudnia kell, hogy az összes ilyen, a lépések összeállításában mivel meg kellett, hogy kérdésekre válaszoljon ezekre. Igen. [Hallgató] sikerült menjünk át ezeket a lépéseket - >> Persze. Mielőtt lépések és összeállítása van előfeldolgozás, összeállítása, összeszerelés, és összekapcsolása. Előfeldolgozó. Mit tegyek? Ez a legegyszerűbb lépés - nos, nem úgy, mint - ez nem jelenti azt, hogy nyilvánvalónak kellene lennie, de ez a legegyszerűbb lépés. Ti is végrehajtja magatokat. Igen. [Hallgató] Vegyünk mi van a részét, mint ez, és másolja és akkor is meghatározza. Úgy néz ki a dolgok, mint a # include és # define, és ez csak másolatok és paszták mik azok valójában jelent. Tehát, ha azt mondod: # include cs50.h az előfeldolgozó a másolás és beillesztés cs50.h abba a vonalat. Amikor azt mondod # define x legyen 4, az előfeldolgozó megy keresztül az egész programot és felváltja az összes példányait x, 4. Tehát a előfeldolgozó vesz egy érvényes C fájlt, és kiad egy érvényes C fájl ahol a dolgok már a vágólapra másolni. Tehát most összeállításában. Mit tegyek? [Hallgató] Ez megy C bináris. [Bowden] Ez nem megy egészen a bináris. [Hallgató] A gépi kódot, majd? >> Ez nem gépi kódot. [Hallgató] Assembly? >> Közgyűlésnek. Megy összeszerelés előtt megy egészen a C kód, és a legtöbb nyelven ilyet. Válassz olyan magas szintű nyelv, és ha akarsz fordítani, ez valószínűleg összeállításához lépésenként. Először fog összeállítani Python a C, akkor fog összeállítani C Közgyűlés majd a Közgyűlés megy kap lefordítva a bináris. Szóval összeállítása fogja hozni azt a C és Assembly. A szó összeállításának általában azt jelenti, így azt egy magasabb szintű egy alacsonyabb szintű programozási nyelv. Szóval ez az egyetlen lépés összeállítás, ahol kezdeni egy magas szintű nyelv és a végén egy alacsony szintű nyelv, és ezért a lépést nevezik összeállításában. [Hallgató] összeállítása során, mondjuk, hogy tettél # include cs50.h. Vajon a fordító újrafordítani a cs50.h, mint a funkciók, amelyek ott, és lefordítani, hogy a közgyűlés kódot is, vagy fog másolja valamit, ami volt pre-közgyűlés? cs50.h fog nagyjából soha végén a közgyűlés. Stuff, mint a függvény prototípusokat, és a dolgok csak az Ön számára, hogy legyen óvatos. Ez garantálja, hogy a fordító megtekintéséhez dolgokat, mint te hívásfunkciók a megfelelő visszatérési típusa és a megfelelő érveket, meg ilyesmi. Szóval cs50.h kerül előfeldolgozott a fájlt, majd amikor ez összeállítása ez gyakorlatilag kidobott miután gondoskodik arról, hogy mindent hívott helyesen. De a funkciók meghatározott CS50 könyvtár, amelyek elkülönülnek cs50.h, ezek nem lesznek külön összeállítani. Ez valóban lejön az összekötő lépésben, így lesz, hogy, hogy egy második. De először is, mi összeszerelés? [Hallgató] Assembly bináris? >> Igen. Összeszerelése. Nem nevezném összeállításáért mert Assembly nagyjából tiszta fordítását bináris. Nagyon kevés logika megy a Közgyűlést, hogy bináris. Olyan, mint keresi fel egy táblában, ó, mi ezt az utasítást; amely megfelel a bináris 01.110. És így a fájlok összeszerelés általában kimenetek. O fájlokat. És. O fájlokat amit mondunk előtt, , hogy egy fájl nem kell, hogy egy fő funkció. Minden fájl lehet összeállítani le a. O fájlt, amíg ez egy érvényes C fájl. Meg lehet összeállítani le. O. Most össze, ami valójában hoz egy csomó. O fájlokat, és hozza őket, hogy egy végrehajtható. És akkor mi linking csinál, akkor véleményed a CS50 könyvtár a. O fájlt. Ez egy már lefordított bináris fájlt. És amikor fordítod a fájlt, a hello.c, amely felszólítja getString, hello.c lesz összeállítani le hello.o, hello.o most bináris. Használ getString, ezért szükséges, hogy menjen át a cs50.o, és a linker smooshes őket együtt, és másolja getString ebbe a fájlba és jön ki egy végrehajtható, amely minden funkcióját van szüksége. Tehát cs50.o valójában nem egy O fájlt, de elég közel, hogy nincs alapvető különbség. Szóval csak össze hoz egy csomó kép együtt hogy a külön-külön tartalmazza az összes olyan funkciót szeretnék használni és létrehozza a futtatható, hogy valóban működik. És így ez is, amit mondunk, mielőtt ahol lehet 1000. c fájlokat, akkor fordítani őket, hogy. o fájlokat, ami valószínűleg eltart egy ideig, akkor módosítsa 1. c fájlt. Csak akkor kell újrafordítani, hogy 1. C fájlt, majd újracsatolása minden mást, kapcsolja vissza mindent együtt. [Hallgató] Ha mi össze írunk lcs50? Igen, úgy lcs50. Ez a zászló jelzi a linker, hogy meg kell összekapcsolása a könyvtárban. Kérdései vannak? Már mi ment át bináris eltérő 5 másodperc az első előadás? Nem hiszem. Tudnia kell, hogy az összes nagy Os, hogy már elment felett, és képesnek kell lennie arra, ha adott egy funkciót, akkor képesnek kell lennie arra, hogy azt mondják, hogy ez nagy O, nagyjából. Vagy jól, nagy O durva. Szóval, ha látod a beágyazott hurok hurok alatt azonos számú dolog, mint például int i, i > [hallgató] n faragva. >> Úgy látszik, hogy n négyzeten. Ha háromágyas beágyazott, akkor hajlamos arra, hogy n felkockázva. Szóval ez a fajta dolog, amit meg kell tenni, hogy rámutatni azonnal. Tudnod kell, beillesztés sort és buborék rendezés és egyesítése fajta és az összes ilyen. Ez könnyebb megérteni, hogy miért ők azok n négyzet és n log n, és minden e mert azt hiszem, volt egy kvíz egyéves, ahol alapvetően adtam neked végrehajtási buborék sort, és azt mondta: "Mi a futási idejét ezt a funkciót?" Tehát, ha elismerik, hogy buborék rendezés, akkor azonnal mondani n faragva. De ha csak megnézzük, akkor nem is kell ismernünk, hogy a buborék rendezés; akkor csak mondom ezt csinálja ezt és ezt. Ez n faragva. [Hallgató] Vannak olyan nehéz példákat akkor jön fel, mint egy hasonló ötlet kitalálni? Nem hiszem, hogy mi lenne Önnek bármilyen kemény példákat. A buborék fajta dolog körülbelül olyan kemény, mint szeretnénk menni, sőt, hogy mindaddig, amíg érted, hogy te iterációjával az array egyes eleme a tömb, ami lesz valami, ami n faragva. Vannak általános kérdések, mint itt van - Oh. Csak a minap, Doug azt állította: "Én már kitalált egy algoritmust, amely rendezni egy tömb "N számok O (log n) idő!" Akkor honnan tudjuk, hogy ez lehetetlen? [Hallhatatlan diák válasza] >> Igen. Legalább meg kell érjen minden elem a tömbben, így lehetetlen rendezni egy sor - Ha minden rendben van rendezetlen sorrendben, akkor leszel megható mindent a tömb, így lehetetlen csinálni kevesebb mint O n. [Hallgató] Megmutatta nekünk, hogy például, hogy képes csinálni O n ha olyan sok memóriát. >> Igen. És ez - Nem emlékszem, mi ez - Vajon számláló sort? Hmm. Ez egy egész szám válogató algoritmus. Kerestem a különleges nevet az, hogy én nem emlékszem a múlt héten. Igen. Ezek a típusok a fajta, amely képes elvégezni a dolgok nagy O n. De vannak korlátai, mint csak akkor használható, egész egy bizonyos számot. Plusz, ha akarsz rendezni valamit ez - Ha a tömb 012, -12, 151, 4 millió akkor az egyetlen elem lesz, hogy teljesen tönkreteszi az egész válogatás. Kérdései vannak? [Hallgató] Ha van egy rekurzív függvény, és ez csak teszi a rekurzív hívások egy return utasítást, ez farok rekurzív, , és így azt, hogy nem használ több memóriát futás közben vagy ez legalábbis használni összehasonlítható memória iteratív megoldás? [Bowden] Igen. Ez valószínűleg valamivel lassabb, de nem igazán. Tail rekurzív nagyon jó. Keresi ismét stack frame, mondjuk mi fő és mi int bar (int x), vagy ilyesmi. Ez nem egy tökéletes rekurzív függvény, de a visszatérő bar (x - 1). Tehát nyilvánvaló, hogy ez a hibás. Be kell, alap esetben, meg ilyesmi. De az ötlet, hogy ez farok rekurzív, ami azt jelenti, ha a fő kéri bar ez lesz, hogy a stack frame. Ebben a stack frame ott lesz egy kis memóriablokkot amely megfelel az érvelését x. És így mondjuk fő történik hívni bar (100); Tehát x fog indulni, mint 100 fő. Ha a fordító elismeri, hogy ez egy farok rekurzív függvény, majd amikor bár teszi rekurzív hívás akadályozza, ahelyett, hogy egy új köteg keret, ott, ahol a köteg kezd nőni nagymértékben, végül hogy fog futni a halom, és akkor kap segfaultol mert a memória kezd ütközik. Tehát ahelyett, hogy a saját stack frame, akkor észre, hé, én soha nem kell, hogy jöjjön vissza erre stack frame, így ahelyett, hogy én csak cserélni ezt az érvelést a 99 és indítsa el bár az egész. És akkor majd újra meg újra, és ez eléri visszatérő bar (x - 1), és ahelyett, hogy egy új stack frame, akkor csak cseréld ki a jelenlegi 98 érv majd ugorj vissza a legelején bar. Ezek a műveletek, a helyébe lépő 1 érték a veremben és ugrás vissza az elejére, elég hatékony. Tehát nem csak ez ugyanaz memória használat egy külön funkció, amely az iteratív mert te csak használ 1 verem keret, de te nem szenvednek az árnyoldalai kelljen hívni funkciókat. Hívása funkciók némileg drága, mert van, hogy mindezt a telepítést és teardown és az összes ezt a cuccot. Tehát ez a farok rekurzió jó. [Hallgató] Miért nem hoz létre új lépések? Mert rájön, hogy nem kell. A hívás bár éppen vissza a rekurzív hívást. Tehát nem kell semmit a visszatérési érték. Ez csak megy, hogy azonnal vissza. Tehát ez csak akarja cserélni a saját érvelését, és indítsa újra. És azt is, ha nem rendelkezik a farok rekurzív változat, akkor kap az összes ezeket a bárok, ahol, ha ez bar visszatér azt vissza annak értékét egy ehhez, akkor a bar azonnal visszatér és visszatér az értékét egy ehhez, akkor ez csak megy azonnal vissza és visszatér az érték ezt. Szóval ez a megtakarítás popping mindezen dolgokat a verem mivel a visszatérési érték csak fog át egészen vissza egyébként. Szóval, miért nem helyettesítheti a érv a frissített érvet és kezdjük újra? Ha a függvény nem rekurzív farok, ha valami ehhez hasonlót - [Hallgató] ha bar (x + 1). >> Igen. Tehát, ha betette állapotban, akkor csinál valamit a visszatérési érték. Vagy akkor is, ha csak nem vissza 2 * bar (x - 1). Így most bar (x - 1) vissza kell annak érdekében, hogy 2-szer kiszámítani ezt az értéket, így már nincs szüksége saját külön stack frame, és most, nem számít, milyen keményen próbálkozol, fogsz kell - Ez nem rekurzív farok. [Hallgató] Vajon próbálom, hogy egy rekurziót, hogy törekedjen a farok rekurzió - [Bowden] Egy ideális világban, de CS50 nem kell. Annak érdekében, hogy farok rekurzió, általában, akkor létrehoz egy további érv ahol bar veszi figyelembe int x y és y megegyezik a végső dolog, amit szeretnénk, hogy visszatérjen. Akkor ezt fogod visszatér bar (x - 1), 2 * y. Szóval ez csak egy magas szintű, hogyan átalakítani a dolgokat, hogy farok rekurzív. De az extra érv - És aztán a végén, amikor eléri a bázis, az esetben, ha csak vissza y mert már halmozódnak egész idő alatt a visszatérési érték, amit akar. Te milyen már csinálja iteratív de a rekurzív hívások. Kérdései vannak? [Hallgató] Lehet, hogy mintegy mutató számtani, mint amikor a húrok. >> Persze. Mutató aritmetika. Ha strings ez könnyű, mert húrok char csillag, karakter van örökké és mindig egy byte, és így mutató aritmetika egyenértékű rendszeres számtani ha dolgunk húrok. Mondjuk char * s = "hello". Tehát van egy mondat a memóriában. Van szüksége, 6 byte, mert mindig szükség van a null terminátor. És char * s fog mutatni az elején ezt a tömb. Szóval, s mutat ott. Nos, ez alapvetően, hogy az egyes array működik, függetlenül attól, hogy volt egy visszatérés a malloc, vagy hogy ez a verem. Minden tömb alapvetően egy mutató a kezdete a tömb, majd minden sor művelet, bármilyen indexálás, csak megy abba a tömb egy bizonyos ellensúlyozni. Tehát amikor azt mondom, valami ilyesmit s [3], ez lesz s és a számolás 3 karakter hüvelyk Így s [3], van 0, 1, 2, 3, így s [3] fog a hivatkozás erre a l. [Hallgató] És tudtuk elérni ugyanazt az értéket csinál s + 3, majd zárójelben sztár? Igen. Ez egyenértékű azzal, hogy * (k + 3); és ez örökké és mindig azonos nem számít, mit teszel. Soha nem kell használni a konzol szintaxist. Bármikor használhatja a * (k + 3) szintaxis. Az emberek hajlamosak mint a zárójeles formával, mégis. [Hallgató] Tehát minden tömbök valójában csak mutató. Van egy kis különbség, amikor azt mondom, int x [4] >> [hallgató]-e, hogy megteremtse a memória? [Bowden] Ez létre fog hozni 4 ints a veremben, így összességében 16 bájt. Ez létre fog hozni 16 byte a verem. x nem tárolja sehol. Ez csak egy szimbólum utal a kezdete a dolog. Mert nyilvánította a tömb belsejében ezt a funkciót, amit a fordító fog tenni éppen helyébe minden esetben a változó x olyan esetekben, amikor ez történt választani, hogy ezeket 16 bájt. Ezt nem tehetem meg a char * s, mert s tényleges mutató. Nem szabad, hogy akkor mutasson más dolog. x egy konstans. Nem lehet, hogy pont egy másik tömbben. >> [Hallgató] Oké. De ez a gondolat, ez indexálás, ugyanaz, függetlenül attól, hogy ez egy hagyományos tömb vagy ha ez egy mutatót valamit, vagy ha ez a mutató egy malloced tömb. És valóban, ez annyira azonos, hogy ez is ugyanaz a dolog. Ez valójában csak fordítja, mi van benne a konzolok és mi maradt a konzolok, hozzáadja őket együtt, és dereferences. Tehát ez éppen olyan érvényes, * (k + 3), vagy s [3]. [Hallgató] Tud tekintette mutatókat mutat 2-dimenziós tömbök? Ez nehezebb. Hagyományosan, nem. A 2-dimenziós tömb csak egy 1-dimenziós tömb néhány kényelmes szintaxis mert amikor azt mondom, int x [3] [3], ez tényleg csak 1 tömb, 9 értékeket. És így amikor index, a fordító tudja, mire gondolok. Ha azt mondom, x [1] [2], hogy tudja, hogy én akarom, hogy a második sort, így megy, hogy kihagyja az első 3, majd azt akarja, a második dolog, hogy így fog kapni ezt. De ez még mindig csak egy dimenziós tömb. És így ha akartam rendelni egy mutatót, hogy a tömb, Azt mondanám, int * p = x; A típus a x csak - Ez durva mondván típusú x mivel ez csak egy szimbólum, és ez nem egy valós változó, de ez csak egy int *. x csak egy mutató a kezdetétől. >> [Hallgató] Oké. És így nem lesz képes elérni [1] [2]. Azt hiszem, van speciális szintaxis nyilvánító mutató, valami nevetséges, mint például int (* p [- valami teljesen nevetséges. Én nem is tudom. De van egy szintaxis nyilvánító mutatókat, mint a zárójeles és dolgokat. Lehet, hogy nem is hagyja, hogy ezt teszed. Tudtam nézni vissza valamit, ami elmondja az igazat. Fogom keresni, hogy később, ha van egy szintaxis pont. De soha nem fogod látni. És még a szintaxis annyira archaikus, hogy ha használják, az emberek fogják terelni. Többdimenziós tömbök elég ritka, ahogy van. Te nagyon sokat - Nos, ha csinálsz mátrix dolgokat ez nem lesz ritka, de a C te ritkán lesz használva többdimenziós tömbök. Igen. >> [Hallgató] Tegyük fel, hogy van egy nagyon hosszú tömb. Tehát a virtuális memória tűnik, hogy minden egymást követő, mint az elemek közvetlenül egymás de a fizikai memória, lehetséges lenne e, hogy szét? >> Igen. Hogyan virtuális memória működik ez csak elválasztja - Az egység kiosztásának egy olyan oldalon, ami általában a 4 kilobyte, és így amikor a folyamat azt mondja, hé, azt akarom, hogy ezt a memóriát, az operációs rendszer fog kiosztani it 4 kilobyte-e kis blokk memória. Még ha csak használni egy kis bájt az egész blokk memória, az operációs rendszer fog adni, hogy a teljes 4 kilobyte. Szóval mi ez azt jelenti, tudtam, hogy - mondjuk ez az én verem. Ezt stack elkülöníthetők. A verem lehet megabájt és megabájt. A verem lehet hatalmas. De a verem magának kell osztani egyes oldalakat, ami ha megnézzük ide mondjuk, ez a mi RAM, ha van 2 GB RAM-mal, ez a tényleges cím 0, mint a 0. byte az én RAM, és ez a 2 gigabájt egészen ide. Szóval, ez az oldal is megfelelnek ennek a blokknak ide. Ez az oldal is megfelel ennek a mondat ide. Ez is megfelel ez ide. Így az operációs rendszer szabadon rendelni fizikai memória minden egyes oldalt önkényesen. És ez azt jelenti, hogy ha ez a határ történik forma, egy tömb, tömb történik hagyni e és jobbra a jelen végzés az oldal, akkor a tömb lesz osztani a fizikai memóriában. És akkor, amikor kilép a program, amikor a folyamat véget ér, E leképezések kap törlik, és akkor ez szabadon használhatják ezeket a kis blokkok más dolog. További kérdések? [Hallgató] A mutató számtani. >> Ó, igen. Strings könnyebb volt, de keres valamit, mint a ints, így hát az int x [4]; Hogy ez egy tömb, vagy hogy ez a mutató egy malloced tömb 4 egészek, ez lesz ugyanúgy kezeljék. [Hallgató] Szóval tömbök vannak a halom? [Bowden] A tömbök nem a kupac. >> [Hallgató] Oh. [Bowden] Ez a típusú tömb általában a a verem ha kijelentette azt - figyelmen kívül hagyva a globális változókat. Ne használja a globális változókat. Belül egy függvény mondom int x [4]; Ez lesz egy 4-egész blokk a verem ezen tömb. De ez a malloc (4 * sizeof (int)); fog menni a kupac. De miután ezen a ponton tudom használni az x és p-ben nagyjából azonos módon, más, mint a kivételek korábban mondtam rólad is hozzárendelése p. Technikailag, a mérete némileg eltérnek, de ez teljesen lényegtelen. Te soha nem használja a méretben. A p Mondhatnám p [3] = 2, vagy x [3] = 2; Használhatod őket, pontosan ugyanolyan módon. Szóval pointer aritmetikai most - Igen. [Hallgató] Hát nem kell tennie, p * ha a zárójelben? A zárójelben szereplő implicit dereference. >> Oké. Igazából, azt is, amit mondasz az tudsz többdimenziós tömbök A mutató, amit tehetünk, valami ilyesmit, mondjuk, int ** pp = malloc (sizeof (int *) * 5); Én csak írni az egészet ki először. Nem akartam, hogy az egyik. Oké. Mit tettem itt - Ez legyen pp [i]. Tehát pp egy mutató egy mutató. Te mallocing pp, hogy pont egy sor az 5 int csillagok. Tehát a memóriában van a verem pp Meg fog mutatni egy sor 5 háztömbnyire amelyek mind maguk mutatók. És akkor, amikor én malloc idelent, azt malloc hogy minden e egyes mutatók kell mutatnia, hogy egy külön blokkot 4 bájt a kupac. Tehát ez rámutat arra, hogy 4 bájt. És ez pont egy másik 4 bájt. És mindegyik pont a saját 4 bájt. Ez ad nekem egy módja a többdimenziós dolgokat. Mondhatnám pp [3] [4], de most ez nem ugyanaz, mint a többdimenziós tömbök mert többdimenziós tömbök úgy fordította [3] [4] egyetlen ellensúlyozza az x tömb. Ez dereferences p, hozzáfér a harmadik index, akkor dereferences hogy és bejáratok - 4 érvénytelenek lennének, - a második index. Mivel ha mi volt a int x [3] [4] előtt, mint egy többdimenziós tömb és ha dupla konzollal ez tényleg csak egy dereference, Ön után egy mutatót, majd egy ofszet, ez tényleg 2D hivatkozásokat. Kövesse 2 külön mutató. Tehát ez technikailag is lehetővé teszi, hogy többdimenziós tömbök ahol minden egyes tömb különböző méretben. Tehát úgy gondolom, csipkézett többdimenziós tömbök, amit a neve mert valóban az első dolog lehetne mutatni valamit, ami már 10 elemet, A második dolog, amit tudott mutatni valamit, ami összesen 100 elemet. [Hallgató] Van-e határa a számát mutató akkor lehet mutató más mutatókat? No. >> Egyszerre int ***** p. Vissza a mutató számtani - >> [hallgató] Oh. >> Igen. [Hallgató] Ha van int *** p, aztán csinál egy dereferencing, és azt mondom, p * egyenlő ez az érték, nem csak fog tenni 1 szint dereferencing? >> Igen. Tehát, ha azt akarom, hogy hozzáférjen a dolog, hogy az utolsó mutató mutat - Akkor te *** p. >> Oké. Szóval ez a p pont, 1 blokk, pont egy másik blokk, pontok másik blokkra. Akkor, ha nem * p = valami mást, akkor változik a hogy most pont egy másik blokk. >> Oké. [Bowden] És ha ezeket malloced, akkor most kiszivárgott memória kivéve, ha történetesen különböző hivatkozásokat e mert akkor nem kap vissza azokra is, hogy csak eldobta. Mutató aritmetika. int x [4]; fog kiosztani egy sor 4-egészek ahol x fog mutatni, hogy az elején a tömbben. Tehát amikor azt mondom, valami ilyesmit x [1], azt akarom, hogy azt jelenti, megy a második egész a tömbben, ami ezt. De tényleg, ez 4 bájt a tömb, mivel ez integer vesz fel 4 byte. Tehát egy offset 1-valójában azt jelenti, eltolt, 1 akkora típusától függetlenül a tömb. Ez egy tömb egészek, így tudja, hogy nem 1-szer méretét int, ha akarja ellensúlyozni. A másik szintaxis. Vegye figyelembe, hogy ez ugyanaz, mint a * (x + 1); Amikor azt mondom, pointer + 1, hogy mi visszatér a cím, hogy a mutató tárolja plusz 1-szer a méretét típusának a mutató. Tehát, ha x = ox100, akkor x + 1 = ox104. És akkor vissza ezt, és mond valamit, mint a char * c = (char *) x; és most c lesz ugyanazon a címen, mint x. c lesz egyenlő ox100, de c + 1 lesz egyenlő ox101 mivel a mutató aritmetika típusától függ a mutató, hogy a felvenni kívánt. Tehát c + 1, úgy néz ki, a C, ez egy char mutatót, így fog hozzá 1-szer méretének char, amely mindig lesz 1, így kap 101, mivel ha mégis x, amely még mindig 100, x + 1 lesz 104. [Hallgató] Lehet használni c + +-ban annak érdekében, hogy előre a mutatót 1-jéig? Igen, lehet. Ezt nem teheted, hogy az x, mert x csak egy szimbólum, ez egy állandó, nem tudja megváltoztatni x. De c történetesen csak egy mutató, így a c + + tökéletesen érvényes, és ez növelni 1-gyel. Ha c voltak, csak egy int *, majd a c + + lenne 104. + + Nem mutató számtani mint c + 1 volna mutató számtani. Ez tulajdonképpen, hogy egy csomó dolgot, mint a merge sort - Ahelyett, hogy a másolatok a dolgok, akkor inkább át - Mint ha azt akartam, hogy adja át ezt a felét a tömb - Menjünk töröljön néhány e. Tegyük fel akartam átadni ezt az oldalát a tömb egy funkciót. Mit is átadni ezt a funkciót? Ha át x vagyok, tompított ezt a címet. De azt akarom, hogy adja át az adott címet. Szóval mit kell átadni? [Hallgató] Pointer + 2? [Bowden] Tehát x + 2. Igen. Ez lesz ezt a címet. Azt is nagyon gyakran jelenik meg, mint x [2], majd a címét. Szóval meg kell tenniük a címét, mert a konzol egy implicit dereference. x [2] az az érték, amely ebben a rovatban, és akkor szeretné, hogy a címét mezőbe, így mondod & x [2]. Szóval így valami merge sort, ahol szeretné, hogy adja át a fél listát valamit Ön tényleg csak át & x [2], és most egészen a rekurzív hívást illeti, új tömb kezdődik ott. Last minute kérdéseket. [Hallgató] Ha nem teszünk egy jelet, vagy - mi ez hívják? >> Star? [Hallgató] Star. >> Technikailag dereference üzemeltető, de - >> [hallgató] dereference. Ha nem tesz egy csillag vagy egy jelet, mi történik, ha csak azt mondom y = x és x egy pointer? Milyen típusú y? >> [Hallgató] Én csak azt mondom, hogy a mutató 2. Tehát, ha csak annyit y = x, most az x és y pont ugyanaz a dolog. >> [Hallgató] Pont ugyanaz a dolog. És ha x egy int pointer? >> Lenne panaszkodni, mert nem tudsz rendelni mutatókat. [Hallgató] Oké. Ne feledje, hogy a mutatók, még akkor is elkészíti őket nyilak, Tényleg mindent áruház - int * x - tényleg minden x tárolja valami hasonló ox100, amit történetesen képviselt, mint rámutatni, hogy a blokk tárolt 100. Tehát amikor azt mondom, int * y = x, Én csak másol ox100 be y, amelyet mi csak fogja képviselni, mint y is mutatva ox100. És ha azt mondom, int i = (int) x, majd én fog tárolni függetlenül értéke ox100 jelentése belül, de most ez lesz úgy kell értelmezni, mint egy egész helyett egy mutatót. De szükség van a leadott vagy máshol fog panaszkodni. [Hallgató] Szóval érted, hogy a leadott - Vajon lesz casting int x vagy öntéssel int y? [Bowden] Mi az? [Hallgató] Oké. Ezek után zárójelben ott van lesz egy x vagy ay ott? [Bowden] Vagy. x és y értéke azonos. >> [Hallgató] Oké. Mert mindketten mutatók. >> Igen. [Hallgató] Szóval ez tárolja a hexadecimális 100-integer formában? >> [Bowden] Igen. De nem az értékét bármit mutat. [Bowden] Igen. >> [Hallgató] Tehát csak a cím integer formában. Oké. [Bowden] Ha volna valamilyen bizarr okból, akkor kizárólag foglalkozni mutatók és soha nem foglalkoznak egészek és csak olyan, mint int * x = 0. Akkor fogod igazán zavarba egyszer pointer aritmetikai elindul történik. Tehát a számok, hogy a tárolni értelmetlenek. Csak, hogy a végén ezeket értelmezze. Szóval szabad másolni ox100 egy int * egy int, és én szabad vagyok rendelni - készen valószínűleg fog kapni kiabált, mert nem casting - Szabad vagyok rendelni valami hasonló (int *) ox1234 ebbe önkényes int *. Szóval ox123 éppolyan érvényes egy memória cím mint & y. & Y lesz visszatérni valamit, ami elég sok ox123. [Hallgató] lenne ez egy nagyon jó módja annak, hogy megy hexadecimális decimális formában, szeretem ha van egy mutató, és öntött, mint egy int? [Bowden] Akkor tényleg csak nyomtathat, mint a printf. Tegyük fel, hogy van int y = 100. Szóval printf (% d \ n - ahogy akkor már tudják -, hogy nyomtassa ki, mint egy egész,% x. Majd csak nyomtatni, mint hexadecimális. Így a mutató nem tárolja hexadecimális, és az egész nem tárolja decimális. Minden tárolt bináris. Csak annyi, hogy hajlamosak vagyunk megmutatni mutatókat, mint hexadecimális mert úgy gondolom, a dolgok ezekben a 4-bájtos blokkok, és a memória címek általában ismerős. Olyanok vagyunk, mint, ha kezdődik bf, akkor az történik, hogy a verem. Szóval, ez csak a mi értelmezési mutatók, mint hexadecimális. Oké. Minden last még kérdése? Itt leszek egy kicsit után, ha van bármi más. És ez a vége, hogy a. [Hallgató] Yay! [Taps] [CS50.TV]