C ++

Hvordan bruke C ++ pekere

Hvordan bruke C ++ pekere
Minnet til en datamaskin er en lang serie celler. Størrelsen på hver celle kalles en byte. En byte er et rom okkupert av et engelsk tegn i alfabetet. Et objekt i vanlig forstand er et sammenhengende sett med byte i minnet. Hver celle har en adresse, som er et helt tall, vanligvis skrevet i heksadesimal form. Det er tre måter å få tilgang til et objekt i minnet. Du kan få tilgang til et objekt ved å bruke det som er kjent som en peker. Den kan nås ved hjelp av det som er kjent som en referanse. Det er fremdeles tilgjengelig ved hjelp av en identifikator. Fokuset i denne artikkelen er bruken av pekere og referanser. I C ++ er det det spisse objektet og pekerobjektet. Det spisse objektet har objektet av interesse. Pekerobjektet har adressen til det spisse objektet.

Du må ha grunnleggende kunnskap i C ++, inkludert identifikatorer, funksjoner og matriser; å forstå denne artikkelen.

Pekerobjektet og det spisse objektet har hver sin identifikator.

Adressen til operatøren, &

Dette er en unarisk operatør. Når den følges av en identifikator, returnerer den adressen til objektet til identifikatoren. Vurder følgende erklæring:

int ptdInt;

Nedenfor kommer koden, følgende uttrykk, til å returnere adressen identifisert av ptdInt:

& ptdInt

Du trenger ikke å vite nøyaktig adresse (nummer) mens du koder.

Indireksjonsoperatøren, *

Dette er en unarisk operatør i sammenheng med pekere. Det blir vanligvis skrevet foran en identifikator. Hvis den brukes i en erklæring om identifikatoren, er identifikatoren pekerobjektet som bare inneholder adressen til det spisse objektet. Hvis den brukes foran pekerobjektidentifikatoren, for å returnere noe, er den returnerte tingen verdien av det spisse objektet.

Opprette en peker

Ta en titt på følgende kodesegment:

float ptdFloat;
flyte * ptrFloat;
ptrFoat = &ptdFloat;

Segmentet begynner med erklæringen til det spisse objektet, ptdFloat. ptdFloat er en identifikator som bare identifiserer et flyteobjekt. Et faktisk objekt (verdi) kunne ha blitt tildelt det, men i dette tilfellet har ingenting blitt tildelt det. Neste i segmentet er det erklæringen til pekerobjektet. Indireksjonsoperatøren foran denne identifikatoren betyr at den må holde adressen til et spiss objekt. Objekttypen, flyter i begynnelsen av uttalelsen, betyr at den spisse gjenstanden er en flottør. Pekerobjektet er alltid av samme type som det spisse objektet. ptrFoat er en identifikator som bare identifiserer et pekerobjekt.

I den siste setningen av koden tildeles adressen til det spisse objektet pekerobjektet. Legg merke til bruken av operatørens adresse, &.

Den siste setningen (linjen) over viser at etter at du har erklært pekerobjektet uten initialisering, trenger du ikke omdirigeringsoperatøren når du må initialisere det. Det er faktisk en syntaksfeil å bruke indireksjonsoperatøren i den tredje (siste) linjen.

Pekerobjektet kan erklæres og initialiseres av det spisse objektet i en uttalelse, som følger:

float ptdFloat;
flyte * ptrFoat = &ptdFloat;

Den første linjen i forrige kodesegment og denne, er den samme. Den andre og tredje linjen i det forrige kodesegmentet er kombinert til en uttalelse her.

Merk deg i koden ovenfor at når du deklarerer og initialiserer pekerobjektet, må indireksjonsoperatøren brukes. Det brukes imidlertid ikke hvis initialiseringen skal gjøres etterpå. Pekerobjektet initialiseres med adressen til det spisse objektet.

I det følgende kodesegmentet brukes indireksjonsoperatøren til å returnere innholdet i det spisse objektet.

int ptdInt = 5;
int * ptrInt = &ptdInt;
cout << *ptrInt << '\n';

Utgangen er 5.

I den siste uttalelsen her har indireksjonsoperatøren blitt brukt til å returnere verdien som er pekt på, av pekeridentifikatoren. Så når den brukes i en erklæring, vil identifikatoren for indireksjonsoperatøren ha adressen til det spisse objektet. Når det brukes i et returuttrykk, i kombinasjon med pekeridentifikatoren, returnerer retningen operatoren verdien av det spisse objektet.

Tilordne null til en peker

Pekerobjektet skal alltid ha typen spiss objekt. Når du erklærer pekerobjektet, må datatypen til det spisse objektet brukes. Imidlertid kan verdien til desimal null tildeles pekeren som i følgende kodesegment:

