Anuncios Google

Comprendiendo los punteros

Tutoriales de Programaciones

El principal problema que encuentran los que se meten con la programación en C/C++, sean nuevos o con experiencia en otros lenguajes de más alto nivel, es el tema de los punteros. Un puntero, es simplemente un dato o variable que contiene una dirección de memoria.

Voy a intentar hacer un símil con la vida real, así que poned un poco las neuronas imaginativas a trabajar.

Imaginad que trabajáis en un banco, de los que salen en las péliculas que tienen cajas de seguridad personales. Son esos cajones numerados pegados en la pared que están dentro de una enooorme caja fuerte en los que la gente de dinero guarda cosas importantes. Bien, pues nosotros somos un trabajador de ese banco, y nos han asignado la tarea de revisar una fila de cajas, de la 110 a la 140. Para revistar esas cajas nos han dado un montón de llaves cada una con un número atado a una cuerda, y esos número van de... ¡¡¡SÍ lo has adivinado!!!, del 110 al 140

INCISO: Valeee en esos bancos no se pueden abrir las cajas sin permiso de los propietarios si no es por una orden judicial, pero es mi Banco y hago con él lo que me da la gana :P

Voy a enumerar algunas cosas que se encuentran en las cajas (Núm. de caja --> lo que tiene)

112 --> Lingote de plata  
118 --> Una llave con el número 133
125 --> Diamante
133 --> Taitantos mil €uros.

¿Todo el mundo se lo ha imaginado ya?. Si tú aún no, abre el notepad/vim y escribe 100 veces (no vale copy/paste) "Veré menos televisión y visitaré más scenebeta.com". ¡Y escríbelo con tildes!. Cuando acabes vuelve a leerlo hasta que te sitúes.

Entonces tenemos las siguientes similitudes:
    El banco --> Es el sistema operativo, el que nos a asignado la memoria (las cajas)
    Nosotros --> Somos el programa que se ejecuta en el SO. (vamos el currante pringaillo)
    Las cajas --> Son las direcciones de memoria (tienen una posición y un contenido)
    Las llaves --> Son los punteros. Acuerdate que cada llave tiene un número (dirección de memoria) atado.
    Lo que hay en las cajas --> El contenido de las cajas sería el contenido de la memoria o de las variables que usemos

Os dejo el programa de ejemplo. He usado variables de cadenas de texto para que los resultado sean más claros, de ahí a usar [0] (primer carácter de la cadena), una dato simple tipo int ó float, no llevaría ese [0]:

#include <iostream>
using namespace std;
int main()
{
    //Las cajas se declaran como variable "normales"
    //Excepto la 118 que apuntaba a la 133
    //Es decir que contiene una llave
    char caja112[50] = "un lingote de plata";
    char *caja118[50];  //Es un puntero que apuntará a la 133
    char caja125[50] = "un diamante";
    char caja133[50] = "taitantos mil euros";
 
    //La caja118 apunta a la dirección de memoria de la caja133
    caja118[0] = &caja133[0];
 
    //Con el asterico indicamos que se trata de un puntero
    char *pllave112[50];
    //Un puntero que apunta a otro puntero
    //O lo que es lo mismo, una llave que apunta a otra llave :D
    char **pllave118;
    char *pllave125[50];
    char *pllave133[50];
 
    //Asignamos a cada llave una caja
    pllave112[0] = &caja112[0];
    *pllave125 = caja125;
    *pllave133 = caja133;
    pllave118 = &caja118[0];
    *pllave118 = caja118[0];
 
    //Lógicamente las llaves tiene una dirección de memoria aletoria
    //Pero echadle imaginación y pensad que son las direcciones 0x112,..
    cout << hex <<
        "La llave 112 apunta a " << &pllave112 << endl <<
        "\ty en la caja hay " << caja112 << " (" << *pllave112 << ")" << endl;
    cout << hex <<
        "La llave 125 apunta a " << &pllave125 << endl <<
        "\ty en la caja hay " << caja125 << " (" << *pllave125 << ")" << endl;
    cout << hex <<
        "La llave 133 apunta a " << &pllave133 << endl <<
        "\ty en la caja hay " << caja133 << " (" << *pllave133 << ")" << endl;
    cout << hex <<
        "La llave 118 apunta a " << &pllave118 << endl <<
        "\ty en la caja hay " << *caja118 << " (" << *pllave118 << ")" << endl;
}

