C++

C++-aanwijzers gebruiken

C++-aanwijzers gebruiken
Het geheugen van een computer is een lange reeks cellen. De grootte van elke cel wordt een byte genoemd. Een byte is een spatie die wordt ingenomen door een Engels karakter van het alfabet. Een object in de gewone zin is een opeenvolgende reeks bytes in het geheugen. Elke cel heeft een adres, dat een geheel getal is, meestal geschreven in hexadecimale vorm. Er zijn drie manieren om toegang te krijgen tot een object in het geheugen. Een object kan worden benaderd met behulp van een zogenaamde pointer. Het kan worden geopend met behulp van wat bekend staat als een referentie. Het is nog steeds toegankelijk met een ID. De focus van dit artikel ligt op het gebruik van pointers en referenties. In C++ is er het puntige object en het aanwijzerobject. Het puntige object heeft het object van belang. Het aanwijzerobject heeft het adres van het puntige object.

U moet basiskennis hebben van C++, inclusief de identifiers, functies en arrays; om dit artikel te begrijpen.

Het aanwijzerobject en het puntige object, elk heeft zijn identifier.

Het adres van de operator, &

Dit is een unaire operator. Wanneer gevolgd door een identifier, retourneert het het adres van het object van de identifier. Denk aan de volgende verklaring:

int ptdInt;

Hieronder vindt u de code, de volgende uitdrukking, die het adres retourneert dat wordt geïdentificeerd door ptdInt:

&ptdInt

U hoeft het exacte adres (nummer) niet te weten terwijl u codeert.

De Indirectie Operator, *

Dit is een unaire operator in de context van pointers. Het wordt meestal voor een identifier getypt. Indien gebruikt in een verklaring van de identifier, dan is de identifier het pointer-object dat alleen het adres van het puntige object bevat. Als het wordt gebruikt voor de aanwijzerobject-ID, om iets terug te geven, dan is het geretourneerde ding de waarde van het puntige object.

Een aanwijzer maken

Bekijk het volgende codesegment:

float ptdFloat;
zweven *ptrFloat;
ptrVoet = &ptdFloat;

Het segment begint met de verklaring van het puntige object, ptdFloat. ptdFloat is een identifier, die alleen een float-object identificeert. Er zou een echt object (waarde) aan kunnen zijn toegewezen, maar in dit geval is er niets aan toegewezen. Vervolgens in het segment is er de verklaring van het aanwijzerobject. De indirectie-operator voor deze identifier betekent dat het het adres van een puntig object moet bevatten. Het objecttype, float aan het begin van de instructie, betekent dat het puntige object een float is. Het aanwijzerobject is altijd van hetzelfde type als het puntige object. ptrFoat is een identifier, die alleen een pointer-object identificeert.

In de laatste instructie van de code wordt het adres van het puntige object toegewezen aan het aanwijzerobject. Let op het gebruik van het adres-van-operator, &.

De laatste instructie (regel) hierboven laat zien dat na het declareren van het aanwijzerobject zonder initialisatie, u de indirecte-operator niet nodig hebt, wanneer u het moet initialiseren. In feite is het een syntaxisfout om de indirecte-operator in de derde (laatste) regel te gebruiken.

Het pointer-object kan als volgt worden gedeclareerd en geïnitialiseerd door het puntige object in één instructie:

float ptdFloat;
zweven *ptrFoat = &ptdFloat;

De eerste regel van het vorige codesegment en deze zijn hetzelfde. De tweede en derde regel van het vorige codesegment zijn hier gecombineerd tot één statement.

Merk op in de bovenstaande code dat bij het declareren en initialiseren van het pointer-object, de indirectie-operator moet worden gebruikt. Het wordt echter niet gebruikt als de initialisatie achteraf moet worden uitgevoerd. Het aanwijzerobject wordt geïnitialiseerd met het adres van het puntige object.

In het volgende codesegment wordt de indirectie-operator gebruikt om de inhoud van het puntige object te retourneren.

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

De uitvoer is 5.

In de laatste instructie hier is de indirectie-operator gebruikt om de waarde te retourneren waarnaar wordt verwezen door de aanwijzer-ID. Dus, wanneer gebruikt in een aangifte, zou de identifier voor de indirectie-operator het adres van het puntige object bevatten. Bij gebruik in een return-expressie, in combinatie met de pointer-ID, retourneert de indirection-operator de waarde van het puntige object.

Nul toewijzen aan een aanwijzer

Het aanwijzerobject moet altijd het type van het puntige object hebben. Bij het declareren van het aanwijzerobject moet het gegevenstype van het puntige object worden gebruikt. De waarde van de decimale nul kan echter worden toegewezen aan de aanwijzer zoals in het volgende codesegment:

