Punteros I

Tutoriales de Programaciones

Los punteros son, al igual que las funciones, uno de los mejores amigos que podemos tener en el mundo de la programación. Son difíciles de comprender, pero nos solucionarán muchas carencias que no podemos hacer de otra manera. En este tutorial aprenderemos a utilizarlos, ganando una pequeña base de ellos. En una próxima entrega aprenderemos a exprimirlos al máximo.

¿Qué es un puntero?

Un puntero es una variable corriente, pero tiene una característica especial: Enlaza a otra variable. Y dirás "Vale muy bien, pero, ¿de qué me sirven?". Los punteros tienen muchísimas aplicaciones, que aprenderemos a utilizar en dos tutoriales.

Definición de un puntero

tipo *nombrepuntero [= valor];

Donde tipo iría el clásico tipo que conocemos (int, char, float...), que será el mismo que el de la variable al que apuntará; * el asterisco es un identificador propio de punteros e indicará que la variable declarada es un puntero; nombrepuntero se refiere al identificador del puntero; por último, = valor es algo opcional (por eso están los corchetes, para indicar que es opcional, es decir, en la definición NO pongas corchetes),  como en toda variable, pues el valor se le puede dar más tarde. Por último se cierra la sentencia con ';'.

Ejemplos:

int *c;

char b = 'A';
char *puntb = &b;

float d = 3.54;
float *puntd;
 
...
 
puntd = &d

La primera definición es simple, se define el puntero "c" de tipo int.

El segundo ya empieza a traer más complicaciones. Se define una variable corriente de tipo char on un valor de 'A'. Después, se define otro puntero de tipo float que apunta a la variable b mediante el operador dirección (&), que veremos en el próximo apartado.

Por último tenemos un ejemplo del tipo float. Es similar al anterior solo que la inicialización del puntero va separada del mismo. Destacar que en la inicialización no hay un asterisco delante del nombre del puntero. Esto se explicará en el próximo apartado.

Operadores unarios dirección e indirección

Operador dirección

El operador dirección es representado por el símbolo internacional "and" (&). Se usa para obtener la dirección dentro de la memoria de una variable.

Ejemplo 1

#include <stdio.h>
 
int main(){
   int a = 46;
 
   printf("El valor de a es: %i", a);
   printf("\nLa direccion de a es: %h", &a);
 
   getchar();
   return 0;
}

El programa dará esta salida:

El valor de a es: 46
La direccion de a es: 23ff54

La primera línea nos debería dar a todos igual. La segunda depende de varios factores, como qué programas se han abierto antes, la capacidad de la memoria RAM entre otros, ya que se ha dicho que el operador & representa la dirección dentro de la memoria (para aclarar, con memoria nos referimos a la RAM), y como esta se limpia cuando se apaga el equipo y también la usan otros programas, como ya se ha dicho dependerá de eso.

Como se viene haciendo de antes, sólo explicaremos las partes nuevas o las partes comparativas con las nuevas.

En primer lugar, se define una variable de tipo int llamada 'a' con un valor de 46. Después, mediante la función printf hacemos que se muestre por pantalla su valor. Por último, se usa la función printf de nuevo para mostrar la dirección de a:

printf("\nLa direccion de a es: %x", &a);

Se observan dos cosas nuevas:

  1. En el printf se ha puesto para representar el valor en hexadecimal lo siguiente: %x. Así es como se representan todas las direcciones de memoria. Para aclarar, aquí tenéis una tabla que muestra para qué sirve cada símbolo.
  2. Delante de a se ha puesto el operador unario dirección. Así obtendremos la suya propia y la mostraremos por pantalla.

Ejemplo 2

A continuación crearemos otro programa similar, pero esta vez utilizaremos los punteros para el mismo fin:

#include <stdio.h>
 
int main(){
   int a = 46;
   int *punta = &a;
 
   printf("El valor de a mediante el uso de puntero es: %i", *punta);
   printf("\nEl valor de a directamente usando la variable es: %i", a);
   printf("\nLa direccion de a mediante el uso de ppuntero es: %x", punta);
   printf("\nLa direccion de a usando la variable es: %x", &a);
   printf("\nLa direccion de punta es: %x", &punta);
   printf("\nEl valor de punta es: %x", punta);
 
   getchar();
   return 0;
}

