[Powered by Google Translate] [Oddelek 4 - Več Udobna] [Rob Bowden - Harvard University] [To je CS50. - CS50.TV] Imamo kviz jutri, v primeru, da vi ne veste. To je v bistvu za vse, kar ste lahko videli v razredu ali bi se morali videti v razredu. To vključuje kazalce, čeprav je to zelo opravljena temo. Morate razumeti, vsaj na visoko stopnjo njih. Vse, kar je več kot v razredu, morate razumeti, za kviz. Torej, če imate vprašanja o njih, jih lahko vprašam. Toda to se bo zelo študent pod vodstvom zasedanje, kjer fantje postavljajo vprašanja, zato upajmo, da imajo ljudje na vprašanja. Ima kdo kakšno vprašanje? Da. >> [Študent] Lahko greste čez kazalci še enkrat? Jaz bom šel čez kazalca. Vse vaše spremenljivk nujno živi v spominu, vendar običajno vam ni treba skrbeti, da in si rekel + 2 x in y + 3 in bo prevajalnik ugotoviti, kje so stvari, ki živijo za vas. Ko imate opravka s kazalci, zdaj ste jasno uporabo teh pomnilniških naslovov. Tako bo ena spremenljivka samo kdaj živel na en naslov v danem trenutku. Če želimo, da razglasi kazalec, kaj je tip bo izgledal? Želim, da razglasi, da je kazalec p. Kaj tip izgleda? [Študent] int * p. >> Ja. Torej, int * p. In kako bi bilo opozoriti, da x? >> [Študent] Znak za. [Bowden] Torej je znak pove dobesedno imenuje naslov izvajalca. Torej, ko sem rekel in x je pridobivanje pomnilniški naslov spremenljivke x. Torej, zdaj imam kazalec p, in nikjer v moji kodo lahko uporabite P * ali bi mi x in bo točno isto stvar. (* P). Kaj je to delaš? Kaj to pomeni, zvezda? [Študent] To pomeni vrednost, na tej točki. >> Ja. Torej, če gledamo na to, je lahko zelo koristno, če bi bile povzete diagramov če je to malo polje pomnilnika za x, ki se zgodi, da ima vrednost 4, potem imamo majhno škatlo pomnilnika za p, in tako p kaže na x, tako da potegnemo puščico od p do x. Torej, ko rečemo, * p mi praviš iti na polje, ki je str. Star je slediti puščico in potem kar hočeš s tem polju tam. Torej lahko rečem, * p = 7, in da bo šel na polje, ki je x in spremembe, ki na 7 dni. Ali pa bi lahko rekel, int z = * p * 2; To je zavajajoče, saj je zvezda, zvezda. Tista zvezda je Dereferenciranje strani, druga zvezda pomnoži z 2. Obvestilo Lahko bi prav tako dobro nadomesti P * s x. Uporabite jih lahko na enak način. In potem lahko kasneje Imam p kažejo na popolnoma novo stvar. Lahko samo rečem, p = &z; Torej, zdaj p nima več točk, na X, to kaže na z. In kadar koli sem naredil * p je to isto, kot počne z. Torej uporabna stvar pri tem je, ko smo začeli že v funkcijah. To je nekako nesmiselno razglasi kazalec, ki kaže na nekaj in potem ste pravkar Dereferenciranje ko bi lahko uporabili prvotno spremenljivko na začetku. Ampak ko prideš v funkcije - tako recimo, da so nekatere funkcije, int foo, da se kazalec in tako ne * p = 6; Kot smo videli prej z zamenjavo, ne moreš učinkovito zamenjavo in ločeno funkcijo z gredo samo cela, ker je vse v C je vedno mimo vrednosti. Tudi, ko si mimo napotke ste mimo vrednosti. Samo tako se zgodi, da te vrednote pomnilniških naslovov. Torej, ko sem rekel, foo (p); sem mimo kazalec na funkcijo foo in potem foo počne * p = 6; Tako znotraj te funkcije, * p je še vedno enaka x, vendar ne morem uporabljati x znotraj te funkcije, ker to ni zajeta v tej funkciji. Torej, * p = 6, je edini način, da lahko dostopajo do lokalnega spremenljivko druge funkcije. Ali pa, no, kazalci so edini način, da lahko dostopajo do lokalnega spremenljivko druge funkcije. [Študent] Recimo, da si je želel, da se vrnete kazalec. Kako točno si to naredil? [Bowden] Nazaj na kazalec, kot nekaj takega int y = 3, vračanje in y? >> [Študent] Ja. [Bowden] Ok. Nikoli ne bi smeli storiti. To je slabo. Mislim, da sem videl v teh predavanje diapozitivih boste začeli videti vso to shemo spomina če tu imaš naslov pomnilnika 0 in tukaj imaš naslov pomnilnika 4 nastopov ali 2 k 32. Torej imaš nekaj stvari in nekaj stvari in potem imate kup in imaš svoj kup, ki ste ga pravkar začeli učenje o odraščanju. [Študent] Ni kup nad kup? Ja. Kup na vrhu, a ne? >> [Študent] No, je dal 0 na vrhu. [Študent] Oh, je dal 0 na vrhu. >> [Študent] V redu. Opozorilo: Kjerkoli s CS50 boste videli, da na ta način. >> [Študent] Ok. To je samo, da ko ste prvič videla kupe, kot takrat, ko misliš, da kup si misliš zlaganje stvari na vrhu med seboj. Tako smo nagnjeni k flip to približno tako sklad je odraščanje kot kup ponavadi namesto žetonov visi dol. >> [Študent] ne kupi tehnično zrastejo preveč, kajne? To je odvisno od tega, kaj misliš s odrasti. Stack in kup vedno rastejo v nasprotnih smereh. Sveženj je vedno odrašča v smislu, da je odraščanje v smeri večje pomnilniške naslove in kopičijo raste navzdol v tem, da raste proti nižjim naslovov pomnilnika. Torej, na vrhu je 0 in dno je visoko pomnilniške naslove. Oni so tako narašča, le v nasprotni smeri. [Študent] sem samo pomenilo, da zato, ker si rekel, da si dal kup na dnu ker se zdi bolj intuitivna, saj za sklad za začetek na vrhu kupa, Kup je na vrhu samo po sebi preveč, tako da that - >> Ja. Prav tako mislim na kup, kot odraščanje in večje, vendar stack toliko bolj. Torej je sklad je tisti, ki smo nekako želim pokazati odraščanja. Toda povsod izgledaš drugače bo pokazal naslov 0 na vrh in najvišji pomnilniški naslov na dnu, tako da je to vaš običajni pogled pomnilnika. Imate vprašanje? [Študent] Lahko poveste kaj več o tem kup? Ja. Jaz bom tisti, ki v sekundi. Prvič, gre nazaj, zakaj vrnitev & Y je slabo, na stack imate kup dimnika okvirjev, ki predstavljajo vse funkcije , ki so bili imenovani. Torej, brez upoštevanja prejšnje stvari, na vrhu vaših žetonov je vedno tekoč, da je glavna funkcija saj to je prva naloga, da se reče. In potem, ko pokličete drugo funkcijo, sklad se bo rast navzdol. Torej, če sem poklical nekatere funkcije, foo, in dobi svojo žetonov okvir, lahko pokličete nekatere funkcije, bar, da dobi svojo dimnika okvirja. In bi bilo rekurzivni bar in bi se zahtevajo, in da drugi razpis za baru bo dobil svoj okvir žetonov. In kaj se dogaja v teh odvodnikom okvirjev so vse lokalne spremenljivke in vse funkcije, ki argumentov - Vse stvari, ki so lokalno zajeta v tej funkciji gre v teh okvirih dimnika. Torej to pomeni, da ko sem rekel kaj takega bara, je funkcija, Grem prijaviti celo število in se nato vrne kazalec na tem celo število. Torej, če ne y živi? [Študent] y živi v baru. >> [Bowden] Ja. Nekje v tem malem trgu v spomin je kvadrat Littler, ki ima y v njem. Ko sem se vrnil in y, bom vrnil kazalec na tej mali blok pomnilnika. Toda potem, ko je funkcija vrne, dobi njegov kup okvir odbil sklada. In zato se imenuje sklad. To je kot struktura dimnika podatkov, če veste, kaj to je. Ali celo kot kup plošč je vedno primer, Glavno, da bo šel na dnu, potem je prva funkcija praviš, da bo šel na vrhu, da in ne moreš priti nazaj na glavno, da se vrnete iz vseh funkcij, ki so bile imenovane , ki so bili dani na vrhu. [Študent] Torej, če si ne vrne in y, da je ta vrednost se lahko spremenijo brez predhodnega obvestila. Da, it's - >> [Študent] To bi lahko bila prepisana. >> Ja. To je popolnoma - Če ste poskusili - To bi bilo tudi int bar *, saj vrača kazalec, zato njeno vrnitev tip int *. Če poskusite uporabiti vrnjeno vrednost te funkcije, je nedefiniran vedenje ker je ta kazalec kaže na slab spomin. >> [Študent] Ok. Pa kaj, če, na primer, boste prijavljeni int * y = malloc (sizeof (int))? To je že bolje. Da. [Študent] smo se pogovarjali o tem, kako, ko smo vleči stvari na naš koš oni dejansko ne izbrišejo, temveč samo izgubili kazalca. Torej, v tem primeru bomo izbrisali dejansko vrednost ali pa je še vedno tam v spomin? Za večino del, to bo še vedno tam. Ampak recimo, da se zgodi, da pokličete kakšno drugo funkcijo, Baz. Baz bo dobil svoj okvir žetonov tukaj. To se dogaja, da se prepiše vse te stvari, in potem, če poskusite pozneje in uporabite kazalec, da imaš pred to ne bo enako vrednost. To se dogaja, da so pravkar spremenila, ker ste poklicali funkcijo BAZ. [Študent] Ampak nismo, bi še vedno dobil 3? [Bowden] Po vsej verjetnosti bi. Ampak ti ne more sklicevati na to. C samo pravi undefined vedenje. [Študent] Oh, ne. Ok. Torej, če želite, da se vrnete kazalec, to je, če pride malloc v uporabi. Jaz sem pravzaprav pisati samo vrnitev malloc (3 * sizeof (int)). Šli bomo čez knjižnične funkcije malloc bolj v drugo, vendar je zamisel o knjižnične funkcije malloc je vse vaše lokalne spremenljivke Vedno gredo na stack. Vse, kar je malloced gre na kup in bo vedno in vedno na kupu dokler ga izrecno sprostiti. Torej to pomeni, da ko malloc kaj pa se dogaja, da preživijo po Funkcija vrne. [Študent] Bo preživel po program ne deluje? Ne >> Ok, tako da bo tam do programa, je pa vse opravljeno vožnjo. >> Da. Lahko gremo v podrobnosti o tem, kaj se zgodi, če program ne deluje. Morda boste morali, da se spomnim, ampak to je stvar popolnoma ločena. [Študent] Torej malloc ustvari kazalec? >> Ja. Malloc - >> [Študent] Mislim, da malloc označuje blok pomnilnika, ki jih lahko uporabite kazalec. [Bowden] Hočem, da diagram znova. >> [Študent] Torej ta funkcija deluje, čeprav? [Študent] Ja, malloc označuje blok pomnilnika, ki ga lahko uporabite, in potem se vrne naslov prvega bloka te spomin. [Bowden] Ja. Torej, ko malloc, da ste oprijemalne nekaj blok pomnilnika , ki je trenutno v kup. Če kup premajhen, nato kup je le, da bo raste in raste v tej smeri. Torej, recimo kup premajhen. Potem gre naprej raste malo in vrne kazalec na tem polju, da samo rasla. Ko free stuff, delaš več prostora v kup, tako da potem kasneje poklicati knjižnične funkcije malloc lahko ponovno ta pomnilnik, ki so ga pred tem sprostila. Pomembna knjižnične funkcije malloc in brezplačnim je, da vam omogoča popoln nadzor v obdobju trajanja teh spominskih blokov. Globalne spremenljivke so vedno živ. Lokalne spremenljivke so živi v njihov obseg. Takoj, ko greš mimo oklepaja kodrasti, lokalne spremenljivke so mrtvi. Malloced spomin živ, če želite, da je živ in se nato sprosti, ko vam povem, da se sprostijo. Tisti, ki so dejansko samo 3 vrste pomnilnika, res. Tam je avtomatsko upravljanje s pomnilnikom, ki je kup. Stvari se dogajajo za vas samodejno. Ko rečeš int x, je dodelitev pomnilnika za int x. Ko gre x zunaj obsega, je spomin za predelane x. Potem je tu še dinamično upravljanje s pomnilnikom, ki je, kar je malloc, ki je, ko imaš nadzor. Ti dinamično odločila, kdaj naj spomin in ne bi bila dodeljena. In potem je statična, kar samo pomeni, da je življenje večno, , ki je tisto, kar globalne spremenljivke. Oni so samo vedno v spominu. Vprašanja? [Študent] lahko določite blok samo z uporabo zavitih oklepajih ne pa da bi imeli, če izkaz ali while izjavo ali kaj podobnega? Določite lahko blok kot v funkciji, ampak da ima tudi zavite oklepaje. [Študent] Torej ne moreš kar so kot naključni par zavitih oklepajih v kodi da imajo lokalne spremenljivke? >> Ja, lahko. Znotraj int vrstice bi lahko imeli {int y = 3;}. To naj bi bilo tukaj. Ampak to je popolnoma opredeljuje področje int y. Po tem drugem oklepaja kodrasti, y ni več mogoče uporabiti. Skoraj nikoli storil, čeprav. Vrnimo se na to, kar se zgodi, ko program konča, obstaja vrsta napačno / pol laži, da smo dali, da bi samo, da se stvari lažje. Povemo vam, da ko dodeliti pomnilnika ste dodeljevanje nekaj kos RAM-a za to spremenljivko. Ampak ne boš res neposredno dotikajo RAM kdaj v svojih programih. Če pomislim, kako sem narisal - In dejansko, če greš skozi v gdb boste videli isto stvar. Ne glede na to, kolikokrat zaženete program ali program, kaj ste tekmovanje v teku, Sveženj je vedno tekoč, da začnete - ste vedno tekoč, da vidim spremenljivk okoli naslova oxbffff nekaj. To je ponavadi nekje v tej regiji. Toda kako lahko program 2 razpolagajo napotke za isti spomin? [Študent] Nekaj ​​arbitrarna določitev, kjer je oxbfff naj bi na RAM da lahko dejansko v različnih krajih, odvisno, ko je bil imenovan funkcijo. Ja. Izraz je navidezni pomnilnik. Ideja je, da vsak postopek, vsak program, ki se izvaja v računalniku ima svojo - predpostavimo, 32 bitov - popolnoma neodvisna naslovnega prostora. To je naslovni prostor. To ima svoje povsem neodvisne 4 GB za uporabo. Torej, če naletite 2 programov hkrati, ta program ne vidi 4 GB sebi, ta program ne vidi 4 GB sebi, in to je nemogoče, da bo ta program ciljne datoteke kazalec in na koncu s spominom iz tega programa. In kaj je navidezni pomnilnik je preslikava iz procesov naslovnega prostora dejanskim stvari na RAM. Torej, to je odvisno od vašega operacijskega sistema vedeti, da je hej, ko je ta tip dereferences kazalec oxbfff, ki v resnici pomeni da želi RAM bajt 1000, ker če tega programa dereferences oxbfff, res želi RAM bajt 10000. Lahko se poljubno daleč narazen. To je tudi res, stvari v enem prostoru procesov naslov. Tako kot se vidi vse 4 gigabajte na sebi, ampak recimo - [Študent] Ali vsak proces - Recimo, da imate računalnik s samo 4 GB RAM-a. Ali vsak proces videti cele 4 gigabajte? >> Da. Ampak 4 gigabajte se mu zdijo, je laž. To je samo misli, da je vse to spomin, saj ne vem kateri koli drug postopek, ne obstaja. To bo le uporaba toliko pomnilnika, kot ga dejansko potrebuje. Operacijski sistem ne bo dal RAM za ta proces če je ne uporabljate pomnilnika, v vsej tej regiji. To se ne dogaja, da ji spomin za to regijo. Toda ideja je, da - Poskušam razmišljati - ne morem razmišljati o analogiji. Analogije je težko. Eno od vprašanj navideznega pomnilnika ali ena izmed stvari, ki jih je za reševanje je, da bi morali biti postopki v celoti zavedajo drug drugega. In tako lahko napisati program, da le dereferences vsak kazalec, želel samo napisati program, ki pravi * (ox1234) in to je pomnilniški naslov Dereferenciranje 1234. Ampak to je odvisno od operacijskega sistema, nato pa prevede kaj pomeni 1234. Torej, če se zgodi, da bo 1234 veljaven naslov spomin na ta proces, kot da je na stack ali kaj podobnega, potem bo ta vrne vrednost tega spomina naslov kolikor je proces ve. Ampak, če je 1234 ni veljaven naslov, kot se to zgodi v tla v nekaterih košček spomina here, ki presega dimnik in preko kopice in ste v resnici ne uporablja, potem je to, ko prideš stvari, kot sesutja zato, ker ste se dotika pomnilnik, ki ga ne bi smeli dotika. To velja tudi za - 32-bitni sistem, 32 bitov pomeni, da imate 32 bitov za opredelitev naslov pomnilnika. To je, zakaj so kazalci 8 bajtov, saj 32 bitov ali 8 bitov - 4 bajtov. Kazalci so 4 bajte. Torej, ko vidite kazalec kot oxbfffff, da je - V vsakem programu lahko samo zgraditi koli samovoljno kazalec, kjerkoli ox0 za vola 8 f's - ffffffff. [Študent] Kaj nisi rekel, da si 4 bajti? >> Ja. [Študent] Potem bo vsak bajt je - >> [Bowden] Šestnajstiški. Šestnajstiški - 5, 6, 7, 8. Torej kazalci boste vedno videli v šestnajstiško. To je samo, kako razvrstiti kazalca. Vsaki 2 številki šestnajstiško je 1 bajt. Torej bo v 8 šestnajstiških števk za 4 bajte. Torej, vsak kazalec na 32-bitnem sistemu se bo 4 bajte, kar pomeni, da v vašem procesu lahko zgraditi samovoljnim 4 bajte in da kazalec od njega, kar pomeni, da, kolikor je to znano, se lahko obravnava celo 2 do 32 bajtov pomnilnika. Kljub temu, da sploh nima dostopa do, da tudi če je vaš računalnik ima le 512 MB, misli, da ima toliko pomnilnika. In operacijski sistem je dovolj pameten, da bo le dodelila tisto, kar dejansko potrebujejo. Ne samo pojdi, oh, nov proces: 4 nastopov. Ja. >> [Študent] Kaj pomeni vola? Zakaj si ga napisal? To je samo znak za šestnajstiško. Ko vidite številke se začnejo z vola, zaporedna stvari šestnajstiško. [Študent] si razložiti, kaj se zgodi, ko program konča. >> Da. Kaj se zgodi, ko se program konča, je operacijski sistem samo izbriše preslikave, ki jih ima za te naslove, in to je to. Operacijski sistem lahko zdaj daj, da spomin na drug program za uporabo. [Študent] Ok. Torej, ko se namenijo nekaj na kup ali dimnika ali globalnih spremenljivk ali kaj podobnega, so vse samo izgine, ko program konča ker operacijski sistem je zdaj prost, da ta spomin na katerem koli drugem postopku. [Študent] Čeprav so verjetno še vedno zapisani v vrednosti? >> Ja. Vrednosti so verjetno še vedno tam. To je samo, da se bo težko priti na njih. To je veliko težje priti do njih, kot je, da se na datoteko izbrisanih ker izbrisane datoteke vrste sedi za dolgo časa in trdega diska, je veliko večja. Torej gre prepisati različnih delov pomnilnika preden se zgodi, da prepišete kos pomnilnika, da ta spis, ki se uporablja za biti. Toda glavni pomnilnik, RAM, da skozi cikel veliko hitreje, tako da se bo zelo hitro prepisana. Vprašanja o tem, ali kaj drugega? [Študent] Imam vprašanja o različnih temah. >> Redu. Ali ima kdo vprašanja o tem? Ok. Različne temo. >> [Študent] Ok. Sem šel skozi nekaj praktičnih preizkusov, in v eni izmed njih pa je govoril o dolľina tipa in vrednost, ki jo vrne ali različnih tipov spremenljivk. >> Da. In je rekel, da tako dolgo int in tako vračanje 4, tako da si jih obe 4 bajte. Ali obstaja razlika med notr in dolgoročno, ali je to isto? Ja, je razlika. Standard C - Jaz sem verjetno bo nered. C standard je ravno tako, kot je C, uradna dokumentacija C. To je tisto, kar piše. Tako standard C samo pravi, da bo znak za vedno in vedno 1 bajt. Vse po tem - kratko je vedno samo opredeljeni kot večji ali enak znak. To je lahko nujno več, vendar ne pozitivno. Int je samo opredeljena kot večja ali enaka kratek. In če že opredelili kot večji ali enak notr. In dolgo dolgo je večje ali enako dolgo. Torej, edina stvar, C standard opredeljuje relativni naročanje vsega. Dejanska količina pomnilnika, ki traja do stvari na splošno do izvedbe, Ampak to je zelo dobro opredeljena v tem trenutku. >> [Študent] Ok. Torej, hlače so skoraj vedno bo 2 bajta. Ints so skoraj vedno bo 4 bajte. Dolga profilni so skoraj vedno bo 8 bajtov. In hrepeni, je odvisno od tega, ali ga uporabljate 32-bitni ali 64-bitni sistem. Torej, če bo ustrezala vrsti sistema. Če uporabljate 32-bitni sistem, kot aparata, se bo v 4 bajte. Če uporabljate 64-bitni kot veliko novejših računalnikih bo v 8 bajtov. Ints so skoraj vedno 4 bajte na tej točki. Dolgi profilni so skoraj vedno 8 bajtov. V preteklosti ints uporablja za samo 2 bajta. Toda opazil, da je to popolnoma izpolnjuje vseh teh odnosov, ki presegajo in enaka. Tako je že dolgo povsem dovoljeno biti enake velikosti kot celo število, in je bilo dovoljeno, da se enake velikosti kot že dolgo časa. In prav tako se zgodi, da se da v 99,999% sistemov, da se bo enako bodisi int ali dolgo dolgo. Prav tako je odvisen od 32-bitno ali 64-bitno različico. >> [Študent] Ok. V plovci, kako je decimalno vejico določena glede bitov? Všeč mi je kot binarna? >> Ja. Ni vam treba vedeti, da je za CS50. Saj sploh ne učijo, da je v 61. Vi ne učijo, da je res v vsakem letu. To je samo predstavitev. Pozabil sem točno bit allotmentov. Ideja plavajočo vejico, je, da dodeli določeno število bitov za zastopanje - V bistvu, vse, kar je v znanstvenem zapisu. Torej ti dodelijo določeno število bitov, ki zastopa več kot 1,2345 sam,. Nikoli ne predstavljajo več z več kot 5 številkami. Potem si tudi dodelila določeno število bitov, tako da kaže, da je kot lahko samo iti do določenega števila, kot da je največji eksponent lahko imate, in lahko samo iti do neke eksponentom, kot da je to najmanjši eksponent lahko imate. Ne spomnim se natančne način bitov se dodelijo vse te vrednosti, vendar so nekateri bitov namenjen 1,2345, še določeno število bitov so namenjeni za eksponentom, in to je mogoče le, da predstavlja eksponent določene velikosti. [Študent] In dvakrat? Je to kot izredno dolgim ​​float? >> Ja. To je isto, kot likvidna sredstva, razen sedaj si z 8 bajte namesto 4 bajte. Zdaj boste lahko uporabljali številke 9 ali 10 cifer, in to bo lahko šel do 300 namesto 100. >> [Študent] Ok. In boje so 4 bajte. >> Da. Torej, še enkrat, je verjetno odvisno splošno o splošnem izvajanju, vendar boje so 4 bajte, dvojice so 8. Dvojice so dvojno imenuje zato, ker so dvojne velikosti plovcev. [Študent] Ok. In tam dvakrat dvojice? >> Ni. Mislim - >> [Študent] Kot dolgo hrepeni? >> Ja. Jaz ne mislim tako. Da. [Študent] Na testu lanskoletnem je bilo vprašanje o glavnih funkcij da bi morali biti del vašega programa. Odgovor je bil, da ni nujno, da bo del svojega programa. V kakšnem položaju? To je tisto, kar sem videl. [Bowden] Zdi se - >> [Študent] Kakšno situacijo? Ali imate težave? >> [Študent] Ja, lahko zagotovo ga potegnite navzgor. Ni nujno, da je tehnično, ampak v bistvu to bo treba. [Študent] sem videl enega na drugo leto je. Bilo je, kot True ali False: veljavnost - >> Oh, c datoteka.? . [Študent], mora vsaka datoteka pa c - [tako govori naenkrat - nerazumljiv] Ok. Tako da je ločena. C datoteke. Samo mora vsebovati funkcije. Lahko pripravijo dokumentacijo v strojni kodi, binarna, ne glede, ne da bi bilo izvedljivo še. Veljavna izvedljiva, mora imeti glavno funkcijo. Lahko napišete 100 funkcij v 1 datoteko, vendar ne glavne in nato prevesti, da do binarne, potem pišete novo datoteko, ki ima samo glavni ampak kliče kup teh funkcij V tem binarne datoteke tam. In tako, ko delaš izvršljiv, da je kaj počne povezovalnik se združuje te 2 binarne datoteke izvedljivi. Torej c datoteka. Ni potrebno, da imajo glavno vlogo na vseh. In na velikih baz kode boste videli na tisoče. Datotek C in 1 glavni datoteki. Še vprašanja? [Študent] je bilo drugo vprašanje. To je dejal, da je prevajalnik. Drži ali ne drži? In odgovor je bil lažen, in sem razumel, zakaj to ni všeč Jek. Toda kaj pravimo, da če ni? Znamka je v bistvu samo - Vidim, kaj jo pokliče. Ampak to samo traja ukazov. Make. Lahko potegnem gor. Ja. Oh, ja. Poskrbite tudi ne da. Ta pravi, da je namen Naredite pripomoček je samodejno določi ki deli velikega programa je treba prevesti in izdal ukaze, da jih prevedem. Lahko naredite, da datoteke, ki so absolutno ogromno. Naj pogleda časovnih žigov datotek in kot smo že omenili, lahko pripravijo posamezne datoteke dol, in to ni, dokler ne pridemo do povezovalnik da oni so skupaj izvedljivi. Torej, če imate 10 različnih datotek in naredite spremembe v 1 izmed njih, potem tisto, zaradi česar se dogaja, da storiti, je le, da prevedem 1 datoteka in potem relink vse skupaj. Vendar pa je mnogo bolj neumen kot to. To je do vas, da popolnoma opredeliti, da je to tisto, kar bi morala delati. To privzeto ima sposobnost prepoznavanja te stvari časovnega žiga, vendar pa lahko napišete make datoteko storiti ničesar. Lahko napišete, da datoteke, tako da ko tipkate, da je samo CD-jev v drugo mapo. Jaz pridobivanje bil razočaran, ker sem prečiti vse v notranjosti mojega aparata in potem vidim PDF, Mac. Zato sem šel v iskalniku in ne morem Go Poveži s strežnikom, in strežnik sem povezati moj aparatov, potem pa sem odprl PDF da dobi zbrala LaTeX. Ampak sem bil pridobivanje uničen, ker vsako ko sem potreben za osvežitev PDF Moral sem jo kopirati v določeno mapo, da bi lahko dostopajo in to je že nadležno. Torej, namesto da sem napisal Naredite datoteko, ki jo morate določiti, kako se naredi stvari. Kako si lahko v to PDF LaTeX. Tako kot vse druge datoteke make - ali Mislim, da niste videli, da datoteke, vendar imamo v napravo svetovnega Naredite datoteko, ki samo pravi, če se pripravi datoteko C, uporabite Jek. In tako sem po mojem Naredite datoteko, da sem ti rekel, To datoteko, ki jo boste želeli pripraviti v PDF LaTeX. In tako je PDF LaTeX, da to počne prevesti. Naj se ne pripravi. To je samo teče ukazov v zaporedju, ki sem. Torej teče PDF LaTeX, jo kopira v imenik, želim, da se kopira, je CD-jev v imenik in ne druge stvari, ampak vse to pa je priznati ko se spremeni datoteka, in če se spreminja, nato pa se bo pognal ukaze, da naj bi vse teče ko se spremeni datoteka. >> [Študent] Ok. Ne vem, če se skupni Naredite datoteke so mi, da preverim. Druga vprašanja? Karkoli iz preteklosti kvizov? Vse kazalec stvari? Obstajajo subtilne stvari, s kazalci, kot so - Ne grem, da bi lahko našli kviz vprašanje o tem - ampak tako kot te stvari. Poskrbite, da boste razumeli, da ko sem rekel, int * x * y - To ni ravno kaj tu, se mi zdi. Ampak kot * x * y, to so 2 spremenljivke, ki so na kupu. Ko rečem x = malloc (sizeof (int)), x je spremenljivka še vedno na sklad, malloc je nekaj čez blok na kup, in da imamo x točka na kup. Torej, kaj na stack točk na kup. Kadarkoli malloc ničesar, boste zagotovo shranjevanje jo globoko v kazalec. Tako, da kazalec na sklad, je malloced blok je na kup. Veliko ljudi se zmeden in pravijo, int * x = malloc, je x na kup. Ne, kaj x opozarja, da je na kupu. x sam na kup, če zaradi kakršnega koli razloga, ki ste jih x je globalna spremenljivka, v tem primeru se zgodi, da bo v drugi regiji pomnilnika. Torej sledenja te sheme box in puščice so precej pogosti v kvizu. Ali pa, če to ni v kvizu 0, bo na kvizu 1. Moral bi vedeti vse te korake v pripravi ker si moral odgovarjati na vprašanja o njih. Da. [Študent] Bi šla skozi te korake - >> Seveda. Pred korake in zbirajo imamo predobdelavo, sestavljanje, montaža in povezovanje. Predobdelavo. Kaj naj bi to naredil? To je najlažji korak - no, ne tako - to ne pomeni, da bi morala biti očitna, toda to je najlažji korak. Vi bi ga izvajajo sami. Ja. [Študent] Vzemi kaj imate v vaši vključuje tako in prepise, nato pa tudi opredeljuje. Videti za stvari, kot so, in # # define, in to samo kopije in paste, kaj so pravzaprav pomeni. Torej, ko ste rekli # include cs50.h je preprocesor kopiranje in lepljenje cs50.h na tej progi. Ko rečeš # define x za 4, preprocesor gre skozi celoten program in nadomešča vse primerke x 4 s. Torej preprocesor meni veljaven C datoteko in izhodi veljaven C datoteko kjer so stvari, kopirali in prilepili. Torej, zdaj prevesti. Kaj naj bi to naredil? [Študent] To gre iz C v binarno. [Bowden] Ne presega vse do binarno. [Študent] V strojni kodi potem? >> To ni strojno kodo. [Študent] zbor? >> Skupščine. Jasno je, da skupščina, preden gre vse do oznako C, in večina jezikov, nekaj takega. Izberite vse visoki ravni jezika, in če boš prevedel, je verjetno, da pripravijo v korakih. Najprej se bo zbiranje Python in C, nato pa se dogaja, da pripravijo C do skupščine, nato pa Skupščina bo dobil preveden v binarno. Tako se bo zbiranje, da bi ga od C do skupščine. Beseda sestavljanje ponavadi pomeni, da ga pripelje do višje ravni na nižji ravni programskega jezika. Torej, to je le korak v zbiranju, kjer ste začeli s visoki ravni jezika in končajo v nizki ravni jezika, in to je, zakaj se imenuje korak prevesti. [Študent] Med pripravo, recimo, da si naredil # include cs50.h. Bo prevajalnik prevedem cs50.h, kot so funkcije, ki so tam, in to pretvorijo v kodo zbor, kot tudi, ali bo to kopiraj in prilepi nekaj, kar je bilo pred zbor? cs50.h bo precej nikoli ne končajo v zboru. Stvari, kot funkcijskih prototipov in stvari so samo za vas, da bodite previdni. To zagotavlja, da lahko prevajalnik preveri stvari, kot kličeš funkcije s pravimi vračanja vrste in pravih argumentov in podobno. Tako bo cs50.h vnaprej obdela v datoteko, in potem, ko se je zbiranje to je v bistvu zavrgli, potem ko je zagotovil, da je vse, kar se pravilno imenovan. Toda naloge, opredeljene v CS50 knjižnice, ki so ločene od cs50.h, tistih, ki se ne bodo posebej pripravljeni. To bo dejansko prišel v povezuje koraku, tako da bomo prišli do, da v drugem. Ampak najprej, kaj je montaža? [Študent] zbor v binarno? >> Ja. Sestavljanje. Mi ne pravimo sestavljanje, ker zbor je precej čist prevod binarno. Obstaja zelo malo logiko bo od skupščine do binarno. To je tako kot je videti v tabeli, oh, imamo ta navodila; ki ustreza binarno 01110. In tako so datoteke, montaža na splošno izhodi so. O files. In o. Slik, kar smo rekli prej, kako datoteka ni treba, da imajo glavno vlogo. Vsaka datoteka se lahko pripravijo navzdol do datoteke. °, dokler je veljavna C datoteka. To je mogoče pripraviti do. ​​O. Zdaj, povezovanje je tisto, kar dejansko prinaša kup. O datoteke in jih pripelje do izvršljiv. In kaj počne, je povezovanje lahko si misliš o CS50 knjižnico kot datoteko. O. To je že izvedla binarna datoteka. In tako, ko pripravijo svojo datoteko, vaš hello.c, ki poziva GetString, hello.c gets pripravljeni do hello.o, hello.o je zdaj v binarno. Uporablja GetString, zato mora iti čez cs50.o, in povezovalnik jih smooshes skupaj in kopira GetString v tej datoteki in pride ven z izvršljiv, ki ima vse funkcije, ki jih potrebuje. Torej cs50.o dejansko ni O datoteka, vendar je dovolj blizu, da ni bistvene razlike. Tako povezovanje prinaša le kup datotek, skupaj da ločeno vsebuje vse funkcije, moram uporabiti in ustvarja izvedljivo, da bodo dejansko vodijo. In tako je tudi tisto, kar so govorili pred kjer lahko imate 1000. c datoteke, lahko prevedete jim vse k. o datoteke, ki bo verjetno trajalo nekaj časa, potem pa ste spremenili 1. c datoteka. Morate le, da prevedem 1. C datoteko in nato relink vse ostalo, povezati vse skupaj nazaj. [Študent] Ko smo povezavo pišemo lcs50? Ja, tako lcs50. To zastavo signale Povezivač, da morate biti povezave v tej knjižnici. Vprašanja? Smo šli v binarno, razen, da je 5 sekund v prvi predavanja? Jaz ne mislim tako. Moral bi vedeti vse o velikem Os, da smo šli čez, in ti bi lahko, če bi ti dal nalogo, bi morali biti sposobni reči, da je velik O, grobo. Ali pa, veliki O grob. Torej, če vidite ugnezdene zanke za večkratno več kot v enakem številu stvari, kot int i, i > [Študent] n kvadrat. >> To kaže, da je n kvadrat. Če ste trojno vgnezditi, pa kaže, da je n kubikov. Torej, da bi morala biti neke vrste stvar, ki jo lahko takoj poudariti. Morate vedeti vstavljanja vrste in mehurček razvrščanje in zlivanjem in vse od njih. To je lažje razumeti, zakaj so tisti kvadrat n in n log n in vse to ker mislim, da je bilo na kvizu eno leto, kjer smo v bistvu ti je dal izvajanje vrste mehurčkov in rekel: "Kaj je čas delovanja te funkcije?" Torej, če jo prizna kot neke mehurčke, potem lahko takoj povedati n kvadrat. Ampak, če si pogledate, vam ni treba niti dojel mehurček vrste; lahko samo rečem to počne to in to. To je n kvadrat. [Študent] Ali obstajajo primeri težke lahko prišli do, kot podobno idejo poskušal ugotoviti? Ne verjamem, da mi bo dal vse težke primere. Bubble sort, kar je približno tako težko, kot bi šla, pa še to, če boste razumeli, da ste ponavljanjem v matriki Za vsak element v matriki, ki se bo nekaj, kar je n kvadrat. Obstaja splošna vprašanja, kot je tukaj imamo - Oh. Samo drugi dan, Doug je trdil: »Jaz sem izumil algoritem, ki lahko razvrstite niz "N od številk v O (log n) časa!" Torej, kako bomo vedeli da je to nemogoče? [Neslišno študentski odziv] >> Ja. Vsaj, morate dotakniti vsakega elementa v matriki, zato je nemogoče razvrstiti array - Če je vse v nesortiranih redu, potem boš se dotika vse, kar je v polju, zato je nemogoče, da to storite v manj kot O n. [Študent] Vi nam je pokazala, da je primer, da lahko to storite O n Če uporabljate veliko pomnilnika. >> Ja. In that - Pozabil sem, kaj that - Je štetje vrste? Hmm. To je celo sortiranje algoritem. Iskal sem za posebno ime za to, da se nisem mogel spomniti prejšnji teden. Ja. To so tipi sort, ki jih lahko dosežete na stvari v veliki O n. Vendar pa obstajajo omejitve, kot jih lahko uporabite samo cela do določenega števila. Plus, če ste poskušali rešiti nekaj, that - Če je vaš matrika 012, -12, 151, 4 mio EUR, potem en element bo popolnoma uniči celotno sortiranje. Vprašanja? [Študent] Če imate rekurzivno funkcijo, in to šele naredi rekurzivni klic v povratni izjavo, da je rep rekurzivni, in zato, da ne bi porabi več pomnilnika med izvajanjem, ali bi vsaj uporabiti primerljivo spomin kot iterativni rešitev? [Bowden] Da. To bi verjetno nekoliko počasneje, vendar ne zares. Rep rekurzivna je precej dobro. Če pogledamo še enkrat dimnika okvirjev, recimo, da imamo glavno in smo int bar (int x) ali kaj podobnega. To ni popoln rekurzivna funkcija, ampak vrnitev bar (x - 1). Torej je očitno, to je napačna. Moraš osnovnih zadev in podobno. Toda ideja tukaj je, da je to rep rekurzivni, kar pomeni, da ko glavni bar klicev pa se dogaja, da bi dobili svojo dimnika okvirja. V tem okviru je dimnik bo še malo blok pomnilnika da ustreza njena trditev x. In tako se recimo zgodi, da pokličete glavni bar (100); Torej x se bo začeti kot 100. Če prevajalnik, da gre rep rekurzivna funkcija, potem ko je bar naredi svoje rekurzivni klic v bar, namesto da bi novo žetonov okvir, ki je, če se začne sveženj večinoma narašča, sčasoma bo naletel na kup in potem dobiš sesutja ker je pomnilnik začne trčenju. Torej, namesto da bi svojo žetonov okvir, se lahko zavedaš, hej, nikoli nisem zares potrebujejo, da pridejo nazaj na to dimnik okvir, Tako namesto da bom samo nadomestiti te trditve z 99 in nato začnite vrstico z vsem. In potem bo to storil še enkrat in da bo dosegla vrnitev bar (x - 1), in namesto da bi novo žetonov okvir, bo to samo zamenjati svoj trenutni argument, s 98 in potem skoči nazaj na samem začetku vrstice. Ti postopki, ki nadomešča to 1 vrednost na kupu in skakanje nazaj na začetek, so zelo učinkoviti. Torej ne samo, da je to ista pomnilnika kot samostojna funkcija, ki se ponavlja saj ste le z uporabo 1 žetonov okvir, ampak si ne trpijo slabosti da bi morali poklicati funkcije. Klicne funkcije lahko nekoliko drago, saj mora storiti vse te nastavitve in razstavitev in vse te stvari. Torej, to repa rekurzija je dobro. [Študent] Zakaj ne ustvarite nove korake? Ker se zaveda, da ni potrebno. Poziv k baru je le vračanje rekurzivni klic. Torej mu ni treba storiti ničesar, s povratno vrednost. To je le, da bo takoj vrnil. Torej, to je le, da bo nadomestil svojo trditev in začeti znova. In tudi, če ne boste imeli rep rekurzivno različico, potem so dobili vse te vrstice, kjer je ta bar, ko se vrne ima svojo vrednost, da se vrnete na to eno, potem se takoj vrne bar in vrne njegovo vrednost do tega, potem se bo kar takoj vrne in vrne njegovo vrednost na to. Torej ste za varčevanje to pokanje vse te stvari off dimnika ker je donosnost vrednost je le, da bo treba posredovati vso pot nazaj do anyway. Torej, zakaj ne samo zamenjati svoje trditve s posodobljeno utemeljitev in začeti znova? Če funkcija ni na rep rekurzivna, če vam kaj takega - [Študent], če bar (x + 1). >> Ja. Torej, če ste jo dali v stanju, potem delaš nekaj s povratno vrednost. Ali pa tudi če si naredil vrnitev 2 * bar (x - 1). Torej, zdaj bar (x - 1) mora vrniti, da bi ta lahko izračunala 2-krat, da je vrednost, tako da zdaj ne potrebujemo svoj lasten okvir žetonov, in zdaj, ne glede na to, kako težko poskusu, boste morali - To ni rekurzivna rep. [Študent] Jaz bi poskusil, da bi rekurzijo, da si prizadeva za rep rekurzije - [Bowden] V idealnem svetu, ampak v CS50 vam ni treba. Da bi dobili rep rekurzijo, na splošno pa lahko določijo dodatne navedbe bar, kjer bo lahko v int x y in y enako končnemu stvar, ki jo želite, da se vrnete. Torej to, da boš lahko vrnil bar (x - 1), 2 * y. Torej, to je samo na visoki ravni, kako spremeniti stvari, ki se rep rekurzivno. Ampak ekstra argument - In potem, na koncu, ko ste dosegli svoj osnovni primer, ki ste jo pravkar vrnil y ker si nabira ves čas, vrne vrednost, ki jo želite. Si nekako so to počeli iterativno, vendar z uporabo rekurzivnih klicev. Vprašanja? [Študent] Mogoče pa aritmetične kazalec, tako kot pri uporabi nizov. >> Seveda. Kazalec aritmetično. Pri uporabi nizov je preprosto zato, ker so nizi char zvezde, znakov za vedno in vedno en zlog, in tako kazalec aritmetična enakovredna redni aritmetike, ko imate opravka s strunami. Reciva, char * s = "zdravo". Torej imamo blok v pomnilniku. Treba 6 bajte, ker ste vedno potrebovali null terminator. In char * i se dogaja, da opozarjajo na začetku tega polja. Torej je Poudarja tam. No, to je v bistvu, kako vsaka matrika deluje, ne glede na to, ali je bil donos po knjižnične funkcije malloc ali pa je na kupu. Vsaka matrika je v bistvu kazalec na začetku niza, in potem vsako polje delovanja, vsako indeksiranje, se bo samo v tem polju določenih izravnavo. Torej, ko sem rekel kaj takega ih [3], kar se bo s in 3 štetju znakov noter Torej s [3], imamo 0, 1, 2, 3, tako da s [3], se dogaja, da se nanašajo na ta l. [Študent] In smo lahko dosegli enako vrednost s tem, S + 3, nato pa oklepaje zvezda? Da. To je enako * (S + 3); in da je vedno in vedno enaka ne glede na to, kaj počnete. Vam nikoli ni treba uporabiti nosilec sintakso. Vedno lahko uporabite * (i + 3) skladnje. Ljudje pogosto radi nosilec sintakso, čeprav. [Študent] Torej so vsi nizi so v resnici le kazalci. Obstaja rahla razlika, ko rečem, int x [4] >> [Študent] Ali da ustvarite spomin? [Bowden] To bo ustvarilo 4 ints na kup, tako da 16 bitov na splošno. To bo ustvarilo 16 bajtov na kupu. x se ne shrani nikamor. To je samo simbol, ki se nanašajo na začetku stvari. Ker ste prijavljeni matriko znotraj te funkcije, kaj se dogaja prevajalnik storiti, je le zamenjati vse primerke spremenljivke x s tem, kje se je to zgodilo, da izberejo, da se ti 16 bajtov. Ne morem storiti s char * s, ker je je dejansko kazalec. Je brezplačno in se potem kaže na druge stvari. x je konstantna. Ne moreš se kažejo na različne matrike. >> [Študent] Ok. Toda ta ideja, ta indeksiranje, je enaka ne glede na to, ali gre za tradicionalno niz ali če je kazalec na nekaj ali, če je kazalec na malloced matrike. In v resnici je tako, da ustreza, da je ista stvar. To dejansko pomeni, le kaj je v oklepaju in kaj je ostalo od oklepaju jih sešteje, in dereferences. Torej, to je prav tako veljavna * (i + 3) ali s [3]. [Študent] Ali ste napotke, ki kažejo na 2-dimenzionalni nizi? To je težje. Običajno ne. 2-dimenzionalni array je le 1-dimenzionalni niz z nekaj priročno sintakso ker če rečem, int x [3] [3], to je res samo 1 polje z 9 vrednostmi. In tako, ko sem indeks, prevajalnik ve, kaj mislim. Če rečem, x [1] [2], da ve, rad bi šel v drugo vrstico, tako da se bo preskočiti prvo 3, in potem hoče drugo stvar v tem, da se dogaja, da bi dobili tole. Ampak to je še vedno samo ena dvodimenzionalna matrika. In tako, če bi hotel dodeliti kazalec na tem polju, Rekel bi, int * p = x; Vrsta x je le - To je grobo rekel tip x saj je samo simbol, in to ni dejansko spremenljivka, ampak to je samo int *. x je samo kazalec na začetek tega. >> [Študent] Ok. In da mi ne bodo mogli dostopati [1] [2]. Mislim, da je posebna sintaksa za razglasitev kazalec, nekaj smešno, kot int (* p [-. nekaj popolnoma smešno sploh ne vem. Vendar pa je sintaksa za razglasitev kazalce, kot so v oklepajih in stvari. Zato ni nujno, da vam to. Lahko se ozremo na nekaj, kar bi mi povej resnico. Bom kasneje poiskal, če je sintaksa za točko. Ampak nikoli ne boste videli. In tudi sintaksa je tako zastarela, da če jo uporabljate bodo ljudje šokirani. Večdimenzionalna polja so precej redki, kot je. Si precej - No, če delaš stvari matrične to ne bo redki, ampak v C ste redko dogaja, da se z uporabo večdimenzionalnih nize. Ja. >> [Študent] Recimo, da imate res dolgo vrsto. Tako v navideznem pomnilniku se zdi, da so vsi izvidi kot elementov, tik ob drugega, ampak v fizični pomnilnik, bi moralo biti omogočeno, da se razideta? >> Da. Kako virtualni spomin deluje, je to samo ločuje - Enota za dodelitev je stran, ki kaže, da je 4 kilobajtov, in tako, ko pravi proces, hej, želim uporabiti ta spomin, Operacijski sistem bo ji dodeli 4 kilobajtov za to malo blok pomnilnika. Tudi če uporabljate samo eno malo bajt v cel blok pomnilnika, operacijski sistem se dogaja, da ga v celoti 4 kilobajtov. Torej, kaj to pomeni, sem lahko - recimo, to je moj dimnik. Ta sklad bi lahko ločiti. Moje sklad lahko megabajtov in megabajti. Moje sklad lahko ogromni. Ampak sklad sama razdeli na posamezne strani, ki, če pogledamo sem recimo to je naša RAM, če imam 2 GB RAM-a, to je dejanski naslov 0, kot je bajt 0. mojega RAM, in to je 2 gigabajta vse tako daleč. Torej bi ta stran ustreza tej rubriki sem. To stran lahko ustrezajo tej rubriki sem. Ta je lahko ustreza tale tam. Tako operacijski sistem je brezplačno dodelitev fizičnega pomnilnika za vsako posamezno stran samovoljno. In to pomeni, da če se to zgodi, da segajo čez meje niz, matrika se zgodi, da ostane to in prav to reda strani, potem je matrika se bo razdeljeno v fizičnem pomnilniku. In potem, ko zaprete program, ko se proces konča, te preslikave se izbrišejo in potem je prost za uporabo teh malo blokov za druge stvari. Še vprašanja? [Študent] Kazalec Aritmetična. >> Oh ja. Strune so bile lažje, vendar si ogleduje nekaj podobnega ints, Torej nazaj na int x [4]; Ali je to polje, ali je kazalec na malloced paleto 4 cela števila, to bo treba obravnavati na enak način. [Študent] Torej nizi so na kup? [Bowden] Matrike niso na kup. >> [Študent] Oh. [Bowden] Ta vrsta matrike kaže, da je na kupu razen če ga deklarira - neupoštevanje globalne spremenljivke. Ne uporabljajte globalnih spremenljivk. Znotraj funkcije rečem int x [4]; To bo ustvarilo celo število 4-blok na kup za to polje. Ampak to malloc (4 * sizeof (int)); je šel na kup. Toda po tej točki lahko uporabim x in p v precej enak način, razen izjem, sem rekel prej o tem si lahko dodelite p. Tehnično njihove velikosti so nekoliko drugačna, vendar je to povsem nepomembno. Nikoli ne dejansko uporabljajo svoje velikosti. P Lahko bi rekel, p [3] = 2 ali x [3] = 2; Uporabite jih lahko v popolnoma enak način. Torej kazalec aritmetična zdaj - Da. [Študent] Ali vam ni treba storiti, p *, če imate nosilce? Nosilci so implicitni dereference. >> Redu. Pravzaprav je tudi to, kar praviš, da z lahko dobite večdimenzionalne matrike s kazalci, kaj lahko naredite, je nekaj takega kot, recimo, int ** pp = malloc (sizeof (int *) * 5); Jaz bom samo pisati vse ven prvi. Nisem hotel tega. Ok. Kaj sem tu - To bi moralo biti odstotne točke [i]. Torej, pp je kazalec na kazalec. Saj mallocing odstotne točke na vrsto 5 zvezdic int. Torej, v spomin imate na kup odstotne točke To se dogaja, da kažejo na paleto 5 blokov, ki so vsi kazalci sami. In potem, ko sem malloc dol, sem malloc, da vsaka od teh posameznih kazalcev Naj opozorim, da poseben sveženj 4 bajte na kup. Torej, to kaže na 4 bajte. In to kaže na drugo 4 bajte. In vse od njih opozarjajo na svoje 4 bajte. To mi daje način, kako večdimenzionalne stvari. Lahko bi rekel, pp [3] [4], zdaj pa to ni ista stvar kot večdimenzionalne matrike ker večdimenzionalna polja preveden [3] [4] v en odmik v polju x. Ta dereferences p, dostopa do 3. kazalo, nato dereferences da in dostopov - bi 4 neveljavna - druga indeks. Ker ko smo imeli int x [3] [4], preden je večdimenzionalna polja in ko se dvakrat držalo, da je res samo ena dereference, ste po en kazalec in nato izravna, to je res 2D reference. Slediš 2 ločeni kazalca. Torej je to tudi tehnično omogoča, da imate večdimenzionalne matrike kjer je vsak posameznik matrika različnih velikosti. Zato mislim, da nazobčane večdimenzionalna polja je, kako se imenuje saj res lahko prva stvar, ki kaže na nekaj, kar je 10 elementov, Druga stvar, ki bi lahko kazal na nekaj, kar ima 100 elementov. [Študent] Ali obstaja omejitev števila kazalcev, da lahko imajo kaže na druge kazalce? Ne >> Lahko imaš int ***** str. Nazaj na aritmetične kazalec - >> [Študent] Oh. >> Ja. [Študent] Če imam int p ***, potem pa sem naredil Dereferenciranje in rečem: p * je enako tej vrednosti, je le, da bo naredil 1 raven Dereferenciranje? >> Da. Torej, če želim dostopati do stvari, da je zadnja kazalec, ki kaže na - Potem vam *** p. >> Redu. Torej, to je p opozarja na bloku 1, točke do drugega bloka, kaže na drugega bloka. Potem, če ne * p = kaj drugega, potem ste to spremembo do sedaj kaže na drugačen blok. >> Redu. [Bowden] In če ti malloced, potem ste zdaj ušli spomin razen če se zgodi, da imajo različne sklicevanja na to saj ne moreš dobiti nazaj tiste tiste, ki ste jo pravkar vrgel stran. Kazalec aritmetično. int x [4], se bo dodelila niz celih 4 kjer je x gre opozoriti na začetku niza. Torej, ko sem rekel kaj takega x [1], želim, da pomeni iti v drugo celo število v matriki, kar bi bilo to. Ampak res, da je 4 bajte v polju, saj je to celo zasede 4 bajte. Torej odmik od 1. resnici pomeni odmik od 1 krat večje ne glede na tip matrike je. To je niz celih števil, tako da ve, da ne 1 krat velikost notr, če želi izravnati. Druga skladnja. Ne pozabite, da je to enako * (x + 1); Ko rečem, da je kazalec + 1, kar da se vrača je naslov, ki je kazalec shranjevanje plus 1-krat velikosti tipa kazalca. Torej, če je x = ox100, potem x + 1 = ox104. In lahko zlorabijo to in kaj takega, kot char * c = (char *) x; in c se zdaj dogaja, da je isti naslov kot x. c se bo enako ox100, ampak c + 1 bo enaka ox101 saj je kazalec aritmetična odvisna od vrste kazalca, ki ga dodajate k. Torej c + 1, je videti na c, to je znak kazalec, zato se dogaja, da dodate 1 krat velikosti char, , ki se bo vedno 1, tako da boste dobili 101, ker če naredim x, ki je še vedno 100, x + 1 se bo 104. [Študent] Ali lahko C + + za napredek kazalec za 1? Ja, lahko. Tega ne moreš storiti, da se z x x saj je samo znak, da je konstantna, ne morete spremeniti x. Ampak c zgodi, da preprosto je kazalec, da C + + je povsem pravilna in bo prirastek po 1. Če si samo c int *, potem pa c + + bi se 104. + + Kazalec ne le kot aritmetično c + 1 bi naredil aritmetično kazalca. To je pravzaprav, kako veliko stvari, kot so vrsta spajanja - Namesto ustvarjanja kopije stvari, lahko namesto mimo - Všeč mi je, če sem hotel prenesti ta polovico matrike - kaj je izbrisalo nekaj od tega. Recimo, da sem hotel prenesti to stran matrike v funkciji. Kaj bi rad, na to funkcijo? Če grem mimo x, sem mimo tega naslova. Ampak jaz želim uspešno prestal to poseben naslov. Torej, kaj naj grem mimo? [Študent] Pointer + 2? [Bowden] Torej x + 2. Da. To se dogaja, da se ta naslov. Prav tako boste zelo pogosto vidijo kot x [2] in nato naslov za to. Torej boste morali vzeti naslov za to, ker je nosilec je implicitna dereference. x [2], se nanaša na vrednost, ki je v tem polju, in nato želite, da se naslov te škatle, Tako si rekel & x [2]. Torej, to je, kako nekaj v vrste spajanja, kjer želite prenesti polovico seznama na nekaj res samo mimo & x [2], in zdaj, ko se tiče rekurzivni klic, moja nova matrika se začne tam. Zadnje minute vprašanja. [Študent] Če ne naredi 'in' znak ali - kaj je to reče? >> Zvezdica? [Študent] Star. >> Tehnično dereference operater, ampak - >> [Študent] dereference. Če nam ne dajo zvezdo ali znak pove, kaj se zgodi, če rečem, y = x in x je kazalec? Kaj je vrsta y? >> [Študent] Jaz bom samo rekel, da je kazalec 2. Torej, če si rekel y = x, zdaj pa x in y točka za isto stvar. >> [Študent] Točka za isto stvar. In če je x int kazalec? Bilo >> pritožujejo, ker jih ni mogoče dodeliti kazalca. [Študent] Ok. Ne pozabite, da kazalci, čeprav smo jih pripravi kakor puščice, res vse, kar trgovina - int * x - x je res vse, kar je nekaj podobnega shranjevanje ox100, , ki se zgodi, da predstavljajo kot kaže na shranjeno na bloku 100. Torej, ko sem rekel, int * y = x, jaz sem samo kopiranje ox100 v y, ki smo le, da bo predstavljajo kot y, prav tako kaže na ox100. In če rečem int i = (int) x, nato pa sem se dogaja, da shranite ne glede na vrednost ox100 je znotraj nje, zdaj pa bo treba razlagati kot celo število namesto kazalca. Ampak morate litine, ali pa se bo pritožil. [Študent] Torej hočeš reči, da glasuje - Ali bo treba litje int int x ali vlivanja y? [Bowden] Kaj? [Študent] Ok. Po teh oklepajih se tam dogaja, da je x ali ay tam? [Bowden] Bodisi. x in y sta enakovredni. >> [Študent] Ok. Ker oni oba kazalca. >> Ja. [Študent] Zato bi bilo shranjevanje šestnajstiško 100 v integer obliki? >> [Bowden] Ja. Ampak ne glede na vrednost kaže na. [Bowden] Ja. >> [Študent] Torej, samo naslov v integer obliki. Ok. [Bowden] Če hočeš nekaj bizarnega razloga, bi lahko izključno s kazalci in nikoli ne ukvarjajo s števil in samo kot int * x = 0. Potem boš dobil res zmeden, ko je kazalec aritmetično začne dogajati. Tako so številke, ki jih shranjujejo, so brez pomena. To je samo, kako ste končali njihovo razlago. Torej sem prost kopirati ox100 od int * za notr, in sem prosta za dodelitev - Ti si verjetno, da bo dobil vpil, da ni litje - Sem brez dodeliti nekaj podobnega (int *) ox1234 v tem samovoljno * int. Torej ox123 je prav tako veljavna pomnilniški naslov, kot je & y. & Y zgodi, da se vrnete nekaj, kar je precej ox123. [Študent], bi bilo to res kul način, da gredo iz šestnajstiško v decimalni obliki, všeč, če imate kazalec in ga odda kot int? [Bowden] Lahko res samo tiskanje z uporabo, kot so printf. Recimo, da imam int y = 100. Torej printf (% d \ n - kot bi že veste - tiskanje, ki so cela,% x. Mi bomo samo tiskanje je kot šestnajstiško. Torej se kazalec ne shrani kot šestnajstiško, in celo ne shrani kot decimalko. Vse je shranjeno v binarni obliki. To je samo, da smo nagnjeni k prikaz kazalcev, kot šestnajstiško ker menimo, da stvari v teh 4-bajtne bloke, in pomnilniške naslove ponavadi pozna. Smo kot, če se začne z BF, potem pa se zgodi, da bo na kupu. Torej, to je le naša interpretacija kazalcev, kot šestnajstiško. Ok. Kakšne zadnje vprašanje? Tukaj bom za nekaj časa po tem, ko, če imate kaj drugega. In to je konec tega. [Študent] Bravo! [Aplavz] [CS50.TV]