C ++

Sådan bruges C ++ pointer

Sådan bruges C ++ pointer
Hukommelsen på en computer er en lang række celler. Størrelsen på hver celle kaldes en byte. En byte er et rum besat af et engelsk alfabet. Et objekt i almindelig forstand er et sammenhængende sæt bytes i hukommelsen. Hver celle har en adresse, som er et heltal, normalt skrevet i hexadecimal form. Der er tre måder at få adgang til et objekt i hukommelsen. Et objekt kan tilgås ved hjælp af det, der kaldes en markør. Den kan tilgås ved hjælp af det, der kaldes en reference. Det kan stadig tilgås ved hjælp af en identifikator. Fokus i denne artikel er brugen af ​​henvisninger og referencer. I C ++ er der det spidse objekt og markørobjektet. Det spidse objekt har genstand for interesse. Markørobjektet har adressen til det spidse objekt.

Du skal have grundlæggende viden i C ++, herunder dens identifikatorer, funktioner og arrays; at forstå denne artikel.

Markørobjektet og det spidse objekt har hver deres identifikator.

Adressen til operatøren &

Dette er en unary operatør. Når den efterfølges af en identifikator, returnerer den adressen på objektet til identifikatoren. Overvej følgende erklæring:

int ptdInt;

Nedenfor er koden, det følgende udtryk, returnerer den adresse, der er identificeret af ptdInt:

& ptdInt

Du behøver ikke at kende den nøjagtige adresse (nummer), mens du koder.

Indirection Operator, *

Dette er en unary operator i sammenhæng med pegepinde. Det er normalt skrevet foran en identifikator. Hvis det bruges i en erklæring om identifikatoren, er identifikatoren det markørobjekt, der kun indeholder adressen på det spidse objekt. Hvis det bruges foran markørobjektidentifikatoren for at returnere noget, så er den returnerede ting værdien af ​​det spidse objekt.

Oprettelse af en markør

Se på følgende kodesegment:

flyde ptdFloat;
flyde * ptrFloat;
ptrFoat = &ptdFloat;

Segmentet begynder med erklæringen af ​​det spidse objekt, ptdFloat. ptdFloat er en identifikator, der bare identificerer et float-objekt. Et faktisk objekt (værdi) kunne have været tildelt det, men i dette tilfælde er der ikke tildelt noget. Næste i segmentet er der erklæringen om markørobjektet. Indirection-operatøren foran denne identifikator betyder, at den skal holde adressen på en spids genstand. Objektypen, flyde i starten af ​​udsagnet, betyder, at den spidse genstand er en flyder. Markørobjektet er altid af samme type som det spidse objekt. ptrFoat er en identifikator, der bare identificerer et markørobjekt.

I den sidste erklæring af koden tildeles markøren objektet til det spidse objekt. Bemærk brugen af ​​operatørens adresse, &.

Den sidste udsagn (linje) ovenfor viser, at efter at have erklæret markørobjektet uden initialisering, behøver du ikke indirection-operatøren, når du skal initialisere det. Faktisk er det en syntaksfejl at bruge indirection-operatoren i den tredje (sidste) linje.

Markørobjektet kan erklæres og initialiseres af det spidse objekt i en sætning som følger:

flyde ptdFloat;
flyde * ptrFoat = &ptdFloat;

Den første linje i det forrige kodesegment og denne er den samme. Den anden og tredje linje i det forrige kodesegment er blevet kombineret til en sætning her.

Bemærk i ovenstående kode, at indirection-operatoren skal bruges til at deklarere og initialisere markørobjektet. Det bruges dog ikke, hvis initialiseringen skal foretages bagefter. Markørobjektet initialiseres med adressen på det spidse objekt.

I det følgende kodesegment bruges indirection-operatoren til at returnere indholdet af det spidse objekt.

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

Outputtet er 5.

I den sidste sætning her er indirection-operatøren blevet brugt til at returnere den værdi, der er peget på, ved hjælp af markør-id'en. Så når det bruges i en erklæring, vil identifikatoren for indirection-operatøren indeholde adressen på det spidse objekt. Når det bruges i et returudtryk, i kombination med markøridentifikatoren, returnerer omdirigeringsoperatoren værdien af ​​det spidse objekt.

