>> [MUSIC SPILLE]
>> DOUG LLOYD: Pekere, her er vi.
Dette er trolig kommer til å være den mest vanskelig tema
at vi snakker om i CS50.
Og hvis du har lest noe om pekere
før du kan være litt skremmende å gå inn i denne videoen.
Det er sant pekere tillater deg muligheten
å kanskje skru opp ganske dårlig når du er
arbeider med variabler og data, og forårsaker programmet til å krasje.
Men de er faktisk veldig nyttig og de tillater oss en virkelig flott måte
å sende data tilbake og tilbake mellom funksjoner,
at vi er ellers ute av stand til å gjøre.
>> Og så hva vi egentlig ønsker å gjøre her er toget
du ha god pekeren disiplin, så som du kan bruke pekere effektivt
å lage dine programmer som mye bedre.
Som jeg sa pekere gi oss et annet måte å overføre data mellom funksjoner.
Nå hvis du husker fra en tidligere video, når
vi snakket om variabel omfang, nevnte jeg
at alle data som vi passerer mellom funksjoner i C er vedtatt av verdi.
Og jeg kan ikke ha brukt som sikt, det jeg mente det
var at vi passerer kopier av data.
Når vi passerer en variabel til en funksjon, vi faktisk ikke bestått variabelen
til funksjonen, ikke sant?
Vi sender en kopi av at data til funksjonen.
Funksjonen gjør det de vil og den beregner noen verdi,
og kanskje vi bruker denne verdien da det gir den tilbake.
>> Det var ett unntak denne regelen for overføring av verdi,
og vi vil komme tilbake til hva som er litt senere i denne videoen.
Hvis vi bruker pekere stedet for å bruke variabler,
eller i stedet for ved hjelp av de variable seg selv eller kopier av variablene,
kan vi nå passerer variablene rundt mellom funksjoner på en annen måte.
Dette betyr at hvis vi gjør en endring av en funksjon,
at endringen vil faktisk ta effekt i en annen funksjon.
Igjen, dette er noe som vi ikke kunne gjøre tidligere,
og hvis du har prøvd å bytte Verdien av to variabler i en funksjon,
du har lagt merke til dette problemet slags snikende opp, ikke sant?
>> Hvis vi ønsker å bytte X og Y, og vi sende dem til en funksjon som kalles swap,
innsiden av funksjon bytte variabler gjør utvekslings verdier.
Man blir to, to blir en, men vi gjør faktisk ikke
endre noe i den opprinnelige funksjon, i den som ringer.
Fordi vi ikke kan, er vi bare arbeider med kopier av dem.
Med pekere skjønt, kan vi faktisk passere X og Y til en funksjon.
Den funksjonen kan gjøre noe med dem.
Og disse variablene verdier kan faktisk endre.
Så det er litt av en endring i vår evne til å arbeide med data.
>> Før vi dykke inn pekere, jeg tror det er verdt
tar et par minutter til gå tilbake til grunnleggende her.
Og ta en titt på hvordan datamaskinminne verk
fordi disse to fagene skal å faktisk være ganske henger sammen.
Som du sikkert vet, på datasystemet
du har en harddisk eller kanskje en solid state drive,
noen form for fillagring plassering.
Det er vanligvis et sted i nabolaget på 250 gigabyte
til kanskje et par terabyte nå.
Og det er der alle dine filer til slutt leve,
selv om datamaskinen er slått av, kan du slå den på igjen
og du vil finne filene dine er der igjen når du starter maskinen på nytt.
Men disker, som en harddisk, en HDD eller en Solid State Drive, en SSD,
er bare lagringsplass.
>> Vi kan faktisk ikke gjøre noe med dataene som er i harddisken,
eller i en solid state drive.
For å faktisk endre data eller flytte den rundt,
vi må flytte den til RAM, random access memory.
Nå RAM, har du mye mindre av på datamaskinen.
Du kan ha et sted i nabolaget på 512 megabyte
hvis du har en eldre datamaskin, til kanskje to, fire, åtte, 16,
muligens enda litt mer, gigabyte RAM.
Så det er mye mindre, men det er hvor alle de flyktige data eksisterer.
Det er der vi kan forandre ting.
Men når vi slår vår datamaskin av, alle data i RAM er ødelagt.
>> Så det er derfor vi må ha harddisk for mer permanent plassering av det,
slik at det exists- det ville være veldig ille hvis hver gang vi
slått vår datamaskin av, hver fil i vårt system ble utslettet.
Så vi jobber inne RAM.
Og hver gang vi snakker om minne, ganske mye, i CS50,
vi snakker om RAM, ikke harddisken.
>> Så når vi flytter ting inn i minnet, den tar opp en viss mengde plass.
Alle datatyper som vi har jobbet med
ta opp forskjellige mengder plass i RAM.
Så hver gang du oppretter et heltall variable, fire byte minne
er satt til side i RAM slik at du kan arbeide med det heltall.
Du kan erklære heltall, endre det, tilordne den
til en verdi 10 inkrementert av en, så videre og så videre.
Alt som må skje i RAM, og du får fire bytes
å arbeide med for hvert heltall som du oppretter.
>> Hver karakter du skape får én byte.
Det er bare hvor mye plass er er nødvendig for å lagre et tegn.
Hver float, en real nummer, får fire bytes
med mindre det er en dobbel presisjon flyttall
nummer, som lar deg har mer presise eller flere sifre
etter desimaltegnet uten å miste presisjon,
som tar opp åtte byte minne.
Lange lengter, virkelig store heltall, også ta opp åtte byte minne.
Hvor mange byte minne trenger strenger ta opp?
Vel la oss sette en nål i det spørsmålet for nå, men vi vil komme tilbake til det.
>> Så tilbake til denne ideen om minnet som et stort utvalg av byte-sized celler.
Det er egentlig alt det er, er det bare et stort utvalg av celler,
akkurat som alle andre matrise som du er kjent med og se,
bortsett fra hver element er en byte bred.
Og akkurat som en matrise, hvert element har en adresse.
Hvert element av en matrise har en indeks, og vi
kan bruke denne indeksen til å gjøre såkalte random access på matrisen.
Vi trenger ikke å starte på begynnelsen av rekken,
iterere gjennom hver enkelt element derav,
å finne det vi leter etter.
Vi kan bare si, jeg ønsker å komme til 15. element eller 100-element.
Og du kan bare bestå i at antall og få verdien du leter etter.
>> Tilsvar hvert sted minne har en adresse.
Så din hukommelse makt se omtrent slik ut.
Her er en veldig liten del av hukommelse, er det 20 byte minne.
De første 20 bytes fordi min løser det på bunnen
er 0, 1, 2, 3, og så på helt opp til 19.
Og når jeg erklærer variabler og når jeg begynner å jobbe med dem,
at systemet kommer til å sette avsett noen plass for meg
i dette minnet til å jobbe med mine variabler.
Så jeg kan si, char c tilsvarer kapital H. Og hva kommer til å skje?
Godt systemet kommer til å satt til side for meg en byte.
I dette tilfellet valgte det byte nummer fire, byte på adressen fire,
og det kommer til å lagre bokstav stor H i det for meg.
Hvis jeg da si int hastighet grense lik 65, er det
kommer til å sette av fire byte minne for meg.
Og det kommer til å behandle dem fire byte som en enkelt enhet
fordi det vi jobber med er et tall her.
Og det kommer til å lagre 65 i der.
>> Nå allerede Jeg er litt fortelle deg litt av en løgn,
rett, fordi vi vet at datamaskiner fungerer i binær.
De forstår ikke nødvendigvis hva en kapital H er
eller hva en 65 er, bare de forstår binære, nuller og enere.
Og så faktisk hva vi lagring i det
er ikke bokstaven H og tallet 65, men heller de binære representasjoner
derav, som ser en litt noe sånt som dette.
Og spesielt i sammenheng med heltallsvariabelen,
det er ikke til å bare spytte den inn, det er ikke til å behandle det som en fire
byte blings nødvendigvis, det er faktisk kommer
å behandle det som fire én byte biter, som kan se omtrent slik ut.
Og selv dette er ikke helt sant heller,
på grunn av noe som kalles en endianness, som vi ikke
kommer til å komme inn nå, men Hvis du er nysgjerrig på,
du kan lese opp på litt og stor endianness.
Men for å få til dette argumentet, for å få til denne videoen
la oss bare anta at er, i Faktisk, hvordan nummer 65 ville
være representert i minne på hvert system,
selv om det ikke er helt sant.
>> Men la oss faktisk bare få kvitt alle binære helt,
og bare tenke på som H og 65, er det mye enklere
å tenke på det som det som et menneske.
All right, så det også virker kanskje en Litt tilfeldig at I've- systemet mitt
ikke gi meg bytes 5, 6, 7, og 8 for å lagre heltall.
Det er en grunn for det, også, som vi vil ikke komme inn på nå, men nok
det å si at det som Datamaskinen gjør her
er sannsynligvis et godt trekk på sin side.
Å ikke gi meg minne som er nødvendigvis rygg mot rygg.
Selv om det kommer til å gjøre det nå hvis jeg ønsker å få en annen streng,
heter etternavn, og jeg vil ha å sette Lloyd der.
Jeg kommer til å trenge å passe en karakter, er hver bokstav som
kommer til å kreve en karakter, en byte minne.
Så hvis jeg kunne sette Lloyd inn i mitt utvalg som dette jeg er ganske god til å gå, ikke sant?
Hva er det som mangler?
>> Husk at hver streng vi jobber med i C slutter med backslash null,
og vi kan ikke utelate det her, heller.
Vi trenger å sette av én byte minne til å holde det slik at vi
vet når vår strengen er avsluttet.
Så igjen denne ordningen av hvordan ting
vises i minnet makt være litt tilfeldig,
men det er faktisk hvordan de fleste systemer er utformet.
Å stille dem opp på multipler av fire, av grunner igjen
at vi ikke trenger å komme inn akkurat nå.
Men dette, så det er nok å si at etter disse tre linjer med kode,
dette er hva minnet kan se ut.
Hvis jeg trenger minnesteder 4, 8 og 12 for å holde mine data,
Dette er hva min hukommelse kan se ut.
>> Og bare være spesielt pedantisk her, når
vi snakker om minne adresser vi vanligvis
gjøre det ved hjelp heksadesimale merknader.
Så hvorfor ikke vi konvertere alle disse fra desimal til heksadesimale notasjon
bare fordi det er generelt hvordan vi refererer til minnet.
Så i stedet for å være 0 gjennom 19, det vi har er null
x null gjennom null x1 tre.
De er 20 byte minne om at vi har eller vi ser på i dette bildet
akkurat her.
>> Så alt som blir sagt, la oss gå bort fra minnet for andre
og tilbake til pekere.
Her er det viktigste ting å huske
som vi begynne å jobbe med pekere.
En peker er ingenting mer enn en adresse.
Jeg sier det igjen fordi det er så viktig,
en peker er ingenting mer enn en adresse.
Pekere er adresser til steder i minnet der variabler bor.
Å vite at det blir forhåpentligvis en litt lettere å jobbe med dem.
En annen ting jeg liker å gjøre er å ha sort
diagrammer visuelt representerer hva som er skjer med ulike linjer med kode.
Og vi vil gjøre dette et par ganger i pekere,
og når vi snakker om dynamisk minnetildeling også.
Fordi jeg tror at disse diagrammene kan være spesielt nyttig.
>> Så hvis jeg sier for eksempel int k i koden min, hva skjer?
Vel hva som egentlig skjer er Jeg får minne avsatt til meg,
men jeg vet ikke engang liker å tenker på det sånn, jeg
liker å tenke på det som en boks.
Jeg har en boks, og det er farget grønn fordi jeg
kan sette heltall i grønne bokser.
Hvis det var en karakter jeg kan ha en blå boks.
Men jeg alltid sier, hvis jeg skaper en boks som kan holde heltall
at boksen er farget grønt.
Og jeg tar en permanent markør og jeg skriver k på siden av den.
Så jeg har en boks kalt k, der jeg kan sette heltall.
Så når jeg sier int k, det er hva som skjer i hodet mitt.
Hvis jeg sier k lik fem, hva gjør jeg?
Vel, jeg setter five i boksen, ikke sant.
Dette er ganske grei, hvis Jeg sier int k, skape en boks som heter k.
Hvis jeg sier k er lik 5, satte fem inn i boksen.
Forhåpentligvis det er ikke for mye av et sprang.
Her er der ting går Litt interessant skjønt.
Hvis jeg sier int * pk, godt selv om jeg ikke gjør det vet hva dette nødvendigvis betyr,
Det er helt klart har noe å gjøre med et heltall.
Så jeg kommer til å farge denne boksen grønn-ish,
Jeg vet det har noe å gjøre med et heltall,
men det er ikke et heltall seg selv, fordi det er en int stjerne.
Det er noe litt annerledes om det.
Så et heltall er involvert, men ellers er det
ikke så forskjellig fra hva vi snakket om.
Det er en boks, de har en etikett, det har på seg en etikett pk,
og det er i stand til beholdning int stjerner, uansett hva de er.
De har noe å gjøre med heltall, tydelig.
Her er den siste linjen skjønt.
Hvis jeg sier pk = & k, whoa, hva skjedde, ikke sant?
Så dette tilfeldig tall, tilsynelatende tilfeldig nummer, blir kastet inn i boksen der.
Alt som er, er pk får adressen til k.
Så jeg stikker hvor k lever i minnet, sin adresse, adressen til dens bytes.
Alt jeg gjør er jeg sier denne verdien er hva jeg skal
å sette innsiden av boksen min heter pk.
Og fordi disse tingene er pekere, og fordi jakt
på en streng som null x eight zero c sju fireåtte
Two Zero er trolig ikke veldig meningsfylt.
Når vi vanligvis visual pekere, vi faktisk gjøre det som pekere.
Pk gir oss informasjon vi trenger å finne k i minnet.
Så i utgangspunktet pk har en pil i den.
Og hvis vi gå lengden av at pilen, tenk
det er noe du kan gå på, hvis vi går langs lengden av pilen
helt på tuppen av at pilen, vi vil finne sted i minnet
hvor k bor.
Og det er veldig viktig fordi når vi vet hvor k lever,
vi kan begynne å jobbe med data Innsiden av den minnelokasjon.
Selv om vi får en teeny Litt i forkant av oss selv for nå.
>> Så hva er en peker?
En peker er et dataelement som Verdien er en lageradresse.
Det var det null x eight zero stuff skjer, det var en minneadresse.
Det var et sted i minnet.
Og typen av en peker beskriver hva slags
av data du vil finne på at minneadresse.
Så det er den int stjerners del rett.
Hvis jeg følger den pilen, er det kommer til å føre meg til et sted.
Og det stedet, hva jeg vil finne det i mitt eksempel,
er en grønn boks.
Det er et tall, det er det jeg vil finne hvis jeg går til denne adressen.
Datatypen til en pekeren beskriver hva
du finner på at minneadresse.
Så her er det virkelig kule ting om.
Pekere tillate oss å passere variabler mellom funksjoner.
Og faktisk passere variabler og ikke passere kopier av dem.
Fordi hvis vi vet nøyaktig hvor i minnet for å finne en variabel,
vi trenger ikke å lage en kopi av det, kan vi bare gå til det stedet
og arbeide med den variabelen.
Så i essensen pekere slags av gjøre en datamaskin miljø
mye mer som den virkelige verden, ikke sant.
>> Så her er en analogi.
La oss si at jeg har en bærbar PC, rett, og den er full av notater.
Og jeg vil gjerne at du skal oppdatere den.
Du er en funksjon som oppdateringer notater, høyre.
På den måten har vi vært arbeider så langt, hva
skjer er at du vil ta min bærbare, du vil gå til kopien butikken,
du vil gjøre en Xerox kopi av hver side av maskinen.
Du vil forlate min bærbare tilbake på pulten min når du er ferdig,
vil du gå og krysse ut ting i mitt bærbar PC som er utdatert eller galt,
og deretter vil du passere tilbake til meg bunken med Xerox-sider
som er en kopi av min bærbare med endringene du har gjort i det.
Og på det punktet, er det opp til meg som kallet funksjon, som den som ringer,
å bestemme seg for å ta notater og integrere dem tilbake til min bærbare.
Så det er mange trinn involvert her, ikke sant.
Som ville det ikke være bedre hvis jeg bare si hei, kan du
oppdatere min bærbare for meg, hånd du min bærbare,
og du tar ting og bokstavelig krysse dem ut
og oppdatere mine notater i notatboken min.
Og deretter gi meg min bærbare tilbake.
Det er litt av hva pekere tillate oss å gjøre,
de gjør dette miljøet mye mer som hvordan vi opererer i virkeligheten.
>> Greit så det er hva en peker er, la oss snakke
om hvordan pekere jobbe i C, og hvordan vi kan begynne å jobbe med dem.
Så det er en veldig enkel peker i C kalles nullpeker.
Nullpilen peker ingenting.
Dette virker nok som det er faktisk ikke en veldig nyttig ting,
men som vi vil se en Litt senere på, det faktum
at dette nullpeker finnes faktisk virkelig kan komme til nytte.
Og når du oppretter en peker, og du trenger ikke sette verdien immediately-
et eksempel på innstilling sin verdi umiddelbart
vil være et par lysbilder tilbake der jeg sa pk lik & k,
pk får k adresse, som vi får se hva det betyr,
vi får se hvordan koden som shortly- hvis vi ikke sette verdien til noe
menings umiddelbart, Du bør alltid
satt pekeren til å peke til null.
Du bør sette den til å peke på noe.
>> Det er veldig annerledes enn bare forlate den verdi som det er
og deretter erklære en pekeren og bare antar
det er null fordi det er sjelden sant.
Så du bør alltid sette verdien av en peker
til null hvis du ikke sette verdien til noe meningsfylt umiddelbart.
Du kan sjekke om en peker verdi er null hjelp av likestilling operator
(==), Akkurat som du sammenligner alle heltall verdier eller tegn verdier ved hjelp av (==)
også.
Det er en spesiell form for konstant verdi som du kan bruke til å teste.
Så det var en veldig enkel pekeren, nullpeker.
En annen måte å lage en peker er å trekke ut
adressen til en variabel du allerede har opprettet,
og du gjør dette ved hjelp av & operatør adresse utvinning.
Som vi allerede har sett tidligere i det første diagrammet eksempel viste jeg.
Så hvis x er en variabel som vi har allerede opprettet av type heltall,
deretter og x er en peker til et heltall.
& x er- huske, og kommer til å trekke ut adressen til den tingen til høyre.
Og siden en peker er bare en adresse, enn & x er en peker til et heltall
der verdien er hvor i minnet x liv.
Det er x adresse.
So & x er adressen til x.
La oss ta dette ett skritt videre og koble til noe
Jeg antydet i en tidligere video.
Hvis arr er en rekke dobles, deretter & arr hakeparentes jeg er en peker
til en dobbel.
OK.
arr hakeparentes i, hvis arr er en rekke dobles,
deretter arr hakeparentes jeg er i-te element i den oppstillingen,
og & arr hakeparentes jeg er der i hukommelse i-te element av arr eksisterer.
>> Så hva er implikasjon her?
En arrays navn, implikasjonen av hele greia,
er at en rekke navn er faktisk selv en peker.
Du har jobbet med pekere langs
hver gang du har brukt en matrise.
Husk fra eksempelet på variabel omfang,
nær slutten av video I frem et eksempel der vi har en funksjon
heter sett int og en Funksjonen kalles set array.
Og din utfordring å bestemme hvorvidt eller ikke, eller hva
verdier som vi trykte ut slutten av funksjon,
ved enden av hovedprogrammet.
>> Hvis du husker fra det eksemplet eller hvis du har sett videoen,
du vet at når deg-kallet til sett int effektivt gjør ingenting.
Men kallet til å sette utvalg gjør.
Og jeg liksom glattet over hvorfor det var tilfelle på den tiden.
Jeg bare sa, vel det er en matrise, er det spesielt, du vet, det er en grunn.
Årsaken er at en matrise s Navnet er egentlig bare en peker,
og det er denne spesielle hakeparentes syntaks som
gjøre ting mye bedre å jobbe med.
Og de gjør ideen om en pekeren mye mindre skremmende,
og det er derfor de er liksom av presentert på den måten.
Men egentlig arrays er bare pekere.
Og det er grunnen til at når vi gjort en endring i rekken,
når vi passerte en rekke som et parameter til en funksjon eller som et argument
til en funksjon, og innholdet i matrisen faktisk endret i både callee
og i den som ringer.
Som for alle andre slags variabel vi så ikke var tilfelle.
Så det er bare noe å holde i tankene når du arbeider med pekere,
er at navnet på en matrisen faktisk en peker
til det første element i matrisen.
>> OK, så nå har vi alle disse fakta, la oss holde det gående, ikke sant.
Hvorfor bryr vi oss om hvor noe liv.
Vel som jeg sa, det er ganske nyttig å vite hvor noe liv
slik at du kan gå dit og endre det.
Jobbe med det og faktisk har ting som du
ønsker å gjøre til den variabelen tre i kraft, og ikke tre i kraft på noen kopi av den.
Dette kalles dereferencing.
Vi går til referanse og vi endre verdien der.
Så hvis vi har en peker og det heter pc, og det peker på en karakter,
så kan vi si * pc og * pc er Navnet på hva vi finner hvis vi går
til adressen pc.
Hva vi vil finne det er en karakter og * pc er hvordan vi refererer til dataene på den
plassering.
Så vi kan si noe sånt * pc = D eller noe sånt,
og det betyr at uansett var på minneadresse pc,
uansett karakter var tidligere der, er nå D, hvis vi sier * pc = D.
>> Så her går vi igjen med noen rare C ting, ikke sant.
Så vi har sett * tidligere som en eller annen måte en del av datatypen,
og nå er det som blir brukt i en litt annen sammenheng
å få tilgang til data på et sted.
Jeg vet det er litt forvirrende og det er faktisk en del av hele denne
like, hvorfor pekere har denne mytologien rundt dem som er så komplisert,
er en slags syntaks problem, ærlig.
Men * brukes i begge sammenhenger både som en del av typenavn,
og vi får se litt senere noe annet, også.
Og akkurat nå er det dereferanseoperator.
Så det går til referansen, Den har tilgang til dataene
ved stedet for pekeren, og gjør det mulig å manipulere det på vilje.
>> Nå er dette svært lik besøker naboen din, ikke sant.
Hvis du vet hva din nabo lever, du er
ikke henger ut med din nabo.
Du vet du tilfeldigvis vet hvor de bor,
men det betyr ikke at ved kraft av å ha denne kunnskapen
du er i samspill med dem.
Hvis du ønsker å samhandle med dem, du må gå til huset deres,
du må gå til hvor de bor.
Og når du gjør det, så du kan samhandle
med dem akkurat som du ønsker å.
Og på samme måte med variabler, du trenger å gå til deres adresse
Hvis du ønsker å samhandle dem, du kan ikke bare vet adressen.
Og måten du går til adressen er å bruke *, den dereferanseoperator.
Hva tror du skjer hvis vi prøver og dereference
en peker som har en verdi er null?
Husker at null pekeren peker til ingenting.
Så hvis du prøver og dereference ingenting eller gå til en adresse ingenting,
hva tror du skjer?
Vel, hvis du gjettet segmentering utsette, ville du ha rett.
Hvis du prøver og dereference en nullpeker,
du lider av en segmentering utsette. Men vent,
det gjorde jeg ikke fortelle deg, at hvis du ikke kommer
å sette verdien av Peker til noe meningsfylt,
bør du sette til null?
Jeg gjorde det og faktisk segmentering feil er en slags god oppførsel.
>> Har du noen gang erklært en variabel og ikke tildelt sin verdi umiddelbart?
Så du bare si int x; du ikke gjør det faktisk tilordne den til noe
og deretter senere i koden din, du skrive ut verdien av x,
har fortsatt ikke tildelt den til noe.
Ofte vil du få null, men noen ganger
kanskje få litt tilfeldig tall, og du aner ikke hvor det kom fra.
Tilsvarende kan ting skje med pekere.
Når du deklarerer en peker int * pk for eksempel
og du ikke tilordne den til en verdi, du får fire byte for minnet.
Uansett fire byte av hukommelse kan systemet
finner ut at har noen meningsfull verdi.
Og det kan ha vært noe som allerede er der som
er ikke lenger nødvendig med en annen funksjon, så du må bare
hva data var der.
>> Hva om du prøvde å gjøre dereference noen adresse som du don't- det var
allerede bytes og informasjon i der, det er nå på pekeren.
Hvis du prøver og deferanseoperasjon som peker, du kan rote med noe minne
at du ikke hadde tenkt å rote med det hele.
Og faktisk kan du gjøre noe virkelig ødeleggende,
som bryter et annet program, eller bryte en annen funksjon,
eller gjøre noe ondsinnet som du har ikke tenkt å gjøre i det hele tatt.
Og så det er derfor det er faktisk en god idé
å sette dine pekere til null hvis du ikke sette dem til noe meningsfylt.
Det er nok bedre på slutten av dagen for programmet
til å krasje da for at den skal gjøre Noe som skruer opp
et annet program eller en annen funksjon.
At atferd er sannsynligvis enda mindre ideelt enn bare å krasje.
Og så det er derfor det er faktisk en god vane
å komme inn å sette dine pekere til null hvis du ikke setter dem
til en meningsfull verdi umiddelbart, en verdi som du vet
og at du trygt kan den dereference.
>> Så la oss komme tilbake nå og ta en titt på den generelle syntaksen av situasjonen.
Hvis jeg sier int * p ;, hva har jeg bare gjort?
Hva jeg har gjort dette.
Jeg kjenner verdien av p er en adresse fordi alle pekere er bare
adresser.
Jeg kan dereference p bruker * operatøren.
I denne sammenheng her, helt top husker * er en del av den typen.
Int * er datatypen.
Men jeg kan dereference p bruke * operatør,
og hvis jeg gjør det, hvis jeg går til denne adressen, hva skal jeg finne på denne adressen?
Jeg vil finne et heltall.
Så int * p er i utgangspunktet sier, er p en adresse.
Jeg kan deferanseoperasjon p og hvis Jeg gjør det, vil jeg finne et heltall
på den minnelokasjon.
>> OK, så jeg sa det var en annen irriterende ting med stjerner
og her er der at irriterende ting med stjerner er.
Har du noen gang prøvd å erklære flere variabler av samme type
på samme linje med kode?
Så for en andre, late som linjen, koden jeg faktisk har det i grønt
er ikke der, og det bare sier int x, y, z ;.
Hva som ville gjøre er å faktisk lage tre heltallsvariabler for deg,
en som heter x, en som heter y, og en som heter z.
Det er en måte å gjøre det uten å måtte dele på tre linjer.
>> Her er der stjerner får irriterende igjen skjønt,
fordi * er faktisk en del av både typenavn og delvis
av variabelnavnet.
Og så hvis jeg sier int * px, py, pz, hva jeg faktisk får er en peker til et heltall
kalt px og to heltall, py og pz.
Og det er nok ikke det vi vil ha, det er ikke bra.
>> Så hvis jeg ønsker å opprette flere pekere på samme linje, av samme type,
og stjerner, hva jeg faktisk trenger å gjøre er å si int * pa, * pb, * pc.
Nå har nettopp sagt at og nå forteller deg dette,
du sannsynligvis aldri vil gjøre dette.
Og det er nok en god ting ærlig, fordi du kanskje utilsiktet
utelate en stjerne, noe sånt.
Det er nok best å kanskje erklære pekere på enkelte linjer,
men det er bare en annen av disse irriterende syntaks
ting med stjerner som gjør pekere så vanskelig å jobbe med.
Fordi det er nettopp dette syntaktisk rotet du må jobbe gjennom.
Med praksis gjør det virkelig blir andre natur.
Jeg fortsatt gjør feil med det fortsatt etter programmering i 10 år,
så ikke bli opprørt hvis noe skjer til deg, det er ganske vanlig ærlig.
Det er virkelig slags en feil av syntaksen.
>> OK så jeg slags lovet at vi ville se
begrepet hvor stor er en streng.
Vel, hvis jeg fortalte deg at en string, har vi virkelig slags
ligget til deg hele tiden.
Det er ingen datatype kalt streng, og faktisk jeg
nevnte dette i et av våre tidligste videoer på datatyper,
at strengen var en datatype som ble opprettet for deg i CS50.h.
Du må #include CS50.h for å bruke den.
>> Vel streng er egentlig bare et alias for noe
kalt char *, en Pekeren til en karakter.
Vel pekere, husker, er bare adresser.
Så hva er størrelsen i byte av en streng?
Vel det er fire eller åtte.
Og grunnen til at jeg sier fire eller åtte er fordi det faktisk
avhenger av systemet, hvis du bruker CS50 ide, char * er på størrelse med en char
* Er åtte, det er en 64-bit system.
Hver adresse i minnet er 64 bits lang.
Hvis du bruker CS50 apparatet eller bruker noen 32-bits maskin,
og du har hørt det uttrykket 32-bit maskin, hva er en 32-bits maskin?
Vel det betyr bare at hver adresse i minnet er 32 bits lang.
Og så 32 biter er fire bytes.
Så en char * er fire eller åtte byte avhengig av systemet.
Og faktisk noen datatyper, og en peker til en hvilken som helst data
skriver, siden alle pekere er bare adresser, er fire eller åtte byte.
Så la oss se dette diagram og la oss konkludere
denne videoen med litt trening her.
Så her er diagrammet vi slapp med helt i begynnelsen av videoen.
Så hva skjer nå hvis jeg sier * pk = 35?
Så hva betyr det når jeg sier, * pk = 35?
Ta et sekund.
* pk.
I sammenheng her, * er dereferanseoperator.
Så når dereferanse operator benyttes,
vi går til adressen pekte av pk, og vi endrer hva vi finner.
Så * pk = 35 effektivt gjør dette til bildet.
Så det er i utgangspunktet syntaktisk identisk for å ha sagt k = 35.
>> En til.
Hvis jeg sier int m, jeg skaper en ny variabel kalt m.
En ny boks, er det en grønn boks fordi det kommer til å holde et heltall,
og den er merket m.
Hvis jeg sier m = 4, satte jeg en heltall inn i den boksen.
Hvis si pk = & m, hvordan dette diagrammet endringen?
Pk = & m, du husker hva & Operatør gjør eller heter?
Husk at & noen variabelnavn er adressen til en variabel navn.
Så det vi sier er pk får adressen m.
Og så effektivt hva som skjer den diagram er at pk ikke lenger poeng
til k, men peker på m.
>> Igjen pekere er svært vanskelig å jobbe med
og de tar mye av praksis, men på grunn
av deres evne til å tillate deg å overføre data mellom funksjoner
og faktisk har de Endringene trer i kraft,
å få hodet rundt er veldig viktig.
Det er trolig den mest kompliserte tema vi diskuterer i CS50,
men verdien du få fra å bruke pekere
langt oppveier komplikasjoner som kommer fra å lære dem.
Så jeg ønsker deg det beste av Lykke til å lære om pekere.
Jeg er Doug Lloyd, dette er CS50.