[Powered by Google Translate] [4. týden, pokračování]
[David J. Malan - Harvard University]
[To je CS50. - CS50.TV]
>> To je CS50, a to je konec 4. týdnu.
Takže nějaká dobrá zpráva, a některé špatné zprávy.
No přednáška v pondělí, není problém nastavit příští týden. [Studenti fandění]
Ty nebude líbit, kde to bude.
Ale máme toto místo příští středu,
a tam je také dle sylabu 1 přednášce pátek příští pátek, takže můžeme zůstat na trati.
Ale všechno bude natočen jako obvykle, takže žádný strach.
>> A pokud jde o kvíz 0, co budeme dělat, ke konce týdne
je příspěvek na hřišti v úvodní cs50.net vysvětlení
z jaké očekávání, měli byste mít, pokud jde o první kvíz.
Obecně platí, že to multiple choice, true-false, krátká odpověď, krátké kódování problémy.
Nebudete se očekává, že k provedení ekvivalent
o problém, který by viděl na PSet, pro které máte počítač
a debugger a podobně, ale bude malé kódování problémy.
>> A skutečně, nejlepším vodítkem získat pocit z toho, co CS50 kvízy jsou jako
, je jít na cs50.net, přejděte na kvízy odkaz,
a můžete vidět, že v minulých několik let v hodnotě kvízů.
Jen si uvědomit, že osnovy není vždy stejná v průběhu let.
Někdy přidáme, někdy odčítání,
takže pokud vidíte nějaké téma na jednom z těch starých kvízy
že nemáte tušení, co to mluví, je to buď, že jsme se pokrýt
nebo že jsme neměli pokrýt.
Ale ve formě recenzí, tuto neděli, pondělí a úterý
stejně jako v průběhu kurzu širokou přezkoumání zasedání v neděli večer -
čas a místo budou oznámeny na hřišti domovskou stránku -
máte všichni možnost prohlédnout s průběhem v učebních kolegy
materiál pro tento rok, a to jak v průřezu a jako plné třídy,
a ty bude natočen jako obvykle také.
>> Dobrá. Takže bez dalších okolků, jeden komentář na vyhověl / nevyhověl a přidejte / drop.
Možná jste viděli své poznámky minulou noc, a to je opravdu jen některé další uklidnění
že patříte-li mezi ty, zejména méně pohodlné, nebo někde mezi
a máte pocit, jen trochu v tom až po hlavu,
si uvědomit, že je opravdu docela normální, a tam je dostatek nosná konstrukce v místě,
z nichž jedna úřední hodiny byl zaujatý na zlepšení všech více na mé e-mailové minulou noc,
a uvědomit si, že příliš možností, jako vyhověl / nevyhověl pro třídu, jako je tento
Opravdu je třeba jako mechanismus vzít okraj pryč kurzu, jako je tato,
takže znovu, pokud trávíte těch 10, 15, 20 hodin
Jen se snažím získat nějaké PSet do práce a víte, že jste 90-95%, jak je
ale nemůžete najít nějaký zatracený chybu, v průsmyku / selhání modelu, který je trochu v pořádku.
>> Myšlenka je, že s tímto mechanismem pak můžete jít se zaměřují na vaše další psets
nebo spát nebo co to je, že chcete zaměřit.
Takže si uvědomit, že máte do této nadcházející úterý - technicky 5. pondělí,
ale je to svátek, takže to přijde úterý - přejít z režimu pass / fail, aby tříděných nebo naopak.
A pokud jste opravdu nad propastí a uvažujete o svržení celkem,
prosím, chyť mě po přednášce nebo napište mi poznámku.
Rádi bychom alespoň chatu před nabídku adieu.
Dobrá. Takže jsme začali brát na školení kola off minule.
Zejména jsme se zaměřili na provázku.
Řetězec je něco, co prohlásil v knihovně CS50,
konkrétně v tomto souboru s názvem cs50.h které začneme dívat na tento týden a příští.
Ale řetězec je opravdu jen zjednodušení něco
to je trochu arcanely popsat jako char *.
Char jsme zvyklí. Je to jen jeden znak.
Ale * v pondělí označil co? >> [Student] ukazatel.
Ukazatel. A co je ukazatel? >> [Student] adresa.
>> Je to jako adresa, umístění v paměti.
Co je to adresa nebo umístění, nebo vzpomínka?
Opět platí, že každý z nás má notebooky s koncertem nebo 2 GB paměti RAM s největší pravděpodobností v těchto dnech,
a to znamená, že máte miliard 2000000000 bajtů v hodnotě paměti.
A to opravdu není jedno, co to fyzicky vypadá,
ale vzít na víře, že můžete očíslovat všechny jednotlivých bajtů, že váš vlastní notebook má -
To je bajt 0, to je bajt 1, to je byte 2000000000 -
a to je přesně to, co dělá počítač.
Když přidělit prostor pro jeden znak, například,
zřejmě musí žít někde v paměti počítače,
a možná, že je to v byte číslo 12345,
a to je někde tady v paměti počítače.
A adresa pak tímto znakem je 12345.
>> Nyní, v týdnu 0 až nyní tak daleko, jsme se opravdu záleží
kde v paměti věci jsou uloženy, protože se obvykle používají symboly,
proměnné, a pole se skutečně dostat na naše data.
Ale v pondělí a všech více dnes, budete nyní muset
všechny další výrazné schopnosti s psaním programů
opravdu manipulovat s paměti počítače však uznáte za vhodné,
jak pro dobré účely a špatných,
chyby je velmi běžný výsledek v tomto bodě v učení tohle.
Ale co to vlastně znamená být char *?
Pojďme dál zpět k - a vrátíme se Binkym, jak jsem slíbil dnes.
Pojďme na jednoduchém příkladu zde.
Dovolte mi, abych tento soubor uložit jako compare.c, a dovolte mi trochu šablony kód zde
tak patří stdio.h, dovolte mi, abych také dávám patří cs50.h. Budu zoomovat až tam.
Dovolte mi, abych začal psát hlavní int, main (void), a teď chci udělat něco takového:
printf ("Dej mi řetězec:") a pak budu používat string s dostane GetString
k získání řetězce od uživatele, pak jsem se zeptat uživatele na jiného.
("Dej mi ještě řetězec:") a budu se jich zeptat přes GetString se dostat, že.
Zavolám jí t, protože t přichází po S a S je hezké jméno pro řetězce, pokud je to docela druhový.
Takže GetString, a teď chci udělat zdravý rozum kontrolu a budu říkat
if (s == t) pak jsem jen tak říct uživatele printf ("Zadali jste to samé \ n!");
jinak budu vytisknout něco jako ("Zadali jste něco jiného! \ n")
nebo co věta bude. Takže něco takového.
Pak jako obvykle, vrátím 0, která se právě znamenali, že se nic nestalo,
a já jdu dál a zkompilovat a spustit tento program.
>> Ale v pondělí jsme spustili tento program,
a vlastně bylo řečeno, že HELLO není HELLO a GOODBYE není GOODBYE.
Chování jsme viděli, bylo trochu více jako toto.
Nech mě jít do mého zdrojového adresáře, zoom sem, a pojďme se udělat porovnání.
Zpracovala pořádku. Dovolte mi, abych spustit porovnání. Dej mi řetězec: HELLO.
Dej mi ještě řetězec: HELLO.
Zadali jste něco jiného!
No, zkusím něco jednoduššího jako 50, 50. Zadali jste něco jiného!
hi, hi. Tak jasně, něco se děje.
Ale co bylo vysvětlení, proč?
Zdá se, že linka 12 je zcela nefunkční.
Co je to zásadní problém tady? Jo. >> [Student] Je to porovnáním adres.
Jo, přesně tak. Je to vlastně porovnávání adresy
, ve kterém jsou uloženy HELLO a HELLO.
Není to porovnáním dopisy HELLO znovu a znovu,
protože to, co se opravdu stalo, celou tu dobu jsme byli s použitím GetString -
Tato tabule je opět naší paměti počítače,
a řekněme, že jsem zavolat GetString po deklarování proměnné s.
Co moje paměť vypadat?
Řekněme libovolně říci, že to vypadá takhle. Je to čtverec.
A skoro žádné, kdy jsem kreslila kus paměti na obrazovce
pokud je to 32 bitů jsem byla kresba čtverců, jako je tento, protože skutečně v zařízení,
ukazatel, adresa, je 32 bitů. Je to stejné jako int.
To může lišit v závislosti na počítačovém systému.
Ti z vás, kteří jsou matně obeznámeni s tím, že váš Mac nebo PC je 64 bitů,
že vlastně označuje, že váš počítač používá 64-bitové ukazatele,
64-bitové adresy, a mezi upsides na které je vaše počítače
mohou mít mnohem více paměti RAM, než minulosti.
Dlouhý příběh krátký, zpět v den, kdy počítače používá pouze 32 bitů
reprezentovat adres, největší počet bytů, by mohlo představovat
v tomto případě je to, co máte 32 bitů?
Takže 4000000000, pravé, protože 2 na 32 je 4 mld. Kč.
Toto číslo se opakující v průběhu.
>> Takže pokud máte pouze 32 bitů, nejvyšší číslo, které se můžete spolehnout, je zhruba 4 mld. Kč.
Ale to byla zásadní omezení počítačů až do doby před několika lety
protože pokud můžete jen počítat jak vysoce jak 4000000000,
nezáleží na tom, jestli si koupíte 8 GB paměti RAM nebo dokonce 5 GB paměti RAM;
nemůžete počítat, že vysoká, takže to bylo k ničemu.
Dalo by se přistupovat pouze první 3 nebo 4 GB paměti vašeho počítače.
To je menší problém teď, a můžete si koupit MacBook Pros a Dells
s 8 GB paměti RAM nebo ještě v těchto dnech.
Ale kdybych přidělit prostě v tomto programu ukazatel, ukazatel nazvaný s,
by to mohlo vypadat takto na obrazovce, protože skutečně potřebujeme odtrhněte této vrstvy.
Pořád říkal řetězec, ale v pondělí, string je opravdu char *,
adresa nějakého charakteru.
Takže pojďme se, že školení kolo off, i když budeme i nadále používat GetString nyní.
Tak jsem prohlásil s, a to je kus paměti, 32 bitů.
Co je tady v paměti ve výchozím nastavení? >> [Neslyšitelné Student odpověď]
Co je to? >> [Student] Garbage. >> Garbage. Přesně tak.
Pokud programátor nedávejte hodnotu proměnné, kdo ví, co to je?
Někdy máte štěstí a je to 0, který je tak trochu pěkné, čisté výchozí hodnoty,
ale jak jsme viděli Pondělí, někdy je to úplný nesmysl,
některé opravdu velké kladné nebo záporné číslo, které přišlo odkud?
Jo. >> [Student] funkce před. Jo >>.
>> Často funkce, která dostala jen předtím, protože zapamatovat,
jak volat funkce v paměti, zabírají více a více prostoru zdola nahoru,
a jakmile se funkce vrátí, dostane znovu, že paměť
do příštího chlap, který se nazývá, který je pomocí stejného plátek paměti.
A pokud jste opustil odpadky tam, předchozí hodnoty,
můžeme mylně s jako s nějakou hodnotu, když opravdu nemáme dát tam něco.
Takže naše RAM v tomto bodě vypadá takto.
Nyní na pravé straně řádku 7 voláme GetString,
které jsme dělali nyní týdnů, ale to, co je GetString opravdu dělá?
GetString napsal CS50 personálu je málo inteligentní
v tom, že jakmile uživatel začne stisku kláves a hity Enter,
GetString postavy z kolika úhozů dělal uživatel hit,
kolik znaků musím přidělit RAM pro.
A kde, že RAM pochází, kdo ví?
Je někde ve vašem počítači je 2 GB nebo kdoví co ještě v paměti.
Ale předpokládejme, že počítač našel prostor pro slovo HELLO tady.
Slovo jsem napsal byl H-E-L-L-O.
A pokud čerpáme to jako sekvence znaků, můžeme nakreslit to takhle.
Ale musím udělat 1 další věc. Co patří na konci každého řetězce v C?
Null znak, který napíšeme, \ 0.
Je to technicky číslo 0, ale zpětné lomítko je celý jasněji
, že je to doslova číslo 0, je celé číslo 0;
to není, například, cituji-konec citátu 0, které by vás mohly zadejte na klávesnici.
Tak tohle je HELLO.
>> A co na to řekneme v pondělí, že funkce jako GetString
je vlastně vrací všechny ty týdny?
Není to vrací řetězec na sobě, protože to opravdu není mít smysl
protože řetězce neexistují. Jsou trochu zhotovení v CS50 knihovně.
Co je opravdu řetězec, více technicky? >> [Student] Je to první znak.
Přesně tak. Je to prostě adresu první znak, který uživatel zadali dovnitř
Takže pokud moje slovo HELLO končí to v byte číslo 123 a pak na byte číslo 124,
125, 126, a tak dále, v případě, jsem číslo mé bytů z 0 na nahoru,
co opravdu GetString se vrací je doslova číslo 123.
Takže to, co se dal v S je číslo 123, nikoli písmeno H, není slovo HELLO,
prostě adresu, na které mohu najít první písmeno HELLO.
Ale to nevypadá jako dost. Ptal jsem se vás na řetězec, nikoli charakter.
Tak jak jsme nebo počítači, že Ello druh přijít spolu s H?
Co je to druh smlouvy máme? Jo.
[Student] Je pořád říká se najít nějaké další znaky. Přesně >>.
>> Tam je to člověk-počítač konvence, kdy když se jednání s řetězci,
jinak známý nyní jako char hvězd, se prostě musí přijít na to,
kde na konci každé řetězce v životě je podle opravdu jen iterace přes to s pro smyčce,
while, cokoliv, takže když vás konec řetězce
Nyní si můžete odvodit z toho, oh, celé slovo bylo HELLO.
Ti z vás, s předchozím programovacím zkušeností by mohl vědět v Javě
stačí zavolat. délka a v jiných jazycích, můžete volat délku nebo podobný.
To proto, že v mnoha jazycích, a to zejména co nazývá objektově orientované jazyky,
délka něco je druh zapouzdřen uvnitř kusu samotná data,
hodně jako my zapouzdřen ID a názvy a domy uvnitř studenta v pondělí.
Ale C je mnohem nižší úrovni. Nejsou zde žádné objekty nebo třídy, pokud jste slyšeli tyto výrazy předtím.
Jediné, co musíte opravdu paměťové adresy.
Tak tohle je něco jako staromódní způsob zastupování zajímavé datové struktury.
Ty mají počáteční hodnotu jako adresu prvního znaku
a pak už jen některé svévolnými konvencemi, že všichni souhlasí s tím, následovat.
Tak jak je délka řetězce realizován, to navrhujeme?
Strlen, strlen, který někteří z vás již používá několikrát. Je to docela jednoduché, ne?
Je to jako 2 řádky kódu.
Je to docela hodně pro smyčka nějakého druhu, možná s další místní proměnné.
Ale strlen prostě musí vzít ukazatel a pak začít hledat \ 0.
>> A jakmile zjistí, může se vrátit celkový počet kroků, které je třeba v tomto řetězci.
Takže můžeme z toho vyvodit, co se děje dál.
Předpokládejme, že pak Prohlašuji t, jak jsem udělal v řádku 10.
To je nějaký odpad hodnota. Kdo ví, na první?
Ale na pravé straně řádku 10 Volám GetString znovu.
Kdo ví, kde to skončí?
Řekněme libovolně říci, že operační systém našel prostor pro to způsobem, tady.
I stalo se, shodou okolností typ H-E-L-L-O znovu,
a tak můžeme čerpat stejný druh obrazu.
Ale fakt, že mám překreslit tento obrázek je úmyslné
protože to je jiný HELLO než tenhle.
Takže zde by mohlo být místo 456, to je 457, a tak dále.
Takže to, co se dal, kde otazník kdysi?
V tomto případě se 456.
Jedeme tato čísla libovolně, protože opravdu po dnešek
nebudeme se tolik starat o to, co adresa něco je.
Vše, co je zajímá, jsou, že můžeme zjistit adresu nějakého kusu dat jako HELLO.
>> Takže opravdu to, co většina lidí dělá v oblasti počítačové vědy, když mluví o paměťových adres
a mluví o ukazatele konkrétně,
spíše než obtěžovat přijít na to, 123 -, kdo se stará, kde tohle vlastně je,
Víme jen, že je to v určitém číselném adrese -
jsme zjednodušit svět a jen říct, že to ukazuje na tento znak
a t ukazuje na tento znak.
A to, že je to šipka je docela úmyslné
protože doslova nyní s ukazuje na H a T je ukazuje na druhou H
protože na konci dne, nezáleží na tom, jaký je adresa,
ale to záleží, že máme možnost vyjádřit tuto adresu s nějakým kusem kódu.
My se opravdu manipulovat tyto adresy zatím
takže uvidíme, kde se můžeme prohodit a nějak dělat věci s ukazateli,
ale nyní v souladu 12 doslova jaké hodnoty jsme porovnání
Podle tohoto příběhu v souladu 12?
Říkáme je 123 equal equal až 456? A to rozhodně není případ.
A to i koncepčně, tento ukazatel rozhodně není stejná jako to
protože jsi volal GetString dvakrát, a GetString nesnaží se být super chytrý,
nepokouší uvědomit, oh, jste zadali HELLO před 5 minutami;
dovolte mi, abych vám stejnou ukazatel, jak jsem ti dal před,
to jen alokuje nový kus paměti pokaždé, když říkáte.
>> Tak jak jsme se tento problém vyřešit?
Pokud vyšší úroveň chci porovnat řetězce HELLO HELLO a -
Nezajímá o ukazatele - jak mohu jít o odpověď na otázku,
se uživatel zadat stejnou věc? Co je třeba tady? Jo.
[Student] Použijte funkci. >> Mohu použít funkci po vybalení z krabice.
Mohu použít funkci nazvanou strcmp, s-t-r-c-m-p,
jen zkrácená verze říká string porovnání.
A pokud půjdeme do, například, porovnat 2, který je mezi dnešní podkladů,
Já přesně to.
Pořád jsem všechno ostatní stejné z linky 1 na až 26 nebo tak,
a teď si toho všimnout část změnilo jen trochu.
Pojďme ignorovat linku 28 na chvíli a soustředit se pouze na tento jeden.
Co řekneme pondělí, že str compare dělá?
Provádí proces brát 2 ukazatele, S a T je v tomto případě,
druh prakticky tím, že své prst na těchto 2 dopisy,
a co musí udělat, je něco jako while nebo pro smyčce,
a to říká, že jsou to stejné? Pokud ano, pohybuje prsty nebo ukazatele vpřed.
Jsou to samé, to samé, to samé,
tyto stejné, to samé? A ooh, jsem na konci řetězce na obou S a T.
Nenašel jsem žádné rozpory. Ano, tyto řetězce jsou stejné.
A co str tyto přiznání, pokud je 2 řetězce jsou stejné, zřejmě? Zero.
Takže 0 je dobré v tomto případě, protože pokud se vrátí -1 nebo 1,
to znamená, že je jen stane dřív, než t abecedně nebo po t.
A proč by to mělo být užitečné mít funkci, která vám řekne, které řetězec přijde před
nebo po ve slovníku?
[Student] Hledám. >> Vyhledávání a třídění.
>> Takže si můžete dělat věci, jako binární vyhledávání nebo bublina seřadit nebo sloučit druh
kde budete muset porovnávat věci.
Tak daleko jsme druh snížit některé rohy a jen mluvil o třídění
v souvislosti s čísly, protože je to pěkné a snadné hovořit o,
ale můžete samozřejmě tyto struny, jablko a banán,
protože pokud jablko je známo, že přijde do banánu, podobně,
se můžete pohybovat řetězce kolem paměti, stejně jako Rob dělal s řadit slučovací ve videu
a my jsme tady na jevišti s výběrem druhu, vložení seřadit, a bublina seřadit.
Takže tam, kde ještě můžeme vzít? Zkusme to.
Pojďme trochu zapomenout, že lekci na chvíli a zkuste teď a zkopírujte 1.c provést následující kroky.
V řádku 21 Říkám tisku něco,
pak jsem dostat řetězec od uživatele,
pak jsem kontrolu to.
Jsme se opravdu dostali do tohoto zvyku ještě ne, ale pojďme se teď to.
Pojďme skutečně Sloupněte této vrstvy. To je opravdu char *. Ten chlap je opravdu char *.
Takže co to znamená být kontrola, zda s == NULL?
Ukazuje se, že při volání funkce, jako je GetString
nebo obecněji zeptejte počítače, aby vám nějaké paměti,
něco mohlo pokazit.
Ty by mohly být blázen a požádat počítač pro terabajt paměti
tím, že žádá o biliony bajtů paměti, které prostě neexistují v počítači,
ale GetString a další funkce potřebovat nějaký způsob, jak křičí na vás
Pokud jste požádáni o příliš mnoho.
A jak GetString dělá je, pokud jste požádali o více paměti
než je k dispozici v počítači, a to i v případě, že je to super, super nízkou pravděpodobnost
protože nikdo z nás se bude psát bilionu znaky a stiskněte Enter,
ale málo pravděpodobné, i když to může být, stále chci zkontrolovat to jen v případě,
a speciální hodnota, která GetString, odpověď, a další funkce vrací
pokud něco špatně, je NULL ve všech velkých písmenech.
>> A co je NULL? NULL jen tak náhodou představují ukazatel. Je to adresa paměti 0.
Svět se rozhodl, že svévolně, je-li to mé paměti počítače - víte, co? -
budeme krást jen 1 bajt každého paměti počítače, a to je místo 0.
Budeme jej přezdívku NULL, a budeme slibovat
, že nikdy skutečně dát skutečné údaje jsou k dispozici
protože jsme právě libovolně potřebujeme zvláštní hodnotu, 0, NULL, aka
takže můžeme křičet na uživatele, pokud se něco pokazí.
Jinak možná nevíte to 0 znamená dát něco, co zde
nebo to znamená něco pokazilo?
Musíme se všichni shodneme, že NULL znamená, nic se vrátil,
žádná skutečná adresa byla vrácena.
Teď, tady jsem jen přijímá svou lidskou konvenci I return 1 z hlavní
když se něco pokazí.
To proto, že hlavní je návrat konvence je nutné vrátit hodnotu 0, pokud dobře,
1 nebo jiné hodnoty, pokud špatně.
Ale GetString a nějaká funkce, která se zabývá v paměti vrací null, pokud se něco pokazí.
>> Dobře. Takže bohužel, linka 27, super jednoduchý i když je zcela nedokáže zkopírovat řetězec.
Proč? Je vidět, to následujícím způsobem.
Já jsem tvrdil v souladu 27 bude dělat kopie s a nazývat to t.
Tak jsem se neptám na uživatele pro 2 řetězce tentokrát, jen říkám, hodnoty v s
by měl být kladen na t i.
Teď už jen stačí prokázat, jak je to zlomený, v souladu 29 vpřed co to dělám?
První jsem kontrolu, když délka t je větší než 0.
Tam je nějaký řetězec tam. Uživatel napsal něco dovnitř
Co je linka 32 dělá, zřejmě?
[Neslyšitelné Student odpověď] >> Právo. Můžete trochu odvodit z toho, co jsem řekl, že to dělá.
Ale technicky, co je to děláš? t [0] představuje, co?
[Student] znak 0.. >> [Malan] znak 0..
Nebo, více člověka-jako, první znak v t, bez ohledu na to je, H možná v tomto případě.
A toupper dělá to, co říká. Těží nultého charakter tun a změní jej.
Takže to znamená, vzít 0. charakter t, aby to velká,
a vložte jej zpět do stejné místo.
Takže pokud jsem typ ahoj malými písmeny, mělo by to změnit malá písmena h na základním kapitálu, H.
Ale problém je, že v řadách 35 a 36, ​​co se chystám udělat, je vytisknout pro nás S a T.
A jaký je váš tušení?
Co mám vlastně jít, jestli jsem psát v ahoj ve všech malými písmeny?
Co se to děje, aby si vytisknout? >> [Neslyšitelné Student odpověď] >> Co je to?
[Student] Big H a zbytek malé. >> Velký H a zbytek malý, pro které je nebo t?
[Student] Obojí. Obě >>. Přesně tak. Tak se podívejme, co se tady děje.
>> Nech mě jít napřed a sestavit to. To je Copy1, takže se COPY1. Dobrá.
Zoom Nech mě jít napřed a spustit COPY1, Enter, řekni něco: ahoj malými písmeny.
To vydělával kopii, ale to zřejmě vydělával původní a,
protože to, co se děje nyní v tomto příběhu?
V souladu 27 Nemám vlastně Zdá se, že kopírování řetězec,
ale i když jste možná intuitivně doufal, že tomu tak bylo,
pokud si myslíte o této obrázku, co se opravdu jsem to udělal?
Polovina obrázku je stejná.
Takže pojďme se vrátit v čase tak, aby t dosud neexistuje v příběhu.
S může existovat v příběhu, ale pojďme malá ahoj tentokrát.
Tak ať mi opravit to, co jsem vlastně napsal palců
V tomto případě zde máme h-e-l-l-o.
Budeme nakreslit jako sekvence znaků, dal jsem oddělovačů tady a mé \ 0.
Takže tohle je místo, kde jsme, jakmile řádek 1 až 24-ish, dávat nebo brát, byly provedeny.
To je obraz mé paměti.
Když jsem se dostat do souladu 27, co se stane?
Stejně jako předtím, než jsem se ukazatel, který budu čerpat jako je náměstí.
Říká se t. A co je jeho hodnota ve výchozím nastavení? Kdo ví? Některé odpadky hodnota.
>> Takže budu abstraktní, že venku jako otazník.
A jakmile pravá strana linky 27 provede, co mám dávat uvnitř t?
Stejný věc, která je v §.
Takže když jsme se na chvíli odstranit tuto abstrakci šipky a říkáme,
oh, to je zatížení paměti adresa 123, když říkáš t dostane s, středník,
jste doslova uvedení 123 zde.
Nyní, když jsme trochu zjednodušit náš svět znovu s obrázky,
co jste opravdu udělal, je právě přidána další šíp do svého světa
, který je polohovací t na stejném přesném řetězci.
Takže když v souladu 31 a 32 jsem vlastně jít o změnu t [0],
to, co je t [0] zřejmě synonymem teď? s [0]
Takže to je všechno, co se děje.
A i když tento druh cítí trochu nízká úroveň a tajemný
a tento druh se cítí jako snad intuitivně by to mělo být jen pracoval -
Já jsem udělal kopie věcí před a to jen fungovalo -
pokud si skutečně myslí o tom, co řetězec skutečně je, je to char *.
No, co to je? Je to adresa nějakého charakteru.
Pak je možná větší smysl, že když se pokusíte udělat něco
Super zdánlivě jednoduchého, jako to, všechno, co děláte, je kopírování adresa paměti.
Ty ve skutečnosti dělat nic s řetězci sám.
Takže, i když nemáte tušení, jak byste tento problém vyřešit v kódu,
na vysoké úrovni, koncepčně, co musíme udělat, aby ta opis s, zřejmě?
Jo. >> [Student] Dej mu nové umístění? Přesně >>.
>> Musíme dát t zbrusu nové umístění.
Musíme se nějak vytvořit svět, v němž se dostaneme nový kus paměti,
které právě z důvodů přehlednosti budu čerpat hned pod tímto jeden, ale to nemusí být.
Ale to musí být stejné velikosti, takže budu čerpat tyto svislé čáry ve stejném místě.
Je to v pořádku, pokud je to všechno smetí zpočátku. Kdo ví, co tam byl?
Ale krok 1 bude muset být dát mi tolik paměti, jak jsem třeba
aby se vešly kopii ahoj, pak zjistit, jak kopírovat h tady, na e zde,
l zde a tak dále.
Ale to už by se neměl cítit trochu zřejmé, i když některé detaily jsou stále abstraktní.
Chcete-li zkopírovat tento řetězec do toho, je to jen pro smyčce nebo smyčky while
nebo něco, s nimiž jste se ještě seznámit.
Tak pojďme to zkusit. Nech mě jít do copy2.c.
V copy2.c máme téměř stejný program, s výjimkou linky 27.
Vypadá to trochu složitější, ale pokud se to všechno pokazí kousek po kousku,
levá strana je stejná.
Char * t vytváří tuto věc v paměti, i když s otazníkem
protože nemáme ponětí, co je tam ve výchozím nastavení.
Na pravé straně jsme nyní představujeme novou funkci, malloc,
pro paměť alokovat, dej mi paměť,
a to zřejmě trvá, kolik argumentů, kolik věcí uvnitř závorek?
Slyšel jsem reptání 1 a 2, ale to je jen 1.
Není čárka, což znamená, že je jen 1 věc v závorkách.
I když je tu další závorky, dovolte mi, abych zmínil
to, co je uvnitř nejvzdálenějších závorek, a to je to výraz:
(Strlen (y) + 1) * sizeof (char).
Takže pokud jsme vlastně si to promyslet, je to říká mi délku s.
Proč jsem, i když s tím, 1 na délku? >> [Neslyšitelné Student odpověď]
Přesně tak. Potřebujeme prostor pro toho chlapa na ocasu, šestý znak, který má žádný anglický význam
ale mají speciální programový význam.
>> Takže potřebujeme + 1 za to, protože strlen vrací lidské očekávání délky,
ahoj nebo 5, to vám nedává dodatečné nulový znak.
Tak jsem ručně přidat to s + 1.
A pak, (char) * velikost, jsme neviděli dřív.
To není technicky funkce.
Je to zvláštní klíčové slovo, které právě vám řekne, co je velikost některých datového typu na počítači
protože ve skutečnosti, někteří z nás mají 32-bitové počítače.
Mám docela starý počítač doma, a používá pouze 32 bitů k reprezentaci ukazatele.
A tak když jsem dělal velikost datový typ, mohlo by to být 32 bitů.
Ale když jsem pomocí mého nového ozdobný počítač, mohl bych získat zpět hodnotu 64 bitů
něco jako adresu.
Takže v tomto případě, jen být super bezpečné, nebudeme na pevný kódu něco jako -
dobře, co je velikost char podle toho, co jsme řekli tak daleko?
Jsme skoro řekl, slovně, že je to 1 byte, a to je docela hodně platí plošně.
Ale znovu, předpoklady bývají špatné.
Vedou k buggy software, pokud lidé používají software způsobem jste neměli v úmyslu.
Takže pojďme abstraktní toto pryč a jen více druhově říct
Potřebuji tolik kousků paměti
a každý blok paměti by měly být stejné velikosti a charakteru,
která je ve skutečnosti rovná 1 v tomto případě, ale je to obecnější způsob psaní.
Takže, pokud je slovo ahoj, kolik bytů se malloc zřejmě přidělit ahoj?
[Student] Six. Šest >>. Přesně tolik, kolik máme otazníky na obrazovce.
A pak se hádat nyní založen na pochopení GetString
co malloc pravděpodobně vrátí? >> [Student] adresa.
Adresa čeho? První kus paměti.
>> Nemáme ponětí, co tam je, protože některé další funkce
by byly pomocí této paměti již dříve.
Ale malloc, stejně jako GetString, vrátí adresu prvního bajtu paměti
že vyčlení pro vás.
Avšak to, co se nedělá, je vyplnit tento prázdné s charakterem zpětného lomítka null
protože se ukázalo, můžete použít malloc alokovat nic: Ints, struny, pole,
plováky, studentské struktury.
Můžete použít malloc zcela obecně.
Nezajímá nebo vědět, co jste přidělování paměti pro.
Tak to by bylo troufalé pro malloc dát \ 0
na konci každého kusu paměti, že to ti dává
protože to \ 0 věc je jen konvence pro řetězce.
To není použita pro ints, to není použit pro plováky, to není používán pro studenty.
A tak mám tě s malloc je, že zátěž je zcela na vás programátor
pamatovat, kolik bytů si přiděleno, a ne vždy používat pro smyčce
nebo while a jít kolem hranice bloku paměti, že jste byl dán.
Jinak řečeno, jakmile alokovat paměť,
můžete se zeptat operační systém, oh, mimochodem, jak velký o kus paměti to bylo?
Je to zcela na vás pamatovat, pokud budete potřebovat tuto hodnotu.
>> Tak se podívejme, jak mám postupovat použít tuto paměť.
V souladu 28 a 29, proč to dělám?
Jen celkem zdravý rozum kontrola.
Jen v případě, že se něco pokazilo, žádám o nějaké šílené množství paměti
nebo jsem tolik věcí, na počítači, že tam prostě není dostatek paměti,
něco takového, aspoň chci zkontrolovat null.
Ve skutečnosti, většina počítačů vám iluzi, že každý program
mohou používat celistvost paměti RAM,
ale i tak, pokud uživatel zadá do nějaké šílené dlouhé šňůře Možná proto, že jsi špatný člověk
a oni jsou vlastně snaží shodit váš program nebo hack do něj,
Chcete-li alespoň zkontrolovat návratovou hodnotu malloc a zda se rovná null.
A pokud ano, ať to prostě skončit právě teď, protože já nevím, co dělat v této věci.
Jak mohu zkopírovat řetězec? Tam je několik způsobů, jak to udělat.
Existují str kopírovat funkce v C, ale je to super jednoduché pro nás udělat staromódním způsobem.
>> Nejprve mi dovolte přijít na to, jaká je délka s je.
Mohl jsem dát do smyčky, ale místo toho jsem jen dát to sem pro přehlednost.
Tak n nyní ukládá délku původního řetězce, který je zřejmě 5.
Pak v mém pro smyčce jsem upravujeme od 0 až na n,
a při každém opakování dávám s [i] uvnitř t [i].
Takže to je to, co jsem naznačil s mými 2 prsty ukazující na struny před.
Vzhledem k tomu, pro smyčce opakuje takhle, budu se kopírování h do tady,
e do zde, l do zde, protože to je s, to je t.
A pak konečně, v souladu 35, proč to dělám?
Musím se ujistit, že jsem konec řetězce t.
A já jsem to takhle bude super explicitní.
Ale navrhnout někoho, kdybys mohl, jiný způsob, jak to udělat.
Nemám opravdu potřebují linku 35. Je tu jiný způsob, jak to udělat.
Jo. >> [Neslyšitelné Student odpověď] >> Řekni to nahlas.
[Student] Menší než nebo rovno. Přesně >>.
Mohli bychom říci menší než nebo roven n, která byla obecně špatné
protože téměř vždy, když jdeme do stejné s tím, co jsme počítání
Půjdeme 1 krok příliš daleko.
Ale pamatujte, kolik bytů jsme přidělovat?
Máme přiděleno strlen S, takže 5 + 1 o celkové 6.
Takže v tomto případě bychom mohli udělat něco takového
tak, že kopírujete nejen ahoj, ale také \ 0 na samém konci.
Případně, mohli bychom použít funkci nazvanou str kopírování, strcpy,
ale to by nebyl ani zdaleka tak zábavné.
Ale to je vše, co dělá pod kapotou.
Pak konečně, uděláme to samé jako předtím.
I vydělávat t a pak jsem tvrdit, že původní vypadá takhle a kopie vypadá, že.
Tak zkusme to teď. Nech mě jít sem. Udělejte kopie copy2. Budeme přiblížit a spustit kopie copy2.
Budu psát ahoj malými písmeny, a opravdu jsem si malá ahoj jako originál
ale kapitál Hello pro kopii.
Ale já jsem neudělal zatím. Musím udělat 1 poslední věc zde.
46 a 47 je jasně uvolnění paměti, ale co to vlastně znamená?
Co mám dělat, myslíte tím, že volajícího 46 a řádek 47?
Jaký vliv to má mít? Jo.
[Neslyšitelné Student odpověď] >> Přesně tak.
>> Jste jen říkám operační systém, hej, díky za této paměti.
Nyní můžete použít pro někoho jiného.
A tady je dokonalým příkladem nesmyslné hodnoty.
Právě jsem použil tento paměti zapsat slovo ahoj v 2 místech,
zde, zde, zde, a zde.
Takže je to h-e-l-l-o-\ 0.
Ale pak jsem zavolat linku 46 a řádek 47, a víte, co se tam děje, pokud jde o obrázku?
Vlastně, počkejte, tento obrázek je starý.
Jakmile uděláme kopii, ten chlap je vlastně ukazuje zde,
takže se pojďme odstranit čísla a jen abstraktní pryč jako naše šípy znovu.
Co se stane v tomto filmu, když jsem volat zdarma?
[Neslyšitelné Student odpověď] >> Ani.
Pokud bych volat zdarma na S a T - trochu chyták - tento obrázek se nemění vůbec
protože volá sa volá t jen říká operační systém,
hej, můžete použít tuto paměť znovu, ale to nic nezmění na null
nebo některé speciální znak, že tím nic nezmění,
to nemění h nebo e nebo l nebo l nebo O v obou místa na cokoliv jiného.
Pokud jde o obraz, jakmile Volejte zdarma, nic změn.
A v tom spočívá původ odpadky hodnot, protože když jsem pak později v tomto programu
požádat operační systém pro více paměti s GetString nebo malloc nebo něco takového
a operační systém říká, jistě, já mám 12 bajtů paměti právě uvolněných,
použití těchto, co budete k předání?
Ty bude podal kus paměti, že bychom obvykle remíza
s otazníky, ale co jsou ty otazníky?
Dochází k nim být h-e-l-l-o, h-e-l-l-o.
Toto jsou naše nové popelářské hodnoty, jakmile uvolnit tuto paměť.
>> Je tu skutečný svět důsledky i zde.
To se stává co do činění s RAM, ale vaše počítače
vlastně to samé s diskem.
Promluvíme si o tom zejména s budoucím problémem soubor, který se zaměřuje na forenzní.
Ale co se skutečně děje, pokud máte nějaké citlivé finanční soubor na ploše
nebo některé útržkovité JPEG a přetáhněte ji do koše,
co se stane, když jej přetáhnout do koše nebo koše?
Věděl jsi, co jsem mluvil. [Smích]
Co se stane, když jste přetažení, že důkazy do vašeho koše nebo popelnice?
[Neslyšitelné Student odpověď]
No, tak pozor. Co se stane, když budeš dělat, že?
Stručná odpověď je nic, ne?
Sketchy nebo citlivé soubor je stále jen sedí někde na pevném disku.
Většina z nás alespoň se těžce poučili, že potřebujete vyprázdnit koš
nebo váš koš skutečně odstranit soubory.
A skutečně, když kliknete pravým tlačítkem myši, nebo regulace kliknutím na vašem koši
nebo zvolte Soubor, Empty Trash nebo cokoliv
a vyprázdnit koš nebo koš, co se skutečně děje a pak na tomto obrázku?
Víc nic. Takže nic se skutečně děje na disku.
>> A pokud jsme jen dočasně odbočit a napsat - budu stačí použít zadní straně tohoto.
Takže teď příběh se mění z paměti RAM, což je místo, kde programy existují
zatímco vedete je, na disk, což je místo, kde jsou uloženy dlouhodobě
i když vypadne proud, prozatím - a vrátíme se v budoucnosti -
pojďme předstírat, že to představuje pevného disku uvnitř vašeho počítače
protože zpět v den, kdy bývaly kruhové disky, podobně jako diskety.
Takže pokud máte nějaké citlivé soubor Excel, může trvat až tento kus paměti
na počítači disk, a já jsem jen kreslení stejný libovolný 1s a 0s.
Při přetažení souboru takhle do koše nebo koše,
doslova se nic nestane, protože Apple a Microsoft se rozhodl
koše a koš je opravdu jen dočasný zástupný.
Možná nakonec OS vyprázdní ji pro vás, ale obvykle to není nic,
alespoň dokud jsi opravdu málo místa.
>> Nicméně, když jdete do prázdné koše nebo Vysypat koš,
podobně, nic se nestane, aby tento obrázek.
Vše, co se stane, je jinde v počítači, tam je nějaký druh tabulky.
Je to něco jako malý tahák, který říká, že, řekněme, resume.doc,
takže váš životopis v souboru aplikace Microsoft Word bydlel v místě 123 na pevném disku,
není v paměti a ne v paměti RAM, ale na pevném disku,
a vaše útržkovité JPEG žije v 456, a soubor aplikace Excel žije na 789 nebo kdekoliv.
Při mazání souborů vlastně vyprazdňování koše nebo Koš,
tento obrázek se nemění. 0s a 1s na pevném disku nejdou nikam.
Ale tato tabulka, tento malý databáze druhů, mění.
Když smažete svůj životopis, je to, jako když je soubor odstraněn v nějakém smyslu,
ale všechny se počítač se zapomenout, kde je ta věc žije na pevném disku.
0s a 1s, že skládat svůj životopis nebo některý z těchto dalších souborů jsou stále neporušené.
>> Takže pokud jste to udělali omylem, je tu stále non-nulová pravděpodobnost
že můžete obnovit vaše data pomocí Norton Utilities nebo nějaký obchodní software
jehož cílem v životě je najít 0s a 1s, které nějak bylo opuštěno,
Zapomněli jste tady, ale nechal tady, takže můžete získat data zpět.
Nebo forenzní vyšetřovatelé s policií nebo FBI by skutečně pevný disk
a vlastně hledat vzory 0s a 1s, které vypadají jako JPEG, vypadají jako soubory Excel,
a obnovit je to tak, i když je počítač zapomněl je tam.
Takže jediný způsob, jak opravdu odstranit data, jak budeme diskutovat v budoucnosti,
je drhnout nebo otřete soubor nebo pevný disk od -
Nemůžete opravdu zbavit 0s a 1s
protože jinak byste začít s gigabitovou pevný disk
a vy byste skončit s megabajt pevného disku, pokud jste neustále museli mazat,
doslovně, 0s a 1s.
Takže to, co byste dělali, kdyby jste opravdu chtěli pokrýt své stopy
a zásadní problém je, že je tu stále 0s a 1s na disku?
Vidím někoho gestikuloval, že byste fyzicky zlomit zařízení. To bude fungovat.
[Smích] Ale jestli je to trochu drahé řešení, co by bylo rozumnější?
Jo. >> [Student] přepsat. Přepsat >> s tím, co? >> [Student] Další data.
Další údaje. Stačí si jen přepsat disku s 0s nebo 1s nebo všech 0s, vše 1s.
>> A to je skutečně to, co některé softwarové dělá.
Můžete si koupit software, nebo dokonce získat zdarma software,
a dokonce postavil do Mac OS v těchto dnech, méně v systému Windows,
je schopnost bezpečně vymazat.
Vlastně, pokud chcete, aby všichni běží domů dnes, pokud máte Mac, a to,
pokud máte nějaké věci v popelnici, můžete tak učinit Secure Empty Trash,
který dělá přesně to.
Spíše než jen mazání souborů zde, že nevymaže 0s a 1s zde,
poněkud, to jen změní je všechny, například, aby 0s a tečka, tečka, tečka.
Takže jeden z vašich budoucích psets bude skutečně úmyslně obnovit data -
fotografie, které jste udělali lidí, míst a věcí na akademické půdě
pro které uděláme forenzní obraz z digitálního fotoaparátu na paměťovou kartu,
což je přesně stejný nápad - a budete muset být vyzváni, aby skutečně najít
vzory, které představují JPEG na pevném disku,
podobně jako tento bývalý student, jehož e-mail jsem četl před několika týdny udělal
obnovit jeho sestry fotografií.
Proč jsme se 5-minut přestávku tady, a my přeskupit se více na paměti.
Tak tady je místo, kde se věci trochu mysl-ohýbání, ale je to velmi silný krok
k pochopení to všechno víc.
Zde je program s názvem pointers.c.
To je mezi dnešním ukázkovém kódu.
Všimněte si, že v prvních několika řádků, 19 až 22, vše, co děláte, je něco jako GetString
a vrácení adresu, ukládání v §.
Od té doby pro PSet i 3, pokud chcete, ale Pset 4 a na
kde si můžete začít užívat tyto vzdělávací kol nad sebe,
není důvod předstírat, že řetězce už neexistuje.
Je to určitě v pořádku jen začít říkat char *.
>> Jak stranou, on-line odkazy a knihách můžete často vidět hvězdu vedle proměnné.
Můžete dokonce vidět prostor kolem obou stranách.
Všechny z nich jsou funkčně správné.
Pro tuto chvíli, když budeme standardizovat na tomto přístupu, aby se super clear
že char * je jako říct, že znak ukazatel.
To je typ dat.
A pak název proměnné je v tomto případě.
Takže jsme dostali řetězec a my jsme říkali s.
A pak tady dole si, že dělám vlastně trochu podvod.
To se nazývá ukazatel aritmetiku, která je jakýmsi super jednoduchý.
To jen znamená, že sčítání a odčítání čísla ukazatelů.
Ale to skutečně funguje.
Tento program zřejmě vypíše řetězce s 1 znak na řádku taková, že konečný výsledek -
Jen tak můžeme zkazit, kde to bude, aby ukazatele, spusťte ukazatele, dovolte mi, abych Zoom
Nyní mi dovolte, abych typ v něco jako HELLO a typ Enter
a tiskne 1 znak na řádku.
Až do druhé před, by jsme udělali s hranatá závorka notace.
Měli bychom pro smyčce, a my bychom to printf S [i], a my bychom to udělat znovu a znovu a znovu
s lomítkem n na konci každého řádku.
Ale tento program je jiný. Tento program používá, doslova, aritmetika.
Tak co se to tady děje?
Za prvé, před smyčka ještě provede, co, jen aby bylo jasno, je to vlastně?
S je? >> [Student] adresa. >> Adresa.
>> A to je adresa, v případě ahoj, první znak v tomto slova, které je h.
Tak s je, že v tomto konkrétním příkladu, adresa h.
Takže co to znamená dělat s. + i?
No, i začíná na hodnotě 0 v tomto pro smyčce. Udělali jsme, že mnohokrát.
I se jít do délky řetězce, jak se zdá.
Tak na první iteraci tohoto cyklu, i je samozřejmě 0.
Takže tento výraz říká s + i - spíše s +0--to je samozřejmě jen s.
Takže to, co je * tady?
Nyní jsme použili na hvězdičku v trochu jiným způsobem.
Nech mě jít napřed a zbavit t, protože jsme udělali mluvíme o t a kopií s.
Teď už jen chci říct příběh zahrnující s..
A tak v tomto okamžiku, poté, co řetězec typu, náš svět vypadá úplně jako to dělal předtím
se jen s uložením adresu h a obecně ukazuje na řetězec ahoj.
Kdybych teď dělat čáry jako * (y + i), zkusme to.
Takže * (s + i). Dovolte mi zjednodušit, protože to je 0, tak se jedná * (y 0).
No, počkejte chvilku. Dále zjednodušit. To je * (y).
No, teď závorky jsou trochu hloupý, takže teď pojďme udělat * s.
Takže v první iteraci tohoto cyklu, že linka, která je zvýrazněna, 26,
je do značné míry odpovídá tisk to.
Jaký je typ dat * s?
V této souvislosti, protože hvězda se stane, že vedle s sám,
ale konkrétně, protože jsme již prohlásil s,
nejsme vytvořením proměnné už, tam žádná zmínka o char * v souladu 26,
tam žádná zmínka o klíčových řetězce, jsme jen pomocí proměnné s názvem s,
to dopadá nyní hvězda má mírně odlišné, a sice, matoucí význam.
* Tady znamená jít na adresu v s a tisknout, co tam je.
Takže s je tady, * s je - něco jako zásobníky a žebříky, za šipkou - zde.
Tak tohle je * s.
>> Takže to, co se má vytisknout na první iteraci tohoto cyklu v souladu 26?
I vytisknout% C, což je zástupný symbol pro znak,
pak \ n pro nový řádek. * (Y + i), kde i je 0, je právě tato.
Takže to, co char si mohu v% c.? H.
V dalším opakování smyčky - můžete pravděpodobně vidět, kde to bude -
další iterace i je samozřejmě 1, takže to znamená s 1,
a pak teď nemám potřebovat závorky, protože nyní hvězda potřebuje říci
přejít na adresu v paměti s 1.
Co je to? Pojďme se vrátit v čase a říkají, že toto arrow teď není ve skutečnosti dělá nám žádnou laskavost.
Ať to konkrétně říci, že je to uložení čísla 123
protože začátku tohoto řetězce ahoj, to je adresa 123, to je 124, a tak dále.
Takže na druhé iteraci, když říkám s. 1, to je jako říct, že 123 1,
jinak známý jako 124, takže to, co char se vytiskne na druhou iteraci?
E na adresu v paměti 124.
Pak znovu +, 125, 126, 127, a tato smyčka naštěstí zastaví předtím, než jsme se sem dostali
protože jsem pomocí strlen, aby se ujistil, že jsem se nepočítá příliš vysoká.
Takže to taky není ono.
Opět, je to stejně jako když jsme dělali před týdnem.
Dovolte mi, abych napsat na řádku níže, i když nechceme dělat obojí.
Toto je totožný se v této oblasti.
>> Takže i když to je řetězec, jak jsme se volat to týdny, to je opravdu char *.
Takže pokud chceme být super anal, je to opravdu správné napsat zvláštní znak
v té poloze pomocí těchto číselných adres a tuto hvězdu operátor,
ale upřímně řečeno, je to tak mnohem čistší. Takže to není špatné.
Není důvod přestat řádek 27 zde, ale 26 je funkčně stejný,
a je to funkčně stejné přesně z důvodů, které jsme byli diskutovat tak daleko.
A konečně, 29 je jen dobré praxe.
Volání zdarma s znamená, že nyní dáváte zpět paměť, která GetString vám dal
protože opět, jak už jsem zmínil Pondělí, GetString týdny
bylo zavedení chybu do kódu.
Váš kód týdny měl úniky paměti
kdy jste se ptali GetString pro paměť, ale nikdy jsi dával zpět.
A to byl uváženě volený námi pedagogicky
protože je to prostě příliš o čem přemýšlet brzy.
Ale teď potřebujeme více symetrii.
Zeptáte-li se počítač paměť, jako je tomu v případě GetString,
jako je tomu v případě očividně pro malloc,
Nyní musíte pro PSet 4 kupředu i bez takové paměti.
Všimněte si, to je něco jiného než říkat int n.
Nemusíte se uvolnit, protože jsi nevolal GetString
a nevolal malloc.
>> A i když jsi volal GetInt jak budeme nakonec vidět,
GetInt není alokovat paměť pro vás, protože můžete skutečně projít kolem celá čísla
a plave a písmen přesně tak, jak jsme to dělali několik týdnů.
Řetězce, i když jsou zvláštní, protože opravdu jsou zřetězení více znaků.
Takže jsou jen odlišné od znaků a plováky a ints a podobně.
Ale vrátíme se, že zanedlouho.
Jakékoli otázky, pak na tomto začátku ukazatelů? Jo.
[Neslyšitelné Student otázka]
Ah, velmi dobrá otázka.
Jedna z mála věcí, C skutečně dělá pro vás, což je výhodné,
je to vyřeší za vás, co je velikost tohoto datového typu
a pak dělá, že druh množení pro vás.
To není v případě znaků, neboť téměř vždy znak je 1 byte,
tak to prostě funguje.
Ale v zájmu diskuse, pokud jste byli skutečně tisku celá čísla
a vy se pokoušíte vytisknout nějakou hodnotu s, který ukazoval na celé číslo,
si podobně nebudou muset dělat + 4 * i jen proto, že int je 4 bajty.
Ukazatel aritmetické znamená, že C a kompilátor dělat všechny, že matematika pro vás.
Jediné, co musíte starat jen o počítání v druhu lidském smyslu. Jo.
[Student] Pokud deklarujete řetězec uvnitř smyčky for, musíš uvolnit později?
Dobrá otázka.
>> Pokud jste prohlásil řetězce uvnitř pro smyčky, budete potřebovat uvolnit později?
Jediné, co potřebujete, abyste uvolnili paměť, že jste přidělit s GetString nebo malloc.
Takže pokud jste právě řekl něco jako - dovolte mi, abych složené závorky nyní tak celý kód je věnována.
Pokud jste něco, byť buggily, jako je tato, char * t = s,
nemusíte se zdarma t, protože t neobsahovala žádnou zmínku o malloc nebo GetString.
Pokud naopak jste to udělali, GetString, pak ano, budete muset zdarma t.
A ve skutečnosti, jediná šance, jak to udělat, je nyní uvnitř této smyčky, pro stejnou vydání působnosti
že jsme diskutovali v minulosti.
Jinak byste se přidělování paměti, přidělování paměti, přidělování paměti,
a na konci programu, protože to mimo tento smyčky,
t neexistuje, ale nikdy jsi na operační systém
že jste nepotřebovali, že paměť už.
A netrvalo dlouho, pro PSet 4 nebo 5 budeme vybavit si s programem s názvem Valgrind,
který je podobný v duchu, aby GDB v tom, že je to má poněkud tajemný rozhraní,
ale jeho účel v životě je, aby vám pomohl.
A Valgrind je program, který bude v budoucnu hledat své programy
hledá úniky paměti, ať už z GetString nebo malloc,
které začneme používat to více, jak jsme přestali používat CS50 knihovny tolik.
Konečně jsme nyní druh slovníku a druh mentálního modelu v teorii
s nimiž se vyřešit tento rozbité program.
>> Takže v tomto rozbité programu, swap funguje uvnitř swapu,
ale nikdy skutečně odpracovaných hodin v hlavním, protože hlavní prošel v x a y, si vzpomenout,
a ty byly předány v roce hodnotami, abych tak řekl.
Kopie z nich dostali na swap.
Do konce roku swapu, a b skutečně byly vyměněny,
ale samozřejmě x a y, jak jsme diskutovali v pondělí, nebyl.
Takže navrhuji zeleně zde, že to je vlastně řešení zde.
A skutečně, dovolte mi, abych přesunout své hvězdy jen proto, aby bylo v souladu
i když, opět, funkčně to nevadí.
V budoucnu týdnů budeme vysvětlit kdy a proč to dělá záležitost.
Takže zeleně Nyní je řešení.
Upřímně řečeno, vypadá to mnohem chaotičnosti, protože mám všechny z těchto hvězd.
Dovolte mi, abych poukázat na jednu věc.
Horní řádek zde, kde se říká, že int * a int * b
je zásadně dělá to samé, jako tomu vždy bylo.
To prohlašuje 2 argumenty nebo parametry vyměnit,
První z nich je int ukazatel nazvaný,
z nichž druhá je int ukazatel nazvaný b.
Jediná věc, která je nová v tomto bodě je fakt, že je tu hvězda tam.
>> Co to znamená? Není int, b není int.
Je adresa int a b je adresa jiného int.
Tady dole, to je místo, kde jsem se přiznat, že C dostane matoucí.
Nyní jsme použili hvězdu, ale to má jiný význam v této souvislosti.
Vzhledem k tomu, že nejsme deklarovat ukazatele, jak jsme tady,
zde jsme dereferencing věci.
Takže technicky, hvězda v této souvislosti první, druhý a třetí řádek uvnitř odkládacího prostoru
je dereference operátor, který prostě znamená jít tam.
Takže stejně jako můj prst následoval na šipku h,
* Prostředek přejít na tuto adresu a najdi mi int, která je tam.
* B prostředky jdou na adresu a předat mi, co tam je.
Takže pojďme překreslit obraz od pondělí nyní používají hromadu snímků,
spodní z nichž jeden je bude hlavní,
horní z nichž jeden je bude výměna,
tak, aby náš svět vypadá, stejně jako pondělí takhle.
Zde je kus paměti, že hlavní je bude používat.
>> Připomeňme, že od pondělí program prostě musel 2 proměnné,
jeden volal X a jeden s názvem y, a já jsem dal čísla 1 a 2 tam.
Teď, když jsem hovor vyměnit jako já v pondělí,
dříve, když jsem použil červenou verzi tohoto programu, který vypadá takto,
Mám 2 parametry, a a b, a co píšeme zde a zde?
Jen 1 a 2, doslova kopíruje x a y.
Dnes jsme změnit.
Dnes místo předání v ints a, b budeme předávat v 2 adresy.
Tyto adresy se stalo, aby ukazoval na ints, ale tyto adresy nejsou ints sami.
Jsou adresy. Je to jako poštovní adresu místo.
Takže teď musíme jen dát si trochu podrobněji na obrazovce.
To je můj počítač paměti, jak to bylo celý den.
Nyní potřebujeme nějaký libovolný schéma číslování.
Takže řekněme, náhodou, že toto je adresa paměti 123, 124.
Řekněme to je 125, to je 126, a tak dále, ale je to zcela libovolný.
Potřebujeme jen trochu číslování v mé paměti.
Takže teď, když jsem vlastně předat x a y, nebudu se pak x a y;
Jdu předat v poštovní adresu, abych tak řekl, o x a y
tak, že to, co je uložena zde a zde není 1 a 2,
ale pokud můžete vidět můj malý text, co je předán v tady a tady?
[Neslyšitelné Student odpověď] >> Přesně tak. 123 dostane dal sem a 124 dostane dát sem.
>> Teď, protože jsem použil hvězdu v tomto prvním řádku až sem na vrchol,
můj program prostě ví, že 123 a 124, i když to samozřejmě celá čísla
že každý člověk může všimnout, by měly být vykládány jako adresy, číselné adresy.
Nejsou samy o sobě ints, jsou adresy,
a to proto, že jsem výslovně dal hvězdy tam.
Takže teď v mé první, druhý a třetí řádek aktuálního kódu, co se tu děje?
Pojďme čerpat zbytek obrazu.
Tmp je, stejně jako to bylo v pondělí. Nic zvláštního tmp.
Je to jen místní 32 bitů proměnné, a uvnitř, že jsem zřejmě uložení hodnoty *.
Teď, když jsem řekl, tmp =, co bych dal tu? >> [Student] 123.
123. Ale to není to, co dělám.
Říkám tmp = *. Počet hvězdiček znamená tam.
Takže zde je, 123. Jak mám jít tam? Předstírat, že se tam šipka.
No, tady to je, 1. Takže to, co je uložena v tmp, zřejmě? Jen 1.
Takže jinými slovy, tmp je * a, * prostředkem přejděte na adresu, která je v současné době v,
což je zřejmě 123.
>> Dobře, tady jsme na místě 123, vidím číslo 1,
tak jsem dám číslo 1 tam.
Teď, co mám dělat, v řádku 2, * = * b?
To je trochu více zapojit, protože nyní to, co je? Je to 123.
Takže * je kde? Přesně tam, kde jsem byl předtím. Takže tam. Dobře.
Nyní, konečně, a pak konečně to začne dávat smysl, doufejme,
* B znamená to, co je v B? 124. Tak jsem třeba tam, což je o 2.
Tak co jsem dal, kde?
2 jde do tady, protože * b přejde do *. Takže to udělám.
A už můžete vidět, možná, že jsme tak mnohem blíže
k řešení tohoto hloupý, jednoduchý problém správně poprvé
protože nyní máme před sebou ještě vzpomínku na to, co bylo x,
máme 2 kopie, sice y,
ale řádek 3 nyní říká, * b.
Tak tady je b. * B prostředky tam. Tak kde je umístění 124?
Je to prý tady. Tak co mám dát sem? Samozřejmě, tmp.
Takže teď jsem to. Tak jsem si tady 1 a 2 zde.
A teď, co o tom všem, 123, 124, a 1?
Jakmile swapových výnosů, tato paměť je stejně dobrý jako ztracené
protože jakmile swapových vrátí, operační systém
je zdarma k použití, že paměť v budoucnu znovu.
Pouze paměť Hlavní je v dolní části této tzv. zásobníku drží kolem.
>> A tak jsme konečně máme nyní pracovní verzi.
Nech mě jít do swap.c, a všimněte si následující.
V horní části programu změnil jsem prototyp být int * a int * b.
Takže jediné, co jsem změnil jít z červené, která byla špatná, na zelenou, což je dobré,
I se přidal tyto hvězdy dnes.
Ale pak tady v prohodit sám jsem musel zkopírovat, vložit to, co bylo právě na snímku.
Mám hvězdu tady, hvězda zde - to odpovídá prototyp -
a pak všechny tyto věci teď mají hvězdy s výjimkou tmp
protože použití pomocné proměnné, tu nic nového.
Potřebuju jen dočasné úložiště pro int.
Takže nepotřebujeme hvězdu tam.
Potřebujeme jen hvězdu, takže můžeme přejít tento druh svévolné hranice
mezi těmito 2 snímků v mé paměti počítače.
Ale jedna poslední věc se musí změnit, a možná jste zahlédli ho již.
Co druhý řádek je samozřejmě jiná teď? >> [Student] & x.
>> Jo, tak 25 je poslední řádek kódu musím změnit pro tuto práci.
Před týdnem a ještě v pondělí řádek 25 vypadal, vyměnit X a Y,
a toto bylo právě rozešla, protože pokud říkáte swap (x, y)
dáváte kopie X a Y vyměňovat, pak to dělá svou věc,
ale vy jste nikdy skutečně mění, x a y sám.
Takže i když jste nikdy neviděl tento znak dříve s ampersand v kódu,
jen hádat. Co ampersand dělat, zřejmě?
[Student] zastává adresu. >> Zastává adresu.
Takže ampersand říká dej mi adresu x.
Kdo ví, kde to je? Stává se, že je 123. Nezajímá mě. Dej mi adresu x.
A y se rozumí dej mi adresu y.
A v tomto bodě příběh je zcela v souladu s obrázkem jsme vycházeli před chvílí.
>> Tak jsem si přiznat ukazatele, určitě pro mě, když jsem poprvé začal učit to,
byly rozhodně jedna z nejtěžších věcí, zabalit svou mysl kolem.
Ale uvědomit, zejména pokud budeme držet hrát s těmito druhy věcí,
Pokud vyrazit na tyto super jednoduchý druh intelektuálně nezajímavý problémy
pouhého pohybu atomů kolem, odpověď na mnoho zmatku s ukazateli
Opravdu je možné odvodit z těchto velmi základní mechaniky.
Tady je adresa. Jděte tam s hvězdou.
Nebo naopak, tady je ampersand. Zjistit, co je adresa ve skutečnosti je.
Dobrá.
Takže tam, kde se všechny tyto paměti pochází z?
Jsme vypracován tento obrázek několikrát, a pořád perspektivní vrátíme k tomu,
ale tady je reprezentace paměti vašeho počítače
to je trochu víc, než náš označené tabuli je zde.
Text segment na vrcholu představuje to, co ve vztahu k programu?
[Neslyšitelné Student odpověď] >> Je nám líto,? Řekni to znovu.
[Student] skutečný program. >> Aktuální program.
>> Takže 0s a 1s, které jste sestavili po zápisu kód v C a pak běží zvonění
a generování 0s a 1s skončí jako dobývání zastrčený tam v paměti
protože při poklepání na ikonu na vašem počítači Mac nebo PC
nebo spustit příkaz jako Mario u Vašeho řádku, vaše 0s a 1s z disku
si nahraje do paměti tak, že počítač může manipulovat s nimi
a realizovat rychleji.
Takže inicializované údaje a neinicializované dat, nebudeme moc mluvit o těch,
ale ty jsou jen globální proměnné.
Inicializováno znamená globální proměnné, které jste zadali hodnoty;
neinicializované znamená globální proměnné, které jste dosud dávají hodnoty.
Pak je tu tyto proměnné prostředí, které budu úplně vlnu ruku na,
ale jsou tam, a že ukládá věci jako uživatelské jméno
a jiný druh na nižší úrovni detailů.
Ale Nejšťavnatější kusy z paměťové tyto rozložení je to, čemu se říká stack a haldy.
Stack znovu, aby bylo jasno, je paměť, která se používá vždy, když jsou volány funkce,
pokud existují místní proměnné
a pokud jsou parametry, které prošel kolem.
To vše se děje v zásobníku.
Haldy jsme nemluvili o tom, ale hádat, kdo používá haldy.
Jen jiný kus paměti.
Stává se to být vypracovány zde nahoře, ale to je arbitrární obrazové konvence.
Kdo je zřejmě používá paměť z haldy týdny?
Je to technicky vy, ale nepřímo. >> [Student] GetString.
GetString a malloc. Tak tady je zásadní rozdíl.
>> Víte, za posledních pár týdnů, že pokud budete potřebovat paměť, stačí deklarovat proměnnou.
Pokud potřebujete hodně paměti, deklarovat pole přímo uvnitř vašeho funkce.
Ale problém jsme stále čelí, je, pokud jste deklarovat proměnné lokálně uvnitř funkcí,
jakmile se funkce vrátí, co se stane do paměti a ty proměnné?
Jen trochu z toho je již tvoje, že jo? Je to prostě zmizí druh koncepčně.
Je to ještě fyzicky tam, samozřejmě, ale to je už ne vaše právo na používání.
To je samozřejmě problematické, pokud chcete psát funkce v životě
že skutečně alokovat paměť a nedávají ji zpět okamžitě.
Věc v bodě: GetString tyto účel v životě je mít tušení předem
jak velký řetězec budu psát na klávesnici,
ale to musí být schopen alokovat paměť držet Davida nebo Hello
nebo celé esej, který uživatel může zadali dovnitř
Takže GetString byl pomocí malloc.
Malloc proto musí používat ne stoh;
místo toho se pomocí tohoto věc s názvem haldy.
Na tom není nic jiného na paměti. Není to rychlejší nebo pomalejší, nebo něco podobného.
Je to jen fyzicky na jiném místě.
>> Ale pravidlo je, že paměť, která je na haldě
nebude nikdy odňato, dokud nezavoláte - hádat - zdarma.
Naopak, každý paměť můžete požádat o na stacku jen deklarovat pole
nebo deklarování proměnné, jako jsme to dělali několik týdnů,
že ve výchozím nastavení skončí na zásobníku.
A to funguje velké 90% času, ale na těch vzácnějších případech
, kde chcete alokovat paměť a udržovat ji kolem,
pak budete muset použít funkci jako malloc.
Nebo jsme používali funkci jako GetString, což používá malloc.
Pojďme se podívat, kde by to mohlo zlomit dolů a pak se podívat na Binkym.
Vrátíme se k tomu v budoucnu.
Zde je super jednoduchý program, který v prvních 2 řádky co dělá?
V angličtině, co tyto první 2 řádky kódu provádějí uvnitř main?
[Neslyšitelné Student odpověď]
Opatrně. To mi nedává adresu X nebo Y.
[Student] dává odkazy na ints. Dobrý >>. Dejte mi 2 ukazatele na celá čísla.
Jinými slovy, dej mi 2 kusy paměti, že jsem udržují výkres dnes,
i když jsem vymazal to teď, jako čtverce.
Dejte mi 2 kusy paměti, jeden s názvem x, jeden volal y -
dříve jsem jim s a t - a co je typ tohoto kusu paměti?
Bude to uložit adresu.
Je to z * typ int.
>> Takže adresa int nakonec žít v x,
adresa int nakonec žít v y,
ale zpočátku, co je uvnitř x a y? Kdo ví? Popelářské hodnoty.
To nemá nic společného s ukazateli.
Pokud jsme se dát tam něco, kdo ví, co je to vlastně je?
Nyní, x. Co se tu děje? To je legitimní nyní, protože x je ukazatel. Je to int *.
Takže to znamená, že mohu dát do x adresu nějakého kusu paměti.
Co malloc vrátí? Perfect, vrátí adresy,
adresa prvního bajtu v celé kus paměti.
Kolik bytů se tato zdánlivě přidělování, například, v přístroji?
Co je to velikost int? 4.
Pokud si myslíte, že zpět do týdne 1, to není super důležité vždy pamatovat na to,
ale v tomto případě je užitečné vědět, 4 bajty.
Takže tohle je přidělování na haldy 4 bajty
a to se vrací adresu první se mi svévolně.
A teď, co je x dělá?
* X = 42 dělá co?
Pokud v tomto okamžiku v příběhu máme x, který vypadá takto s některými odpadky hodnotou,
To je nyní y s některými odpadky hodnotou, nyní v souladu 3 jsem přidělena 4 bajty.
Tento obrázek v podstatě vypadá takto.
Nebo více specificky, pokud je to libovolná adresa 123, to je to, co náš příběh teď vypadá.
* X = 42 nyní znamená co? To znamená, že jít na adresu 123 a dal číslo 42 tam.
Nepotřebuji k tomu tyto řádky, protože neděláme řetězce.
>> Měl jsem právě napsal takhle, a jen pro demonstraci boží,
42 jako int druh zabírá hodně místa, 4 bajty.
Tak to je to, co se tam stalo, ale je tu problém nyní.
* Y = 13. Co se bude dít tady?
Problém je * y v našem zjednodušeném světě jen znamená, že jít na adresu v y.
Co je v y? Je to nějaký popelářský hodnota.
Takže předpokládejme, že odpad hodnota je 5551212, něco šílené takového.
* Y znamená jít řešit 5551212.
To je jako tady. To neexistuje, například.
Takže * y dostane 13 znamená, že jsem se snaží čerpat 13 zde. To neexistuje.
Jsem překročil segment tabuli. Co získám?
To tajemná zpráva segmentation fault, protože se snažím, aby v paměti
hodnota jako 13 na místě, které neexistuje.
Zbytek programu by mohlo fungovat v pořádku, ale až do té doby to dělá ne.
Takže pojďme se pokusit vyprávět tento příběh.
Vrátíme se k tomu jednou jsme mluvili o hex.
Vraťme se k tomu, a uzavřít s tímto, čemu se říká Binky,
který odvolání je profesorem Stanfordské sedí doma hraje s Claymation,
vyprávět příběh o přesně stejné programu.
Je to jen asi 3 minuty dlouhé. Zde máme Binky.
[Male reproduktor na videu] Ahoj Binky, probudit. Je čas na ukazatel zábavu.
[Binky] Co je to? Další informace o ukazateli? Oh, dobrota!
[Samec reproduktor] No, začít, myslím, že budeme potřebovat pár rad.
>> [Binky] Dobře. Tento kód přiděluje 2 ukazatele, které mohou ukazovat na celá čísla.
[Samec reproduktor] Dobře. No, vidím 2 ukazatele, ale nezdá se, že se ukázal k ničemu.
[Binky] To je pravda. Zpočátku, ukazatele neukazují na nic.
Věci, které směřují k se nazývá pointees, a jejich nastavení je samostatný krok.
[Samec reproduktor] Oh, dobře, dobře. Věděl jsem, že. V pointees jsou oddělené.
Ehm, tak jak si přidělit pointee?
[Binky] Dobře. Tento kód alokuje nový integer pointee, a tato část nastaví x poukázat na to.
[Samec reproduktor] Hej, to vypadá lépe.
Tak, aby to něco udělat. >> [Binky] Dobře.
Budu dereference ukazatele x pro uložení čísla 42 do svého pointee.
Pro tento trik budu potřebovat svou kouzelnou hůlku z dereferencing.
[Samec reproduktor] Vaše kouzelná hůlka z dereferencing? To je skvělé.
[Binky] To je to, co kód vypadá. Já si jen nastavit počet a ... [Praskání zvuku]
[Samec reproduktor] Hele podívej, tam to jde.
Tak dělá dereference na X následuje šipka přístup k jeho pointee,
v tomto případě k uložení 42 tam.
Ahoj, zkuste jej uložit číslo 13 přes jiné ukazatele, y.
[Binky] Dobře. Já půjdu sem k y a dostat číslo 13 nastavení
a pak mít hůlku z dereferencing a jen ... [Bzučení] Whoa!
[Samec reproduktor] Oh hey, to nepomohlo.
>> Řekni, Binky, já si nemyslím, že dereferencing y je dobrý nápad
protože nastavení pointee je samostatný krok
a já si nemyslím, že jsme kdy udělali.
[Binky] Hmm, dobrá připomínka.
[Samec reproduktor] Jo. Jsme přiděleno ukazatel y, ale nikdy jsme nastavit, aby ukazoval na pointee.
[Binky] Hmm, velmi pozorný.
[Samec reproduktor] Hej, vypadáš dobře tam, Binky.
Dokážeš to opravit tak, že y odkazuje na stejný pointee jako x? >> [Binky] Jasně.
Budu používat svůj kouzelnou hůlku ukazovací práce.
[Samec reproduktor] je, že bude problém jako dřív?
[Binky] No, to nedotýká pointees.
Je to prostě změní jednoho ukazatel ukazovat na stejnou věc jako jiný. [Praskání zvuku]
[Samec reproduktor] Oh, vidím. Nyní y poukazuje na stejném místě jako x.
Tak počkat. Nyní y je stanovena. Má pointee.
Takže si můžete vyzkoušet hůlku z dereferencing znovu poslat 13 OVER.
[Binky] Uh, jo. Tady jde. [Praskání zvuku]
[Samec reproduktor] Hele, podívej se na to. Nyní dereferencing práce na y.
A protože ukazatele jsou nelegální, že jeden pointee, oba viz 13.
[Binky] Jo, sdílení. Cokoliv.
>> Takže se budeme přepínat místa teď?
[Samec reproduktor] Oh look, jsme mimo čas. >> [Binky] Ale -
[Samec reproduktor] Jen si vzpomeňte na 3 ukazatele pravidla.
Číslo 1, základní struktura je, že máte ukazatel, a to ukazuje na na pointee.
Ale ukazatel a pointee jsou oddělené, a Častou chybou je nastavit ukazatel
ale zapomněl dát jí pointee.
Číslo 2, ukazatel dereferencing začíná u ukazatele a sleduje šipku přes
přístup k jeho pointee.
Jak všichni víme, to funguje pouze v případě, že je pointee,
jaký druh se vrací do Pravidlo číslo 1.
Číslo 3, ukazatel přiřazení vezme jeden ukazatel a změní ji
poukázat na stejné pointee jako jiný ukazatel.
Takže po zadání, budou tyto 2 ukazatele ukazovat na stejnou pointee.
Někdy tomu se říká sdílení.
>> A to je vše, co k ní opravdu. Bye-bye teď.
To je Binky. To je CS50. Uvidíme se příští týden. [Potlesk]
>> [CS50.TV]