Tildeling af nul til en markør

Markørobjektet skal altid have typen af ​​det spidse objekt. Når deklarerer objektet, skal datatypen for det spidse objekt bruges. Værdien af ​​decimal nul kan dog tildeles markøren som i følgende kodesegment:

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

I begge tilfælde kaldes markøren (identifikator) nullmarkøren; betyder, det peger på ingen steder. Det vil sige, den har ikke adressen på noget spids genstand. Her er 0 decimal nul og ikke hexadecimal nul. Hexadecimal nul ville pege på den første adresse i computerens hukommelse.

Forsøg ikke at få den værdi, som en nulmarkør peger på. Hvis du prøver det, kan programmet kompilere, men muligvis ikke udføre.

Array Name as a Constant Pointer

Overvej følgende array:

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

Navnet på arrayet, arr er faktisk den identifikator, der har adressen på det første element i arrayet. Følgende udtryk returnerer den første værdi i arrayet:

* arr

Med arrayet opfører sig inkrementoperatoren ++ sig forskelligt. I stedet for at tilføje 1 erstatter den markørens adresse med adressen på det næste element i arrayet. Navnet på arrayet er dog en konstant markør; hvilket betyder, at dets indhold (adresse) ikke kan ændres eller øges. For at inkrementere skal matrixens startadresse tildeles en ikke-konstant markør som følger:

int * ptr = arr;

Nu kan ptr forøges for at pege på det næste element i arrayet. ptr er her blevet erklæret som et pointerobjekt. Uden * her ville det ikke være en pointer; det ville være en identifikator at holde et int-objekt og ikke at have en hukommelsesadresse.

Følgende kodesegment peger endelig på det fjerde element:

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

Den følgende kode udsender den fjerde værdi af arrayet:

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

Outputtet er 300.

Funktionsnavn som identifikator

Navnet på en funktion er identifikatoren for funktionen. Overvej følgende funktionsdefinition:

int fn ()

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

fn er identifikatoren for funktionen. Udtrykket,

& fn

returnerer adressen på funktionen i hukommelsen. fn er som det spidse objekt. Følgende erklæring erklærer en markør til en funktion:

int (* func) ();

Identifikatoren for det spidse objekt og identifikatoren for markørobjektet er forskellig. func er en markør til en funktion. fn er identifikatoren for en funktion. Og så kan funk gøres til at pege på fn som følger:

func = &fn;

Værdien (indhold) af func er adressen på fn. De to identifikatorer kunne have været knyttet til en initialiseringserklæring som følger:

int (* func) () = &fn;

Bemærk forskellene og lighederne i håndtering af funktionspegere og skalarpekere. func er en markør til en funktion; det er den spidse genstand; det erklæres forskelligt fra en skalar markør.

Funktionen kan kaldes op med,

fn ()
eller
func ()

Det kan ikke kaldes med * func ().

Når funktionen har parametre, har de andre parenteser parametertyperne og behøver ikke have identifikatorerne til parametrene. Følgende program illustrerer dette:

#omfatte
ved hjælp af namespace std;
float fn (float fl, int in)

returnere fl;

int main ()

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

Outputtet er 2.5.

C ++ Reference

Henvisning i C ++ er bare en måde at producere et synonym (et andet navn) på en identifikator. Det bruger & operatoren, men ikke på samme måde som & bruges til markører. Overvej følgende kodesegment:

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

Outputtet er:

8
8

Den første sætning initialiserer identifikatoren, myInt; jeg.e. myInt er erklæret og gjort til at holde værdien, 8. Den anden erklæring gør en ny identifikator, dinInt et synonym med myInt. For at opnå dette placeres & operatøren mellem datatypen og den nye identifikator i erklæringen. Cout-udsagnene viser, at de to identifikatorer er synonymer. For at returnere værdien i dette tilfælde behøver du ikke forud for den med * . Brug bare identifikatoren.

myInt og yourInt her er ikke to forskellige objekter. De er to forskellige identifikatorer, der refererer til (identificerer) den samme placering i hukommelsen med værdien 8. Hvis værdien af ​​myInt ændres, ændres værdien af ​​dinInt også automatisk. Hvis værdien af ​​dinInt ændres, ændres værdien af ​​myInt også automatisk.

