Dominando punteros constantes y punteros a constantes en C
En C, un puntero es una variable que almacena la dirección de memoria de otra variable, y la palabra clave const se usa para definir una variable o puntero cuyo valor no puede cambiarse una vez inicializado. Cuando combinamos punteros con la palabra clave const, podemos controlar dos cosas:
- Si la dirección almacenada en el puntero puede cambiar.
- Si el valor almacenado en esa dirección puede cambiar.
En este capítulo, veremos las tres variaciones principales de punteros constantes:
- Puntero constante
- Puntero a constante
- Puntero constante a constante
Puntero constante
Un puntero constante significa que el puntero en sí es constante. Una vez inicializado para apuntar a una ubicación de memoria, no puede apuntar a una ubicación diferente, pero el valor almacenado en esa ubicación sí puede cambiarse.
Siguiente es la sintaxis de un puntero constante:
tipo_dato *const nombre_puntero = &variable;
En esta sintaxis, tipo_dato es el tipo de dato al que apunta el puntero, *const hace que el puntero en sí sea constante, nombre_puntero es el nombre del puntero, y &variable le asigna la dirección de memoria de una variable.
Ejemplo de puntero constante
En este ejemplo, declaramos un puntero constante ptr e inicializamos con la dirección de la variable x. Luego, cambiamos el valor de x usando ptr e imprimimos su valor.
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int *const ptr = &x; // puntero constante a int
printf("Valor de x: %d\n", *ptr);
*ptr = 15; // puede cambiar el valor en la dirección
printf("Valor modificado de x: %d\n", *ptr);
// ptr = &y; // cambiar la dirección del puntero no está permitido
return 0;
}
La salida del programa anterior muestra que el puntero permanece fijo a x, pero el valor de x puede actualizarse.
Valor de x: 10
Valor modificado de x: 15
Ejemplo de error de puntero constante
Aquí hay un ejemplo donde declaramos un puntero constante ptr e inicializamos con la dirección de la variable x. Luego, intentamos hacer que apunte a la dirección de la variable y. Esto dará un error porque un puntero constante no puede apuntar a otra ubicación de memoria una vez inicializado.
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int *const ptr = &x; // puntero constante a int
printf("Valor de x: %d\n", *ptr);
// Intentando cambiar el puntero para que apunte a y
ptr = &y; // no se puede cambiar la dirección de un puntero constante
return 0;
}
Puedes ver el error abajo, indicando que no podemos cambiar la dirección de un puntero constante.
error: assignment of read-only variable 'ptr'
Puntero a constante
Un puntero a constante significa que el valor al que apunta no puede cambiarse, pero el puntero en sí sí puede apuntar a diferentes direcciones de memoria (o variables).
Siguiente es la sintaxis para puntero a constante:
const tipo_dato *nombre_puntero = &variable;
tipo_dato const *puntero = &variable;
En esta sintaxis, const tipo_dato o tipo_dato const significa que el puntero apunta a un valor constante, nombre_puntero es el nombre del puntero, y &variable le asigna la dirección de una variable.
Ejemplo de puntero a constante
En este ejemplo, declaramos un puntero ptr que apunta a un valor constante y le asignamos la dirección de la variable a. Luego, hacemos que el puntero apunte a una dirección diferente de la variable b e imprimimos su valor.
#include <stdio.h>
int main() {
int a = 5;
int b = 30;
const int *ptr = &a; // puntero a int constante
printf("Valor de a: %d\n", *ptr);
// *ptr = 10; // no podemos modificar el valor a través del puntero
ptr = &b; // cambiando la dirección del puntero
printf("Ahora apuntando a b: %d\n", *ptr);
return 0;
}
La salida del programa anterior muestra el mismo puntero apuntando a diferentes variables.
Valor de a: 5
Ahora apuntando a b: 30
Ejemplo de error de puntero a constante
Aquí hay un ejemplo donde declaramos un puntero a constante ptr e inicializamos con la dirección de la variable a. Luego, intentamos cambiar el valor de a a través del puntero. Esto dará un error porque un puntero a constante no permite modificar el valor al que apunta.
#include <stdio.h>
int main() {
int a = 5;
const int *ptr = &a; // puntero a int constante
printf("Valor de a: %d\n", *ptr);
// no podemos modificar el valor a través de puntero a constante
*ptr = 10;
return 0;
}
Abajo puedes ver la salida, que muestra un error indicando que no podemos modificar el valor a través de un puntero a constante.
error: assignment of read-only location '*ptr'
Puntero constante a constante
Un puntero constante a una constante es un puntero que no puede cambiar su dirección de memoria, y el valor almacenado en esa dirección de memoria tampoco puede cambiarse. Ambas acciones están restringidas, por lo que solo podemos leer el valor, nada más.
Siguiente es la sintaxis para un puntero constante a una constante:
const tipo_dato *const nombre_puntero = &variable;
En esta sintaxis:
- const tipo_dato indica que el valor en la ubicación de memoria no puede cambiarse a través del puntero.
- *const nombre_puntero significa que el puntero en sí no puede apuntar a ninguna otra dirección de memoria después de la inicialización.
- &variable asigna el puntero a la dirección de memoria de la variable.
Ejemplo de puntero constante a constante
En este ejemplo, declaramos un puntero constante a constante ptr y le asignamos la dirección de memoria de la variable a. Luego imprimimos el valor de a usando el puntero.
#include <stdio.h>
int main() {
int a = 10;
const int *const ptr = &a; // puntero constante a constante
printf("Valor de a: %d\n", *ptr);
// *ptr = 15; // no podemos modificar el valor
// ptr = &b; // no podemos cambiar la ubicación del puntero
return 0;
}
La salida del programa anterior:
Valor de a: 10
Ejemplo de error de puntero constante a constante
En este ejemplo, declaramos un puntero constante a constante ptr e inicializamos con una variable a. Luego, intentamos modificar el valor a través del puntero y también intentamos hacer que el puntero apunte a otra variable. Ambas operaciones no están permitidas y resultarán en un error de compilador.
#include <stdio.h>
int main() {
int a = 10;
int b = 20;
const int *const ptr = &a; // puntero constante a constante
printf("Valor de a: %d\n", *ptr);
// *ptr = 15; // no podemos modificar el valor
// ptr = &b; // no podemos cambiar la dirección del puntero
return 0;
}
Abajo puedes ver la salida mostrando los errores:
Valor de a: 10
Diferencia entre tipos de punteros constantes
La siguiente tabla muestra las diferencias entre un puntero constante, un puntero a constante y un puntero constante a constante.
| Variación | Definición | ¿Puede cambiar dirección? | ¿Puede cambiar valor? | Sintaxis de ejemplo |
|---|---|---|---|---|
| Puntero constante | Un puntero cuya dirección es fija, pero el valor en esa dirección puede modificarse. | No | Sí | int *const p = &x; |
| Puntero a constante | Un puntero que puede apuntar a diferentes direcciones, pero no puede modificar el valor en la ubicación apuntada. | Sí | No | const int *p = &x; |
| Puntero constante a constante | Un puntero cuya dirección es fija y el valor en esa dirección no puede modificarse. | No | No | const int *const p = &x; |
Conclusión
En este capítulo, cubrimos punteros constantes y punteros a constante en C. Los punteros constantes fijan la dirección pero permiten cambiar el valor, los punteros a constante permiten cambiar la dirección pero no el valor, y los punteros constantes a constante restringen ambos.
Lenguaje C
- Dominando la precedencia y asociatividad de operadores en C#: Guía práctica
- Dominando bucles en C: Guía completa de control de repetición
- Los 15 Mejores IDEs para C++ en Windows, macOS y Linux – Opciones Gratuitas y de Pago (2021)
- Dominando las plantillas de clase en C++: guía práctica
- Serialización y Deserialización en C#: Un Ejemplo Práctico
- Sobrecarga de operadores en C++: Guía práctica con ejemplos de código
- Manejo de archivos en C++: Dominando apertura, lectura, escritura y cierre
- Tipos anulables en C#: Manejo seguro de valores null
- Dominando std::vector en C++: Arrays dinámicos, iteradores y ejemplos prácticos
- Dominando punteros en C++: Conceptos, ejemplos y aplicaciones prácticas
- Dominando los Espacios de Nombres en C#: Organización, Ámbito y Mejores Prácticas