>> [Musik spiller]
>> DOUG Lloyd: Pointers, her er vi.
Dette er sandsynligvis vil være det vanskeligste emne
at vi taler om i CS50.
Og hvis du har læst noget om pointers
før du kan være en lille smule skræmmende at gå ind i denne video.
Det er sandt at pointere tillader dig mulighed
til måske skrue op temmelig dårligt, når du er
arbejder med variabler, og data, og forårsager dit program til at gå ned.
Men de er faktisk virkelig nyttige og de giver os mulighed for en virkelig god måde
at videregive data frem og tilbage mellem funktioner,
at vi ellers ikke kan gøre.
>> Og så hvad vi virkelig ønsker at gøre her er toget
at du har gode pointer disciplin, så at du kan bruge pegepinde effektivt
at gøre dine programmer, der meget bedre.
Som jeg sagde pegepinde give os en anden måde at videregive data mellem funktioner.
Nu, hvis du husker fra en tidligere video, når
vi talte om variabel rækkevidde, nævnte jeg
at alle de data, vi passerer mellem funktioner i C forbi værdi.
Og jeg kan ikke har brugt, at sigt, hvad jeg mente der
var, at vi passerer kopier af data.
Når vi passerer en variabel til en funktion, Vi er faktisk ikke passerer den variable
til funktionen, ikke?
Vi passerer en kopi af at data til funktionen.
Funktionen gør, hvad den vil og beregner en vis værdi,
og måske bruger vi denne værdi når det giver det tilbage.
>> Der var en undtagelse til denne regel passere efter værdi,
og vi vil komme tilbage til, hvad det er lidt senere i denne video.
Hvis vi bruger pegepinde stedet for at anvende variable,
eller i stedet for ved hjælp af variabler selv eller kopier af de variabler,
Vi kan nu passere variablerne rundt mellem funktioner på en anden måde.
Det betyder, at hvis vi gør en ændring i en funktion,
at ændringen vil faktisk tage virkning i en anden funktion.
Igen, det er noget, vi ikke kunne gøre tidligere,
og hvis du nogensinde har prøvet at bytte værdien af ​​to variabler i en funktion,
du har bemærket, dette problem slags snigende op, ikke?
>> Hvis vi ønsker at bytte X og Y, og vi videregive dem til en funktion kaldet swap,
indersiden af ​​funktionen swap variabler gør bytteværdier.
Man bliver to, to bliver en, men vi faktisk ikke
ændre noget i den oprindelige funktion, i den, der ringer.
Fordi vi ikke kan, vi er kun arbejder med kopier af dem.
Med pointere selv, vi kan faktisk passerer X og Y til en funktion.
Denne funktion kan gøre noget med dem.
Og disse variabler værdier kan faktisk ændre.
Så det er noget af en ændring i vores evne til at arbejde med data.
>> Før vi dykke ned i pointere, jeg synes det er værd
tage et par minutter til gå tilbage til basics her.
Og have et kig på, hvordan computer hukommelse værker
fordi disse to emner vil faktisk være temmelig indbyrdes.
Som du sikkert ved, på din computer system
du har en harddisk eller måske et SSD-drev,
en slags fil opbevaring placering.
Det er normalt et sted i kvarter på 250 gigabyte
til måske et par terabytes nu.
Og det er hvor alle dine filer i sidste ende lever,
selv når computeren er lukket fra, kan du slå det til igen
og du vil finde dine filer er der igen, når du genstarter dit system.
Men diskdrev, ligesom en harddisk, en harddisk eller et SSD-drev, en SSD,
er blot lagerplads.
>> Vi kan faktisk ikke gøre noget med de data, der er i harddisken,
eller i en SSD-drev.
For at rent faktisk at ændre data eller flytte den rundt,
vi er nødt til at flytte det til RAM, random access memory.
Nu RAM, du har en masse mindre af på din computer.
Du har måske et eller andet sted i kvarter af 512 megabyte
hvis du har en ældre computer, til måske to, fire, otte, 16,
måske endda lidt mere, gigabyte RAM.
Så det er meget mindre, men det er hvor alle de flygtige data findes.
Det er, hvor vi kan ændre tingene.
Men når vi vende vores computer slukket, alle data i RAM er ødelagt.
>> Så det er derfor vi har brug for harddisk for mere permanent placering af det,
så det exists- det ville være virkelig dårligt, hvis hver gang vi
vendte vores computer slukket, hver fil i vores system blev udslettet.
Så arbejder vi inde RAM.
Og hver gang vi taler om hukommelse, temmelig meget, i CS50,
vi taler om RAM, ikke harddisk.
>> Så når vi flytte ting ind i hukommelsen, det tager en vis mængde plads.
Alle de datatyper, der vi har arbejdet med
tage forskellige mængder af plads i RAM.
Så hver gang du opretter et heltal variable, fire bytes hukommelse
er afsat i RAM, så du kan arbejde med at heltal.
Du kan erklære heltal, ændre det, tildele den
til en værdi 10 inkrementeres efter én, så videre og så videre.
Alt, der skal ske i RAM, og du får fire bytes
at arbejde med for hver heltal, du opretter.
>> Hvert tegn, du skaber får én byte.
Det er bare, hvor meget plads er for at kunne rumme et tegn.
Hver svømmer, en reel nummer, får fire bytes
medmindre det er en dobbelt præcision floating point
nummer, som giver dig mulighed for at har mere præcise eller flere cifre
efter kommaet uden at miste præcision,
som optager otte bytes hukommelse.
Lange længes, virkelig store heltal, også tage otte bytes hukommelse.
Hvor mange bytes hukommelse gør strygere tage op?
Jamen så lad os sætte en stift i dette spørgsmål for nu, men vi vil vende tilbage til det.
>> Så tilbage til denne idé om hukommelse som en stor vifte af byte-størrelse celler.
Det er virkelig alt, hvad det er, det er bare en enorm matrix af celler,
ligesom enhver anden array, der du er fortrolig med og se,
undtagen hvert element er en byte bred.
Og ligesom et array, hvert element har en adresse.
Hvert element i et array har et indeks, og vi
kan bruge dette indeks til at gøre såkaldte random access på arrayet.
Vi behøver ikke at starte ved begyndelsen af ​​grupperingen,
gentage gennem hver enkelt element heraf,
at finde, hvad vi leder efter.
Vi kan bare sige, jeg ønsker at komme til 15. element eller 100-element.
Og du kan bare passere i dette nummer og få den værdi, du leder efter.
>> Tilsvarende hver placering i hukommelsen har en adresse.
Så din hukommelse måske se noget som dette.
Her er en meget lille luns af hukommelse, det er 20 bytes hukommelse.
De første 20 byte, fordi min adresser der nederst
er 0, 1, 2, 3, og så på hele vejen op til 19.
Og når jeg erklærer variabler og når jeg begynder at arbejde med dem,
systemet vil sætte afsat nogle plads til mig
i denne hukommelse til at arbejde med mine variabler.
Så jeg kan sige, char c lig kapital H. Og hvad der vil ske?
Godt systemet kommer til at afsat til mig en byte.
I dette tilfælde valgte byte nummer fire, byte på adresse fire,
og det kommer til at gemme bogstavet kapital H i ​​der for mig.
Hvis jeg så sige int hastighed grænse er lig med 65, er det
kommer til at afsætte fire bytes hukommelse for mig.
Og det kommer til at behandle dem, fire bytes som en enkelt enhed
fordi det, vi arbejder med, er et helt tal her.
Og det kommer til at gemme 65 derinde.
>> Nu allerede Jeg er lidt fortæller dig lidt af en løgn,
ret, fordi vi ved, at computere arbejde i binær.
De forstår ikke nødvendigvis, hvad en kapital H er
eller hvad en 65 er, at de kun forstår binære, nuller og ettaller.
Og så faktisk, hvad vi opbevaring derinde
er ikke bogstavet H og antallet 65, men snarere de binære repræsentationer
heraf, som ser et lidt noget som dette.
Og især i forbindelse med heltalsvariablen,
Det kommer ikke til at bare spytte det ind, Det kommer ikke til at behandle det som en fire
byte chunk nødvendigvis, Det er faktisk at gå
at behandle det som fire én byte bidder, som kunne se noget som dette.
Og selv dette ikke er helt rigtigt enten,
på grund af noget, der hedder en endethed, som vi ikke
vil komme ind nu, men hvis du er nysgerrig efter at vide,
du kan læse op på lidt og store endethed.
Men af ​​hensyn til dette argument, af hensyn til denne video,
lad os bare antage, at er i Faktisk hvordan antallet 65 ville
være repræsenteret i hukommelse på ethvert system,
selv om det ikke er helt rigtigt.
>> Men lad os faktisk bare få komme af med alle binære helt,
og bare tænke som H og 65, det er meget nemmere
til at tænke over det som at som et menneske.
Okay, så det også virker måske en lidt tilfældigt, at I've- mit system
gav mig ikke byte 5, 6, 7, og 8 for at gemme heltal.
Der er en grund til det, også, hvilket Vi vil ikke komme ind lige nu, men tilstrækkeligt
Det vil sige, at det, computer gør her
er nok et godt træk på sin side.
Hvis du ikke vil give mig hukommelse, der er nødvendigvis ryg mod ryg.
Selvom det kommer til at gøre det nu hvis jeg ønsker at få en anden streng,
kaldet efternavn, og jeg vil at sætte Lloyd derinde.
Jeg har tænkt mig at brug for at passe en karakter, hvert bogstav i det er
vil kræve en karakter, en byte hukommelse.
Så hvis jeg kunne sætte Lloyd i min matrix som dette Jeg er temmelig god til at gå, ikke?
Hvad mangler?
>> Husk, at hver streng vi arbejder med i C slutter med omvendt skråstreg nul,
og vi kan ikke udelade at her, enten.
Vi er nødt til at afsætte én byte hukommelse til at fastslå, at så vi
vide, når vores strengen er afsluttet.
Så igen dette arrangement af den måde, tingene
vises i hukommelsen magt være lidt tilfældigt,
men det faktisk er sådan, de fleste systemer er konstrueret.
At line dem op på multipler af fire grunde igen
at vi ikke behøver at komme ind lige nu.
Men dette, så er det tilstrækkeligt at sige, at efter disse tre linjer kode,
dette er, hvad hukommelse kunne se ud.
Hvis jeg har brug for hukommelsespladser 4, 8 og 12 for at holde mine data,
dette er hvad min hukommelse kunne se ud.
>> Og bare være særlig pedantiske her, når
vi taler om hukommelse adresser vi normalt
gøre det ved hjælp hexadecimale notationer.
Så hvorfor gør vi ikke konvertere alle disse fra decimal til hexadecimal notation
bare fordi det er generelt hvordan vi henvise til hukommelsen.
Så i stedet for at være 0 ved 19, hvad vi har, er nul
x nul gennem nul x1 tre.
Det er de 20 bytes hukommelse, som vi har eller vi kigger på i dette billede
lige her.
>> Så alt dette er sagt, så lad os skridt væk fra hukommelse til en anden
og tilbage til pointere.
Her er det vigtigste ting at huske
da vi begynder at arbejde med pointere.
En pointer er intet mere end en adresse.
Jeg vil sige det igen, fordi det er så vigtigt,
en pointer er intet mere end en adresse.
Pegepinde er adresser til steder i hukommelsen, hvor variabler bor.
Vel vidende, at det bliver forhåbentlig en lidt lettere at arbejde med dem.
En anden ting jeg kan lide at gøre, er at have sortering
diagrammer visuelt repræsenterer, hvad der er sker med forskellige linjer kode.
Og vi vil gøre det et par gange i pointere,
og når vi taler om dynamisk hukommelse tildeling så godt.
Fordi jeg tror, ​​at disse diagrammer kan være særligt nyttigt.
>> Så hvis jeg siger for eksempel, int k i min kode, hvad der sker?
Nå, hvad der dybest set sker der Jeg får hukommelse afsat til mig,
men jeg ved ikke engang lide at tænker over det på den måde, jeg
lide at tænke på det som en æske.
Jeg har en kasse, og det er farvet grøn fordi jeg
kan sætte tal i grønne kasser.
Hvis det var et tegn I kan have en blå boks.
Men jeg siger altid, hvis jeg opretter en boks, der kan rumme hele tal
at kassen er farvet grønt.
Og jeg tager en permanent markør og jeg skriver k på siden af ​​den.
Så jeg har en kasse kaldet k, ind som jeg kan sætte heltal.
Så når jeg siger int k, der er hvad der sker i mit hoved.
Hvis jeg siger k lig fem, hvad gør jeg?
Nå, jeg lægger fem i boksen, højre.
Dette er temmelig ligetil, hvis Jeg siger int k, skal du oprette en boks kaldet k.
Hvis jeg siger k lig 5, lægge fem ind i feltet.
Forhåbentlig det er ikke for meget af et spring.
Her er hvor tingene går en lidt interessant selvom.
Hvis jeg siger int * pk, godt selv om jeg ikke ved, hvad det nødvendigvis betyder,
det er klart fået noget at gøre med et heltal.
Så jeg har tænkt mig at farve dette felt grøn-ish,
Jeg ved, det har noget at gøre med et heltal,
men det er ikke et heltal selv, fordi det er en int stjerne.
Der er noget lidt anderledes om det.
Så et heltal er involveret, men ellers er det
ikke alt for forskellige fra hvad vi taler om.
Det er en boks, dens fik en etiket, det er iført en etiket pk,
og det er stand til at holde int stjerner, uanset hvad de er.
De har noget at gøre med heltal, klart.
Her er den sidste linje selv.
Hvis jeg siger pk = & k, whoa, hvad der lige skete, ikke?
Så denne tilfældige tal, tilsyneladende tilfældig nummer, bliver kastet ind i feltet der.
Alt det er, er pk får adressen på k.
Så jeg stikning hvor k bor i hukommelsen, dens adresse, adressen på dens bytes.
Alt jeg gør er jeg siger denne værdi er, hvad jeg har tænkt mig
at sætte indersiden af ​​min boks kaldes pk.
Og fordi disse ting er pegepinde, og fordi at kigge
ved en streng som nul x otte nul c syv fire otte
to nul er sandsynligvis ikke meget mening.
Når vi generelt visualisere pointere, vi rent faktisk gøre det så pointere.
Pk giver os oplysninger vi nødt til at finde k i hukommelsen.
Så dybest set pk har en pil i det.
Og hvis vi gå længden af denne pil, forestille sig
det er noget du kan gå på, hvis vi gå langs længden af ​​pilen,
på selve spidsen af ​​denne pil, vi vil finde sted i hukommelsen
hvor k bor.
Og det er virkelig vigtigt fordi når vi ved, hvor k lever,
Vi kan begynde at arbejde med data indersiden af ​​den hukommelsesposition.
Selvom vi får en teeny bit foran os selv for nu.
>> Så hvad er en pointer?
En pointer er et dataelement, hvis værdi er en lageradresse.
Det var, at nul x otte nul kram foregår, det kunne lageradresse.
Det var en placering i hukommelsen.
Og typen af ​​en pegepind beskriver den type
af data, du finder på at hukommelsen adresse.
Så der er den int stjernede del til højre.
Hvis jeg følger, at pilen, er det kommer til at føre mig til en placering.
Og at placering, hvad jeg vil finde der i mit eksempel,
er en grøn farvet boks.
Det er et heltal, det er hvad jeg vil finde, hvis jeg går til denne adresse.
De data type af en pointer beskriver, hvad
du vil finde på at hukommelsen adresse.
Så her er virkelig cool ting selv.
Pointers tillade os at passere variable mellem funktioner.
Og faktisk videregive variable og ikke passere kopier af dem.
For hvis vi ved præcis, hvor i hukommelsen for at finde en variabel,
Vi behøver ikke at lave en kopi af det, kan vi bare gå til denne placering
og arbejde med denne variabel.
Så i det væsentlige pejlemærker sortere af gøre en computer miljø
meget mere som den virkelige verden, højre.
>> Så her er en analogi.
Lad os sige, at jeg har en notesbog, højre, og det er fuld af noter.
Og jeg vil gerne have dig til at opdatere den.
Du er en funktion, der opdateringer noter, højre.
På den måde har vi været arbejder så videre, hvad
sker, er, du vil tage min notesbog, du vil gå til kopien butikken,
du vil gøre en Xerox kopi af hver side af den bærbare computer.
Du vil forlade min notesbog tilbage på mit skrivebord, når du er færdig,
du vil gå og krydse ud ting i mit notesbog, der er forældede eller forkert,
og så vil du passerer tilbage til mig stakken af ​​Xerox-sider
der er en kopi af min notesbog med de ændringer, du har foretaget på det.
Og på det tidspunkt, er det op til mig som den kaldende funktion, som den, der ringer,
at beslutte at tage dine noter og integrere dem tilbage i min notesbog.
Så der er en masse trin involveret her, lige.
Lignende ville det ikke være bedre hvis jeg bare sige, hey, kan du
opdatere min notebook til mig, hånd du min notesbog,
og du tager ting og bogstaveligt krydse dem ud
og opdatere mine noter i min notesbog.
Og derefter give mig min notesbog tilbage.
Det er lidt af, hvad pointere tillade os at gøre,
de gør dette miljø en masse mere ligesom hvordan vi opererer i virkeligheden.
>> Okay, så det er, hvad en pointer er, lad os tale
om, hvordan pegepinde fungerer i C, og hvordan vi kan begynde at arbejde med dem.
Så der er en meget enkel pointer i C kaldet nulhenvisning.
De null pointer peger på ingenting.
Dette formentlig ser ud som det er faktisk ikke en meget nyttig ting,
men som vi vil se en lidt senere, det faktum
at denne null-pointer eksisterer faktisk rigtig kan komme i handy.
Og når du opretter en pegepind, og behøver du ikke indstille sin værdi straks-
et eksempel på indstilling dens værdi straks
vil være et par glider tilbage hvor jeg sagde pk lig & k,
pk får k adresse, som vi vil se, hvad det betyder,
vi vil se, hvordan man kode det shortly- hvis vi ikke sætte værdien til noget
meningsfuld samme, Du bør altid
indstille din pointer til at pege til null.
Du bør indstille den til at pege på ingenting.
>> Det er meget anderledes end bare overlade værdien, som det er
og derefter om en pointer og blot antager
det er null, fordi det er sjældent sandt.
Så du bør altid indstillet værdien af ​​en pegepind
til null hvis du ikke indstiller sin værdi til noget meningsfuldt med det samme.
Du kan kontrollere, om en pegepind værdi er nul ved hjælp af lighed operatøren
(==), Ligesom du sammenligner ethvert heltal værdier eller tegn værdier ved hjælp (==)
samt.
Det er en særlig slags konstant værdi, som du kan bruge til at teste.
Så det var en meget enkel pointer, null pointer.
En anden måde at skabe en pointer er at udvinde
adressen på en variabel du allerede har oprettet,
og du gør dette ved brug af & operatør adresse ekstraktion.
Som vi allerede har set tidligere i det første diagram eksempel jeg viste.
Så hvis x er en variabel, vi har allerede skabt af typen heltal,
derefter & x er en pointer til et heltal.
& x er-huske, og kommer til at udtrække adressen på ting til højre.
Og da en pointer er blot en adresse, end & x er en pointer til et heltal
hvis værdi er, hvor i hukommelsen x liv.
Det er x adresse.
Så & x er adressen på x.
Lad os tage et skridt videre og oprette forbindelse til noget
Jeg hentydede til i en tidligere video.
Hvis arr er en vifte af doubler, så & arr firkantede beslag i er en pointer
til en dobbelt.
OK.
arr firkantede beslag i, hvis arr er en vifte af doubler,
derefter arr firkantede beslag i er den i'te element i denne matrix,
og & arr firkantede beslag i er hvor i hukommelse den i'te element i arr eksisterer.
>> Så hvad er konsekvenserne her?
En arrays navn, implikation af hele denne ting,
er, at et array navn er faktisk selv en pegepind.
Du har arbejdet med pointere langs
hver gang du har brugt et array.
Husk fra eksempel om variabel rækkevidde,
nær slutningen af ​​videoen jeg præsentere et eksempel, hvor vi har en funktion
kaldes sæt int og en funktion kaldet sæt array.
Og din udfordring at bestemme hvorvidt eller hvad
værdier, som vi udskrives udgangen af ​​funktionen,
ved udgangen af ​​hovedprogrammet.
>> Hvis du husker fra eksempel eller hvis du har set videoen,
du ved, at når Dem for-opkaldet til sæt int effektivt gør ingenting.
Men opfordringen til at indstille vifte gør.
Og jeg slags tilsløres hvorfor det var tilfældet på det tidspunkt.
Jeg sagde bare, godt det er et array, er det særligt, du ved, der er en grund.
Årsagen er, at en arrayets navn er egentlig bare en pointer,
og der er denne særlige firkantede beslag syntaks,
gøre tingene meget pænere at arbejde med.
Og de gør tanken om en pointer meget mindre skræmmende,
og det er derfor de er sortering af præsenteres på den måde.
Men virkelig arrays er bare pointere.
Og det er derfor, når vi foretaget en ændring til array,
når vi passerede en matrix som en parameter til en funktion eller som et argument
til en funktion, indholdet af arrayet faktisk ændret i både callee
og i den, der ringer.
Hvilket for enhver anden form for variabel vi så ikke var tilfældet.
Så det er bare noget at holde i tænke på, når du arbejder med pointere,
er, at navnet på en matrix faktisk en pointer
til det første element i denne matrix.
>> OK, så nu har vi alle disse fakta, lad os holde ud, til højre.
Hvorfor skal vi bekymre sig om hvor noget bor.
Nå som jeg sagde, er det temmelig nyttigt at vide, hvor noget bor
så du kan gå der og ændre det.
Arbejde med det, og faktisk har den ting, som du
ønsker at gøre til denne variabel får virkning, og ikke i kraft på nogle kopi af den.
Dette kaldes dereferere.
Vi går til referencen og vi ændre værdien der.
Så hvis vi har en pegepind og det hedder pc, og den peger på et tegn,
så kan vi sige * pc og * pc er den navn på, hvad vi kan finde, hvis vi går
til adressen pc.
Det, vi finder der er en karakter og * pc er, hvordan vi henvise til de data, der
placering.
Så vi kunne sige noget lignende * pc = D eller noget lignende,
og det betyder, at uanset var på hukommelsesadresse pc,
uanset karakter var tidligere der, nu er D, hvis vi siger * PC = D.
>> Så her går vi igen med nogle underlige C ting, højre.
Så vi har set * tidligere som værende en eller anden måde en del af den datatype,
og nu er det bliver brugt i en lidt anden sammenhæng
at få adgang til data på et sted.
Jeg ved det er lidt forvirrende og der er faktisk en del af hele denne
lignende, hvorfor pointers har denne mytologi omkring dem som værende så kompliceret,
er lidt af en syntaks problem, ærligt.
Men * anvendes i begge sammenhænge, både som en del af navnet type,
og vi vil se lidt senere noget andet, også.
Og lige nu er det dereference operatør.
Så det går til referencen, det får adgang til data
ved placeringen af ​​markøren, og giver dig mulighed for at manipulere det efter behag.
>> Nu er meget lig besøger din nabo, højre.
Hvis du ved, hvad din nabo bor, er du
ikke hænge ud med din nabo.
Du ved du tilfældigvis ved, hvor de bor,
men det betyder ikke, at ved i kraft af at have denne viden
du interagerer med dem.
Hvis du ønsker at interagere med dem, du nødt til at gå til deres hus,
du er nødt til at gå til, hvor de bor.
Og når du gør det, så kan du interagere
med dem ligesom du gerne vil.
Og tilsvarende med variabler, du nødt til at gå til deres adresse
hvis du ønsker at interagere dem, du kan ikke bare kender adressen.
Og den måde, du går til adressen at bruge *, de dereference operatøren.
Hvad tror du der sker hvis vi prøver og dereference
en pegepind, hvis værdi er nul?
Husk på, at null pointer peger på ingenting.
Så hvis du prøver og dereference intet eller gå til en adresse ingenting,
hvad tror du der sker?
Tja, hvis du gættede segmentering skyld, ville du have ret.
Hvis du prøver og dereference en null-pointer,
du lider en segmentering fejl. Men vent,
ikke jeg fortælle dig, at Hvis du ikke kommer
at indstille værdien af ​​din pointer til noget meningsfuldt,
du skal sætte til null?
Jeg gjorde, og faktisk segmenteringen skyld er lidt af en god opførsel.
>> Har du nogensinde erklæret en variabel og ikke er tildelt sin værdi med det samme?
Så du bare sige int x; du ikke faktisk tildele den til noget
og så senere i din kode, du udskrive værdien af ​​x,
der stadig ikke tildelt det til noget.
Ofte får du nul, men nogle gange er du
måske få nogle tilfældige tal, og du har ingen idé om, hvor det kom fra.
Ligeledes kan ting ske med pointere.
Når du erklærer en pegepind int * pk f.eks
og du behøver ikke tildele den til en værdi, du får fire bytes for hukommelse.
Uanset fire bytes hukommelse kan systemet
finder, at have en vis meningsfuld værdi.
Og der kunne have været noget der allerede, at
ikke længere er nødvendig af en anden funktion, så du bare nødt
uanset data var der.
>> Hvad hvis du forsøgte at gøre dereference nogle adresse, du don't- der var
allerede bytes og information i der, det er nu i markøren.
Hvis du prøver og dereference den pointer, du måske rode med noget hukommelse
at du ikke havde til hensigt at rode med det hele.
Og i virkeligheden, du kunne gøre noget virkelig ødelæggende,
ligesom bryde et andet program, eller bryde en anden funktion,
eller gøre noget ondsindet, at du ikke havde til hensigt at gøre overhovedet.
Og så det er derfor, det er faktisk en god idé
til at indstille dine pegepinde til null, hvis du ikke sætte dem til noget meningsfuldt.
Det er nok bedre på slutningen af ​​dagen til dit program
til at gå ned og derefter for det at gøre Noget der skruer op
et andet program eller en anden funktion.
Denne adfærd er sandsynligvis endnu mindre ideel end bare at styrte ned.
Og så det er derfor, det er faktisk en god vane
at komme ind for at indstille din pegepinde til null hvis du ikke sætte dem
til en meningsfuld værdi straks, er en værdi, som du kender
og at du kan sikkert den dereference.
>> Så lad os komme tilbage nu, og tage et kig på den overordnede syntaks af situationen.
Hvis jeg siger int * p ;, hvad har jeg lige gjort?
Hvad jeg har gjort, er dette.
Jeg kender værdien af ​​p er en adresse fordi alle pointere er lige
adresser.
Jeg kan dereference p ved hjælp af * operatøren.
I denne sammenhæng her i det top huske * er en del af den type.
Int * er den datatype.
Men jeg kan dereference p ved hjælp af * operatøren,
og hvis jeg gør det, hvis jeg går til denne adresse, hvad vil jeg finde på denne adresse?
Jeg vil finde et heltal.
Så int * p er dybest set sagde: p er en adresse.
Jeg kan dereference p og hvis Jeg gør, vil jeg finde et heltal
på denne hukommelsesplads.
>> OK, så jeg sagde, at der var en anden irriterende ting med stjerner
og her er hvor der irriterende ting med stjerner er.
Har du nogensinde prøvet at erklære flere variabler af samme type
på den samme linje kode?
Så for en anden, foregive, at linien, koden jeg faktisk har der i grøn
er der ikke, og det bare siger int x, y, z ;.
Hvad der ville gøre er faktisk at skabe tre heltalsvariabler for dig,
én kaldet x, en kaldet y og en kaldet z.
Det er en måde at gøre det uden skulle opdeles på tre linjer.
>> Her er, hvor stjerner får irriterende igen dog,
fordi * er faktisk en del både navn og Deltype
af den variable navn.
Og så hvis jeg siger int * px, py, pz, hvad jeg faktisk får, er en pointer til et heltal
kaldes px og to heltal, py og pz.
Og det er nok det, der ikke vi ønsker, det er ikke godt.
>> Så hvis jeg ønsker at oprette flere pointers på samme linje, af samme type,
og stjerner, hvad jeg rent faktisk har brug for at gøre, er at sige int * pa, * PB, * pc.
Nu har netop sagt, at og nu fortæller dig dette,
du sandsynligvis vil aldrig gøre dette.
Og det er nok en god ting ærligt, fordi du måske uforvarende
udelade en stjerne, noget lignende.
Det er nok bedst at måske erklære fingerpeg om de enkelte linjer,
men det er bare en anden af de irriterende syntaks
ting med stjerner, der gør pointers så svært at arbejde med.
Fordi det er netop denne syntaktiske rod, du nødt til at arbejde igennem.
Med praksis gør virkelig bliver anden karakter.
Jeg stadig lave fejl med det stadig efter programmering i 10 år,
så du skal ikke være ked af, hvis der sker noget til dig, er det temmelig almindeligt ærligt.
Det er virkelig slags en fejl i syntaksen.
>> OK, så jeg slags lovet at vi ville revidere
begrebet hvor stor er en streng.
Tja, hvis jeg fortalte dig, at en streng, har vi virkelig slags
ligget til dig hele tiden.
Der er ingen datatype kaldet streng, og faktisk jeg
nævnt dette i en af ​​vores tidligste videoer på datatyper,
at strengen var en datatype, blev oprettet for dig i CS50.h.
Du er nødt til at # include CS50.h for at bruge det.
>> Nå streng er virkelig bare et alias for noget
kaldet char *, en pointer til et tegn.
Nå pointere, tilbagekaldelse, er blot adresser.
Så hvad er størrelsen i byte af en streng?
Jamen det er fire eller otte.
Og grunden til at jeg siger fire eller otte er fordi det faktisk
afhænger af det system, Hvis du bruger CS50 ide, char * er størrelsen af ​​en char
* Er otte, er det en 64-bit system.
Hver adresse i hukommelsen er 64 bit lang.
Hvis du bruger CS50 apparatet eller ved hjælp af en 32-bit maskine,
og du har hørt, at udtrykket 32-bit maskine, hvad er en 32-bit maskine?
Jamen det betyder bare, at hver adresse i hukommelsen er 32 bit lang.
Og så 32 bit er fire bytes.
Så en char * er fire eller otte bytes afhængigt af dit system.
Og faktisk nogen datatyper, og en pointer til en hvilken som helst data
skriver, da alle pejlemærker er blot adresser, er fire eller otte bytes.
Så lad os revidere denne diagram og lad os slutte
denne video med lidt øvelse her.
Så her er diagrammet vi slap med i begyndelsen af ​​videoen.
Så hvad sker der nu, hvis jeg siger * pk = 35?
Så hvad betyder det, når jeg siger, * pk = 35?
Tag et sekund.
* pk.
I sammenhæng her, * er dereference operatør.
Så når dereference operatøren anvendes,
vi gå til adressen pegede på ved pk, og vi ændre, hvad vi finder.
Så * pk = 35 effektivt gør dette til billedet.
Så det er dybest set syntaktisk identisk med for at have sagt k = 35.
>> En mere.
Hvis jeg siger int m, jeg skaber en ny variabel kaldet m.
En ny boks, er det en grøn boks, fordi det kommer til at holde et heltal,
og det er mærket m.
Hvis jeg siger m = 4, sætter jeg en heltal ind i denne boks.
Hvis sige pk = & m, hvordan gør dette diagram forandring?
Pk = & m, gør du huske, hvad den & Operatør gør eller kaldes?
Husk, at & nogle variabelnavn er adressen på en variabel navn.
Så det, vi siger, er pk får adressen på m.
Og så effektivt hvad der sker den diagrammet er der pk ikke længere peger
til k, men peger på m.
>> Igen pointere er meget vanskelig at arbejde med
og de tager en masse af praksis, men på grund
af deres evne til at give dig overføres data mellem funktioner
og faktisk har de, ændringerne træder i kraft,
få dit hoved omkring er virkelig vigtigt.
Det sandsynligvis er den mest komplicerede emne, vi diskuterer i CS50,
men den værdi, du får fra at bruge pointers
langt opvejer de komplikationer der kommer fra at lære dem.
Så jeg ønsker dig det bedste af held at lære om pointere.
Jeg er Doug Lloyd, det er CS50.