logo

C++-aanwijzers

Pointers zijn symbolische representaties van adressen. Ze stellen programma's in staat call-by-reference te simuleren en dynamische datastructuren te creëren en te manipuleren. Het herhalen van elementen in arrays of andere datastructuren is een van de belangrijkste toepassingen van pointers.

Het adres van de variabele waarmee u werkt, wordt toegewezen aan de pointervariabele die naar hetzelfde gegevenstype verwijst (zoals een int of string).

Java instellen

Syntaxis:



datatype *var_name; int *ptr; // ptr can point to an address which holds int data>
Hoe aanwijzer werkt in C++

Hoe gebruik je een aanwijzer?

  • Definieer een pointervariabele
  • Het adres van een variabele aan een pointer toewijzen met behulp van de unaire operator (&) die het adres van die variabele retourneert.
  • Toegang krijgen tot de waarde die is opgeslagen in het adres met behulp van de unaire operator (*) die de waarde retourneert van de variabele die zich bevindt op het adres dat is opgegeven door de operand.

De reden dat we gegevenstype associëren met een pointer is dat het weet in hoeveel bytes de gegevens zijn opgeslagen . Wanneer we een pointer verhogen, vergroten we de pointer met de grootte van het gegevenstype waarnaar deze verwijst.

Aanwijzers in C++C++
// C++ program to illustrate Pointers #include  using namespace std; void geeks() {  int var = 20;  // declare pointer variable  int* ptr;  // note that data type of ptr and var must be same  ptr = &var;  // assign the address of a variable to a pointer  cout << 'Value at ptr = ' << ptr << '
';  cout << 'Value at var = ' << var << '
';  cout << 'Value at *ptr = ' << *ptr << '
'; } // Driver program int main()  {   geeks();   return 0; }>

Uitvoer
Value at ptr = 0x7ffe454c08cc Value at var = 20 Value at *ptr = 20>

Referenties en aanwijzingen

Er zijn 3 manieren om C++-argumenten aan een functie door te geven:

  • Call-by-waarde
  • Call-By-Reference met een pointer-argument
  • Call-By-Reference met een referentieargument
C++
// C++ program to illustrate call-by-methods #include  using namespace std; // Pass-by-Value int square1(int n) {  // Address of n in square1() is not the same as n1 in  // main()  cout << 'address of n1 in square1(): ' << &n << '
';  // clone modified inside the function  n *= n;  return n; } // Pass-by-Reference with Pointer Arguments void square2(int* n) {  // Address of n in square2() is the same as n2 in main()  cout << 'address of n2 in square2(): ' << n << '
';  // Explicit de-referencing to get the value pointed-to  *n *= *n; } // Pass-by-Reference with Reference Arguments void square3(int& n) {  // Address of n in square3() is the same as n3 in main()  cout << 'address of n3 in square3(): ' << &n << '
';  // Implicit de-referencing (without '*')  n *= n; } void geeks() {  // Call-by-Value  int n1 = 8;  cout << 'address of n1 in main(): ' << &n1 << '
';  cout << 'Square of n1: ' << square1(n1) << '
';  cout << 'No change in n1: ' << n1 << '
';  // Call-by-Reference with Pointer Arguments  int n2 = 8;  cout << 'address of n2 in main(): ' << &n2 << '
';  square2(&n2);  cout << 'Square of n2: ' << n2 << '
';  cout << 'Change reflected in n2: ' << n2 << '
';  // Call-by-Reference with Reference Arguments  int n3 = 8;  cout << 'address of n3 in main(): ' << &n3 << '
';  square3(n3);  cout << 'Square of n3: ' << n3 << '
';  cout << 'Change reflected in n3: ' << n3 << '
'; } // Driver program int main() { geeks(); }>

Uitvoer
address of n1 in main(): 0x7fffa7e2de64 address of n1 in square1(): 0x7fffa7e2de4c Square of n1: 64 No change in n1: 8 address of n2 in main(): 0x7fffa7e2de68 address of n2 in square2(): 0x7fffa7e2de68 Square of n2: 64 Change reflected in n2: 64 address of n3 in main(): 0x7fffa7e2de6c address of n3 in square3(): 0x7fffa7e2de6c Square of n3: 64 Change reflected in n3: 64>

