Els punters són representacions simbòliques d'adreces. Permeten que els programes simulin la trucada per referència, així com per crear i manipular estructures de dades dinàmiques. Iterar sobre elements en matrius o altres estructures de dades és un dels principals ús dels punters.
L'adreça de la variable amb la qual esteu treballant s'assigna a la variable punter que apunta al mateix tipus de dades (com ara un int o una cadena).
punt java
Sintaxi:
datatype *var_name; int *ptr; // ptr can point to an address which holds int data>

Com utilitzar un punter?
- Definiu una variable punter
- Assignació de l'adreça d'una variable a un punter mitjançant l'operador unari (&) que retorna l'adreça d'aquesta variable.
- Accedint al valor emmagatzemat a l'adreça mitjançant l'operador unari (*) que retorna el valor de la variable situada a l'adreça especificada pel seu operand.
La raó per la qual associem el tipus de dades amb un punter és que sap quants bytes s'emmagatzemen les dades . Quan incrementem un punter, augmentem el punter per la mida del tipus de dades al qual apunta.

// 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; }>
Sortida
Value at ptr = 0x7ffe454c08cc Value at var = 20 Value at *ptr = 20>
Referències i punters
Hi ha 3 maneres de passar arguments C++ a una funció:
- Trucada per valor
- Crida per referència amb un argument de punter
- Crida per referència amb un argument de referència
// 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(); }>
Sortida
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>
En C++, per defecte els arguments es passen per valor i els canvis fets a la funció cridada no es reflectiran a la variable passada. Els canvis es realitzen en un clon fet per la funció cridada. Si es vol modificar la còpia original directament (especialment en passar un objecte o una matriu enorme) i/o evitar la sobrecàrrega de la clonació, utilitzem el pas per referència. Pass-by-Reference amb arguments de referència no requereix cap sintaxi maldestra per fer referència i desreferenciar.
- Apuntadors de funció en C
- Punter a una funció
Nom de la matriu com a punters
An matriu name conté l'adreça del primer element de la matriu que actua com un punter constant. Vol dir que l'adreça emmagatzemada al nom de la matriu no es pot canviar. Per exemple, si tenim una matriu anomenada val, aleshores val i &val[0] es pot utilitzar indistintament.
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(); }>
Sortida
Elements of the array are: 5 10 20>

Si el punter ptr s'envia a una funció com a argument, es pot accedir a la matriu val d'una manera similar. Punter vs Array
Expressions de punter i aritmètica de punter
Un conjunt limitat de aritmètica es poden realitzar operacions sobre punters que són:
prova catch block a java
- incrementat (++)
- disminuït (—)
- es pot afegir un nombre enter a un punter (+ o +=)
- un nombre enter es pot restar d'un punter (- o -=)
- diferència entre dos punters (p1-p2)
( Nota: L'aritmètica del punter no té sentit tret que es realitzi en una matriu.)
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(); }>
Sortida
Value at ptr = 0x7ffe5a2d8060 Value at *ptr = 10 Value at ptr = 0x7ffe5a2d8064 Value at *ptr = 100 Value at ptr = 0x7ffe5a2d8068 Value at *ptr = 200>

Notació de punter avançada
Considereu la notació de punter per a les matrius numèriques bidimensionals. considerar la següent declaració
int nums[2][3] = { { 16, 18, 20 }, { 25, 26, 27 } };>
En general, nums[ i ][ j ] és equivalent a *(*(nums+i)+j)

Punters i literals de cadena
Els literals de cadena són matrius que contenen seqüències de caràcters terminades en null. Els literals de cadena són matrius de caràcters de tipus més un caràcter nul final, amb cadascun dels elements de tipus const char (ja que els caràcters de la cadena no es poden modificar).
>
Això declara una matriu amb la representació literal de geek, i després s'assigna un punter al seu primer element a ptr. Si imaginem que el geek s'emmagatzema a les ubicacions de memòria que comencen a l'adreça 1800, podem representar la declaració anterior com:
itera el mapa en java

Com que els punters i les matrius es comporten de la mateixa manera en les expressions, ptr es pot utilitzar per accedir als caràcters d'un literal de cadena. Per exemple:
char ptr = 0; char x = *(ptr+3); char y = ptr[3];>
Aquí, tant x com y contenen k emmagatzemat a 1803 (1800+3).
Punters a punters
En C++, podem crear un punter a un punter que al seu torn pot apuntar a dades o un altre punter. La sintaxi simplement requereix l'operador unari (*) per a cada nivell d'indirecció mentre es declara el punter.
char a; char *b; char ** c; a = ’g’; b = &a; c = &b;>
Aquí b apunta a un caràcter que emmagatzema 'g' i c apunta al punter b.
Punters buits
Aquest és un tipus especial de punter disponible en C++ que representa l'absència de tipus. Apunts buits són punters que apunten a un valor que no té cap tipus (i, per tant, també una longitud indeterminada i propietats de desreferenciació indeterminades). Això vol dir que els punters buits tenen una gran flexibilitat, ja que poden apuntar a qualsevol tipus de dades. Hi ha un benefici per aquesta flexibilitat. Aquests indicadors no es poden desreferenciar directament. Primer s'han de transformar en un altre tipus de punter que apunti a un tipus de dades concret abans de ser desreferenciats.
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(); }>
Sortida
*data points to a char The new value of c is: y *data points to an int The new value of i is: 11>
Apuntadors no vàlids
Un punter hauria d'apuntar a una adreça vàlida, però no necessàriament a elements vàlids (com ara les matrius). Aquests s'anomenen punters no vàlids. Els punters no inicialitzats també són invàlids.
int *ptr1; int arr[10]; int *ptr2 = arr+20;>
Aquí, ptr1 no està inicialitzat, de manera que es converteix en un punter no vàlid i ptr2 està fora dels límits d'arr, de manera que també es converteix en un punter no vàlid. (Nota: els punters no vàlids no necessàriament generen errors de compilació)
Punters NULL
A punter nul és un punter que no apunta enlloc i no només una adreça no vàlida. A continuació es mostren 2 mètodes per assignar un punter com a NULL;
int *ptr1 = 0; int *ptr2 = NULL;>
Avantatges dels punters
- Els punters redueixen el codi i milloren el rendiment. S'utilitzen per recuperar cadenes, arbres, matrius, estructures i funcions.
- Els punters ens permeten retornar diversos valors de les funcions.
- A més d'això, els punters ens permeten accedir a una ubicació de memòria a la memòria de l'ordinador.
Articles relacionats:
Característiques de java8
- Apuntador opac
- Punters propers, llunyans i enormes
Proves:
- Conceptes bàsics del punter
- Punter avançat