Esta sería la salida del programa
La llave 112 apunta a 0xbf9601ec
        y en la caja hay un lingote de plata (un lingote de plata)
La llave 112 apunta a 0xbf960124
        y en la caja hay un diamante (un diamante)
La llave 133 apunta a 0xbf96005c
        y en la caja hay taitantos mil euros (taitantos mil euros)
La llave 118 apunta a 0xbf960414
        y en la caja hay taitantos mil euros (taitantos mil euros)

    
Bueno, os voy a comentar las lineas que os puedan llevar a más confusión.

char *caja118[50]

    Al ponerle el asterisco delante  estamos diciéndole al compilador que esa variable es un puntero, acordáos que la caja de 118 tiene otra llave que abre la 133

char **pllave118;

    Esto es un puntero que apunta a otro puntero. Es decir, la llave es un puntero, si la declaramos como un puntero normal, con la llave cogeríamos otra llave, PERO queremos que la llave coja "a lo que apunta" la 133. A esto se le llama indirección.

    

pllave112[0] = &caja112[0];
*pllave125 = caja125;   

    Aquí tenemos 2 formas de decir lo mismo, en el primer caso decimos "la variable puntero 112 toma el valor de la dirección de memoria de la caja 112", y en el segundo "el contenido de la dirección a la que apunta el 125, toma el valor de la caja 125".     Si os lo leéis detenidamente, ambas cosas son lo mismo.
    
    Ojo porque hemos usado [0] en pllave112 para indicar la primera dirección de memoria de la cadena, en la segunda no usamos índice porque al decir "el contenido de" ya estamos indicando explícitamente esa dirección.
    
Para terminar, comentaros que no os desaniméis si os cuesta entenderlo enseguida, la mejor forma de hacerlo es experimentar por vuestra cuenta. Practicando conseguiréis dominarlos enseguida.

4.67857
Tu voto: Ninguno Votos totales: 4.7 (28 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.

pspgorrister

 pspgorrister , todos sabemos siempre de algo, pero para dar tutos no tan facil se le entiende a cualquiera,

mis respetos para ti y para Tanos, que he seguido la secuencia y explican como lo decimos aca en castellano comparando con ejemplos de cosas de la vida, y poniendo la explicacioncita dentro del codigo,

se entiende a la perfeccion nosotros los novatos, adelante con los demas Tutoriales que sigo avanzando leyendolos y aprendiendo!!!

 

Saludos,

 

tambien se le llama APUNTADORES

Tambien se les llama Apuntadores, y Memoria Dinamica. tego varios libros en pdf si alguien los quiere mandeme un privado. exitos a todos

Imagen de Guillermo_Cornielle

Petición de novato

Podrias hacer un tuto en el cual expliques como cambiar los valores a los arrays y a todo lo que se pueda modificar con los punteros???

Un saludo y gracias de antemano.


Manual del Perfecto Votante Para un voto libre y justo!.

TheGCProjects

Imagen de pspgorrister

Re: tuto

Te refieres a un tuto para manejar variables (sean arrays, estructuras, etc) a través de punteros, ¿no?

Imagen de Guillermo_Cornielle

Seee

Pues eso es lo que me da más prblemas de aprender los punteros.

Y de paso, si es que puedes y tienes tiempo, un tuto sobre elmanejo de strings no estaria mal, disculpa si soy muy exigente.

Un saludo gorrister.


Manual del Perfecto Votante Para un voto libre y justo!.

TheGCProjects

Imagen de burnxez

Muy bueno el tuto

La verdad, si que me ha ayudado a comprender los punteros, antes se me hacia algo muy extraño y no lo entendia, la primera vez que lei sobre ellos pensé que se trataba del puntero del ordenador xD

Saludos

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.