Referencer er af samme type.

Henvisning til en funktion

Ligesom du kan have en henvisning til en skalar, kan du også have en henvisning til en funktion. Kodning af en henvisning til en funktion er imidlertid forskellig fra kodning af en henvisning til en skalar. Følgende program illustrerer dette:

#omfatte
ved hjælp af namespace std;
float fn (float fl, int in)

returnere fl;

int main ()

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

Outputtet er 2.5.

Bemærk den første sætning i hovedfunktionen, som gør func til et synonym for fn. Begge refererer til den samme funktion. Bemærk engangsbrug og placering af &. Så & er referenceoperatøren her og ikke operatørens adresse. For at ringe til funktionen skal du bare bruge begge navne.

En referenceidentifikator er ikke den samme som en markøridentifikator.

Funktion, der returnerer en markør

I det følgende program returnerer funktionen en markør, som er adressen på det spidse objekt:

#omfatte
ved hjælp af namespace std;
flyde * fn (flyde fl, int ind)

flyde * fll = &fl;
returnere fll;

int main ()

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

Outputtet er 2.5

Den første sætning i funktionen, fn () er der bare for at oprette et markørobjekt. Bemærk engangsbrug og placering af * i funktionssignaturen. Bemærk også, hvordan markøren (adresse) blev modtaget i hovedfunktionen () af et andet markørobjekt.

Funktion, der returnerer en reference

I det følgende program returnerer funktionen en reference:

#omfatte
ved hjælp af namespace std;
float & fn (float fl, int in)

flyde & frr = fl;
returnere frr;

int main ()

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

Outputtet er 2.5.

Den første sætning i funktionen, fn () er der bare for at oprette en reference. Bemærk engangsbrug og placering af & i funktionssignaturen. Bemærk også, hvordan referencen blev modtaget i hovedfunktionen () af en anden reference.

Videregivelse af en markør til en funktion

I det følgende program sendes en markør, som faktisk er adressen på et flydende objekt, som et argument til funktionen:

#omfatte
ved hjælp af namespace std;
flyde fn (flyde * fl, int ind)

returnere * fl;

int main ()

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

Outputtet er 2.5

Bemærk brugen og placeringen af ​​* for float-parameteren i funktionssignaturen. Så snart evalueringen af ​​fn () -funktionen starter, fremsættes følgende erklæring:

flyde * fl = & v;

Både fl og & v peger på den samme spidse genstand, der holder 2.5. * fl ved returopgørelsen er ikke en erklæring; det betyder værdien af ​​det spidse objekt, som pegerobjektet peger på.

Videregive en henvisning til en funktion

I det følgende program sendes en reference som et argument til funktionen:

#omfatte
ved hjælp af namespace std;
float fn (float & fl, int in)

returnere fl;

int main ()

flyde v = 2.5;
flydeval = fn (v, 6);
cout << val << '\n';
returnere 0;

Outputtet er 2.5

Bemærk brugen og placeringen af ​​& for float-parameteren i funktionssignaturen. Så snart evalueringen af ​​fn () -funktionen starter, fremsættes følgende erklæring:

flyde & fl = v;

Videregive en matrix til en funktion

Følgende program viser, hvordan man overfører en matrix til en funktion:

#omfatte
ved hjælp af namespace std;
int fn (int arra [])

returnere arra [2];

int main ()

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

Outputtet er 200.

I dette program er det arrayet, der sendes. Bemærk, at parameteren for funktionssignaturen har en tom matrixerklæring. Argumentet i funktionsopkaldet er kun navnet på et oprettet array.

Kan en C ++ - funktion returnere en matrix?

En funktion i C ++ kan returnere værdien af ​​et array, men kan ikke returnere arrayet. Kompilering af følgende program resulterer i en fejlmeddelelse:

#omfatte
ved hjælp af namespace std;
int fn (int arra [])

returnere arra;

int main ()

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

Markør af en markør

En markør kan pege på en anden markør. Det vil sige, et markørobjekt kan have adressen på et andet markørobjekt. De skal stadig alle være af samme type. Følgende kodesegment illustrerer dette:

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