Este programa hace lo siguiente:

  1. Crea una variable "a" de valor 46
  2. Crea un puntero que apunta a la variable "a". Notar el asterisco que precede al nombre de la variable.
  3. Muestra el valor de a mediante el uso de un puntero (*punta, hace uso del operador indirección que aprenderemos en el siguiente apartado)
  4. Muestra el valor de a directamente (usa "a", nada nuevo)
  5. Muestra la dirección de a usando un puntero (punta, es el valor de punta. Su valor es la dirección de "a")
  6. Muestra la dirección de a directamente usando el operador "&" (&a)
  7. Muestra la dirección de punta (el nombre elegido significa puntero a, y no punta como tal) (&punta)
  8. Muestra el valor de punta (notar que el valor de punta es la dirección de a) (punta)

Operador indirección

El operador indirección se representa con un asterisco ("*", no ha de confundirse con el operador multiplicación) y se utiliza para mostrar que una variable es un puntero. Para saber su funcionamiento, mira los ejemplos del apartado anterior. Más adelante se verán otros ejemplos, pero no se ponen en este apartado por ser demasiado avanzados para lo que aún conocemos.

Paso de argumentos por referencia

Hasta ahora venimos usando los punteros pasándolos a las funciones por valor. Esto quiere decir que de un argumento, se hace una copia de la variable con el mismo valor en la función y se procesa, dejando intacta la variable original. Pero ¿y si queremos que el valor de nuestra variable cambie en el curso de la función? Ahí llegan los punteros. En vez de usar una copia, lo que se modifica es el contenido de la dirección de memoria asignada a la variable. Esto todavía te puede parecer dificil de comprender, pero, como siempre, con un par de ejemplos lo comprenderás.

Para comparar el paso de argumentos por referencia del paso de argumentos por valor, haremos el mismo programa dos veces usando un método en cada uno de ellos y comparando los resultados.

/*Paso de argumentos por valor
De P22
Para Scenebeta
12-8-2010*/
 
#include <stdio.h>
 
int main(){
   int a = 2;
   void computar(int a);
 
   printf("a desde main ANTES de llamar a la funcion vale %i\n", a);
 
   computar(a);
 
   printf("a desde main DESPUES de llamar a la funcion vale %i\n", a);
 
   getchar();
   return 0;
}
 
void computar(int a){
   a = a + 2;
   printf("a desde la funcion vale %i\n", a);
   return;
}

Este programa dará la siguiente salida (recuerda que es la version de paso por valor):

a desde main ANTES de llamar a la funcion vale 2
a desde la funcion vale 4
a desde main DESPUES de llamar a la funcion vale 2

A continuación, el mismo programa pero la versión por referencia:

/*Paso de argumentos por valor
De P22
Para Scenebeta
12-8-2010*/
 
#include <stdio.h>
 
int main(){
   int a = 2;
   int *punta = &a;
   void computar(int *punta);
 
   printf("a desde main ANTES de llamar a la funcion vale %i\n", a);
 
   computar(punta);
 
   printf("a desde main DESPUES de llamar a la funcion vale %i\n", a);
 
   getchar();
   return 0;
}
 
void computar(int *a){
   *a += 2;
   printf("a desde la funcion vale %i\n", *a);
   return;
}

Cabe destacar el operador unario indirección (*) tanto en la definición de la función como en su respectivo prototipo.

Este programa generará la siguiente salida:

a desde main ANTES de llamar a la funcion vale 2
a desde la funcion vale 4
a desde main DESPUES de llamar a la funcion vale 4


Hasta aquí es todo. Quiero enfatizar que este tutorial no ha sido realizado expresamente para conocer los punteros al 100 %, sino para obtener una buena base de los mismos. En la próxima entrega de punteros aprenderemos a utilizarlos y exprimirlos al máximo. Hasta entonces te recomiendo que trates de crear programas sencillos para que se te quede en la cabeza lo que llevamos hasta ahora.

4.5
Tu voto: Ninguno Votos totales: 4.5 (44 votos)

Anuncios Google

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de User170294

Mejor Explicado

a mi manera de verlo en este manual que os adjunto se explica de una manera muchísimo más sencilla el tema de los punteros y os quedará mucho más claro. os pongo el link aquí mismo:

link: http://www.scenebeta.com/node/21031

espero que os sirva como me ha servido a mí. salu2


Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.