In C++ worden argumenten standaard per waarde doorgegeven en worden de wijzigingen die in de aangeroepen functie worden aangebracht niet weerspiegeld in de doorgegeven variabele. De wijzigingen worden aangebracht in een kloon gemaakt door de aangeroepen functie. Als we de originele kopie direct willen wijzigen (vooral bij het doorgeven van grote objecten of arrays) en/of de overhead van klonen willen vermijden, gebruiken we pass-by-reference. Pass-by-Reference met referentieargumenten vereist geen onhandige syntaxis voor het verwijzen en derefereren.

Arraynaam als aanwijzers

Een reeks naam bevat het adres van het eerste element van de array dat als een constante pointer fungeert. Dit betekent dat het adres dat is opgeslagen in de arraynaam niet kan worden gewijzigd. Als we bijvoorbeeld een array met de naam val hebben, dan val En &val[0] kunnen door elkaar gebruikt worden.

C++
// C++ program to illustrate Array Name as Pointers #include  using namespace std; void geeks() {  // Declare an array  int val[3] = { 5, 10, 20 };  // declare pointer variable  int* ptr;  // Assign the address of val[0] to ptr  // We can use ptr=&val[0];(both are same)  ptr = val;  cout << 'Elements of the array are: ';  cout << ptr[0] << ' ' << ptr[1] << ' ' << ptr[2]; } // Driver program int main() { geeks(); }>

Uitvoer
Elements of the array are: 5 10 20>
Weergave van gegevens in het geheugen

Als pointer ptr als argument naar een functie wordt gestuurd, kan de array val op een vergelijkbare manier worden benaderd. Aanwijzer versus array

Pointer-expressies en pointer-berekeningen

Een beperkte set rekenkundig bewerkingen kunnen worden uitgevoerd op pointers die:

java-bestand openen
  • verhoogd (++)
  • verlaagd ( — )
  • een geheel getal kan aan een pointer worden toegevoegd (+ of += )
  • een geheel getal kan worden afgetrokken van een aanwijzer ( – of -= )
  • verschil tussen twee wijzers (p1-p2)

( Opmerking: Pointer-berekeningen zijn zinloos, tenzij ze op een array worden uitgevoerd.)

C++
// C++ program to illustrate Pointer Arithmetic #include  using namespace std; void geeks() {  // Declare an array  int v[3] = { 10, 100, 200 };  // declare pointer variable  int* ptr;  // Assign the address of v[0] to ptr  ptr = v;  for (int i = 0; i < 3; i++) {  cout << 'Value at ptr = ' << ptr << '
';  cout << 'Value at *ptr = ' << *ptr << '
';  // Increment pointer ptr by 1  ptr++;  } } // Driver program int main() { geeks(); }>

Uitvoer
Value at ptr = 0x7ffe5a2d8060 Value at *ptr = 10 Value at ptr = 0x7ffe5a2d8064 Value at *ptr = 100 Value at ptr = 0x7ffe5a2d8068 Value at *ptr = 200>
Weergave van gegevens in het geheugen

Geavanceerde aanwijzernotatie

Overweeg pointernotatie voor de tweedimensionale numerieke arrays. denk aan de volgende verklaring

int nums[2][3] = { { 16, 18, 20 }, { 25, 26, 27 } };>

Over het algemeen is nums[ i ][ j ] gelijk aan *(*(nums+i)+j)

Aanwijzernotatie in C++

Aanwijzers en letterlijke tekenreeksen

Letterlijke tekenreeksen zijn arrays die op nul eindigende tekenreeksen bevatten. Letterlijke tekenreeksen zijn arrays van het type karakter plus het afsluitende nul-teken, waarbij elk van de elementen van het type const char is (aangezien de karakters van de string niet kunnen worden gewijzigd).

>

Dit declareert een array met de letterlijke weergave voor geek, en vervolgens wordt een verwijzing naar het eerste element toegewezen aan ptr. Als we ons voorstellen dat nerd is opgeslagen op de geheugenlocaties die beginnen op adres 1800, kunnen we de vorige declaratie als volgt weergeven:

Aanwijzers en letterlijke tekenreeksen