int ptdInt = 5;
int * ptrInt;
ptrInt = 0;
eller i segmentet,
int ptdInt = 5;
int * ptrInt = 0;

I begge tilfeller kalles pekeren (identifikatoren) nullpekeren; mening, det peker mot ingensteds. Det vil si at den ikke har adressen til noe spiss objekt. Her er 0 desimal null og ikke heksadesimal null. Heksadesimalt null peker mot den første adressen til dataminnet.

Ikke prøv å få verdien som en nullpeker peker på. Hvis du prøver det, kan programmet kompilere, men kanskje ikke utføre.

Array Name as a Constant Pointer

Tenk på følgende matrise:

int arr [] = 000, 100, 200, 300, 400;

Navnet på matrisen, arr er faktisk identifikatoren som har adressen til det første elementet i matrisen. Følgende uttrykk returnerer den første verdien i matrisen:

* arr

Med matrisen, inkrementoperatoren, ++ oppfører seg annerledes. I stedet for å legge til 1, erstatter den adressen til pekeren, med adressen til neste element i matrisen. Navnet på matrisen er imidlertid en konstant peker; noe som betyr at innholdet (adressen) ikke kan endres eller økes. Så for å øke må startadressen til matrisen tilordnes en ikke-konstant peker som følger:

int * ptr = arr;

Nå kan ptr økes for å peke på neste element i matrisen. ptr er her blitt erklært som et pekerobjekt. Uten * her ville det ikke være en pekepinn; det ville være en identifikator å holde et int-objekt og ikke å holde en minneadresse.

Følgende kodesegment peker til slutt på det fjerde elementet:

++ptr;
++ptr;
++ptr;

Følgende kode sender ut den fjerde verdien av matrisen:

int arr [] = 000, 100, 200, 300, 400;
int * ptr = arr;
++ptr;
++ptr;
++ptr;
cout << *ptr << '\n';

Utgangen er 300.

Funksjonsnavn som identifikator

Navnet på en funksjon er identifikatoren for funksjonen. Vurder følgende funksjonsdefinisjon:

int fn ()

cout << "seen" << '\n';
retur 4;

fn er identifikatoren for funksjonen. Uttrykket,

& fn

returnerer adressen til funksjonen i minnet. fn er som det spisse objektet. Følgende erklæring erklærer en peker til en funksjon:

int (* func) ();

Identifikatoren for det spisse objektet og identifikatoren for pekerobjektet er forskjellig. func er en peker til en funksjon. fn er identifikatoren for en funksjon. Og så kan funk gjøres for å peke på fn som følger:

func = &fn;

Verdien (innholdet) av func er adressen til fn. De to identifikatorene kunne ha vært knyttet til en initialiseringsuttalelse som følger:

int (* func) () = &fn;

Legg merke til forskjellene og likhetene i håndtering av funksjonspekere og skalarpekere. func er en peker til en funksjon; det er det spisse objektet; det er erklært annerledes enn en skalarpeker.

Funksjonen kan kalles med,

fn ()
eller
func ()

Det kan ikke kalles med * func ().

Når funksjonen har parametere, har de andre parentesene parametertypene og trenger ikke ha identifikatorene for parametrene. Følgende program illustrerer dette:

#inkludere
bruker navneområde std;
float fn (float fl, int in)

retur fl;

int main ()

float (* func) (float, int) = &fn;
float val = func (2.5, 6);
cout << val << '\n';
retur 0;

Utgangen er 2.5.

C ++ referanse

Henvisning i C ++ er bare en måte å produsere et synonym (et annet navn) for en identifikator. Den bruker & operatoren, men ikke på samme måte som & brukes til pekere. Vurder følgende kodesegment:

int myInt = 8;
int & yourInt = myInt;
cout << myInt << '\n';
cout << yourInt << '\n';

Utgangen er:

8
8

Den første utsagnet initialiserer identifikatoren, myInt; Jeg.e. myInt er erklært og laget for å holde verdien, 8. Den andre utsagnet gjør en ny identifikator, dinInt et synonym til myInt. For å oppnå dette plasseres & operatøren mellom datatypen og den nye identifikatoren i erklæringen. Cout-uttalelsene viser at de to identifikatorene er synonymer. For å returnere verdien i dette tilfellet, trenger du ikke å gå foran den med * . Bare bruk identifikatoren.

myInt og yourInt her, er ikke to forskjellige objekter. De er to forskjellige identifikatorer som refererer til (identifiserer) samme sted i minnet som har verdien 8. Hvis verdien til myInt endres, endres også verdien til dinInt automatisk. Hvis verdien på dinInt endres, endres også verdien på myInt automatisk.

