Puntero

 

Puntero



Los punteros se utilizan para pasar parámetros por referencia. Esto es útil si el programador quiere modificaciones de una función a un parámetro sea visible para llamador de la función de la función. Esto también es útil para devolver varios valores de una función.      
Los punteros también se puede utilizar para asignar y desasignar en la memoria variables dinámicas y matrices. Ya que muchas veces una variable puede volverse redundante después de que haya cumplido su objetivo, que resulta en una pérdida de la memoria mantenerla, en consecuencia es una buena práctica para desasignarla cuando ya no se necesita, utilizando la referencia de puntero original. El no hacerlo puede resultar en una pérdida de memoria (donde la memoria libre disponible va disminuyendo gradualmente, o en casos severos rápidamente, a causa de una acumulación de numerosos bloques de memoria redundantes).

Punteros en C

La sintaxis básica para definir un puntero es:

int * ptr;

Esto declara ptr como el identificador de un objeto, de la siguiente forma:

  • puntero que apunta a un objeto de tipo int

Esto usualmente se manifiesta de forma más sucinta como 'ptr es un puntero a int.'

Debido a que el lenguaje C no especifica una inicialización implícita para los objetos de duración automática de almacenamiento,​ frecuentemente se debe prestar atención para asegurarse de que la dirección a la que ptr puntea es válida; por eso a veces se sugiere que un puntero pueda ser explícitamente inicializado al valor de puntero nulo, que es tradicionalmente especificado en C con la macro estandarizado NULL:

int *ptr = NULL;

Desreferenciar un puntero nulo en C produce un comportamiento indefinido, que podría ser catastrófico. Sin embargo, la mayoría de las implementaciones [cita requerida], simplemente detienen la ejecución del programa en cuestión, usualmente con un fallo de segmentación.

Sin embargo, punteros inicializados podría obstaculizar innecesariamente el análisis del programa, ocultando de ese modo los bugs.

En cualquier caso, una vez que un puntero ha sido declarado, el siguiente paso lógico es que se apunte a algo:

int a = 5;
int *ptr = NULL;
 
ptr = &a;

Esto asigna el valor de la dirección de a a ptr. Por ejemplo, si a está almacenado en la ubicación de memoria de 0x8130 entonces el valor de ptr será 0x8130 después de la asignación. Para eliminar la referencia al puntero, se utiliza de nuevo el asterisco:

*ptr = 8;

Esto significa tomar el contenido de ptr (que es 0x8130), "localizar" la dirección en memoria y establecer su valor en 8. Si, más tarde, se accede de nuevo, su nuevo valor será 8.

Este ejemplo puede ser más claro si la memoria no es directamente examinada. Supongamos que a se localiza en la dirección 0x8130 en memoria y ptr en 0x8134; también asume de que se trata de un equipo de 32 bits de tal manera que un int tiene un ancho de 32 bits. Lo que sigue es lo que estaría en la memoria después de que se ejecuta el siguiente fragmento de código:

int a = 5;
int *ptr = NULL;
DirecciónContenido
0x81300x00000005
0x81340x00000000

(El puntero NULL que se muestra aquí es 0x00000000.) Mediante la asignación la direcciona de a a ptr:

 ptr = &a;

produce los siguientes valores de memoria:

DirecciónContenido
0x81300x00000005
0x81340x00008130

Entonces desreferenciando ptr mediante codificación:

 *ptr = 8;

la computadora tendrá el contenido de ptr (que es 0x8130), 'localizado' esa dirección, y asignar 8 a esa ubicación produciendo la siguiente memoria:

DirecciónContenido
0x81300x00000008
0x81340x00008130

Claramente, el acceso a a producirá el valor de 8 porque la instrucción anterior modificó el contenido de a por medio del puntero ptr.


Comentarios