Anuncios Google

[C/C++ Miniguía] Comprendiendo los punteros

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.


LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.


Anuncios Google

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 Guillermo_Cornielle

Perfecto

Me encanta, y sobre todo, loauemas me encanta de C++ es su control de flujo de entrada y salida, peor hay una cosa que em tiene curioso, que significa eso de ''hex'', para que sirve?.

Un saludo.


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

TheGCProjects

Imagen de d.m.n.

el << cout << hex está

el << cout << hex está diciendo que imprima el valor de la direccion que se esta pidiendo que muestre en Hexadecimal, en este caso en que localidad de memoria se situa el arreglo pllave112

"La llave 112 apunta a " << &pllave112 << endl <<"

asi en todos los caso que aparece hex, espero haberte ayudado

 

Imagen de Guillermo_Cornielle

Gracias

Mil gracias, ahora si entiendo todo.

Saludos.

Imagen de d.m.n.

De nada, para eso estamos

De nada, para eso estamos por aqui. :)

Imagen de Churristian8

En breve

En breve lo tendras en portada ;-)

Una cosa que si te pediria, ya que me ayudaria mucho a la hora de pasarlas es que me dieses una descripcion general al principio a modo de cabecera.

Saludos y gracias por las miniguias ;-)

Imagen de pspgorrister

Re: cabecera

"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."

 

¿no vale eso?


LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.

Imagen de Churristian8

Bueno vale

Ese me vale. Pronto lo tendras en portada ;-)

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.