Punteros en C

Como están!, hoy vengo a introducirles un nuevo concepto el cual les sera usado mucho en la programación C y C++, el uso de Punteros.

Que necesitas conocer?
  1. Funciones y procedimientos
  2. Pase de parámetros por valor y por referencia (funciones)
  3. (Opcional) Uso de estructuras por medio de Struct
Aspectos que debes conocer antes de continuar:
  • Operador de referencia "&": Devuelve direcciones de memoria 
  • Operador de indiferencia "*": Toma la dirección de memoria y devuelve su contenido
Recuerdas las funciones que podían recibir parámetros por referencia? no?


Si no sabes ni papa, te recomiendo leer este articulo, te facilitara el entendimiento de este temar.

Lo único que debo mencionarte es que cuando estabas manejando funciones por referencia, estabas manipulando direcciones de memoria, algo que podrás observar con mas detalle en este tema (aunque no del todo).

Podemos relacionar un puntero con la acción de apuntar las direcciones de memoria de las variables, y así a su vez, ser capaz de manipular los datos contenidas en ellas, mas no cambiar la dirección de memoria como tal.

Una dirección de memoria es una posición de la memoria en el hardware con el que podemos contener datos, como una variable.

Un ejemplo podría ser el de un control remoto y un televisor, el control permite manipular los aspectos que contiene el televisor en su software (el volumen, canal, contraste, brillo), sin embargo el control solo puede funcionar para televisores, y no puede cambiar los aspectos físicos de ella.

Podríamos crear un puntero que funcione para un tipo especifico de dato, sea int, float, char o cualquier tipo de estructura a usar, este puntero no guardara datos como los contenido en las variables, sino direcciones de memoria de variables.

Podemos representar un puntero de la siguiente forma:

Dato* nombre_del_dato;

int* puntero_para_int;
float* puntero_para_float;
char* puntero_para_char;

Como puedes ver, es casi idéntico a una variable para enteros, con la excepción del operador de indirección (*).

Un ejemplo de asignación de datos en un puntero es el siguiente:

puntero_para_int = NULL;

"NULL" es un valor de memoria nulo, relativo al 0 de los enteros.

Ahora, digamos que tenemos una variable entera a la que queremos obtener mediante un puntero, tendríamos que hacer lo siguiente:

int* puntero;
int  entero;

puntero = &entero;

Las primeras dos lineas de código son para declarar el puntero y la variable, la cuarta linea nos permite asignar la dirección de memoria de la variable al puntero, el operador de referencia & devuelve la dirección de memoria de la variable, la cual es almacenada en el apuntador. Si hacemos la siguientes lineas de códigos:

int variable = 5;

printf("Direccion de memoria que contiene a la variable: %p\n
        Valor dentro de la variable: %d", &variable, variable);

El primer valor a imprimir sera la ubicación de la variable, debido al operador &, y seguidamente el valor que contiene esa dirección de memoria.

Ahora, para cambiar el contenido de la variable por medio del apuntador:

Bastaría con des-referenciar el puntero, esto se hace por medio del operador de indiferencia *:

*puntero= 5;

El operador de indiferencia permite acceder al valor contenido en el puntero, que en este caso seria la variable entero, y así, cambiar el contenido de la variable, Este método es el mismo a decir "entero = 5;".

Recuerda que un puntero solo puede funcionar para apuntar direcciones de memoria, no puedes hacer lo siguiente:

int* puntero;
puntero = 5;

Esto generara un error. Debes antes asignar la dirección de memoria de una variable, o crear espacio de memoria en el puntero de forma dinámica.

Punteros para datos tipo Struct:

Para asignar una estructura en un puntero, se realiza los mismos métodos ejecutados anteriormente:


Estructura variable;
Estructura* puntero;

puntero = &variable;

Ahora, la diferencia esta en el acceso a sus elementos, en vez de utilizar ".",
desde un puntero debemos utilizar el operador "->" para acceder a sus subdatos.

puntero -> dato_1 = 5;
puntero -> dato_2 = 'a';

Aparte de eso, posee los mismos detalles que una estructura cualquiera.

Recuerda, un puntero no puede contener valores que no sean direcciones de memoria, debes asignarle direcciones como &variable o alojar memoria dinámicamente.


Comentarios