Programación en C/Punteros

De Wikilibros, la colección de libros de texto de contenido libre.

← Estructuras y Uniones Punteros Manejo dinámico de memoria →


Un puntero es una variable que contiene la dirección, o ubicación en memoria, de algún valor.

[editar] Declarando puntero

Tenga en cuenta el siguiente bloque de código que declara 2 punteros

/*1*/ struct MyStruct {
/*2*/     int   m_aNumber;
/*3*/     float num2;
/*4*/ };
/*5*/ 
/*6*/ int             * pJ2;
/*7*/ struct MyStruct * pAnItem;

Las primeras 4 líneas definen la estructura. La linea 6 declara una variable que apuntará a un entero, y la línea 7 declara una variable que apunta a algo de la estructura MyStruct. Entonces declarar un puntero es algo que apunta a algo de algún tipo, más que contener el tipo. El asterisco (*) se coloca antes del nombre de la variable.

En las siguientes líneas de código, var1 es un puntero a un entero largo (long) mientras var2 es un entero largo (long) y no un puntero a un entero largo. En la segunda línea se declara p3 como un puntero a un puntero de un entero.

	long  *  var1, var2;
	int   ** p3;

Los punteros se usan habitualmente como parámetros de funciones. El siguiente código muestra como declarar una función que usa un puntero como argumento. Teniendo en cuenta que C pasa todos los argumentos por valor, para poder modificar un valor desde el código de la función, se debe usar un puntero al valor a modificar. También se usan punteros a estructuras como argumentos de una función aún cuando la estructura no sea modificada dentro de la función. Esto es realizado para evitar copiar todo el contenido de la estructura dentro de la pila.

	int MyFunction( struct MyStruct *pStruct );

[editar] Asignando valores a punteros

Continuamos con el proceso de asignar valores a los punteros, para esto utilizamos el operador & o 'la dirección de'.

	int   myInt;
	int  *pPointer;
	struct MyStruct   dvorak;
	struct MyStruct  *pKeyboard;
 
	pPointer = &myInt;
	pKeyboard = &dvorak;

Aquí, pPointer apuntara a myInt y pKeyboard apuntara a dvorak.

Los punteros también pueden ser asignados a referencias de memorias dinamicas creadas comúnmente por las funciones malloc() y calloc().

#include <stdlib.h>
	...
	struct MyStruct *pKeyboard;
	...
	pKeyboard = malloc(sizeof(struct MyStruct));
	...

La función malloc retorna un puntero de memoria asignada de manera dinámica (o NULL si falla). El tamaño de esta memoria es definido de modo que pueda contener la estructura MyStruct

El siguiente código es un ejemplo mostrando un puntero siendo asignado a una referencia y se retorna el valor del puntero en la función.

static struct MyStruct val1, val2, val3, val4;
...
struct MyStruct *ASillyFunction( int b )
{
	struct MyStruct *myReturn;
 
	if (b == 1) myReturn = &val1;
	else if (b==2) myReturn = &val2;
	else if (b==3) myReturn = &val3;
	else myReturn = &val4;
 
	return myReturn;
}
	...
	struct MyStruct *strPointer;
	int     *c, *d;
	int     j;
	...
	c = &j;                           /* puntero asignado usando el operador & */
	d = c;                            /* asignando un puntero a otro           */
	strPointer = ASillyFunction( 3 ); /* puntero retornado de la funcion       */

Cuando se retorna un puntero de una funcion, se tiene que tener cuidado de que el valor apuntado no sea de una referencia de una variable local a la funcion, porque estos valores desaparecen despues de salir de la funcion y el puntero estaria mal referenciado, causando errores en tiempo de ejecucion en el programa. La memoria creada dinamicamente dentro de la funcion puede devolverse como puntero, el valor de retorno aunque es creado en una variable local la direccion como tal se devuelve por valor dejando esta informacion valida.


← Estructuras y Uniones Punteros Manejo dinámico de memoria →
Herramientas personales