int ptdInt = 5;
int *ptrInt;
ptrInt = 0;
of in het segment,
int ptdInt = 5;
int *ptrInt = 0;

In beide gevallen wordt de aanwijzer (identifier) ​​de nulaanwijzer genoemd; wat betekent dat het nergens naar wijst. Dat wil zeggen, het heeft niet het adres van een puntig object. Hier is 0 decimaal nul en niet hexadecimaal nul. Hexadecimale nul zou verwijzen naar het eerste adres van het computergeheugen.

Probeer niet de waarde te verkrijgen waarnaar wordt verwezen door een null-pointer. Als u dat probeert, kan het programma compileren, maar niet uitvoeren.

Matrixnaam als constante aanwijzer

Beschouw de volgende array:

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

De naam van de array, arr is eigenlijk de identifier die het adres heeft van het eerste element van de array. De volgende expressie retourneert de eerste waarde in de array:

*arr

Met de array gedraagt ​​​​de increment-operator ++ zich anders. In plaats van 1, wordt het adres van de aanwijzer vervangen door het adres van het volgende element in de array element. De naam van de array is echter een constante aanwijzer; wat betekent dat de inhoud (adres) niet kan worden gewijzigd of verhoogd. Dus, om te verhogen, moet het startadres van de array als volgt worden toegewezen aan een niet-constante pointer:

int *ptr = arr;

Nu kan ptr worden verhoogd om naar het volgende element van de array te wijzen. ptr is hier gedeclareerd als een pointer-object. Zonder * hier zou het geen pointer zijn; het zou een identifier zijn om een ​​int-object vast te houden en niet om een ​​geheugenadres vast te houden.

Het volgende codesegment verwijst uiteindelijk naar het vierde element:

++pnt;
++pnt;
++pnt;

De volgende code voert de vierde waarde van de array uit:

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

De uitvoer is 300.

Functienaam als identificatie

De naam van een functie is de identifier van de functie. Beschouw de volgende functiedefinitie:

int fn()

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

fn is de identifier van de functie. De uitdrukking,

&fn

geeft het adres van de functie in het geheugen terug. fn is als het puntige object. De volgende declaratie declareert een pointer naar een functie:

int (*func)();

De identifier voor het puntige object en de identifier voor het pointer-object is verschillend. func is een aanwijzer naar een functie. fn is de identifier van een functie. En dus kan func als volgt naar fn wijzen:

func = &fn;

De waarde (inhoud) van func is het adres van fn. De twee identifiers kunnen als volgt zijn gekoppeld aan een initialisatie-instructie:

int (*func)() = &fn;

Let op de verschillen en overeenkomsten in het omgaan met functieaanwijzers en scalaire aanwijzers. func is een pointer naar een functie; het is het puntige object; het wordt anders gedeclareerd dan een scalaire aanwijzer.

De functie kan worden aangeroepen met,

fn()
of
func()

Het kan niet worden aangeroepen met *func().

Als de functie parameters heeft, hebben de tweede haakjes de typen parameters en hoeven ze niet de identifiers voor de parameters te hebben. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
float fn(float fl, int in)

retour fl;

int hoofd()

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

De uitvoer is 2.5.

C++-referentie

Verwijzen in C++ is slechts een manier om een ​​synoniem (een andere naam) voor een identifier te produceren. Het gebruikt de operator &, maar niet op dezelfde manier als & wordt gebruikt voor aanwijzers. Overweeg het volgende codesegment:

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

De uitvoer is:

8
8

De eerste instructie initialiseert de identifier, myInt; ik.e. myInt wordt gedeclareerd en gemaakt om de waarde 8 . te behouden. De tweede instructie maakt een nieuwe identifier, yourInt een synoniem voor myInt. Om dit te bereiken, wordt de operator & tussen het gegevenstype en de nieuwe identifier in de aangifte geplaatst. De cout-statements laten zien dat de twee identifiers synoniemen zijn. Om de waarde in dit geval te retourneren, hoeft u deze niet vooraf te laten gaan door * . Gebruik gewoon de identifier.

myInt en yourInt hier zijn geen twee verschillende objecten. Het zijn twee verschillende identifiers die verwijzen (identificeren) naar dezelfde locatie in het geheugen met de waarde 8. Als de waarde van myInt wordt gewijzigd, verandert de waarde van yourInt ook automatisch. Als de waarde van yourInt wordt gewijzigd, verandert de waarde van myInt ook automatisch.

