Guía Completa de Punteros en C: Creación, Desreferenciación y Relación con Arrays

Punteros en Lenguaje C

Creación de Punteros

Podemos utilizar el operador de referencia & para obtener la dirección de memoria de una variable:

Código:

int edadPersona = 43; // Una variable de tipo int

printf("%d", edadPersona); // Muestra el valor de edadPersona (43)
printf("%p", &edadPersona); // Muestra la dirección de memoria de edadPersona (0x7ffe5367e044)

Un puntero es una variable cuyo valor es la dirección de memoria de otra variable.

Una variable puntero apunta a un tipo de dato específico (como int) y se crea utilizando el operador *. La dirección de la variable que se utiliza se asigna al puntero:

Código:

int edadPersona = 43; // Una variable de tipo int
int* punteroEdad = &edadPersona; // Variable puntero llamada punteroEdad que almacena la dirección de edadPersona

// Muestra el valor de edadPersona (43)
printf("%d\n", edadPersona);

// Muestra la dirección de memoria de edadPersona (0x7ffe5367e044)
printf("%p\n", &edadPersona);

// Utilizando el puntero para mostrar la dirección de memoria de edadPersona (0x7ffe5367e044)
printf("%p\n", punteroEdad);

Explicación del ejemplo:

  • Se crea una varible puntero llamada punteroEdad que apunta a una variable de tipo int (edadPersona). Es importante que el tipo del puntero coincida con el tipo de la variable a la que apunta (en este caso, int).
  • Se utiliza el operador & para almacenar y asignar la dirección de memoria de la variable edadPersona al puntero.
  • Ahora, punteroEdad contiene el valor de la dirección de memoria de edadPersona.
Desreferenciación

En el ejemplo anterior, utilizamos la variable puntero para obtener la dirección de memoria de una variable (en combinación con el operador de referencia &).

También podemos obtener el valor de la variable a la que apunta el puntero utilizando el operador * (operador de desreferenciación):

Código:

int edadPersona = 43; // Declaración de variable
int* punteroEdad = &edadPersona; // Declaración de puntero

// Referencia: utilizando el puntero para mostrar la dirección de memoria de edadPersona (0x7ffe5367e044)
printf("%p\n", punteroEdad);

// Desreferenciación: utilizando el puntero para mostrar el valor de edadPersona (43)
printf("%d\n", *punteroEdad);

Es importante notar que el símbolo * puede resultar confuso porque tiene dos funciones en nuestro código:

  • Cuando se usa en una declaración (int* punteroEdad), crea una variable puntero.
  • Cuando no se usa en una declaración, actúa como operador de desreferenciación.

Es relevante mencionar que en C existen dos formas de declarar variables puntero:

Código:

int* miNumero;
int *miNumero;

Consideraciones sobre punteros:

  • Los punteros son una característica distintiva del lenguaje C en comparación con otros lenguajes de programación como Python y Java.
  • Son fundamentales en C porque nos permiten manipular datos en la memoria del ordenador. Esto puede reducir la cantidad de código y mejorar el rendimiento. Si estás familiarizado con estructuras de datos como listas, árboles y grafos, debes saber que los punteros son especialmente útiles para implementarlos. A veces incluso es obligatorio usar punteros, como al trabajar con archivos.
  • Sin embargo, ten cuidado; los punteros deben manejarse con precaución, ya que existe la posibilidad de dañar datos almacenados en otras direcciones de memoria.

Punteros y Arrays en C

También puedes utilizar punteros para acceder a arrays.

Considera el siguiente array de enteros:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {
  printf("%d\n", numerosEnteros[i]);
}

Resultado:

25
50
75
100

Intentemos imprimir la dirección de memoria de cada elemento del array en lugar de sus valores:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {
  printf("%p\n", &numerosEnteros[i]);
}

Resultado:

0x7ffe70f9d8f0
0x7ffe70f9d8f4
0x7ffe70f9d8f8
0x7ffe70f9d8fc

Observa que el último dígito de cada dirección de memoria es diferente, aumentando en 4.

Esto se debe a que el tamaño del tipo int suele ser de 4 bytes, recuerda:

Código:

// Crear una variable int
int miEntero;

// Obtener el tamaño en memoria de un int
printf("%lu", sizeof(miEntero));

Resultado: 4

Por lo tanto, en el ejemplo de "direcciones de memoria" anterior,

puedes ver que el compilador ha reservado 4 bytes de memoria para cada elemento del array, lo que significa que todo el array ocupa 16 bytes (4 * 4) de espacio de almacenamiento en memoria:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};

// Obtener el tamaño del array numerosEnteros
printf("%lu", sizeof(numerosEnteros));

Resultado: 16

Relación entre Punteros y Arrays

Entonces, ¿cuál es la relación entre punteros y arrays? Bueno, en C, el nombre de un array en realidad es un puntero que apunta al primer elemento del array.

¿Te resulta confuso? Intentemos entenderlo mejor volviendo al ejemplo de "direcciones de memoria" anterior.

La dirección de memoria del primer elemento es la misma que el nombre del array:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};

// Obtener la dirección de memoria del array numerosEnteros
printf("%p\n", numerosEnteros);

// Obtener la dirección de memoria del primer elemento del array
printf("%p\n", &numerosEnteros[0]);

Resultado:

0x7ffe70f9d8f0
0x7ffe70f9d8f0

Esto básicamente significa que podemos manipular arrays utilizando punteros.

¿Cómo hacerlo? Dado que numerosEnteros es un puntero que apunta al primer elemento de numerosEnteros, puedes usar el operador * para acceder a él:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};

// Obtener el valor del primer elemento de numerosEnteros
printf("%d", *numerosEnteros);

Resultado: 25

Para acceder a otros elementos de numerosEnteros, puedes incrementar el puntero/array (+1, +2, etc.):

Código:

int numerosEnteros[4] = {25, 50, 75, 100};

// Obtener el valor del segundo elemento de numerosEnteros
printf("%d\n", *(numerosEnteros + 1));

// Obtener el valor del tercer elemento de numerosEnteros
printf("%d", *(numerosEnteros + 2));

// Y así sucesivo...

Resultado:

50
75

O puedes recorrerlo con un bucle:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};
int *ptr = numerosEnteros;
int i;

for (i = 0; i < 4; i++) {
  printf("%d\n", *(ptr + i));
}

Resultado:

25
50
75
100

También puedes usar punteros para modificar los valores de los elementos del array:

Código:

int numerosEnteros[4] = {25, 50, 75, 100};

// Cambiar el valor del primer elemento a 13
*numerosEnteros = 13;

// Cambiar el valor del segundo elemento a 17
*(numerosEnteros + 1) = 17;

Consideraciones Finales

Los punteros son una herramienta poderosa en C que permite un control directo sobre la memoria, pero requieren un manejo cuidadoso para evitar errores como punteros nulos o desreferenciación incorrectta.

Al dominar los punteros y su relación con arrays, podrás escribir código más eficiente y aprovechar al máximo las capacidades del lenguaje C.

Etiquetas: punteros C desreferenciación arrays en C manejo de memoria programación en C

Publicado el 7-3 06:16