Omdat pointers en arrays zich in expressies op dezelfde manier gedragen, kan ptr worden gebruikt om toegang te krijgen tot de tekens van een letterlijke tekenreeks. Bijvoorbeeld:

char ptr = 0; char x = *(ptr+3); char y = ptr[3];>

Hier bevatten zowel x als y k opgeslagen in 1803 (1800+3).

wat maakt een pc snel

Verwijzingen naar verwijzingen

In C++ kunnen we een pointer naar een pointer maken die op zijn beurt naar gegevens of een andere pointer kan verwijzen. De syntaxis vereist eenvoudigweg de unaire operator (*) voor elk indirectieniveau bij het declareren van de aanwijzer.

char a; char *b; char ** c; a = ’g’; b = &a; c = &b;>

Hier wijst b naar een char waarin ‘g’ is opgeslagen en c wijst naar de aanwijzer b.

Ongeldige wijzers

Dit is een speciaal type pointer dat beschikbaar is in C++ en dat de afwezigheid van type vertegenwoordigt. Ongeldige aanwijzingen zijn verwijzingen die verwijzen naar een waarde die geen type heeft (en dus ook een onbepaalde lengte en onbepaalde dereferentie-eigenschappen). Dit betekent dat void pointers een grote flexibiliteit hebben, omdat ze naar elk gegevenstype kunnen verwijzen. Er is een beloning voor deze flexibiliteit. Er kan niet rechtstreeks naar deze verwijzingen worden verwezen. Ze moeten eerst worden omgezet in een ander pointertype dat naar een concreet gegevenstype verwijst voordat er dereferentie van wordt gemaakt.

C++
// C++ program to illustrate Void Pointer #include  using namespace std; void increase(void* data, int ptrsize) {  if (ptrsize == sizeof(char)) {  char* ptrchar;  // Typecast data to a char pointer  ptrchar = (char*)data;  // Increase the char stored at *ptrchar by 1  (*ptrchar)++;  cout << '*data points to a char'  << '
';  }  else if (ptrsize == sizeof(int)) {  int* ptrint;  // Typecast data to a int pointer  ptrint = (int*)data;  // Increase the int stored at *ptrchar by 1  (*ptrint)++;  cout << '*data points to an int'  << '
';  } } void geek() {  // Declare a character  char c = 'x';  // Declare an integer  int i = 10;  // Call increase function using a char and int address  // respectively  increase(&c, sizeof(c));  cout << 'The new value of c is: ' << c << '
';  increase(&i, sizeof(i));  cout << 'The new value of i is: ' << i << '
'; } // Driver program int main() { geek(); }>

Uitvoer
*data points to a char The new value of c is: y *data points to an int The new value of i is: 11>

Ongeldige aanwijzingen

Een pointer moet naar een geldig adres verwijzen, maar niet noodzakelijkerwijs naar geldige elementen (zoals bij arrays). Dit worden ongeldige verwijzingen genoemd. Niet-geïnitialiseerde pointers zijn ook ongeldige pointers.

int *ptr1; int arr[10]; int *ptr2 = arr+20;>

Hier is ptr1 niet geïnitialiseerd, dus het wordt een ongeldige pointer en ptr2 ligt buiten de grenzen van arr, dus het wordt ook een ongeldige pointer. (Opmerking: ongeldige verwijzingen veroorzaken niet noodzakelijkerwijs compileerfouten)

generiekheid in Java

NULL-aanwijzers

A nul punten is een aanwijzer die nergens naar verwijst en niet alleen naar een ongeldig adres. Hieronder volgen twee methoden om een ​​pointer als NULL toe te wijzen;

int *ptr1 = 0; int *ptr2 = NULL;>

Voordelen van Wijzers

  • Pointers verminderen de code en verbeteren de prestaties. Ze worden gebruikt om strings, bomen, arrays, structuren en functies op te halen.
  • Met pointers kunnen we meerdere waarden uit functies retourneren.
  • Daarnaast geven pointers ons toegang tot een geheugenlocatie in het geheugen van de computer.

Gerelateerde artikelen:

  • Ondoorzichtige aanwijzer
  • Dichtbij, veraf en grote wijzers

Quizzen:

  • Basisprincipes van aanwijzer
  • Geavanceerde aanwijzer