Referenties zijn van hetzelfde type.

Verwijzing naar een functie

Net zoals u een verwijzing naar een scalaire waarde kunt hebben, kunt u ook een verwijzing naar een functie hebben. Het coderen van een verwijzing naar een functie is echter anders dan het coderen van een verwijzing naar een scalar. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
float fn(float fl, int in)

retour fl;

int hoofd()

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

De uitvoer is 2.5.

Let op de eerste instructie in de hoofdfunctie, waardoor func een synoniem is van fn. Beide verwijzen naar dezelfde functie. Let op het eenmalig gebruik en de positie van &. Dus & is hier de referentie-operator en niet de adres-van-operator. Gebruik gewoon een van beide namen om de functie aan te roepen.

Een referentie-ID is niet hetzelfde als een pointer-ID.

Functie die een aanwijzer retourneert

In het volgende programma retourneert de functie een pointer, dit is het adres van het puntige object:

#include
namespace std; gebruiken;
float *fn(float fl, int in)

zweven *fll = &fl;
retour fll;

int hoofd()

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

De uitvoer is 2.5

De eerste instructie in de functie, fn() is er alleen om een ​​pointer-object te maken. Let op het eenmalige gebruik en de positie van * in de functiehandtekening. Merk ook op hoe de aanwijzer (adres), werd ontvangen in de functie main() door een ander aanwijzerobject.

Functie die een referentie retourneert

In het volgende programma retourneert de functie een referentie:

#include
namespace std; gebruiken;
float &fn(float fl, int in)

zweven &frr = fl;
retour vr;

int hoofd()

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

De uitvoer is 2.5.

Het eerste statement in de functie, fn() is er alleen om een ​​referentie te maken. Let op het eenmalige gebruik en de positie van & in de functiehandtekening. Merk ook op hoe de referentie werd ontvangen in de functie main() door een andere referentie.

Een aanwijzer naar een functie doorgeven

In het volgende programma wordt een pointer, die eigenlijk het adres is van een zwevend puntig object, als argument naar de functie gestuurd:

#include
namespace std; gebruiken;
float fn(float *fl, int in)

retour *fl;

int hoofd()

zweven v = 2.5;
vlotterwaarde = fn(&v, 6);
cout << val << '\n';
retourneer 0;

De uitvoer is 2.5

Let op het gebruik en de positie van * voor de float-parameter in de functiehandtekening. Zodra de evaluatie van de functie fn() start, wordt het volgende statement gemaakt:

zweven *fl = &v;

Zowel fl als &v wijzen naar hetzelfde puntige object dat 2 . bevat.5. *fl bij de aangifte is geen aangifte; het betekent, de waarde van het puntige object waarnaar wordt verwezen door het aanwijzerobject.

Een verwijzing naar een functie doorgeven

In het volgende programma wordt een verwijzing als argument naar de functie gestuurd:

#include
namespace std; gebruiken;
float fn(float &fl, int in)

retour fl;

int hoofd()

zweven v = 2.5;
vlotterwaarde = fn(v, 6);
cout << val << '\n';
retourneer 0;

De uitvoer is 2.5

Let op het gebruik en de positie van & voor de float-parameter in de functiehandtekening. Zodra de evaluatie van de functie fn() start, wordt het volgende statement gemaakt:

zweven &fl = v;

Een array doorgeven aan een functie

Het volgende programma laat zien hoe je een array doorgeeft aan een functie:

#include
namespace std; gebruiken;
int fn(int arra[])

retourneer [2];

int hoofd()

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

De uitvoer is 200.

In dit programma is het de array die wordt doorgegeven. Merk op dat de parameter van de functiehandtekening een lege arraydeclaratie heeft. Het argument in de functieaanroep is alleen de naam van een gemaakte array.

Kan een C++-functie een array retourneren??

Een functie in C++ kan de waarde van een array retourneren, maar kan de array niet retourneren. Het compileren van het volgende programma resulteert in een foutmelding:

#include
namespace std; gebruiken;
int fn(int arra[])

retourzending;

int hoofd()

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

Aanwijzer van een aanwijzer

Een aanwijzer kan naar een andere aanwijzer wijzen. Dat wil zeggen, een pointer-object kan het adres hebben van een ander pointer-object. Ze moeten toch allemaal van hetzelfde type zijn. Het volgende codesegment illustreert dit:

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

De uitvoer is 5.

In de declaratie van pointer-to-pointer wordt dubbel * gebruikt. Om de waarde van het laatste puntige object terug te geven, wordt nog steeds dubbel * gebruikt.

Reeks aanwijzers

