[Powered by Google Translate] [Odjeljak 4 - ugodnije]
[Rob Bowden - Sveučilište Harvard]
[Ovo je CS50. - CS50.TV]
Imamo komentar sutra, u slučaju da vi ne znate.
To je u osnovi o svemu mogli ste vidjeti u razredu ili su trebali vidjeti u razredu.
To uključuje pokazivače, iako su oni vrlo nedavno tema.
Trebali bi barem razumjeti visoke razine njih.
Sve što je prešao u razredu trebali razumjeti za kviz.
Dakle, ako imate pitanja o njima, možete ih pitati sada.
No, to će biti vrlo student na čelu sjednica gdje vi postavljati pitanja,
pa se nadam da ljudi imaju pitanja.
Ima li tko pitanja?
Da. >> [Student] Mogu li ići preko pokazivača opet?
Ja ću ići preko pokazivača.
Svi vaši varijabli nužno živjeti u sjećanju,
ali obično ne brinuti o tome, a vi samo reći x + 2 y + 3
i prevodilac će shvatiti gdje su stvari žive za vas.
Nakon što ste se bave pokazivače, sada izričito koristite one memorijske adrese.
Dakle, jedna varijabla samo da će ikada živjeti u jednoj adresi u bilo kojem trenutku.
Ako želimo da se proglasi pokazivač, što je vrsta će izgledati?
>> Želim da proglasi pokazivač str. Što tip izgleda?
[Student] int * p. >> Da. Dakle, int * p.
I kako sam to učiniti ukazati na x? >> [Student] Ampersand.
[Bowden] Dakle, znak za struju doslovno se zove adresa operatora.
Dakle, kada kažem & x to je dobivanje memorijsku adresu varijable x.
Dakle, sada imam pokazivač p, i bilo gdje u mom kodu mogu koristiti * p
ili sam mogao koristiti x, a to će biti točno ista stvar.
(* P). Što se to radi? Što to znači zvijezda?
[Student] To znači da je vrijednost u tom trenutku. >> Da.
Dakle, ako gledamo na to, to može biti vrlo korisno izvući dijagrame
gdje je to kutijica memorije za x, što će se dogoditi da imaju vrijednost 4,
onda imamo malo okvir memorije za p,
i tako p ukazuje na x, tako da smo nacrtali strelicu iz p na X.
Dakle, kada kažemo * p Mi tvrdimo ići na kutiji da je str.
Star je slijediti strelicu, a zatim učinite što god želite s tom okviru tamo.
Dakle, ja mogu reći * p = 7, te da će ići na kutiji da je x i promjena koje bi sedam.
Ili bih mogao reći int z = * p * 2; To je zbunjujuće jer je zvijezda, zvijezda.
Onaj zvijezda dereferencing p, druga zvijezda pomnoži sa dva.
Obavijest bih mogao imati jednako dobro zamijenio * p sa x.
Možete ih koristiti na isti način.
A onda kasnije mogu imati p točku na potpuno novu stvar.
Ja samo mogu reći p = &z;
Dakle, sada p se više ne bodove na X, to ukazuje na z.
I svaki put sam napraviti * p je isti kao i radi z.
Tako je korisna stvar o tome je jednom počnemo uzimajući u funkcijama.
>> To je vrsta beskorisno proglasiti pokazivač koji pokazuje na nešto
i onda ste samo ga dereferencing
kad ste mogli koristiti izvornu varijablu za početak.
No, kada ste dobili u funkcijama - pa recimo imamo neku funkciju, int foo,
koji uzima pokazivač i samo se * p = 6;
Kao što smo vidjeli prije s swapa, ne možete učiniti djelotvorno swap i zasebnu funkciju
a upravo prolazi cijela broja jer je sve u C uvijek prolazi vrijednosti.
Čak i kada ste prolazi upućuje ste u prolazu vrijednosti.
To samo tako dogodi da te vrijednosti su memorijske adrese.
Dakle, kada kažem foo (p); sam prolazeći pokazivač na funkciju foo
a zatim foo radi * p = 6;
Dakle, unutar te funkcije, * p je uvijek jednak x,
ali ja ne mogu koristiti x unutar te funkcije jer to nije opfateno roku tu funkciju.
Dakle, * p = 6 je jedini način ja mogu pristupiti lokalnu varijablu iz druge funkcije.
Ili, dobro, pokazivači su jedini način ja mogu pristupiti lokalnu varijablu iz druge funkcije.
[Student] Recimo da ste htjeli vratiti pokazivač. Kako točno to učiniti?
[Bowden] Povratak pokazivač kao nešto poput int y = 3; povratak & y? >> [Student] Aha.
[Bowden] Ok. Vi nikada ne bi trebao to učiniti. To je loše.
Mislim da sam vidjela u ovih predavanja slajdovima ste počeli vidjeti cijeli ovaj dijagram memorije
gdje ovdje imaš memorijsku adresu 0
i ovdje dolje imate memorijske adrese četiri nastupa ili dva na 32.
Pa onda imaš neke stvari i neke stvari i onda imate svoj stack
i ti imaš svoju hrpu, koju upravo počeo učiti o tome, odrastanju.
[Student] Zar nije hrpa iznad stog?
>> Da. Gomila je na vrhu, zar ne? >> [Student] Pa, on je stavio 0 na vrhu.
[Student] Oh, on stavi 0 na vrhu. >> [Student] Oh, u redu.
Odricanje od odgovornosti: Bilo gdje sa CS50 ćeš vidjeti da na ovaj način. >> [Student] Ok.
To je samo da kad ste prvi put vidite hrpe,
sviđa kada mislite hrpom mislite slaganje stvari na vrhu jedan drugoga.
Dakle, mi imaju tendenciju da okretanje ovo okolo tako stog raste kao stog inače
umjesto hrpe visi. >> [Student] Ne hrpe tehnički odrasti previše, iako?
To ovisi o tome što znači odrasti.
Stog i hrpa uvijek raste u suprotnim smjerovima.
Stog uvijek raste u smislu da je odrastao
prema višim memorijske adrese, i nagomilati raste prema dolje
u da raste prema nižim memorijskim adresama.
Dakle, na vrhu je 0, a dno je visoke memorijske adrese.
Oni oboje raste, samo u suprotnim smjerovima.
[Student] Ja samo značilo da zato što je rekao da stavi snop na dnu
jer mi se čini više intuitivno, jer za hrpu početi na vrhu hrpe,
gomila je na vrhu sebe previše, pa that's - >> Da.
Također mislim na hrpi kao odrastanja i veći, ali stog više.
Dakle, stog je onaj koji smo vrsta žele pokazati odrastanja.
Ali kud god da pogledamo inače će pokazati adresu 0 na vrh
i najviši memorijska adresa na dnu, tako da je ovo vaš uobičajeni pogled memorije.
>> Imate li pitanje?
[Student] Možete li nam reći nešto više o hrpi?
Da. Ja ću dobiti da u drugi.
Prvo, ide natrag zašto povratka & Y je loša stvar,
na stog imate hrpu stog okvira koji predstavljaju sve funkcije
koji su bili pozvani.
Dakle ignoriranje prethodnih stvari, na vrhu vašeg stacka uvijek će biti glavna funkcija
budući da je prvi funkcija koja se zove.
I onda kad zoveš drugu funkciju, stog će rasti prema dolje.
Dakle, ako sam nazvati neku funkciju, Foo, i to dobiva svoj vlastiti stog okvir,
to može nazvati neke funkcije, bar, ona dobiva svoj vlastiti stog okvir.
A bar mogao biti rekurzivna i to bi mogao se zvati,
i tako da drugi poziv na traci će dobiti svoj vlastiti stog okvir.
I tako ono što ide u tim okvirima stog su sve lokalne varijable
i sve funkcije argumenata da -
Bilo stvari koje su lokalno opfateno na ovoj funkciji ići u tim okvirima stog.
Dakle, to znači da kad sam rekao nešto slično bar je funkcija,
Samo ću objaviti cijeli broj, a zatim se vratiti pokazivač na taj cijeli.
Dakle, gdje se god živjeti?
[Student] y živi u baru. >> [Bowden] Aha.
Negdje u tom malom trgu memorije je littler trg koji ima y u njemu.
Kad sam se vratiti i y, ja sam se vraćaju pokazivač na ovom malom bloku memorije.
Ali onda kada funkciju vraća, njegova stog okvir dobiva popped off snop.
I to je razlog zašto se zove stog.
To je kao strukture stog podataka, ako znate što je to.
Ili čak kao hrpu ladica je uvijek primjer,
Glavni će ići na dnu, zatim prvi funkcija nazovete će ići na vrhu da,
i ne može se vratiti na glavni dok se ne vratite iz svih funkcija koje su pod nazivom
koji su smješteni na vrhu.
>> [Student] Dakle, ako vam je to vratiti i y, koja vrijednost je podložan promjenama bez prethodne najave.
Da, it's - >> [student] To bi mogao biti prepisan. >> Da.
To je u potpunosti - Ako ste probati i -
To bi također biti int bar * jer je vraća pokazivač,
tako da je njegova povratni tip je int *.
Ako pokušate koristiti povratnu vrijednost ove funkcije, to je nedefinirano ponašanje
jer da pokazivač pokazuje na lošem sjećanju. >> [Student] Ok.
Pa što ako, na primjer, proglasio int * y = malloc (sizeof (int))?
To je bolje. Da.
[Student] Razgovarali smo o tome kako, kada smo povucite stvari na naš koš za smeće
oni ne zapravo izbrisani, a mi se samo izgubiti svoje naputke.
Dakle, u ovom slučaju mi ​​zapravo izbriše vrijednost ili je to još uvijek postoji u sjećanju?
Za veći dio, to će još uvijek biti tamo.
No, recimo da mi se dogoditi nazvati neku drugu funkciju, Baz.
Baz će dobiti svoj stack frame ovdje.
To će biti prepisivanja sve ove stvari,
i onda ako kasnije probati i koristiti pokazivač da li je dobio prije,
to neće biti ista vrijednost.
To se događa da su se promijenile samo zato što se zove funkcije Baz.
[Student] Ali nije mi ne bismo dobili još tri?
[Bowden] U svim vjerojatnost, što bi.
No, ne možete se osloniti na to. C samo kaže nedefinirano ponašanje.
>> [Student] Oh, to ne. Ok.
Dakle, ako želite da se vrati pokazivač, ovo je mjesto gdje malloc dolazi u uporabi.
Pišem zapravo samo vratili malloc (3 * sizeof (int)).
Mi ćemo ići preko malloc više u drugi, ali ideja malloc je sve svoje lokalne varijable
uvijek ići na stog.
Sve što je malloced ide na hrpu, i to će zauvijek i uvijek biti na hrpi
dok je izričito ga osloboditi.
Dakle, to znači da kada malloc nešto, to će preživjeti nakon funkcijskih vraća.
[Student] Hoće li preživjeti nakon Program zaustavi? >> Ne
Ok, tako da će biti tamo dok program je sve način učinio trčanje. >> Da.
Možemo ići preko pojedinosti o tome što se događa kada se program zaustavi.
Možda ćete morati da me podsjeti, ali to je zasebna stvar u cijelosti.
[Student] Pa malloc stvara pokazivač? >> Da.
Malloc - >> [student] Mislim malloc označava blok memorije koja pokazivač može koristiti.
[Bowden] Želim da dijagram opet. >> [Student] Dakle, ova funkcija radi, iako?
[Student] Da, malloc označava blok memorije koju možete koristiti,
a zatim ga vraća adresu prvog bloka te memorije.
>> [Bowden] Aha. Dakle, kada ste malloc, ti si grabbing neki blok memorije
koja je trenutno u hrpi.
Ako gomila je premala, onda hrpa samo će rasti, a raste u tom smjeru.
Pa recimo hrpa je premala.
Tada je riječ o rastu malo i vratiti pokazivač na ovom bloku koji samo rasla.
Kada besplatne stvari, radite više prostora u gomili,
pa onda kasnije nazvati za malloc može ponovno tu memoriju koju je prethodno oslobodio.
Važna stvar o malloc i free je da vam daje potpunu kontrolu
tijekom trajanja tih memorijskih blokova.
Globalne varijable su uvijek živ.
Lokalne varijable su živi unutar svog djelokruga.
Čim idete prošlosti kovrčave vitice, lokalne varijable su mrtvi.
Malloced memorija je živ kada želite da bude živ
, a zatim je pušten kada ga reći da će biti objavljen.
Oni su zapravo samo tri vrste memorije, stvarno.
Tu je automatsko upravljanje memorijom, što je stog.
Stvari se dogoditi za vas automatski.
Kada kažem int x, memorija se dodjeljuje za int x.
Kada x odlazi iz djelokruga, memorija je obuzela za x.
Zatim tu je dinamičan upravljanje memorijom, što je ono što malloc je,
koji je kada imate kontrolu.
Vi dinamički odlučiti kada memorije treba i ne treba biti dodijeljeno.
A onda tu je statična, što samo znači da je to živi vječno,
što je ono što su globalne varijable su.
Oni su samo uvijek u sjećanju.
>> Pitanja?
[Student] Može li definirati blok samo pomoću vitičastih zagrada
ali ne moraju imati, ako izjavi ili while ili nešto slično?
Možete definirati blok kao u funkciji, ali da ima vitičastim zagradama previše.
[Student] Pa ne možete samo imati kao slučajni para vitičastih zagrada u kodu
koje imaju lokalne varijable? >> Da, možete.
Unutar int bar smo mogli imati {int y = 3;}.
To je trebao biti ovdje.
No, da u potpunosti definira opseg int y.
Nakon toga drugi kovrčave vitice, y ne mogu koristiti više.
Gotovo nikada učiniti, iako.
Vratimo se na ono što se događa kada program završi,
postoji vrsta zabluda / pola laži koje dajemo kako bi samo napraviti stvari lakše.
Mi vam reći da kada se alocirati memoriju
ti si neki dodjele komad RAM-a za tu varijablu.
Ali niste stvarno izravno dira RAM ikada u svojim programima.
Ako mislite o tome, kako sam nacrtao -
A zapravo, ako idete kroz u GDB vidjet ćete istu stvar.
Bez obzira koliko puta ste pokrenuti program ili što program radite,
stog uvijek će početi -
uvijek ćeš vidjeti varijable oko adresa oxbffff nešto.
To je obično negdje u toj regiji.
Ali kako mogu dva programi možda imaju upućuje na isto memorije?
[Student] Ima neka proizvoljna oznaka gdje oxbfff je trebao biti na RAM
koji zapravo mogu biti u različitim mjestima, ovisno o tome kada je funkcija zove.
Da. Pojam je virtualna memorija.
Ideja je da svaki proces, svaki program koji se izvodi na računalu
ima vlastitu - pretpostavimo 32 bita - potpuno neovisan adresnog prostora.
Ovo je adresni prostor.
To ima svoje potpuno neovisne četiri gigabajta za korištenje.
>> Dakle, ako vam ponestane dva programa istovremeno, ovaj program vidi četiri gigabajta sebi,
ovaj program vidi četiri gigabajta sebi,
a to je nemoguće za ovaj program dereference pokazivač
, a završiti s memorijom iz ovog programa.
I ono što je virtualna memorija je mapiranje iz prostora procesa adresa
stvarnim stvari na RAM.
Dakle, to je do svog operativnog sustava je znati da,
hej, kad je ovaj pokazivač čovjek dereferences oxbfff, to zapravo znači
da želi RAM bajt 1000,
a ako se to oxbfff Program dereferences, on stvarno želi RAM bajt 10000.
Oni mogu biti proizvoljno udaljeni.
To je čak i istina stvari unutar jednog procesa adresnog prostora.
Dakle, kao što se vidi sve četiri gigabajta sebi, ali recimo -
[Student] Da li svaki pojedini proces -
Recimo imate računalo sa samo četiri gigabajta RAM-a.
Da li svaki proces vidjeti cijeli 4 gigabajta? >> Da.
Ali četiri gigabajta to vidi je laž.
To je samo ona misli da ima sve ovo sjećanje, jer ne znam bilo koji drugi proces postoji.
To će koristiti samo kao puno memorije jer zapravo treba.
Operativni sustav neće dati RAM ovom procesu
ako to ne koristeći bilo memoriju u ovoj cijeloj regiji.
To se neće dati memorije za tu regiju.
No, ideja je da se - Pokušavam se sjetiti - ja ne mogu misliti na analogiji.
Analogije su teško.
Jedan od problema virtualne memorije ili jedna od stvari to je rješavanje
je da procesi trebaju biti potpuno svjesni jedan drugoga.
I tako možete pisati bilo koji program koji samo dereferences bilo pokazivač,
sviđa samo napisati program koji kaže * (ox1234),
i da je dereferencing memorijska adresa 1234.
>> No, to je do operativnog sustava kako bi onda prevesti što znači 1234.
Dakle, ako se dogodi da se 1234 vrijedi memorijska adresa za ovaj proces,
kao da je na dimnjaku ili tako nešto, onda će to vratiti vrijednost tog memorijsku adresu
koliko proces zna.
Ali ako 1234 nije valjana adresa, kao što se to događa na zemlji
u nekom malom komadu memorije ovdje da je izvan dimnjaka i izvan hrpi
a niste stvarno koristi, onda je to kad se stvari poput segfaults
jer ste dira memorije koju ne treba dira.
To je također istina -
32-bitni sustav, 32 bita znači da imate 32 bita definiraju memorijsku adresu.
To je razlog zašto pointeri su 8 bajtova jer 32 bita su 8 bytes - ili 4 bajta.
Pokazivači su četiri bajta.
Dakle, kada vidite pokazivač poput oxbfffff, koji je -
Unutar svakom programu možete jednostavno konstruirati bilo proizvoljnog pokazivač,
nigdje iz ox0 da volovskih 8 f's - ffffffff.
[Student] Zar vam reći da su četiri bajta? >> Da.
[Student] Onda svaki bajt će imati - >> [Bowden] Heksadecimalni.
Heksadecimalni - 5, 6, 7, 8. Dakle, upućuje da ćeš uvijek vidjeti u heksadecimalnom.
To je samo kako ćemo klasificirati naputke.
Svake dvije znamenke heksadecimalnom je jedan bajt.
Tako će biti osam heksadecimalnih znamenki za 4 bajta.
Dakle, svaki pokazivač na 32-bitni sustav će biti 4 bajta,
što znači da je u procesu možete konstruirati bilo proizvoljnih 4 bajta
i napraviti pokazivač izvan nje,
što znači da što se tiče da je svjestan, to može riješiti cijeli 2 do 32 bajtova memorije.
Iako se to zapravo ne imati pristup koji,
čak i ako vaše računalo ima samo 512 megabajta, ona misli da ima toliko memorije.
A operativni sustav je dovoljno pametan da je to samo će izdvojiti ono što vam je zapravo potrebno.
To ne samo ići, oh, novi proces: 4 nastupa.
>> Da. >> [Student] Što vol znači? Zašto ste ga pisati?
To je samo simbol za heksadecimalnom.
Kada vidite broj start s vola, uzastopna stvari su heksadecimalni.
[Student] Ti si objasniti o tome što se događa kada program završi. >> Da.
Što se događa kad program završi je operativni sustav
samo briše preslikavanja koje ona ima za tim adresama, i to je to.
Operativni sustav sada može samo dati tu memoriju na drugom programu za korištenje.
[Student] Ok.
Dakle, kada ste izdvojiti nešto na hrpi ili stog ili globalne varijable ili bilo što,
svi oni samo nestati čim Program završava
jer operativni sustav je sada slobodan dati da sjećanje na bilo koji drugi proces.
[Student] Iako postoje vjerojatno još uvijek vrijednosti napisane u? >> Da.
Vrijednosti su vjerojatno još uvijek tamo.
To je samo da će to biti teško dobiti na njih.
To je puno teže dobiti na njih nego ga je dobiti na izbrisane datoteke
jer briše datoteku vrsta tamo sjedi za dugo vremena, a hard disk je puno veća.
Dakle, to će prebrisati različite dijelove memorije
prije nego se dogodi da prebrisati komad memorije da je datoteka se koristi za biti.
No, glavna memorija, RAM, vozite bicikl kroz puno brže,
tako da će vrlo brzo biti prepisane.
Pitanja na ovaj ili nešto drugo?
[Student] Imam pitanja o različitim temama. >> Ok.
Ima li netko pitanja o ovome?
>> Ok. Različite temu. >> [Student] Ok.
Bio sam prolazio kroz neke od praksi testovi,
a jedan od njih je riječ o sizeof
i vrijednost koja se vraća ili različite varijabilne vrste. >> Da.
I to je rekao da su obje int i dugo i povratak četiri, pa oni su oba 4 bajta dugo.
Je li postoji razlika između int i dugo, ili je to ista stvar?
Da, postoji razlika.
C standard -
Vjerojatno ću zabrljati.
C Standardna baš kao što je C, službena dokumentacija C.
To je ono što on kaže.
Dakle C standardno samo kaže da je char će zauvijek i uvijek će biti jedan bajt.
Sve nakon toga - kratko je uvijek samo definira kao veći ili jednak char.
To bi moglo biti strogo veći od, ali ne pozitivno.
Int samo je definirana kao veća od ili jednaka do kratko.
I dug samo je definirana kao veća od ili jednaka do int.
I dugo dugo je veći ili jednak dugo.
Dakle, jedina stvar C standard definira je relativna poredak od svega.
Stvarna količina memorije da stvari uzme je općenito do provedbe,
ali to je prilično dobro definirana u ovom trenutku. >> [Student] Ok.
Dakle, gaćice su gotovo uvijek će biti dva bajta.
Ints su gotovo uvijek će biti 4 bajta.
Duge čezne su gotovo uvijek će biti 8 bajtova.
I čezne, to ovisi o tome hoće li koristite 32-bitni ili 64-bitni sustav.
Tako dugo će odgovarati vrsti sustava.
Ako koristite 32-bitni sustav kao Appliance, to će biti 4 bajta.
Ako koristite 64-bitnu kao puno posljednjih računala, to će biti 8 bajtova.
>> Ints su gotovo uvijek 4 bajta u ovom trenutku.
Duge čezne su gotovo uvijek 8 bajtova.
U prošlosti, Ints koristiti samo biti dva bajta.
Ali primijetite da je ovo u potpunosti zadovoljava sve ove odnosa veća nego i jednaka.
Tako dugo savršeno je dozvoljeno da bude iste veličine kao cijeli broj,
i to je također dozvoljeno da bude iste veličine kao i dugo dugo.
I to samo tako dogodi da se da se u 99,999% sustava, to će biti jednaka
ili int ili dugo dugo. To samo ovisi o 32-bitni ili 64-bitni. >> [Student] Ok.
U plovaka, kako je decimalna točka određen u smislu bita?
Sviđa mi se kao binarno? >> Da.
Ne morate znati da za CS50.
Vi čak ne bi saznali da je u 61.
Vi ne uče da stvarno u svakom naravno.
To je samo reprezentacija.
Zaboravio sam točno bitne allotments.
Ideja plutajuće točke je da vam dodijeliti određeni broj bitova za zastupanje -
Uglavnom, sve je u znanstvenom zapisu.
Dakle, dodijeliti određeni broj bitova za zastupanje broj sama, kao što 1,2345.
Ja nikada ne može predstavljati broj s više znamenki nego pet.
Zatim možete također dodijeliti određeni broj bitova, tako da je sklon biti poput
možete samo ići do određenog broja, kao i da je najveći eksponent možete imati,
a ti samo može ići dolje do određenog eksponenta,
kao da je najmanji eksponent možete imati.
>> Ne sjećam se točno način na koji su dijelovi dodijeljen svih tih vrijednosti,
ali određeni broj bitova su posvećeni 1,2345,
još određeni broj bitova su posvećena eksponenta,
i to je jedino moguće da predstavlja eksponent određene veličine.
[Student] A dvostruko? Je li to kao dodatni dugo float? >> Da.
To je ista stvar kao float, osim sada ste koristeći 8 bajtova umjesto 4 bajta.
Sada ćete biti u mogućnosti koristiti devet znamenki ili 10 znamenki,
a to će biti u mogućnosti otići do 300 umjesto 100. >> [Student] Ok.
I plovci su također četiri bajta. >> Da.
Pa, opet, to vjerojatno ovisi sveukupno na opću provedbu,
ali plovci su 4 bajta, parovi su osam.
Parovi su pozvani dvostruko jer su dvostruko veličine plovaka.
[Student] Ok. A tu su bračni parovi? >> Ne postoje.
Mislim - >> [student] Kao duga čezne? >> Da. Ne mislim tako. Da.
[Student] Na prošlogodišnjem testu je bilo pitanje o glavnoj funkciji
ima da bude dio vašeg programa.
Odgovor je bio da to ne mora biti dio vašeg programa.
U kojoj situaciji? To je ono što sam vidio.
[Bowden] Čini se - >> [student] Što situacija?
Imate li problem? >> [Student] Da, ja definitivno mogu ga podići.
To ne mora biti, tehnički, ali u osnovi to će biti.
[Student] Vidio sam jednom na drugačiji ovogodišnjeg.
Bilo je to kao True ili False: vrijedi - >> Oh, c datoteka.?
. [Student] Bilo c datoteka mora imati - [kako govori odjednom - nerazumljivo]
Ok. Dakle, to je odvojeni.
>> C. File samo treba da sadrži funkcije.
Možete sastaviti datoteke u strojnom kodu, binarni, što god,
bez da se izvršna gostiju.
Vrijedi izvršna mora imati glavnu funkciju.
Možete pisati sto funkcije u jednoj datoteci, ali ne glavne
, a zatim sastaviti da dolje u binarni,
onda napisati drugu datoteku koja ima samo glavni, ali to naziva hrpa tih funkcija
u ovom binarnu datoteku ovamo.
I tako kada radite izvršnu, to je ono što čini linker
se kombinira ove dvije binarne datoteke u izvršnu.
Dakle, c. Datoteka ne trebate imati glavnu funkciju.
I na velikim koda baze vidjet ćete tisuće. C datoteka i jedan glavni datoteku.
Više pitanja?
[Student] Bilo je drugo pitanje.
On je rekao da je prevodilac. Točno ili netočno?
A odgovor je bio lažan, a ja sam shvatio zašto to nije kao jeka.
No, ono što mi zovemo napraviti ako to nije?
Provjerite je u osnovi samo - Ja mogu vidjeti točno ono što on naziva.
No, to je samo radi naredbe.
Napravite.
Ja mogu izvući ovo gore. Da.
Oh, da. Provjerite također da li to.
To govori svrha marku korisnosti je odrediti automatski
koji komadi velikog programa treba recompiled
i izdavati naredbe da ih rekompiliranje.
Možete napraviti napraviti datoteke koje su apsolutno ogroman.
Napravite izgleda na vrijeme markica datoteka i, kao što smo već rekli,
možete sastaviti pojedinačne datoteke dolje, i to ne dok ne dođete do linker
da oni sastavili u izvršnu.
Dakle, ako imate 10 različitih datoteka i napraviti promjenu na jednom od njih,
što onda učiniti je učiniti je samo rekompiliranje da jedna datoteka
a zatim RELINK sve zajedno.
No, to je mnogo gluplji od toga.
To je do vas da se u potpunosti definirati da je to ono što treba raditi.
To po defaultu ima sposobnost da se prepoznaju ove stvari vremenski pečat,
, ali možete napisati datoteku marku ništa učiniti.
Možete pisati napraviti datoteku, tako da kada upišete bi to samo cd-a na drugi direktorij.
Sam bio uzimajući frustriran jer sam tack sve unutar mog Appliance
i onda sam pogledati PDF od Mac.
>> Tako sam ići na Finder i ja mogu učiniti Idi, Connect na poslužitelj,
i poslužitelj sam spojiti moj aparati, a onda sam otvoriti PDF
koji se sastavljaju LaTeX.
Ali ja sam bio uzimajući frustriran jer svaki put mi je trebalo osvježiti PDF,
Morao sam ga kopirati u određeni direktorij da bi to moglo pristupiti
i to je bio uzimajući neugodno.
Dakle, umjesto da sam napisao marku datoteku koja morate definirati kako to čini stvari.
Kako napraviti u to PDF LaTeX.
Baš kao i bilo koji drugi marku datoteku - ili Pretpostavljam da niste vidjeli make datoteke,
ali imamo u Appliance globalnu marku datoteku koja samo kaže,
ako sastavljanje C datoteku, koristite zveka.
I tako ovdje u mom marku datoteku da ću ja reći,
ovu sliku idete da želite sastaviti s PDF LaTeX.
I tako je PDF LaTeX da se radi sastavljanja.
Provjerite nije sastavljanja. To je samo radi ove naredbe u nizu sam navedenom.
Tako to radi PDF lateksa, to kopira u direktorij želim da se kopirati,
to cd-u direktorij i obavlja i druge stvari,
ali sve to ipak je prepoznati kada je datoteka promjena,
a ako se ne promijeni, onda će pokrenuti naredbe koje je trebalo pokrenuti
Kada je datoteka mijenja. >> [Student] Ok.
Ne znam gdje su globalna napraviti datoteke su za mene to provjeriti.
Ostala pitanja? Sve iz prošlosti kvizova? Bilo pokazivač stvari?
Postoje suptilne stvari s pokazivačima poput -
Neću biti u mogućnosti pronaći kviz pitanje na njemu -
ali baš kao i ovu vrstu stvar.
Pobrinite se da razumijete da kad kažem int * x * y -
To nije točno ništa ovdje, pretpostavljam.
No, kao što je * x * y, one su dvije varijable koje su na stog.
Kad kažem x = malloc (sizeof (int)), x je još uvijek varijabla na stog,
malloc je neki blok više u gomili, i imamo x točku na hrpi.
>> Tako nešto na stog ukazuje na hrpi.
Kad god malloc ništa, neizbježno ste spremanje ga unutar jednog pokazivača.
Tako da je pokazivač na stog, malloced blok je na hrpi.
Puno ljudi se zbune i reći int * x = malloc, x je na hrpi.
Broj Što x ukazuje je na hrpi.
x sama je na stogu, ako iz bilo kojeg razloga ste x biti globalna varijabla,
u kojem slučaju se dogodi da se u drugoj regiji memorije.
Dakle, praćenje, ove kutije i strijela dijagrami su prilično uobičajene za kviz.
Ili, ako to nije na kvizu 0, to će biti na kvizu 1.
Ti bi trebao znati sve to, korake u sastavljanju
budući da je morao odgovarati na pitanja o onima. Da.
[Student] Možemo ići preko tih koraka - >> Naravno.
Prije koraka i sastavljanje imamo predobradba,
izradu, montažu i povezivanje.
Predobradba. Što to učiniti?
To je najlakši korak u - dobro, a ne kao -
to ne znači da bi trebalo biti očito, ali to je najlakši korak.
Vi mogli provesti ga sami. Da.
[Student] Uzmi ono što imate u svom uključuje ovako i kopira, a zatim i definira.
To izgleda za stvari kao što su # include i # define,
i to samo kopija i paste što one zapravo znače.
Dakle, kada kažeš # include cs50.h, preprocesor je kopiranje i lijepljenje cs50.h
u toj liniji.
Kada kažeš # define x da bude 4, preprocesor ide kroz cijeli program
i zamjenjuje sve instance x sa četiri.
Dakle preprocesor traje valjanu C datoteku i izlazi valjanu C datoteku
gdje stvari su kopirati i zalijepiti.
Tako sada sastavljanja. Što to učiniti?
[Student] To ide iz C u binarni.
>> [Bowden] To ne ide sve na putu u binarni.
[Student] Da strojnom kodu onda? >> To nije stroj kod.
[Student] Skupština? >> Skupština.
To ide na skupštini prije nego što ide skroz do C koda,
i većina jezici učiniti nešto ovako.
Pick bilo jezik visoke razine, a ako idete da ga sastaviti,
to je vjerojatno da će sastaviti u koracima.
Prvo to će sastaviti Python i C, onda će sastaviti C do skupštine,
a zatim Skupština će se prevesti u binarni.
Dakle sastavljanju će ga dovesti iz C do skupštine.
Riječ sastavljanje obično znači da ga stavi na višu razinu
na nižoj razini programskog jezika.
Dakle, ovo je samo korak u obračunu gdje možete početi s visoke razine jeziku
i završiti u low-level jeziku, i to je razlog zašto se zove korak sastavljanja.
[Student] Tijekom sastavljanja, recimo da ste učinili # include cs50.h.
Hoće prevodilac rekompiliranje cs50.h, kao i funkcije koje su u njemu,
i prevesti u Skupštini koda kao dobro,
ili će to kopirati i zalijepiti nešto što je bilo prije skupštine?
cs50.h prilično će puno nikad završiti u Skupštini.
Stvari poput funkcijskih prototipova i stvari su samo za vas biti oprezni.
To jamči da prevodilac može provjeriti stvari kao što zovete funkcije
s pravom povratka vrstama i pravim argumentima i slično.
>> Dakle cs50.h će preprocessed u datoteku, a zatim kad je sastavljanje
to u osnovi je odbačen nakon što čini sigurni da je sve što se zove točno.
Ali funkcije definirane u CS50 knjižnici, koji su odvojeni od cs50.h,
one neće biti zasebno sastavio.
To će zapravo sići u povezivanju koraku, pa ćemo doći do da u drugi.
Ali prvo, što je okupljanje?
[Student] Skupština u binarni? >> Da.
Sastavljanje.
Mi ne zovu sastavljanje jer Skupština je prilično čista prijevod binarni.
Tu je vrlo malo logike u idući od Skupštine u binarni.
To je kao u potrazi gore u tablici, oh, imamo ovu pouku;
koji odgovara binarnom 01110.
I tako su datoteke koje sastavljanje općenito izlazi. O datotekama.
A o datotekama. Smo ono što su govorili prije,
kako sliku ne treba imati glavnu funkciju.
Svaka datoteka može se sastaviti dolje do. O datoteci dok je valjana C datoteka.
To se može sastaviti dolje. O..
Sada, povezujući je ono što zapravo donosi hrpu. O datoteka i dovodi ih do izvršne datoteke.
I tako ono povezivanje ipak možete misliti na CS50 knjižnici kao o datoteci..
To je već sastavio binarna datoteka.
I tako kada sastaviti datoteku, vaš hello.c, koja poziva GetString,
hello.c dobiva sastavio dolje hello.o,
hello.o je sada u binarnom.
Ona koristi GetString, tako da treba ići preko cs50.o,
i linker ih smooshes zajedno i kopira GetString u ovoj datoteci
i izlazi s izvršnu koji ima sve funkcije treba.
Dakle cs50.o nije zapravo O datoteku, ali to je dovoljno blizu da ne postoji temeljna razlika.
Dakle povezuje samo donosi hrpa datoteka zajedno
da odvojeno sadrže sve funkcije moram koristiti
i stvara izvršnu da će zapravo pokrenuti.
>> I tako je to također ono što smo pričali prije
gdje možete imati 1000. c datoteka, sastaviti ih sve. o datotekama,
koji će vjerojatno potrajati, a zatim promijenite jedan. c datoteka.
Vi samo morate rekompiliranje taj jedan. C datoteku, a zatim RELINK sve ostalo,
povezati sve vratiti zajedno.
[Student] Kad smo povezuje pišemo lcs50?
Da, tako lcs50. To zastava signalizira linker koji bi trebali biti povezivanje u toj knjižnici.
Pitanja?
Jesmo li otišli preko binarnog osim toga pet sekundi u prvom predavanju?
Ne mislim tako.
Ti bi trebao znati sve o velikom OS koji smo otišli preko,
i trebali biste biti u mogućnosti da, ako mi ti dao funkciju,
trebali biti u mogućnosti reći da je veliki O, otprilike. Ili dobro, velika je O gruba.
Dakle, ako vidite ugniježđena za petlje loop nad istim brojem stvari,
kao int i, ja <n, int j, j > [student] n kvadratna. >> Sklon je biti n kvadratna.
Ako ste trostruki su ugniježđena, sklon je biti n kubu.
Tako da vrsta stvar koju bi trebao biti u mogućnosti istaknuti odmah.
Morate znati unosa vrsta i bubble sortiranje i spajanje vrsta i sve one.
Lakše je razumjeti zašto su oni n kvadratna i n log n i sve to
jer mislim da je bio na kvizu jedna godina u kojoj smo zapravo ti dao
provedba bubble vrste i reče: "Što je trajanje ove funkcije?"
Dakle, ako ste ga prepoznali kao bubble sort, onda možete odmah reći n kvadratna.
Ali ako samo gledati na to, ne treba ni da shvate da je mjehur vrsta;
možete samo reći ovo radi to i to. To je n kvadratna.
[Student] Ima li kakvih teške primjera možete doći do,
kao sličnom idejom figuring out?
>> Ja ne mislim da bi vam bilo teške primjere.
Stvar balon vrsta je o kao tvrd kao što će ići,
pa čak i da, koliko god shvatite da ste Ponavljanje preko niza
za svaki element u polju, koji će biti nešto što je n kvadratna.
Postoji opća pitanja, kao što ovdje imamo - Oh.
Samo drugi dan, Doug je tvrdio: "Ja sam izumio algoritam koji može sortirati niz
"Od n brojeva u O (log n) vrijeme!"
Dakle, kako znamo da je to nemoguće?
[Nečujno učenik odgovor] >> Da.
Na samom kraju, imate na dodir svaki element u polju,
tako da je nemoguće riješiti niz -
Ako je sve u nerazvrstani bi, onda ćete biti dodirivanje sve što je u polju,
tako da je nemoguće to učiniti u manje od O iz n.
[Student] Ti nam je pokazao taj primjer biti u mogućnosti to učiniti u O iz n
ako koristite puno memorije. >> Da.
I that's - ja zaboraviti ono što that's - Je li to računajući vrsta?
Hmm. To je cijeli sortiranje algoritam.
Bio sam u potrazi za poseban naziv za to da se nisam mogao sjetiti prošlog tjedna.
Da. To su vrste sorti koje se mogu ostvariti stvari u velikom O iz n.
No, tu su i ograničenja, kao što možete koristiti samo prirodni brojevi do određenog broja.
Plus, ako ste pokušavate izdvojiti nešto that's -
Ako je vaš polje je 012, -12, 151, 4 milijuna kuna,
zatim da jedan element će u potpunosti uništiti cijelu sortiranja.
>> Pitanja?
[Student] Ako imate rekurzivna funkcija i to samo čini rekurzivnih poziva
unutar povratka izjavi, da je rep rekurzivna,
pa da ne bi koristiti više memorije tijekom izvođenja
ili bi barem koristiti usporedivu memoriju kao rješenje iterativnog?
[Bowden] Da.
To će vjerojatno biti nešto sporiji, ali ne i stvarno.
Rep rekurzivna je prilično dobra.
Gledajući opet na stog okvire, recimo imamo glavni
i imamo int bar (int x) ili nešto.
Ovo nije savršen rekurzivna funkcija, ali povratak bar (x - 1).
Dakle, očito, ovo je manjkav. Trebate bazu slučajeve i stvari.
No, ideja je da je to rep rekurzivna,
što znači kada glavni pozivi bar to ide da biste dobili svoj stack okvir.
U tom okviru postoji stack će biti malo blok memorije
koji odgovara njegovu argumenta x..
I tako recimo glavni dogodi nazvati bar (100);
Dakle, x će početi kao sto.
Ako prevodilac priznaje da je to rep rekurzivna funkcija,
onda kada bar čini njegov rekurzivni poziv na zabranu,
umjesto da novi stog okvir, što je gdje stog počinje raste uglavnom,
na kraju će se izvoditi u gomili i onda ćete dobiti segfaults
jer memorija počinje sudara.
>> Dakle, umjesto da svoj stack frame, to može shvatiti,
hej, ja nikada stvarno morati vratiti na ovaj stack okvira,
pa umjesto samo ću zamijeniti ovaj argument s 99 i onda početi bar sve više.
I onda će to učiniti opet i to će doći do povratka bar (x - 1),
i umjesto da novi stog okvir, samo će zamijeniti svoj trenutni argument s 98
i onda skočiti natrag na samom početku traci.
Ti poslovi, zamijenivši taj jedan vrijednost na stog i skakanje natrag na početak,
su prilično učinkovit.
Dakle, ne samo da je to isto memorije kao zasebna funkcija koja je iterativni
jer ste samo pomoću jedne stog okvir, ali ne trpi downsides
vlasništvo na poziv funkcije.
Pozivanje funkcije može biti nešto skuplji, jer ona mora učiniti sve ove postavke
i teardown i sve ove stvari.
Dakle, ovo rep rekurzije je dobro.
[Student] Zašto ne stvoriti nove korake?
Budući da shvati da ne treba.
Poziv na traci samo vraćanjem rekurzivni poziv.
Tako da ne treba ništa učiniti s povratnom vrijednosti.
Upravo će se odmah vratiti.
Dakle, to je samo će zamijeniti svoj argument i početi ispočetka.
I također, ako nemaju rep rekurzivna verzija,
onda ste dobili sve ove barova gdje kada se to bar vraća
to mora vratiti njegovu vrijednost na ovom jednom, a zatim da bar odmah vraća
i vraća svoju vrijednost na ovom jednom, onda je to samo ide odmah vratiti
i vratiti svoju vrijednost na ovom jednom.
Dakle, uštedjet ćete to iskakanje sve ove stvari izvan dimnjaka
jer povratna vrijednost samo će biti donesen sve na putu natrag do svejedno.
Pa zašto ne samo zamijeniti naše argumente s ažuriranim argument i početi ispočetka?
Ako funkcija nije rep rekurzivna, ako to ne učinite nešto slično -
[Student] ako bar (x + 1). >> Da.
>> Dakle, ako ste ga stavili u stanju, onda radite nešto s povratnom vrijednosti.
Ili čak i ako samo ne vraćaju 2 * bar (x - 1).
Dakle, sada bar (x - 1) treba vratiti kako bi za to da izračunati dva puta da vrijednosti,
pa sad to ne treba svoj zasebni okvir stog,
i sada, bez obzira koliko se trudili, ti si idući u morati -
To nije rep rekurzivna.
[Student] Želite li pokušati donijeti rekurzija za cilj za rep rekurzije -
[Bowden] U idealnom svijetu, ali u CS50 ne moraju.
Da bi dobili rep rekurzija, općenito, postavite dodatne argumente
gdje bar će se int x u y
i y odgovara ultimate stvar koju želite vratiti.
Dakle, onda je to da ćeš se vratiti bar (x - 1), 2 * y.
Dakle, to je samo na visokoj razini kako transformirati stvari biti rep rekurzivna.
No, dodatni argument -
I onda na kraju kada dođete do svoje baze slučaj, samo vratiti y
jer ste bili gomilaju cijelo vrijeme povratnu vrijednost koju želite.
Vi vrsta su to iterativno, ali pomoću rekurzivnih poziva.
Pitanja?
[Student] Možda o ciljnikom aritmetike, kao kada koristite nizove. >> Naravno.
Pointer aritmetika.
Kada koristite konce je lako jer su nizovi char zvijezde,
znakovi su zauvijek i uvijek jedan byte,
i tako pokazivač aritmetika je ekvivalentno redovitom aritmetike kada ste se bave žice.
Ajmo reći char * s = "halo".
Dakle, imamo blok u memoriji.
To treba 6 bajtova jer ćete uvijek trebati null terminator.
I char * s će ukazati na početku ovog niza.
Tako je ukazuje tamo.
Sada, to je u osnovi kako je bilo niz djela,
bez obzira da li je to bio povratak strane malloc ili da li je na stogu.
Svaki niz je u osnovi pokazivač na početak niza,
i onda bilo niz operacija, bilo indeksiranje, samo se ide u tom polju određeni pomak.
>> Dakle, kada kažem nešto poput s. [3], a to će ih i računajući tri slova u.
Tako i [3], imamo 0, 1, 2, 3, pa i [3] će da se odnosi na ovaj l.
[Student] A mogli smo doći do iste vrijednosti koje rade s + 3, a zatim zagrade zvijezda?
Da.
Ovo je ekvivalent * (s + 3);
i da je zauvijek i uvijek jednaka bez obzira na ono što radite.
Vi nikada ne morate koristiti nosača sintaksu.
Uvijek možete koristiti * (s + 3) sintaksa.
Ljudi imaju tendenciju da vole nosača sintaksu, iako.
[Student] Dakle, svi nizovi su zapravo samo upućuje.
Tu je blagi razlika kad kažem int x [4]; >> [student] Znači li to da stvoriti pamćenje?
[Bowden] To će stvoriti četiri Ints na stog, tako da 16 bajtova u ukupnom poretku.
To će stvoriti 16 bajtova na stog.
x nije pohranjena bilo gdje.
To je samo simbol koji se odnosi na početku stvar.
Zato što je proglasio niz unutar ove funkcije,
ono prevodilac će učiniti samo zamijeniti sve instance varijable x
s kojima se to dogodilo da se odlučite za staviti ove 16 bajtova.
To ne može učiniti da se s char * s, jer je je stvarni pokazivač.
To je besplatno onda ukazati na druge stvari.
x je konstanta. Vi ne možete imati točku na nekom drugom polju. >> [Student] Ok.
No, ta ideja, to indeksiranje, je ista, bez obzira da li je tradicionalna niz
ili ako je pokazivač na nešto ili ako je pokazivač na niz malloced.
A u stvari, to je tako odgovara da je to također ista stvar.
To je zapravo samo prevodi ono što je unutar zagrada i što je ostalo od zagradama,
ih dodaje zajedno, i dereferences.
Dakle, ovo je samo kao ispravna * (s + 3) ili s [3].
[Student] Može li pokazivače koji upućuju na 2-dimenzionalnim nizovima?
>> To je teže. Tradicionalno, br.
2-dimenzionalni niz je samo 1-dimenzionalni niz s nekim praktičnim sintakse
jer kad kažem int x [3] [3], to je zapravo samo jedan niz s devet vrijednostima.
I tako, kada sam indeks, prevodilac zna što mislim.
Ako kažem x [1] [2], on zna da ja želim ići u drugom redu, tako da će preskočiti prvi 3,
i onda želi drugi stvar u tome, pa se događa da se ovaj jedan.
Ali, to je još uvijek samo jednodimenzionalnu polje.
I tako, ako sam htio dodijeliti pokazivač na tom polju,
Rekao bih int * p = x;
Tip x je samo -
To je grubo govoreći tip x, budući da je samo simbol i to nije stvarna varijabla,
ali to je samo int *.
x je samo pokazivač na početak ove. >> [Student] Ok.
I tako sam neće moći pristupiti [1] [2].
Mislim da je posebna sintaksa za proglašenje pokazivač,
nešto smiješno kao int (* p [-. nešto apsolutno smiješno Ja čak ne znam.
No, tu je sintaksa za proglašenje upućuje kao sa zagradama i stvari.
To ne može čak ti to dopustiti.
Mogao bih se osvrnuti na nešto što bi mi reći istinu.
Ja ću gledati za to kasnije, ako je sintaksa za točku. No, nikada nećete vidjeti.
A čak i sintaksa je tako arhaično da ako ga koristite, ljudi će biti zbunjeni.
Višedimenzionalna polja su prilično rijetke, kao što je to.
Možete prilično mnogo -
Pa, ako radite matrica stvari to neće biti rijetka,
ali u C rijetko ćeš se koriste višedimenzionalni nizovi.
Da. >> [Student] Recimo da ste stvarno dugo niz.
>> Tako je u virtualne memorije to bi izgledalo da se sve redom,
poput elemenata tik jedna do druge,
ali u fizičke memorije, to će biti moguće da se razišli? >> Da.
Kako virtualna memorija radi je to samo razdvaja -
Jedinica raspodjele je stranica, koja teži da bude 4 kilobajta,
pa kad proces, kaže, hej, želim koristiti ovu memoriju,
operativni sustav će se dodijeliti ga 4 kilobajta za tom malom bloku memorije.
Čak i ako koristite samo jednu malu bajt u cijelom bloku memorije,
operativni sustav će dati punu 4 kilobajta.
Dakle, što to znači da je sam mogao imati - ajmo reći da je ovo moj stog.
Ovaj stog može odvojiti. Moj stog mogao biti megabajta i megabajta.
Moj stog mogao biti ogroman.
No, stog sama mora biti podijeljena na pojedine stranice,
koji, ako ćemo gledati na ovamo ajmo reći da je ovo naša RAM-a,
ako imam dva gigabajta RAM-a, to je stvarna adresa 0 kao 0. bajtu moje RAM-a,
a to je dva gigabajta sve putu ovamo.
Dakle, ovo bi moglo stranica odgovara ovom bloku ovamo.
Ova stranica može odgovarati ovom bloku ovamo.
To bi se moglo odgovarati ovaj jedan ovamo.
Dakle, operativni sustav je besplatan za dodjeljivanje fizičke memorije
bilo pojedinačne stranice samovoljno.
A to znači da ako se to dogodi na granici zahvatila niz,
Niz se događa da se ostavi toga i desno od ovog reda stranice,
Tada polje će biti podijeljen u fizičke memorije.
I onda kada prestati program, kada je proces završi,
ove preslikavanja dobiti izbrisani, a zatim je besplatan za korištenje ove male blokove za druge stvari.
Više pitanja?
[Student] pokazivač aritmetika. >> Oh yeah.
Strings bilo lakše, ali gleda na nešto poput Ints,
tako natrag na int x [4];
Bilo je to polje ili da li je pokazivač na malloced niz brojeva 4,
to će biti tretirani na isti način.
[Student] Dakle, polja su na hrpi?
[Bowden] Nizovi nisu na hrpi. >> [Student] Aha.
>> [Bowden] Ova vrsta niza teži da bude na stog
osim ako ga prijaviti na - ignoriranje globalne varijable. Nemojte koristiti globalne varijable.
Unutar funkcije kažem int x [4];
To će stvoriti 4-cijeli blok na stog za ovaj niz.
Ali to malloc (4 * sizeof (int)); će ići na hrpi.
Ali nakon ove točke mogu koristiti X i P u podjednakim načine,
osim iznimaka sam prije rekao da si mogu prenamijeniti str.
Tehnički, njihove veličine su nešto drugačiji, ali to je potpuno nebitno.
Vi zapravo nikada koristiti svoje veličine.
P ja mogao reći p [3] = 2; ili x [3] = 2;
Možete ih koristiti na isti način.
Dakle pokazivač aritmetika sada - Da.
[Student] Zar ne morate učiniti p * ako imate nosače?
U zagradama su implicitno dereference. >> Ok.
Zapravo, i što govoriš s možete dobiti višedimenzionalni nizovi
s pokazivačima, što možete učiniti je nešto kao, recimo, int ** pp = malloc (sizeof (int *) * 5);
Samo ću napisati sve to na prvom mjestu.
Nisam željela da se jedan.
Ok.
Ono što sam učinio ovdje je - To bi trebalo biti pp [i].
Dakle pp je pokazivač na pokazivač.
Vi ste mallocing pp ukazati na niz pet int zvijezda.
Dakle, u spomen imate na stog str
To će ukazati na niz pet blokova koji su sve sami pokazivače.
I onda kad sam malloc ovdje dolje, ja malloc da svaki od tih pojedinačnih pokazivače
treba ukazati na zasebnom bloku 4 bajta na hrpi.
Dakle, ovo ukazuje na 4 bajta.
I to jedan ukazuje na različitim 4 bajta.
>> I svi oni ukazuju na vlastitim četiri bajta.
To mi daje način obavljanja višedimenzionalni stvari.
Mogao bih reći pp [3] [4], ali sada to nije ista stvar kao višedimenzionalni nizovi
jer višedimenzionalna polja je preveo [3] [4] u jednom pomak u x niz.
Ovo dereferences p, pristupa treći indeks, onda dereferences da
i pristupi - 4 će biti nevažeći - drugi indeks.
Dok kada smo imali int x [3] [4] prije kao višedimenzionalni niz
i kada dvaput konzolu to je stvarno samo jedan dereference,
ti si nakon jednog pokazivač, a zatim offset,
ovo je stvarno 2D reference.
Možete pratiti dva odvojena naputke.
Dakle, ovo je također tehnički vam omogućuje da imaju višedimenzionalni nizovi
gdje svaki pojedinačni polje je različite veličine.
Dakle, mislim nazubljeni višedimenzionalna polja je ono što se zove
jer stvarno je prva stvar mogla ukazati na nešto što ima 10 elemenata,
Druga stvar mogla ukazati na nešto što ima 100 elemenata.
[Student] Ima li ograničenje broja pokazivače možete imati
ukazujući na druge pokazivače? >> Ne
Možete imati int ***** str.
Povratak na ciljnikom aritmetike - >> [student] Aha. >> Da.
[Student] Ako imam int *** p i onda radim dereferencing i kažem p * je jednaka toj vrijednosti,
je to samo će učiniti jedan stupanj dereferencing? >> Da.
Dakle, ako želim pristupiti stvar da je posljednji pokazivač pokazuje na -
Onda ti *** str. >> Ok.
Dakle, ovo je p ukazuje na jedan blok, ukazuje na drugom bloku, ukazuje na drugom bloku.
Zatim, ako to učinite * p = nešto drugo, onda se mijenjaju ovo
do sada ukazuju na drugom bloku. >> Ok.
>> [Bowden] A ako su oni bili malloced, onda ste sada procurila memoriju
osim ako vam se dogoditi da imaju različite reference to
budući da ne možete dobiti natrag na one one koje ste upravo bacio.
Pointer aritmetika.
int x [4]; će dodijeliti niz četiriju brojeva
gdje x ide ukazati na početku niza.
Dakle, kada kažem nešto poput x [1]; želim to znači ići u drugi cijeli broj u polju,
što će biti ovaj jedan.
Ali stvarno, to je 4 bajta u nizu jer cijeli zauzima 4 byte.
Dakle odmakom od jednog stvarno znači pomak od 1
puta veći od bez obzira na vrstu polja je.
To je niz brojeva, tako da ne zna napraviti jedan puta veličine int kada se želi nadoknaditi.
Druga sintaksa. Sjetite se da je to ekvivalent * (x + 1);
Kad kažem pokazivač + 1, što da se vraća je adresa koja se pokazivač pohranu
plus jedan puta veće od tipa pokazivača.
Dakle, ako je x = ox100, tada x + 1 = ox104.
A možete zlostavljati to i reći nešto poput char * c = (char *) x;
a sada c će biti na istoj adresi kao x.
c će biti jednak ox100,
ali c + 1 će biti jednaka ox101
budući pokazivač aritmetika ovisi o vrsti pokazivač da ste dodajući da.
Dakle, c + 1, to izgleda na c, to je char pokazivač, tako da će se dodati 1 puta veličinu char,
koji uvijek će biti jedan, tako da ćete dobiti 101,
a ako mi je činiti X, koji je također još uvijek 100, x + 1 će biti 104.
[Student] Mogu li koristiti C + +, kako bi se unaprijed pokazivač po jedan?
Da, možete.
Ne možete to učiniti s x jer je x samo simbol, ona je konstantna, ne možete promijeniti x..
>> No, c dogodi da samo biti pokazivač, tako da c + + je savršeno vrijedi i to će povećavati po jedan.
Ako c je samo int *, a zatim C + + će biti 104.
+ + Ne pokazivač aritmetika baš kao c + 1 bi učinio pokazivača aritmetiku.
To je zapravo kako puno stvari poput spajanja vrste -
Umjesto stvaranja kopije stvari, umjesto toga možete proći -
Sviđa mi se, ako sam htio da prođe ovaj polovicu polja - neka se izbriše nešto od toga.
Ajmo reći da sam željela da prođe ovu stranu polja u funkciji.
Što bih prijeći na tu funkciju?
Ako sam proći x, ja sam prolazeći ovu adresu.
Ali želim da prođe ovaj adresu. Pa što bih trebao proći?
[Student] pointer + 2?
[Bowden] Dakle, x + 2. Da.
To će biti ta adresa.
Također ćete vrlo često ga vide kao x [2], a zatim adresa koje.
Dakle, morate uzeti adresu njega jer je nosač je implicitno dereference.
x [2] se odnosi na vrijednost koja je u tom okviru, a zatim želite adresu tog okvira,
tako da kažem & x [2].
Dakle, to je kako se nešto u spajanja sortiraj gdje želite da prođe pola popis na nešto
vi stvarno samo prolaze & x [2], a sada koliko rekurzivna poziva tiče,
moj novi niz počinje tamo.
Last minute pitanja.
[Student] Ako mi ne stavi ampersand ili - što je to zove? >> Zvijezda?
[Student] zvjezdice. >> Tehnički, dereference operater, ali - >> [student] Dereference.
>> Ako mi ne stavi zvijezdu ili ampersand, što se događa ako sam samo reći y = x i x je pokazivač?
Koja je vrsta y? >> [Student] ja ću samo reći da je pokazivač dva.
Dakle, ako ste samo reći y = x, sada xiy ukazuju na istu stvar. >> [Student] rose na istu stvar.
A ako je x int pointer? >> To će se žaliti jer ne možete dodijeliti naputke.
[Student] Ok.
Zapamtite da naputke, iako smo ih privući što strijela,
stvarno sve što su trgovina - int * x - stvarno sve x je spremanje je nešto poput ox100,
koji mi se dogoditi da predstavljaju ukazujući na blok pohranjene na 100.
Dakle, kada kažem int * y = x; ja sam samo kopirate ox100 u y,
koje smo upravo ide predstavljati kao y, također ukazuje na ox100.
A ako kažem int i = (int) x; onda ja će pohraniti bez obzira na vrijednost ox100 je
unutar njega, ali sada će to tumačiti kao integer umjesto pokazivača.
Ali, morate cast inače će se žaliti.
[Student] Dakle, misliš da se baci -
Je li će biti lijevanje int od x ili lijevanje int y?
[Bowden] Što?
[Student] Ok. Nakon tih zagradama tamo će biti x ili ay tamo?
>> [Bowden] Ili. x i y su ekvivalent. >> [Student] Ok.
Jer oni su oba pointeri. >> Da.
[Student] Dakle, to bi pohraniti heksadecimalni 100 u integer obliku? >> [Bowden] Aha.
Ali nije vrijednost bez obzira na to ukazuje.
[Bowden] Aha. >> [Student] Dakle, samo je adresa u integer obliku. Ok.
[Bowden] Ako si htio da se za neke bizarne razloga,
ti isključivo mogao nositi s pokazivačima i nikad se bave brojeva
i samo biti poput int * x = 0.
Tada ćete stvarno dobiti zbunjeni kada pokazivač aritmetika počinje događa.
Tako su brojevi koji su pohraniti su besmislene.
To je samo kako ćete završiti ih interpretirajući.
Dakle, ja sam slobodan kopirati ox100 od int * kao int,
i ja sam slobodna dodijeliti - Ti si vjerojatno će dobiti vikao na za ne bacaju -
Ja sam slobodan dodijeliti nešto poput (int *) ox1234 u ovom samovoljnom int *.
Dakle ox123 je jednako vrijedi memorijska adresa kao što je i y.
& Y dogodi da se vrati nešto što je prilično puno ox123.
[Student] Bi li to stvarno cool način da ide iz heksadecimalnom na decimalnom obliku,
sviđa ako imate pokazivač, a vi ga baci kao int?
[Bowden] Vi stvarno može samo ispisati kao printf.
Recimo imam int y = 100.
Dakle printf (% d \ n - kao što je već trebao znati - ispisati da su cjelobrojne,% x.
Samo ćemo ispisati ga kao heksadecimalni.
Dakle, pokazivač ne pohranjuju kao heksadecimalni,
i cijeli ne pohranjuje kao decimalni.
Sve je pohranjen kao binarno.
To je samo da smo skloni pokazati pokazivače kao heksadecimalni
jer mislimo stvari u ovih 4-byte blokova,
i memorijske adrese imaju tendenciju da se upoznate.
Mi smo kao, ako se počinje s BF, onda se dogodi da se na hrpu.
Dakle, to je samo naša interpretacija upućuje kao heksadecimalni.
Ok. Bilo zadnjih pitanja?
>> Ja ću biti ovdje za malo nakon ako imate bilo što drugo.
I to je kraj.
>> [Student] Jupi! [Pljesak]
>> [CS50.TV]