Punteros en C

Uno de los conceptos más complejos del lenguaje C, por lo abstracto de los mismos, es el de los punteros. Su principal utlidad está en que nos permiten hacer una asignación dinámica de memoria.

Un puntero realmente no es más que una dirección de memoria, que normalmente lleva asociado un tipo de datos. Por ejemplo un puntero a entero, que será una dirección de memoria donde podemos almacenar un entero. Para designar un puntero sólo tenemos que poner, en la declaración, un asterisco (*) entre el nombre de la variable y el tipo de datos, tal que así:

int *primero; //declaramos un puntero a entero
int* segundo; //el asterisco puede ir en cualquiera de los dos lados
float *tercero; //y podemos declarar flotantes, caracteres, ficheros...

Para reservar la memoria necesaria utilizaremos la función malloc, abreviatura de memory allocation, pasando como parámetros el tamaño que queremos reservar. La función sizeof() nos puede ayudar mucho, ya que por ejemplo sizeof(int) nos devolverá el tamaño de un entero. Ojea este ejemplo, donde decimos que en la dirección apuntada por el puntero primero vamos a guardar la cantidad de enteros definida en la variable cantidadX:

primero = (*int) malloc(cantidadX*sizeof(int));

Para usar malloc debemos incluir la librería stdlib.h al principio del código. Después de usar malloc se debe usar free para liberar la memoria asignada dinámicamente.

El siguiente es un ejemplo del manual de introducción a C de Nacho Cabanes que ilustra un poco todo esto:

/*---------------------------*/ 
/*  Ejemplo en C nº 73:      */ 
/*  c073.c                   */ 
/*                           */ 
/*  Manejo básico de         */ 
/*  punteros                 */ 
/*                           */ 
/*  Curso de C,              */ 
/*    Nacho Cabanes          */ 
/*---------------------------*/ 
 
#include <stdio.h> 
#include <stdlib.h> 
 
main() { 
  float n1;           /* Primer número, estático */ 
  float *n2, *suma;   /* Los otros dos números */       
   
  n1 = 5.0;           /* Damos un valor prefijado a n1 (real) */ 
  n2 = (float *) malloc (sizeof(float)); /* Reservamos espacio para n2 */ 
  *n2 = 6.7;          /* Valor prefijado para n2 (puntero a real) */ 
   
  suma = (float *) malloc (sizeof(float)); /* Reservamos espacio para suma */ 
  *suma = n1 + *n2;   /* Calculamos la suma */ 
   
  printf("El valor prefijado para la suma era %4.2f\n", 
    *suma); 

printf("Ahora es tu turno: Introduce el primer número "); 
  scanf("%f",&n1);   /* Leemos valor para n1 (real) */ 
   
  printf("Introduce el segundo número "); 
  scanf("%f",n2);    /* Valor para n2 (puntero a real) */   
 
  *suma = n1 + *n2;  /* Calculamos nuevamente la suma */ 
   
  printf("Ahora la suma es %4.2f\n", *suma); 
 
  free(n2);          /* Liberamos la memoria reservada */ 
  free(suma); 
} 

A la hora de meternos en la aritmética de punteros cabe destacar que, en estos casos, los operadores unarios de incremento y decremento no funcionan como una variable estática. Por ejemplo, si tenemos un puntero i y ejecutamos i++, el valor de i no se incrementará en uno, lo que ocurrirá es que la dirección a la que apunta el puntero se incrementará, apuntando hacia el siguiente elemento (Por ejemplo, si i es un entero y apunta a la posición 1000, i++ le hará apuntar a la posición 1004 en un sistema de 32bits, donde un entero ocupa 4bytes). Si queremos incrementar el valor almacenado en el puntero i debemos acceder a él, por lo que deberíamos haber usado (*i)++. Hay que tener cuidado con esto, porque si movemos accidentalmente la posición del puntero podríamos apuntar a una posición de memoria sin reservar que haga romper el programa.

En la página de Nacho Cabanes que os cité antes, y de la que saqué el ejemplo, tenéis un manual muy bueno y claro de introducción a C. No dudéis en descargarlo o en consultarlo on-line cuando lo necesitéis, porque es muy bueno.

Anuncios

3 comentarios en “Punteros en C

  1. Tienes una discrepancia en las diferentes líneas de printf. SI los argumentos numéricos se pasan por valor, todos los punteros deberían pasarse así: *puntero. Y las variables enteras así: variable. Sinembargo en un caso haces: &variable y en otro haces: puntero (sin *).

    Gracias por recordarme aquellos tiempos del C.

    1. Es un ejemplo sacado de un manual, no es mío. Manual que puede ser consultado en el enlace que adjunté en el artículo (y manual que recomiendo). De todas formas, lo hace así para poner tanto un ejemplo de ambas formas de pasarlo.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s