Punteros de C++ con ejemplos
¿Qué son los punteros?
En C++, un puntero se refiere a una variable que contiene la dirección de otra variable. Al igual que las variables regulares, los punteros tienen un tipo de datos. Por ejemplo, un puntero de tipo entero puede contener la dirección de una variable de tipo entero. Un puntero de tipo carácter puede contener la dirección de una variable de tipo carácter.
Debería ver un puntero como una representación simbólica de una dirección de memoria. Con punteros, los programas pueden simular llamadas por referencia. También pueden crear y manipular estructuras de datos dinámicas. En C++, una variable de puntero se refiere a una variable que apunta a una dirección específica en una memoria a la que apunta otra variable.
En este tutorial de C++, aprenderá:
- ¿Qué son los punteros?
- Direcciones en C++
- Sintaxis de declaración de puntero
- Operador de referencia (&) y operador de deferencia (*)
- Puntero y Matrices
- Puntero NULL
- Puntero de Variables
- Aplicación de punteros
- Ventajas de usar Punteros
Direcciones en C++
Para comprender los punteros de C++, debe comprender cómo las computadoras almacenan datos.
Cuando crea una variable en su programa C++, se le asigna un espacio en la memoria de la computadora. El valor de esta variable se almacena en la ubicación asignada.
Para conocer la ubicación en la memoria de la computadora donde se almacenan los datos, C++ proporciona el & (referencia) operador. El operador devuelve la dirección que ocupa una variable.
Por ejemplo, si x es una variable, &x devuelve la dirección de la variable.
Sintaxis de declaración de puntero
La declaración de C++ toma la siguiente sintaxis:
datatype *variable_name;
- El tipo de datos es el tipo base del puntero que debe ser un tipo de datos C++ válido.
- El nombre_variable debe ser el nombre de la variable de puntero.
- El asterisco que se usó anteriormente para la declaración del puntero es similar al asterisco que se usa para realizar operaciones de multiplicación. Es el asterisco que marca la variable como puntero.
Aquí hay un ejemplo de declaraciones de puntero válidas en C++:
int *x; // a pointer to integer double *x; // a pointer to double float *x; // a pointer to float char *ch // a pointer to a character
Operador de referencia (&) y operador de deferencia (*)
El operador de referencia (&) devuelve la dirección de la variable.
El operador de desreferencia (*) nos ayuda a obtener el valor que se ha almacenado en una dirección de memoria.
Por ejemplo:
Si tenemos una variable de nombre num, almacenada en la dirección 0x234 y almacenando el valor 28.
El operador de referencia (&) devolverá 0x234.
El operador de desreferencia (*) devolverá 5.
Ejemplo 1:
#include <iostream> using namespace std; int main() { int x = 27; int *ip; ip = &x; cout << "Value of x is : "; cout << x << endl; cout << "Value of ip is : "; cout << ip<< endl; cout << "Value of *ip is : "; cout << *ip << endl; return 0; }
Salida:
Cómo funciona esto:
Aquí hay una captura de pantalla del código:
Explicación del código:
- Importe el archivo de encabezado de iostream. Esto nos permitirá usar las funciones definidas en el archivo de encabezado sin obtener errores.
- Incluya el espacio de nombres estándar para usar sus clases sin llamarlo.
- Llama a la función main(). La lógica del programa debe agregarse dentro del cuerpo de esta función. El { marca el comienzo del cuerpo de la función.
- Declare una variable entera x y asígnele un valor de 27.
- Declare una variable de puntero *ip.
- Almacene la dirección de la variable x en la variable puntero.
- Imprime algo de texto en la consola.
- Imprime el valor de la variable x en la pantalla.
- Imprime algo de texto en la consola.
- Imprime la dirección de la variable x. El valor de la dirección se almacenaba en la variable ip.
- Imprime algo de texto en la consola.
- Imprime el valor de almacenado en la dirección del puntero.
- El programa debe devolver valor tras una ejecución exitosa.
- Fin del cuerpo de la función main().
Punteros y matrices
Las matrices y los punteros funcionan en función de un concepto relacionado. Hay diferentes cosas a tener en cuenta cuando se trabaja con matrices que tienen punteros. El propio nombre de la matriz denota la dirección base de la matriz. Esto significa que para asignar la dirección de una matriz a un puntero, no debe usar un ampersand (&).
Por ejemplo:
p = arr;
Lo anterior es correcto ya que arr representa la dirección de los arreglos. Aquí hay otro ejemplo:
p = &arr;
Lo anterior es incorrecto.
Implícitamente podemos convertir una matriz en un puntero. Por ejemplo:
int arr [20]; int * ip;
A continuación se muestra una operación válida:
ip = arr;
Después de la declaración anterior, ip y arr serán equivalentes y compartirán propiedades. Sin embargo, se puede asignar una dirección diferente a ip, pero no podemos asignar nada a arr.
Ejemplo 2:
Este ejemplo muestra cómo atravesar una matriz usando punteros:
#include <iostream> using namespace std; int main() { int *ip; int arr[] = { 10, 34, 13, 76, 5, 46 }; ip = arr; for (int x = 0; x < 6; x++) { cout << *ip << endl; ip++; } return 0; }
Salida:
Aquí hay una captura de pantalla del código:
Explicación del código:
- Declare una variable de puntero entero ip.
- Declare una matriz llamada arr y almacene 6 enteros en ella.
- Asigne arr a ip. La ip y arr se volverán equivalentes.
- Cree un bucle for a. La variable de bucle x se creó para iterar sobre los elementos de la matriz desde el índice 0 al 5.
- Imprime los valores almacenados en la dirección de la IP del puntero. Se devolverá un valor por iteración y se realizarán un total de 6 repeticiones. El endl es una palabra clave de C++ que significa la línea final. Esta acción le permite mover el cursor a la siguiente línea después de imprimir cada valor. Cada valor se imprimirá en una línea individual.
- Para mover el puntero a la siguiente posición int después de cada iteración.
- Fin del bucle for a.
- El programa debe devolver algo después de una ejecución exitosa.
- Fin del cuerpo de la función main().
Puntero NULO
Si no hay una dirección exacta que se deba asignar, entonces se puede asignar NULL a la variable de puntero. Debe hacerse durante la declaración. Este puntero se conoce como puntero nulo. Su valor es cero y está definido en muchas bibliotecas estándar como iostream.
Ejemplo 3:
#include <iostream> using namespace std; int main() { int *ip = NULL; cout << "Value of ip is: " << ip; return 0; }
Salida:
Aquí hay una captura de pantalla del código:
Explicación del código:
- Declare una variable de puntero ip y asígnele un valor NULL.
- Imprime el valor de la variable de puntero ip junto con algún texto en la consola.
- El programa debe devolver valor al completarse con éxito.
- Fin del cuerpo de la función main().
Puntero de Variables
Con C++, puede manipular datos directamente desde la memoria de la computadora.
El espacio de memoria se puede asignar o reasignar según se desee. Esto es posible gracias a las variables de puntero.
Las variables de puntero apuntan a una dirección específica en la memoria de la computadora a la que apunta otra variable.
Se puede declarar de la siguiente manera:
int *p;
O,
int* p;
En el ejemplo, hemos declarado la variable puntero p.
Contendrá una dirección de memoria.
El asterisco es el operador de desreferencia que significa un puntero a.
El puntero p apunta a un valor entero en la dirección de memoria.
Ejemplo 4:
#include <iostream> using namespace std; int main() { int *p, x = 30; p = &x; cout << "Value of x is: " << *p; return 0; }
Salida:
Aquí hay una captura de pantalla del código:
Explicación del código:
- Declare una variable puntero p y una variable x con un valor de 30.
- Asigne la dirección de la variable x a p.
- Imprime el valor de la variable de puntero p junto con algún texto en la consola.
- El programa debe devolver valor al completarse con éxito.
- Fin del cuerpo de la función main().
Aplicación de Punteros
Las funciones en C++ pueden devolver solo un valor. Además, todas las variables declaradas en una función se asignan en la pila de llamadas de función. Tan pronto como la función regresa, todas las variables de la pila se destruyen.
Los argumentos para funcionar se pasan por valor, y cualquier modificación realizada en las variables no cambia el valor de las variables reales que se pasan. El siguiente ejemplo ayuda a ilustrar este concepto:-
Ejemplo 5:
#include <iostream> using namespace std; void test(int*, int*); int main() { int a = 5, b = 5; cout << "Before changing:" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; test(&a, &b); cout << "\nAfter changing" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; return 0; } void test(int* n1, int* n2) { *n1 = 10; *n2 = 11; }
Salida:
Aquí hay una captura de pantalla del código:
Explicación del código:
- Cree un prototipo de una función llamada prueba que tomará dos parámetros enteros.
- Llama a la función main(). Agregaremos la lógica del programa dentro de su cuerpo.
- Declare dos variables enteras a y b, cada una con un valor de 5.
- Imprime algo de texto en la consola. El endl (línea final) moverá el cursor para comenzar a imprimir en la siguiente línea.
- Imprime el valor de la variable a en la consola junto con otro texto. El endl (línea final) moverá el cursor para comenzar a imprimir en la siguiente línea.
- Imprime el valor de la variable b en la consola junto con otro texto. El endl (línea final) moverá el cursor para comenzar a imprimir en la siguiente línea.
- Cree una función llamada test() que tome las direcciones de las variables ayb como parámetros.
- Imprime algo de texto en la consola. El \n creará una nueva línea en blanco antes de que se imprima el texto. El endl (línea final) moverá el cursor para comenzar a imprimir en la siguiente línea después de que se imprima el texto.
- Imprime el valor de la variable a en la consola junto con otro texto. El endl (línea final) moverá el cursor para comenzar a imprimir en la siguiente línea.
- Imprime el valor de la variable b en la consola junto con otro texto. El endl (línea final) moverá el cursor para comenzar a imprimir en la siguiente línea.
- El programa debe devolver valor al completarse con éxito.
- Fin del cuerpo de la función main().
- Definiendo la función test(). La función debe tomar dos variables de puntero entero *n1 y *n2.
- Asignando a la variable puntero *n1 un valor de 10.
- Asignar a la variable puntero *n2 un valor de 11.
- Fin del cuerpo de la función test().
Aunque se asignan nuevos valores a las variables a y b dentro de la prueba de función, una vez que se completa la llamada a la función, no se refleja lo mismo en la función principal externa.
El uso de punteros como argumentos de función ayuda a pasar la dirección real de la variable en la función, y todos los cambios realizados en la variable se reflejarán en la función externa.
En el caso anterior, la función 'prueba' tiene la dirección de las variables 'a' y 'b'. Estas dos variables son directamente accesibles desde la función 'prueba' y, por lo tanto, cualquier cambio realizado en estas variables se refleja en la función de llamada 'principal'
Ventajas de usar Punteros
Estos son los pros/beneficios de usar Pointers
- Los punteros son variables que almacenan la dirección de otras variables en C++.
- La función puede modificar y devolver más de una variable usando punteros.
- La memoria se puede asignar y desasignar dinámicamente mediante punteros.
- Los punteros ayudan a simplificar la complejidad del programa.
- La velocidad de ejecución de un programa mejora mediante el uso de punteros.
Resumen:
- Un puntero se refiere a una variable que contiene la dirección de otra variable.
- Cada puntero tiene un tipo de datos válido.
- Un puntero es una representación simbólica de una dirección de memoria.
- Los punteros permiten que los programas simulen llamadas por referencia y creen y manipulen estructuras de datos dinámicas.
- Las matrices y los punteros usan un concepto relacionado.
- El nombre de la matriz indica la base de la matriz.
- Si desea asignar la dirección de una matriz a un puntero, no use un ampersand (&).
- Si no hay una dirección específica para asignar una variable de puntero, asígnele un NULL.
Lenguaje C
- Matrices en C++ | Declarar | Inicializar | Ejemplos de puntero a matriz
- C++ do...while bucle con ejemplos
- Punteros de C++ con ejemplos
- Tipo de datos Char de C++ con ejemplos
- Sobrecarga de operadores de C++ con ejemplos
- Estructura C++ con ejemplo
- std::list en C++ con ejemplo
- Funciones de C++ con ejemplos de programas
- Tutorial de colecciones de C# con ejemplos
- Punteros en C:¿Qué es un puntero en la programación C? Tipos
- C - Punteros