Referanser er av samme type.

Henvisning til en funksjon

Akkurat som du kan ha en referanse til en skalar, kan du også ha en referanse til en funksjon. Imidlertid er koding av en referanse til en funksjon forskjellig fra koding av en referanse til en skalar. Følgende program illustrerer dette:

#inkludere
bruker navneområde std;
float fn (float fl, int in)

retur fl;

int main ()

flyte (& func) (flyte, int) = fn;
float val = func (2.5, 6);
cout << val << '\n';
retur 0;

Utgangen er 2.5.

Legg merke til den første setningen i hovedfunksjonen, som gjør func til et synonym for fn. Begge refererer til den samme funksjonen. Legg merke til engangsbruk og plassering av &. Så & er referanseoperatøren her og ikke adressen til operatøren. For å ringe til funksjonen, bruk bare hvilket som helst navn.

En referanseidentifikator er ikke den samme som en pekeridentifikator.

Funksjon som returnerer en peker

I det følgende programmet returnerer funksjonen en peker, som er adressen til det spisse objektet:

#inkludere
bruker navneområde std;
float * fn (float fl, int in)

flyte * fll = &fl;
retur fll;

int main ()

flyte * val = fn (2.5, 6);
cout << *val << '\n';
retur 0;

Utgangen er 2.5

Den første setningen i funksjonen, fn () er der bare for å lage et pekerobjekt. Legg merke til engangsbruk og plassering av * i funksjonssignaturen. Legg også merke til hvordan pekeren (adressen) ble mottatt i hovedfunksjonen () av ​​et annet pekerobjekt.

Funksjon som returnerer en referanse

I det følgende programmet returnerer funksjonen en referanse:

#inkludere
bruker navneområde std;
float & fn (float fl, int in)

flyte & frr = fl;
returnere frr;

int main ()

float & val = fn (2.5, 6);
cout << val << '\n';
retur 0;

Utgangen er 2.5.

Den første setningen i funksjonen, fn () er der bare for å lage en referanse. Legg merke til engangsbruk og plassering av & i funksjonssignaturen. Legg også merke til hvordan referansen ble mottatt i hovedfunksjonen () av ​​en annen referanse.

Gi en peker til en funksjon

I det følgende programmet sendes en peker, som egentlig er adressen til et flytende objekt, som et argument til funksjonen:

#inkludere
bruker navneområde std;
float fn (float * fl, int in)

returnere * fl;

int main ()

flyte v = 2.5;
flyteval = fn (& v, 6);
cout << val << '\n';
retur 0;

Utgangen er 2.5

Legg merke til bruken og plasseringen av * for flottørparameteren i funksjonssignaturen. Så snart evalueringen av funksjonen fn () starter, kommer følgende uttalelse:

flyte * fl = & v;

Både fl og & p viser til det samme spisse objektet som holder 2.5. * fl på returoppgaven er ikke en erklæring; det betyr verdien av det spisse objektet som pekerobjektet peker på.

Gi en referanse til en funksjon

I det følgende programmet sendes en referanse som et argument til funksjonen:

#inkludere
bruker navneområde std;
float fn (float & fl, int in)

retur fl;

int main ()

flyte v = 2.5;
flyteval = fn (v, 6);
cout << val << '\n';
retur 0;

Utgangen er 2.5

Legg merke til bruken og plasseringen av & for flottørparameteren i funksjonssignaturen. Så snart evalueringen av funksjonen fn () starter, kommer følgende uttalelse:

flyte & fl = v;

Gi en matrise til en funksjon

Følgende program viser hvordan du overfører en matrise til en funksjon:

#inkludere
bruker navneområde std;
int fn (int arra [])

retur arra [2];

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
cout << val << '\n';
retur 0;

Utgangen er 200.

I dette programmet er det matrisen som sendes. Merk at parameteren til funksjonssignaturen har en tom matrixerklæring. Argumentet i funksjonsanropet er bare navnet på en opprettet matrise.

Kan en C ++ - funksjon returnere en matrise?

En funksjon i C ++ kan returnere verdien til en matrise, men kan ikke returnere matrisen. Kompilering av følgende program resulterer i en feilmelding:

#inkludere
bruker navneområde std;
int fn (int arra [])

retur arra;

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
retur 0;

Pointer of a Pointer

En peker kan peke på en annen peker. Det vil si at et pekerobjekt kan ha adressen til et annet pekerobjekt. De må fremdeles alle være av samme type. Følgende kodesegment illustrerer dette:

int ptdInt = 5;
int * ptrInt = &ptdInt;
int ** ptrptrInt = &ptrInt;
cout << **ptrptrInt << '\n';

