Annonse
Enten du er klar over det eller ikke, de aller fleste programmene du har brukt, bruker påpeker på noen måte. Kanskje har du opplevd a NullPointerException på et tidspunkt. Som programmerer vil kode du skriver mer enn sannsynlig bruke pekere, selv om du ikke har implementert dem selv.
I dag skal jeg vise deg hvordan pekere fungerer, så det kan være lurt å sjekke ut hvordan matriser og lister fungerer Hvordan arrays og lister fungerer i PythonArrays og lister er noen av de mest nyttige datastrukturene i programmering - selv om få mennesker bruker dem til sitt fulle potensiale. Les mer for en programmeringsgrunning. Denne artikkelen vil være mer teoribasert enn vanlig, men hold deg til den, pekere er veldig sammensatte!
Utarbeide kode
Før du graver deg i pekere, må du forstå hvordan kode bygges og kjøres - kanskje du allerede vet dette. Denne delen vil ha ganske generelle uttalelser - ting som gjelder for flertall av språk, men ikke nødvendigvis alle.
La oss ta ting tilbake til starten. Hver datamaskin
bruker binær Hva er binær? [Teknologi forklart]Gitt at binær er så absolutt grunnleggende for datamaskinens eksistens, virker det rart at vi aldri har taklet temaet før - så i dag hadde jeg trodd at jeg ville gi en kort oversikt over hva binær ... Les mer , en serie med nuller som utgjør moderne teknologi slik vi kjenner den. Det er ekstremt vanskelig å kode noe i binær (filene vil være veldig forvirrende), da dette er de rå instruksjonene du trenger sentralenhet eller CPU til å fungere Hva er en CPU og hva gjør den?Å beregne akronymer er forvirrende. Hva er en CPU likevel? Og trenger jeg en fir- eller dual-core prosessor? Hva med AMD, eller Intel? Vi er her for å forklare forskjellen! Les mer . Dette er kjent som Maskinkode.Neste steg opp fra maskinkode er montering. Dette er et noe menneskelig lesbart format. Selv om det fremdeles er komplekst å programmere i, er det mulig. Montering består av en serie enkle kommandoer for å utføre oppgaver, og er kjent som en lavt nivå programmeringsspråk. Det er mulig å skrive komplekse programmer, men det er vanskelig å uttrykke abstrakte begreper, og krever mye hensyn.
Mange videospill og applikasjoner med høy ytelse har noen av logikkene som er skrevet i samlingen, ettersom noen reelle hastighetsøkninger kan bli funnet hvis du vet hva du gjør. For de aller fleste programmeringsprosjekter trenger du imidlertid ikke vite noen samling i det hele tatt.
Så hvis maskinkode er for vanskelig å skrive, og montering er for vanskelig å programmere, hva skriver du kode med? Her er hvor høy level språk kommer inn. Språk på høyt nivå gjør programmer enkle å skrive. Du kan programmere på noe som ligner morsmålet ditt, og det er lett å uttrykke komplekse algoritmer. Du har kanskje hørt om mange språk på høyt nivå (og du vil definitivt ha brukt et program skrevet i dem):
- BASIC
- C ++
- Lisp
Disse språkene er veldig gamle nå, og mange ble utviklet på begynnelsen av 1950-tallet! Nesten alle moderne programmeringsspråk er et høyt nivå språk, inkludert PHP og Python. Det blir oppfunnet flere språk hver dag (selv om det nok er nok nå), men hvordan fungerer koden din fortsatt ordentlig hvis datamaskiner krever maskinkode?
Her er kompilering. En kompilator er et program som konverterer koden på høyt nivå til et skjema som kan utføres. Dette kan være et annet høyt nivå språk, men det er vanligvis montering. Noen språk (for eksempel Python eller Java) konverterer koden din til et mellomtrinn som heter Bytecode. Dette må samles på et senere tidspunkt, noe som vanligvis gjøres på forespørsel, for eksempel når programmet kjører. Dette er kjent som akkurat i tide samlingen, og den er ganske populær.
Minnehåndtering
Nå som du vet hvordan programmeringsspråk fungerer, la oss se på minnestyring på høyt nivå språk. For disse eksemplene bruker jeg pseudokode - kode skrevet ikke på noe spesifikt språk, men brukes til å vise begreper i stedet for nøyaktig syntaks. I dag vil dette stort sett ligne C ++ som det er det beste språket på høyt nivå (etter min mening).
For denne delen vil det hjelpe hvis du har forståelse for hvordan RAM fungerer En rask og skitten guide til RAM: Hva du trenger å viteRAM er en avgjørende komponent i hver datamaskin, men det kan være forvirrende. Vi deler det ned i lettfattelige termer du vil forstå. Les mer .
De fleste språk har variabler - containere som lagrer noe data. Du må definere datatypen eksplisitt. Noen dynamisk maskinskrevne språk som Python eller PHP håndterer dette for deg, men de må fortsatt gjøre det.
Si at du har en variabel:
int myNumber;
Denne koden deklarerer en variabel som heter Nummeret mitt, og gir den en datatype av heltall. Når den er samlet, tolker datamaskinen denne kommandoen som:
“Finn noe tomt minne, og reserver en plass stor nok til å lagre et heltall”
Når denne kommandoen er blitt utført, kan ikke den biten minne brukes av et annet program. Den inneholder ingen data ennå, men den er reservert for myNumber-variabelen din.
Tildel nå en verdi til variabelen din:
myNumber = 10;
For å fullføre denne oppgaven får datamaskinen tilgang til den reserverte minneplassen og endrer den verdien som er lagret der, til denne nye verdien.
Nå er alt vel og bra, men hvordan blir minneplasseringer uforbeholdne? Hvis programmer reserverte alt minnet de liker, ville RAM-en fylt ut umiddelbart - det vil gi en veldig sakte system.
For å unngå dette potensielle problemet, implementerer mange språk a søppelmann, brukt til å ødelegge variabler (og derfor frigjøre de reserverte minneplasseringene) som har gått utenfor omfanget.
Du lurer kanskje på hva omfanget er, og hvorfor det er så viktig. Scope definerer grensene og levetiden for variabler eller hvilket som helst minne som brukes av et program. En variabel er "utenfor omfanget" når den ikke lenger kan nås med noen kode (det er når søppeloppsamleren trer inn). Her er et eksempel:
funksjonsmatematikk () {int firstNumber = 1; } int secondNumber = 2; print (firstNumber + secondNumber); // vil ikke fungere
Dette eksemplet vil ikke samles. Variabelen firstNumber er innenfor matte funksjon, så det er omfanget. Det er ikke tilgang til det fra utsiden av funksjonen der den er erklært. Dette er et viktig programmeringskonsept, og å forstå det er avgjørende for å jobbe med pekere.
Denne måten å håndtere minne kalles stable. Det er slik de aller fleste programmene fungerer. Du trenger ikke å forstå tips for å bruke det, og det er ganske godt strukturert. Ulempen med stabelen er hastigheten. Ettersom datamaskinen må tilordne minne, holde oversikt over variabler og kjøre søppelsamlingen, er det et lite overhead. Dette er bra for mindre programmer, men hva med høyytelsesoppgaver, eller datatunge applikasjoner?
Skriv inn: pekere.
pekere
På overflaten høres pekere enkle ut. De refererer til (peker på) et sted i minnet. Dette kan ikke virke annerledes enn "vanlige" variabler på stabelen, men stol på meg, det er stor forskjell. Pekere lagres på heap. Dette er motsatt av bunken - den er mindre organisert, men er mye raskere.
La oss se på hvordan variabler blir tildelt i bunken:
int antall En = 1; int nummerTo = antall En;
Dette er enkel syntaks; Variabelen nummer to inneholder nummer en. Det er verdien som blir kopiert over under oppgaven fra nummer en variabel.
Hvis du ville få tak i minneadresse av en variabel, i stedet for verdien, må du bruke ampersand-tegnet (&). Dette kalles adresse til operatør, og er en viktig del av pekeren verktøysett.
int antall En = 1; int numberTwo = & numberOne;
Nå nummer to variabel punkter til et minneplass, i stedet for å få nummer én som er kopiert over til sin egen, nye minneplassering. Hvis du skulle produsere denne variabelen, ville den ikke være nummer én (selv om den er lagret på minneplassen). Det vil gi ut minnets plassering (sannsynligvis noe i likhet med 2167, selv om det varierer avhengig av systemet og tilgjengelig RAM). For å få tilgang til verdien som er lagret i en peker, må du i stedet for minneposisjonen dereference pekeren. Denne får direkte tilgang til verdien, som vil være nummer én i dette tilfellet. Slik avgir du en peker:
int nummerTo = * antall En;
De dereference operatør er en stjerne (*).
Dette kan være et vanskelig konsept å forstå, så la oss gå over det igjen:
- De adresse til operator (&) lagrer minneadressen.
- De dereference operatør (*) får tilgang til verdien.
Syntaksen endres litt når deklarerer pekere:
int * myPointer;
Datatypen av int her refererer til datatypen pekeren punkter til, og ikke selve pekeren.
Nå som du vet hva tips er, kan du gjøre noen ryddige triks med dem! Når minnet brukes, starter operativsystemet sekvensielt. Du kan tenke på RAM som duehull. Mange hull for å lagre noe, bare ett kan brukes samtidig. Forskjellen her er at disse duehullene er alle nummererte. Når du tildeler minne, starter operativsystemet ditt med det laveste tallet, og fungerer opp. Det vil aldri hoppe rundt mellom tilfeldige tall.
Når du arbeider med pekere, hvis du har tildelt en matrise, kan du enkelt navigere til neste element ved å enkelt øke pekeren.
Her blir det interessant. Når du overfører verdier til en funksjon (ved å bruke variabler som er lagret på bunken), kopieres disse verdiene til din funksjon. Hvis dette er store variabler, lagrer du dem nå to ganger. Når funksjonen er ferdig, kan det hende du trenger en måte å returnere disse verdiene på. Funksjoner kan generelt bare returnere én ting - så hva om du ville returnere to, tre eller fire ting?
Hvis du sender en peker til funksjonen din, blir bare minneadressen kopiert (som er liten). Dette sparer CPU-en mye arbeid! Kanskje pekeren peker på et enormt bildeopplegg - ikke bare funksjonen din kan fungere på nøyaktig det samme data som er lagret på nøyaktig samme minneplassering, men når det er gjort, er det ikke nødvendig å returnere hva som helst. Ryddig!
Du må imidlertid være veldig forsiktig. Pekere kan fremdeles gå utenfor omfanget og bli samlet inn av søppelsamleren. Verdiene som er lagret i minnet blir imidlertid ikke samlet. Dette kalles en minnelekkasje. Du har ikke lenger tilgang til dataene (ettersom pekerne er blitt ødelagt), men det bruker fremdeles minne. Dette er en vanlig årsak for at mange programmer krasjer, og det kan mislykkes spektakulært hvis det er en stor mengde data. Det meste av tiden vil operativsystemet drepe programmet ditt hvis du har en stor lekkasje (bruker mer RAM enn systemet har), men det er ikke ønskelig.
Feilsøkingspekere kan være et mareritt, spesielt hvis du jobber med store datamengder, eller jobber i løkker. Deres ulemper og vanskeligheter med å forstå er virkelig verdt de avveiningene du oppnår i ytelsen. Selv om du husker, kan det hende at det ikke alltid er nødvendig.
Det er det for i dag. Jeg håper du har lært noe nyttig om et sammensatt emne. Vi har selvfølgelig ikke dekket alt det er å vite - det er et veldig sammensatt tema. Hvis du er interessert i å lære mer, anbefaler jeg på det sterkeste C ++ om 24 timer.
Hvis dette var litt sammensatt, ta en titt på vår guide til de enkleste programmeringsspråk 6 enkleste programmeringsspråk å lære for nybegynnereÅ lære å programmere handler om å finne riktig språk like mye som det handler om oppbyggingsprosessen. Her er de seks enkleste programmeringsspråkene for nybegynnere. Les mer .
Lærte du hvordan pekere fungerer i dag? Har du noen tips og triks du vil dele med andre programmerere? Hopp inn i kommentarene og del tankene dine nedenfor!
Joe er utdannet innen informatikk fra University of Lincoln, Storbritannia. Han er en profesjonell programvareutvikler, og når han ikke flyr droner eller skriver musikk, kan han ofte finne bilder og produsere videoer.