logo

Indicatori C++

Pointerii sunt reprezentări simbolice ale adreselor. Acestea permit programelor să simuleze apelul prin referință, precum și să creeze și să manipuleze structuri dinamice de date. Iterarea peste elemente din matrice sau alte structuri de date este una dintre principalele utilizări ale pointerilor.

Adresa variabilei cu care lucrați este atribuită variabilei pointer care indică același tip de date (cum ar fi un int sau șir).

hopa

Sintaxă:



datatype *var_name; int *ptr; // ptr can point to an address which holds int data>
Cum funcționează pointerul în C++

Cum se folosește un pointer?

  • Definiți o variabilă pointer
  • Atribuirea adresei unei variabile unui pointer folosind operatorul unar (&) care returnează adresa acelei variabile.
  • Accesarea valorii stocate în adresă utilizând operatorul unar (*) care returnează valoarea variabilei situate la adresa specificată de operandul acesteia.

Motivul pentru care asociem tipul de date cu un pointer este că știe în câți octeți sunt stocate datele . Când incrementăm un pointer, creștem indicatorul cu dimensiunea tipului de date către care indică.

Pointeri în 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; }>

Ieșire
Value at ptr = 0x7ffe454c08cc Value at var = 20 Value at *ptr = 20>

Referințe și indicatori

Există 3 moduri de a transmite argumente C++ unei funcții:

  • Apel după valoare
  • Apel prin referință cu un argument pointer
  • Apel prin referință cu un argument de referință
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(); }>

Ieșire
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>

În C++, implicit argumentele sunt transmise după valoare, iar modificările făcute în funcția apelată nu se vor reflecta în variabila transmisă. Modificările sunt făcute într-o clonă făcută de funcția apelată. Dacă doriți să modificați copia originală în mod direct (mai ales prin trecerea unui obiect sau a unei matrice uriașe) și/sau a evita suprasolicitarea clonării, folosim trecerea la referință. Pass-by-Reference cu argumente de referință nu necesită nicio sintaxă stângace pentru referire și dereferentare.

Numele matricei ca pointeri

Un matrice name conține adresa primului element al matricei care acționează ca un pointer constant. Înseamnă că adresa stocată în numele matricei nu poate fi schimbată. De exemplu, dacă avem o matrice numită val, atunci val și &val[0] poate fi folosit interschimbabil.

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(); }>

Ieșire
Elements of the array are: 5 10 20>
Reprezentarea datelor în memorie

Dacă pointerul ptr este trimis la o funcție ca argument, matricea val poate fi accesată într-un mod similar. Pointer vs Array

Expresii pointer și aritmetică pointer

Un set limitat de aritmetic operațiunile pot fi efectuate pe pointeri care sunt:

  • incrementat (++)
  • decrementat ( — )
  • un număr întreg poate fi adăugat la un indicator ( + sau += )
  • un număr întreg poate fi scăzut dintr-un indicator ( – sau -=)
  • diferența dintre două indicatori (p1-p2)

( Notă: Aritmetica pointerului este lipsită de sens dacă nu este efectuată pe o matrice.)

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(); }>

Ieșire
Value at ptr = 0x7ffe5a2d8060 Value at *ptr = 10 Value at ptr = 0x7ffe5a2d8064 Value at *ptr = 100 Value at ptr = 0x7ffe5a2d8068 Value at *ptr = 200>
Reprezentarea datelor în memorie

Notație avansată cu indicator

Luați în considerare notația pointer pentru tablourile numerice bidimensionale. luați în considerare următoarea declarație

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

În general, nums[ i ][ j ] este echivalent cu *(*(nums+i)+j)

ce este o interfață
Notație pointer în C++

Indicatori și literali șir

Literale șiruri sunt tablouri care conțin secvențe de caractere terminate cu nul. Literale șiruri sunt matrice de tipul caracter plus caracterul nul de sfârșit, fiecare dintre elemente fiind de tipul const char (deoarece caracterele șirului de caractere nu pot fi modificate).

>

Aceasta declară o matrice cu reprezentarea literală pentru geek, iar apoi un pointer către primul său element este atribuit lui ptr. Dacă ne imaginăm că geek este stocat în locațiile de memorie care încep la adresa 1800, putem reprezenta declarația anterioară ca:

Indicatori și șiruri literale

Deoarece pointerii și matricele se comportă în același mod în expresii, ptr poate fi folosit pentru a accesa caracterele unui șir literal. De exemplu:

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

Aici, atât x, cât și y conțin k stocat la 1803 (1800+3).

fișier .tif

Indicatori către indicatori

În C++, putem crea un pointer către un pointer care, la rândul său, poate indica date sau un alt pointer. Sintaxa necesită pur și simplu operatorul unar (*) pentru fiecare nivel de indirectare în timp ce declară pointerul.

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

Aici b indică un caracter care stochează „g” și c indică indicatorul b.

Indicatori de gol

Acesta este un tip special de pointer disponibil în C++ care reprezintă absența tipului. Indicatoare goale sunt pointeri care indică o valoare care nu are niciun tip (și astfel, de asemenea, o lungime nedeterminată și proprietăți de dereferențiere nedeterminate). Aceasta înseamnă că indicatorii de gol au o mare flexibilitate, deoarece pot indica orice tip de date. Există o recompensă pentru această flexibilitate. Acești indicatori nu pot fi dereferențiați direct. Ele trebuie mai întâi transformate într-un alt tip de indicator care indică un tip de date concret înainte de a fi dereferențiate.

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(); }>

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

Indicatori nevalidi

Un pointer ar trebui să indice către o adresă validă, dar nu neapărat către elemente valide (cum ar fi pentru matrice). Acestea se numesc indicatori invalidi. Pointerii neinițializați sunt, de asemenea, indicatori invalidi.

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

Aici, ptr1 este neinițializat, astfel încât devine un pointer invalid și ptr2 este în afara limitelor arr, așa că devine și un pointer invalid. (Notă: indicatorii nevalidi nu generează neapărat erori de compilare)

Indicatori NULL

A indicator nul este un indicator care nu indică nicăieri și nu doar o adresă invalidă. Următoarele sunt 2 metode de a atribui un pointer ca NULL;

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

Avantajele Pointerilor

  • Pointerii reduc codul și îmbunătățesc performanța. Sunt folosite pentru a prelua șiruri, arbori, matrice, structuri și funcții.
  • Pointerii ne permit să returnăm mai multe valori din funcții.
  • În plus, pointerii ne permit să accesăm o locație de memorie din memoria computerului.

Articole similare:

  • Indicator opac
  • Aproape, departe și uriașe Pointers

Chestionare:

primavara si primavara mvc
  • Noțiuni de bază pentru pointer
  • Indicator avansat