Utgangen er 5.

I erklæringen om peker-til-peker brukes dobbelt *. For å returnere verdien av det endelige spisse objektet, brukes fortsatt * dobbel.

Array of Pointers

Følgende program viser hvordan du koder en rekke pekere:

#inkludere
bruker navneområde std;
int main ()

int num0 = 000, num1 = 100, num2 = 200, num3 = 300, num4 = 400;
int * no0 = & num0, * no1 = & num1, * no2 = & num2, * no3 = & num3, * no4 =&num4;
int * arr [] = no0, no1, no2, no3, no4;
cout << *arr[4] << '\n';
retur 0;

Utgangen er:

400

Legg merke til bruken og plasseringen av * i erklæringen til matrisen. Legg merke til bruken av * når du returnerer en verdi i matrisen. Med pekepinner er to * involvert. Når det gjelder en rekke pekere, er en * allerede tatt vare på, fordi matrisens identifikator er en peker.

Array of Strings of Variable Length

En streng bokstavelig er en konstant som returnerer en peker. En rekke strenger med variabel lengde er en rekke pekere. Hver verdi i matrisen er en peker. Pekere er adresser til minnesteder og har samme størrelse. Strenger av forskjellige lengder er andre steder i minnet, ikke i matrisen. Følgende program illustrerer bruken:

#inkludere
bruker navneområde std;
int main ()

const char * arr [] = "kvinne", "gutt", "jente", "voksen";
cout << arr[2] << '\n';
retur 0;

Resultatet er "jente".

Erklæringen til matrisen begynner med det reserverte ordet "const" for konstant; etterfulgt av "char" for tegnet, deretter stjernen, * for å indikere at hvert element er en peker. For å returnere en streng fra matrisen brukes ikke * på grunn av den implisitte karakteren til pekeren til hver streng. Hvis * brukes, vil det første elementet i strengen returneres.

Peker til en funksjon som returnerer en peker

Følgende program illustrerer hvordan en peker til en funksjon som returnerer en peker er kodet:

#inkludere
bruker navneområde std;
int * fn ()

int num = 4;
int * inter = #
returnere inter;

int main ()

int * (* func) () = &fn;
int val = * func ();
cout << val << '\n';
retur 0;

Utgangen er 4.

Erklæringen om en peker til en funksjon som returnerer en peker er lik erklæringen om en peker til en vanlig funksjon, men foran en stjerne. Den første setningen i hovedfunksjonen () illustrerer dette. For å ringe funksjonen ved hjelp av pekeren, gå foran den med *.

Konklusjon

For å lage en peker til en skalar, gjør du noe sånt,

flyte spiss;
flyte * peker = &pointed;

* har to betydninger: i en erklæring indikerer det en peker; for å returnere noe, er det for verdien av det spisse objektet.

Matrisenavnet er en konstant peker til det første elementet i matrisen.

For å lage en peker til en funksjon, kan du gjøre det,

int (* func) () = &fn;

der fn () er en funksjon definert andre steder og func er pekeren.

& har to betydninger: i en erklæring indikerer den en referanse (synonym) til det samme objektet som en annen identifikator; når du returnerer noe, betyr det adressen til.

For å opprette en referanse til en funksjon kan du gjøre det,

flyte (& refFunc) (flyte, int) = fn;

der fn () er en funksjon definert andre steder og refFunc er referansen.

Når en funksjon returnerer en peker, må den returnerte verdien mottas av en peker. Når en funksjon returnerer en referanse, må den returnerte verdien mottas av en referanse.

Når du sender en peker til en funksjon, er parameteren en erklæring, mens argumentet er adressen til et spiss objekt. Når du sender en referanse til en funksjon, er parameteren en erklæring, mens argumentet er referansen.

Når du overfører en matrise til en funksjon, er parameteren en erklæring mens argumentet er matrisenavnet uten []. C ++ - funksjonen returnerer ikke en matrise.

En peker-til-peker trenger to * i stedet for en, der det er aktuelt.

Chrys

Hvordan utvikle et spill på Linux
For et tiår siden ville ikke mange Linux-brukere forutsi at deres favorittoperativsystem en dag ville være en populær spillplattform for kommersielle ...
Åpne kildeporter for kommersielle spillmotorer
Gratis, åpen kildekode og plattformspillmotorrekreasjoner kan brukes til å spille gamle så vel som noen av de ganske nylige spilletitlene. Denne artik...
Beste kommandolinjespill for Linux
Kommandolinjen er ikke bare din største allierte når du bruker Linux, den kan også være kilden til underholdning fordi du kan bruke den til å spille m...