Het volgende programma laat zien hoe je een array van pointers codeert:

#include
namespace std; gebruiken;
int hoofd()

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';
retourneer 0;

De uitvoer is:

400

Let op het gebruik en de positie van * in de declaratie van de array. Let op het gebruik van * bij het retourneren van een waarde in de array. Bij pointers of pointers zijn er twee * betrokken. In het geval van een array van pointers is er al voor één * gezorgd, omdat de array-ID een pointer is.

Reeks snaren met variabele lengte

Een letterlijke tekenreeks is een constante die een aanwijzer retourneert. Een array van strings met variabele lengte is een array van pointers. Elke waarde in de array is een pointer. Pointers zijn adressen naar geheugenlocaties en hebben dezelfde grootte. De strings van de verschillende lengtes bevinden zich elders in het geheugen, niet in de array. Het volgende programma illustreert het gebruik:

#include
namespace std; gebruiken;
int hoofd()

const char *arr[] = "vrouw", "jongen", "meisje", "volwassene";
cout << arr[2] << '\n';
retourneer 0;

De uitvoer is "meisje".

De declaratie van de array begint met het gereserveerde woord "const" voor constant; gevolgd door "char" voor het teken, dan de asterisk, * om aan te geven dat elk element een aanwijzer is. Om een ​​tekenreeks uit de array te retourneren, wordt * niet gebruikt, vanwege de impliciete aard van de aanwijzer van elke tekenreeks. Als * wordt gebruikt, wordt het eerste element van de tekenreeks geretourneerd.

Pointer naar een functie die een pointer retourneert

Het volgende programma laat zien hoe een aanwijzer naar een functie die een aanwijzer retourneert, wordt gecodeerd:

#include
namespace std; gebruiken;
int *fn()

int aantal = 4;
int *inter = #
retour tussen;

int hoofd()

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

De uitvoer is 4.

De declaratie van een pointer naar een functie die een pointer retourneert is vergelijkbaar met de declaratie van een pointer naar een gewone functie, maar wordt voorafgegaan door een asterisk. De eerste instructie in de functie main() illustreert dit:. Om de functie aan te roepen met de aanwijzer, laat u deze voorafgaan door *.

Conclusie

Om een ​​aanwijzer naar een scalaire waarde te maken, doe je zoiets als,

vlotter puntig;
zweven *pointer = &pointed;

* heeft twee betekenissen: in een declaratie geeft het een pointer aan; om iets terug te geven, het is voor de waarde van het puntige object.

De arraynaam is een constante aanwijzer naar het eerste element van de array.

Om een ​​aanwijzer naar een functie te maken, kunt u het volgende doen:,

int (*func)() = &fn;

waarbij fn() een functie is die elders is gedefinieerd en func de aanwijzer is.

& heeft twee betekenissen: in een declaratie geeft het een verwijzing (synoniem) aan naar hetzelfde object als een andere identifier; als je iets retourneert, betekent dit het adres van.

Om een ​​verwijzing naar een functie te maken, kunt u het volgende doen:,

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

waarbij fn() een functie is die elders is gedefinieerd en refFunc de referentie is.

Wanneer een functie een pointer retourneert, moet de geretourneerde waarde worden ontvangen door een pointer. Wanneer een functie een referentie retourneert, moet de geretourneerde waarde worden ontvangen door een referentie.

Bij het doorgeven van een aanwijzer naar een functie is de parameter een declaratie, terwijl het argument het adres is van een puntig object. Bij het doorgeven van een verwijzing naar een functie is de parameter een declaratie, terwijl het argument de verwijzing is.

Bij het doorgeven van een array aan een functie is de parameter een declaratie terwijl het argument de arraynaam is zonder []. De C++-functie retourneert geen array.

Een pointer-to-pointer heeft twee * nodig in plaats van één, indien van toepassing.

Chrys

Hoe de muisaanwijzer en cursorgrootte, kleur en schema op Windows 10 te veranderen
De muisaanwijzer en cursor in Windows 10 zijn zeer belangrijke aspecten van het besturingssysteem. Dit geldt ook voor andere besturingssystemen, dus i...
Gratis en open source game-engines voor het ontwikkelen van Linux-games
Dit artikel behandelt een lijst met gratis en open source game-engines die kunnen worden gebruikt voor het ontwikkelen van 2D- en 3D-games op Linux. E...
Shadow of the Tomb Raider voor Linux-zelfstudie
Shadow of the Tomb Raider is de twaalfde toevoeging aan de Tomb Raider-serie - een actie-avonturengame-franchise gemaakt door Eidos Montreal. De game ...