Outputtet er 5.

I erklæringen om pointer-til-pointer bruges dobbelt *. For at returnere værdien af ​​det sidste spidse objekt bruges dobbelt * stadig.

Array of Pointers

Følgende program viser, hvordan man koder en række markører:

#omfatte
ved hjælp af namespace 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';
returnere 0;

Outputtet er:

400

Bemærk brugen og placeringen af ​​* i matrixens erklæring. Bemærk brugen af ​​*, når du returnerer en værdi i arrayet. Med henvisninger til henvisninger er to * involveret. I tilfældet med en række markører er en * allerede taget hånd om, fordi matrixidentifikatoren er en markør.

Array af strenge med variabel længde

En streng bogstavelig er en konstant, der returnerer en markør. En række strenge med variabel længde er en række markører. Hver værdi i arrayet er en markør. Markører er adresser til hukommelsesplaceringer og har samme størrelse. Strengene med forskellige længder findes andre steder i hukommelsen, ikke i arrayet. Følgende program illustrerer brugen:

#omfatte
ved hjælp af namespace std;
int main ()

const char * arr [] = "kvinde", "dreng", "pige", "voksen";
cout << arr[2] << '\n';
returnere 0;

Output er "pige".

Erklæringen af ​​arrayet begynder med det reserverede ord "const" for konstant; efterfulgt af "char" for tegnet, derefter stjernen, * for at angive, at hvert element er en markør. For at returnere en streng fra arrayet bruges * ikke på grund af den implicitte karakter af markøren for hver streng. Hvis * bruges, returneres det første element i strengen.

Markør til en funktion, der returnerer en markør

Følgende program illustrerer, hvordan en markør til en funktion, der returnerer en markør, er kodet:

#omfatte
ved hjælp af namespace std;
int * fn ()

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

int main ()

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

Outputtet er 4.

Erklæringen om en markør til en funktion, der returnerer en markør, svarer til erklæringen om en markør til en almindelig funktion, men forud for en stjerne. Den første sætning i hovedfunktionen () illustrerer dette. For at ringe til funktionen ved hjælp af markøren skal du foran *.

Konklusion

For at oprette en markør til en skalar skal du gøre noget lignende,

flyde spids;
flyde * pointer = &pointed;

* har to betydninger: i en erklæring angiver det en markør; for at returnere noget, er det for værdien af ​​det spidse objekt.

Arraynavnet er en konstant markør til det første element i arrayet.

For at oprette en markør til en funktion kan du gøre,

int (* func) () = &fn;

hvor fn () er en funktion defineret andetsteds, og func er markøren.

& har to betydninger: i en erklæring angiver det en henvisning (synonym) til det samme objekt som en anden identifikator; når du returnerer noget, betyder det adressen til.

For at oprette en henvisning til en funktion kan du gøre,

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

hvor fn () er en funktion defineret andetsteds og refFunc er referencen.

Når en funktion returnerer en markør, skal den returnerede værdi modtages af en markør. Når en funktion returnerer en reference, skal den returnerede værdi modtages af en reference.

Når du sender en markør til en funktion, er parameteren en erklæring, mens argumentet er adressen på et spids objekt. Når du sender en henvisning til en funktion, er parameteren en erklæring, mens argumentet er referencen.

Når en matrix overføres til en funktion, er parameteren en erklæring, mens argumentet er arraynavnet uden []. C ++ - funktionen returnerer ikke en matrix.

En markør til markør har brug for to * i stedet for en, hvor det er relevant.

Chrys

Sådan installeres og afspilles Doom på Linux
Introduktion til undergang Doom-serien opstod i 90'erne efter frigivelsen af ​​den originale Doom. Det var et øjeblikkeligt hit, og fra den tid af har...
Vulkan til Linux-brugere
Med hver nye generation af grafikkort ser vi spiludviklere skubbe grænserne for grafisk troskab og komme et skridt tættere på fotorealisme. Men på tro...
OpenTTD vs Simutrans
Oprettelse af din egen transportsimulering kan være sjovt, afslappende og ekstremt lokkende. Derfor skal du sørge for at prøve så mange spil som mulig...