Tutorial de programación en C para Linux Parte 19: Punteros y matrices
Hasta ahora, en esta serie de tutoriales de programación en C, hemos tratado brevemente los fundamentos de los punteros. Sin embargo, hay varios conceptos más relacionados con los punteros que deben ser discutidos. Así que en este tutorial trataremos el concepto de punteros y matrices.
Antes de empezar con los punteros y las matrices, vamos a refrescar rápidamente el concepto básico de los punteros en sí. Los punteros son un tipo especial de variables que pueden contener direcciones. Por ejemplo, un puntero ‘ptr’ a un carácter puede declararse de la siguiente manera
char *ptr;
Y puedes utilizar el signo ampersand para almacenar una dirección en él. Aquí tienes un ejemplo:
char c = 'a';
ptr = &c;
Así que ahora, el puntero ‘ptr’ contiene la dirección de la variable ‘c’. También puedes decir que ‘ptr’ apunta ahora a la variable ‘c’.
Para acceder o manipular el valor de la variable apuntada por el puntero, puedes utilizar el operador *. Por ejemplo, para cambiar el valor de la variable c de ‘a’ a ‘b’, puedes utilizar el puntero ‘ptr’ de la siguiente manera:
*ptr = 'b';
El siguiente programa debería darte una mejor idea sobre estos conceptos básicos de los punteros que hemos discutido hasta ahora:
#include <stdio.h>
int main()
{
char c = 'a';
char *ptr = &c;
*ptr = 'b';
printf ("variable c = %c", c);
return 0;
}
Este es el resultado de este programa:
variable c = b
Para que veas que utilizando un puntero se ha cambiado el valor de una variable.
Punteros y matrices
A medida que pases más y más tiempo escribiendo y leyendo código C, observarás que los punteros y las matrices se utilizan a menudo juntos. Por ejemplo, puedes acceder a elementos individuales de una matriz utilizando un puntero. Considera el siguiente fragmento de código:
...
...
...
char arr[] = {'a','b','c','d','e'}
char *ptr;
ptr = &arr[0]
...
...
...
Aquí, el puntero ‘ptr’ apunta al primer elemento de la matriz ‘arr’, que si hablas en términos de índices, se encuentra en la posición cero de la matriz. Ahora puedes utilizar el operador * con ‘ptr’ para acceder/manipular el valor al que apunta el puntero.
Además, una vez que tienes un puntero que apunta al primer elemento de una matriz, es fácil acceder también a otros elementos de la matriz. Por ejemplo, si -en el contexto del extracto de código anterior- utilizas la siguiente expresión en cualquier lugar
*(ptr+1)
entonces te permite acceder al segundo elemento de la matriz, algo que normalmente se hace de la siguiente manera:
arr[1]
Así que, efectivamente, añadir 1 a ‘ptr’ te lleva a la dirección del siguiente elemento de la matriz, y utilizando * puedes acceder al valor almacenado en esa dirección. Del mismo modo, añadir 2 te lleva al tercer elemento… y así sucesivamente.
Aquí tienes un programa que debería darte una idea más clara de lo que acabamos de discutir:
#include <stdio.h>
int main()
{
char arr[] = {'a','b','c','d','e'};
char *ptr = &arr[0];
for(int i=0;i<strlen(arr);i++)
printf ("arr[%d] is %c \n", i, *(ptr+i));
return 0;
}
Y aquí está la salida:
arr[0] is a
arr[1] is b
arr[2] is c
arr[3] is d
arr[4] is e
Como ves, la expresión ‘*(ptr+i)’ -con i que varía de 0 al último índice de la matriz- nos ha permitido acceder a todos los elementos de la matriz.
NOTA 1: El nombre de la matriz, cuando se utiliza en el código, te da la dirección base de la matriz. Esto significa que el nombre de la matriz y la dirección de su primer elemento son la misma cosa. Así, en el contexto de un array ‘arr’, ‘&arr[0]’ y ‘arr’ es una y la misma cosa. Esto se extiende también a otros elementos, lo que significa que &arr[2] también puede escribirse como (arr+2) y así sucesivamente.
NOTA 2: Ampliando lo que hemos comentado en la nota anterior, toda representación de elementos de matrices puede descomponerse en representación de punteros. Por ejemplo: arr[2] equivale a ‘*(arr + 2)’.
NOTA 3: Aunque puedes asignar una dirección de matriz a un puntero, no es válido lo contrario. Además, a diferencia de los punteros, no puedes utilizar los operadores ++ o — con el nombre del array. En términos generales, no puedes cambiar las direcciones en las que se encuentran originalmente los elementos del array.
Conclusión
Este tutorial se ha centrado en el concepto de punteros y arrays, en cómo se relacionan y en cómo se puede acceder a los elementos de los arrays mediante punteros. Hacia el final, también hemos discutido algunos puntos importantes cuando se trata de código que utiliza punteros a arrays.
Prueba estos conceptos localmente en tu máquina para tener una mejor idea de cómo funcionan estas cosas, y en caso de cualquier duda o consulta, deja un comentario abajo.