elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
29 Mayo 2012, 03:05  


Tema destacado: Sigue las noticias más importantes de elhacker.net en ttwitter!

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  [C++] Iniciación al manejo de los punteros
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: [C++] Iniciación al manejo de los punteros  (Leído 6,620 veces)
Horricreu
Wiki

Desconectado Desconectado

Mensajes: 290

¡La verdad os hará libres!


Ver Perfil WWW
[C++] Iniciación al manejo de los punteros
« en: 10 Julio 2010, 00:04 »

INICIACIÓN AL MANEJO DE LOS PUNTEROS



INTRODUCCIÓN

Debido al miedo general que provocan los punteros y, la mala información y explicación en la mayoría de talleres que corren por Internet e incluso en algunos libros, me dispongo a crear este pequeño texto intentando explicarlos lo mejor que pueda ya que cuesta mucho encontrar información decente.



MANEJANDO LOS PUNTEROS

¿Qué es un puntero? Un puntero es una variable que hace referencia a una dirección de memoria, como puede ser 0x000F212A, en hexadecimal. Un ejemplo es:

Código
int a; //Declaración de una variable entera
int *ptr; //Declaración de un puntero

Pero es mejor así:

Código
int a = 0; //Declaración de una variable entera
int *ptr = NULL; //Declaración de un puntero

Otros ejemplos:

Código
char a = 0; //Declaración de una variable de caracteres
char *ptr = NULL; //Declaración de un puntero

Ya hemos visto la declaración de una variable normal y la de un puntero, pero nos preguntamos, ¿y por qué de la segunda manera? Al hacer esto, inicializamos las variables con un valor predeterminado en cambio de la primera forma las variables tienen un valor indeterminado y pueden contener, como llamamos en programación, basura. Recordemos que NULL es una constante declarada en los archivos de cabecera estándar y su valor es 0 o 0x00000000.

Antes de continuar, aclaremos dudas. Hemos visto que un puntero almacena una dirección de memoria como 0x000F212A o NULL y, también hemos dicho que si no sabemos a qué apuntar le asignamos NULL, pero claro, tener una dirección inválida es una estupidez, pero si hacemos por ejemplo:

Código
a = 1;
ptr = &a;

El operador "&" obtiene la dirección de memoria de una variable cuando se aplica a esta. Por lo tanto:

a = 1 => 0x000F212A (imaginemos que tiene esta dirección de memoria).
ptr = &a => 0x000F212A (consecuentemente, aplicando este operador obtenemos la misma dirección de memoria).

Podríamos decir que ptr "apunta a" a. Ahora, para comprobar lo que acabamos de hacer:

Código
std::cout << "a= " << a << std::endl;
std::cout << "ptr= " << *ptr << std::endl;

Lo que nos mostrará en pantalla será:

Código:
a= 1
ptr= 1

Vemos que sale lo mismo. El operador "*" aplicado a una variable de puntero obtiene el valor almacenado en una dirección de memoria indicada por este. Y además, podemos hacer lo siguiente:

Código
*ptr = 2;

Estamos haciendo que el contenido apuntado por ptr almacene ahora: 2. O sea, como ptr apunta a a, es como hacer:

Código
a = 2;

Luego, si hacemos:

Código
std::cout << "a= " << a << std::endl;
std::cout << "ptr= " << *ptr << std::endl;

Lo que nos mostrará ahora en pantalla es:

Código:
a= 2
ptr= 2



ARREGLOS Y PUNTEROS

Un ejemplo de arreglo sería:

Código
int x[4] = {11, 12, 13, 14};

Para este arreglo se le asigna una memoria contigua de la siguiente manera:



A x se le asigna la dirección de memoria del primer elemento del arreglo, en este caso: 11. Ahora vamos a crear un puntero al arreglo y a enseñar lo que pasa, jugando con el puntero:

Código
int *ptr = NULL;
ptr = x;
 
std::cout << *ptr << std::endl;
ptr++;
 
std::cout << *ptr << std::endl;
ptr++;
 
std::cout << *ptr << std::endl;
ptr++;
 
std::cout << *ptr << std::endl;

Lo que nos mostrará en pantalla será:

Código:
11
12
13
14

Antes de empezar, una cosa importante: para que un puntero apunte a un arreglo, no hace falta que tenga el operador "&", ya que un arreglo es un puntero constante y por la misma razón no se puede tampoco incrementar un arreglo.

Bien, ptr apunta al primer elemento del arreglo, en el cual su dirección de memoria es 0x0012FF60. Lo mostramos por pantalla y, lógicamente como hemos puesto el operador "*" antes de ptr nos saldrá el contenido almacenado en esta posición de memoria: 11. Seguidamente, hacemos un postincremento al puntero, por lo tanto aumentará la dirección de memoria y apuntará al segundo elemento del arreglo; la dirección de memoria será 0X0012FF64, recordemos que un entero ocupa 4 bytes. Luego mostramos el contenido de esta dirección de memoria: 12. Hacemos esto hasta llegar al último elemento.



MEMORIA DINÁMICA

Comprendiendo todo lo explicado hasta ahora nos sirve para comprender el funcionamiento y las características más básicas de los punteros, ahora bien, entrando en el sector de la memoria dinámica, profundizamos y obtenemos una mayor potencia de estos mismos. Recordemos que se crea un puntero de la siguiente manera:

Código
int *ptr = NULL;

Recordemos también, que al hacer esto el puntero apunta a una dirección inválida de memoria por lo que hacer:

Código
*ptr = 1;

Sería inválido. Si queremos reservar memora exclusivamente para que nuestro puntero apunte a algo lo hacemos con el operador new. Por ejemplo:

Código
int *ptr = new int;

Con el operador new reservamos memoria dinámica y, se le pasa como operando el tipo de variable a reservar. Luego de esto, se retorna la dirección de esta memoria reservada, por lo que necesitamos obligatoriamente un puntero para acceder a esta memoria.

Pero, al igual que reservamos memoria dinámica, también la podemos borrar o destruir. Y es obligatorio borrar toda esta memoria reservada ya que si no podemos ocasionar un agotamiento de memoria. Por ejemplo:

Código
int *ptr = new int;
delete ptr;

Reservamos memoria exclusivamente para el puntero con el operador new y, la eliminamos al final con el operador delete (el nombre del puntero es el que debe acompañar a delete).



ARREGLOS DINÁMICOS

Ya hemos visto el funcionamiento de la memoria dinámica y cómo utilizarla pero, aún podemos sacarle más jugo al tema. La aplicaremos a los arreglos. Un ejemplo de arreglo utilizando dinámico:

Código
int *ptr = new int[5];

En este caso, reservamos cinco celdas consecutivas, o sea un arreglo y, cada de una de ellas tiene la memoria de un entero, 4 bytes.

Código
for(int n = 0; n < 5; n++) std::cout << ptr[n] << std::endl;

Así ya accedemos a los elementos del arreglo.

La ventaja de utilizar arreglos dinámicos es que puedes establecer su tamaño en tiempo de ejecución, justo al contrario que los arreglos normales. Para establecer el tamaño de un arreglo dinámico, se puede hacer por ejemplo:

Código
int n = 0;
 
std::cin >> n;
 
int *ptr = new int[n];

De la misma forma que se puede eliminar la memoria dinámica normal, también se puede eliminar los arreglos dinámicos. Un ejemplo sería:

Código
int *ptr = new int[5];
delete[] ptr;

La única diferencia con el delete de antes es que sólo se le añaden estos signos "[]" después del delete.



DESPEDIDA

Aquí termina este escrito y, espero que me haya explicado bien y que os haya servido para comprender un poquito más los punteros. Podéis contactar conmigo para cualquier duda que tengáis o simplemente, comentarlo acá.

Saludos :P


« Última modificación: 16 Octubre 2010, 12:00 por Horricreu » En línea

Leo Gutiérrez.
. . .. ... ..... ........ ............. .....................
Colaborador
***
Desconectado Desconectado

Mensajes: 2.968


/^$/


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #1 en: 10 Julio 2010, 00:14 »

Estaría bien que trataras más la aritmética de punteros.

Me gustó, continúa así.


En línea

Código
(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}
 

leorocko13@hotmail.com
https://github.com/leogtzr/
Horricreu
Wiki

Desconectado Desconectado

Mensajes: 290

¡La verdad os hará libres!


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #2 en: 10 Julio 2010, 00:17 »

Estaría bien que trataras más la aritmética de punteros.

Me gustó, continúa así.

¡Sí! Justamente lo pensaba, a ver si mañana me animo y escribo ejemplos de aritmética de punteros ;)

Saludos :P
En línea

isseu


Desconectado Desconectado

Mensajes: 305


°º¤ø,¸¸,El conocimiento es poder°º¤ø,¸¸,ø¤º°`°º¤ø,


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #3 en: 10 Julio 2010, 00:17 »

muy bueno, sigue así
En línea

[Zero]
Wiki

Desconectado Desconectado

Mensajes: 1.065


CALL DWORD PTR DS:[0]


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #4 en: 10 Julio 2010, 00:19 »

Está francamente bien, hace una semana no te veía capaz de escribir algo así, pero me alegro de equivocarme, ojalá lo siga haciendo  ;).

Saludos
En línea


“El Hombre, en su orgullo, creó a Dios a su imagen y semejanza.”
Nietzsche
Daemon Freedom
Wiki

Desconectado Desconectado

Mensajes: 488


typedef struct Nodo


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #5 en: 10 Julio 2010, 00:22 »

Está de 10, como siempre con tus post, solo una pequeña pega, según mi gusto, te has limitado a contar, a tu forma, lo que ya dicen todos los libros y manuales que he visto, y me imagino que la mayoría de los que no he visto. Si intentaras enfocar esto a cosas mas "nuevas" (Sé que es imposible hacer cosas nuevas con esto, pero es para que se me entienda) ya sería mas que perfecto.

Un saludo

Pd. estaría muy bien en la WIki  ;)
« Última modificación: 10 Julio 2010, 00:24 por Daemon Freedom » En línea

Horricreu
Wiki

Desconectado Desconectado

Mensajes: 290

¡La verdad os hará libres!


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #6 en: 10 Julio 2010, 00:22 »

Está francamente bien, hace una semana no te veía capaz de escribir algo así, pero me alegro de equivocarme, ojalá lo siga haciendo  ;).

Saludos

:o ¡Muchas gracias, de verdad! Me vienen ganas de escribir y aprender más :)

Saludos :P

Está de 10, como siempre con tus post, solo una pequeña pega, según mi gusto, te has limitado a contar, a tu forma, lo que ya dicen todos los libros y manuales que he visto, y me imagino que la mayoría de los que no he visto. Si intentaras enfocar esto a cosas mas "nuevas" (Sé que es imposible hacer cosas nuevas con esto, pero es para que se me entienda) ya sería mas que perfecto.

Un saludo

Te juro que hace unas pocas semanas no sabía que era un puntero (estoy exagerando). Leí, leí y leí libros y manuales y, en ninguno me quedaba claro... a ver si con esto queda todo bien clarito. Verás que me repito mucho, para que quede muy bien explicado :)

Y sí, tienes razón, quizás se tiene que cambiar el método de aprendizaje y no ir al método clásico ;) Gracias por tu crítica :)

Saludos :P
« Última modificación: 10 Julio 2010, 11:58 por Horricreu » En línea

Daemon Freedom
Wiki

Desconectado Desconectado

Mensajes: 488


typedef struct Nodo


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #7 en: 10 Julio 2010, 00:28 »

Está de 10, como siempre con tus post, solo una pequeña pega, según mi gusto, te has limitado a contar, a tu forma, lo que ya dicen todos los libros y manuales que he visto, y me imagino que la mayoría de los que no he visto. Si intentaras enfocar esto a cosas mas "nuevas" (Sé que es imposible hacer cosas nuevas con esto, pero es para que se me entienda) ya sería mas que perfecto.

Un saludo

Te juro que hace unas pocas semanas no sabía que era un puntero (estoy exagerando). Leí, leí y leí libros y manuales y, en ninguno me quedaba claro... a ver si con esto queda todo bien clarito. Verás que me repito mucho, para que quede muy bien explicado :)

Y sí, tienes razón, quizás se tiene que cambiar el método de aprendizaje y no ir al método clásico ;) Gracias por tu crítica :)

Saludos :P

Si me das permiso colaboro un poco contigo, que hace tiempo que dejé atrás punteros y al verdad, estoy muy puteado por no recordarlos...  :-\
En línea

Horricreu
Wiki

Desconectado Desconectado

Mensajes: 290

¡La verdad os hará libres!


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #8 en: 10 Julio 2010, 00:30 »

Está de 10, como siempre con tus post, solo una pequeña pega, según mi gusto, te has limitado a contar, a tu forma, lo que ya dicen todos los libros y manuales que he visto, y me imagino que la mayoría de los que no he visto. Si intentaras enfocar esto a cosas mas "nuevas" (Sé que es imposible hacer cosas nuevas con esto, pero es para que se me entienda) ya sería mas que perfecto.

Un saludo

Te juro que hace unas pocas semanas no sabía que era un puntero (estoy exagerando). Leí, leí y leí libros y manuales y, en ninguno me quedaba claro... a ver si con esto queda todo bien clarito. Verás que me repito mucho, para que quede muy bien explicado :)

Y sí, tienes razón, quizás se tiene que cambiar el método de aprendizaje y no ir al método clásico ;) Gracias por tu crítica :)

Saludos :P

Si me das permiso colaboro un poco contigo, que hace tiempo que dejé atrás punteros y al verdad, estoy muy puteado por no recordarlos...  :-\

Como quieras ;) Ponte en contacto conmigo a través del MSN (está en mi perfil).

Saludos :P
En línea

Novlucker
Ninja y
Ex-Staff
*
Desconectado Desconectado

Mensajes: 10.239


Yo que tu lo pienso dos veces


Ver Perfil
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #9 en: 16 Julio 2010, 17:49 »

... te has limitado a contar, a tu forma, lo que ya dicen todos los libros y manuales que he visto, y me imagino que la mayoría de los que no he visto ...

No obstante, conozco a varios con dolores de cabeza cuando recién comienzan con los punteros, y que lo explique así de claro alguien que recién lo entiende tiene su mérito, además de que puede resultar más sencillo para otros que comienzan al igual que él :)

Saludos
En línea

Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD
http://twitter.com/novlucker

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

[L]ord [R]NA


Desconectado Desconectado

Mensajes: 1.507


El Dictador y Verdugo de H-Sec


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #10 en: 16 Julio 2010, 17:59 »

... te has limitado a contar, a tu forma, lo que ya dicen todos los libros y manuales que he visto, y me imagino que la mayoría de los que no he visto ...

No obstante, conozco a varios con dolores de cabeza cuando recién comienzan con los punteros, y que lo explique así de claro alguien que recién lo entiende tiene su mérito, además de que puede resultar más sencillo para otros que comienzan al igual que él :)

Saludos

+1
En línea

.:BlackCoder:.


Desconectado Desconectado

Mensajes: 388


Cada dia C++!!


Ver Perfil
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #11 en: 16 Julio 2010, 19:18 »

Muy bueno, un consejito es que pongas codigos de ejemplos, es decir ejercicios hechos, eso fue lo que mas me costo a mi, la practica  :xD... De hecho todavia creo que no la domino del todo...

Por ahi hay un post mio haciendo un ejercicio que no me salia sobre memoria dinamica y funciones... No tiene mucho sentido pero es muy bueno para ver formas de utilizar memoria dinamica... Te puede servir para hacer ejemplos, o simplemente colocarlo a manera de cultura general  :xD

Saludos... Muy buen aporte...
En línea

"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja



Horricreu
Wiki

Desconectado Desconectado

Mensajes: 290

¡La verdad os hará libres!


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #12 en: 16 Julio 2010, 20:29 »

Muy bueno, un consejito es que pongas codigos de ejemplos, es decir ejercicios hechos, eso fue lo que mas me costo a mi, la practica  :xD... De hecho todavia creo que no la domino del todo...

Por ahi hay un post mio haciendo un ejercicio que no me salia sobre memoria dinamica y funciones... No tiene mucho sentido pero es muy bueno para ver formas de utilizar memoria dinamica... Te puede servir para hacer ejemplos, o simplemente colocarlo a manera de cultura general  :xD

Saludos... Muy buen aporte...

Ya he publicado un ejercicio. Publicaré más si veo que tiene éxito. ¡Animaos todos!

Saludos :P
En línea

Micah Genji

Desconectado Desconectado

Mensajes: 52


learn more to life


Ver Perfil
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #13 en: 1 Agosto 2010, 19:32 »

excelente lo estuve revisando y esta comprensivo.
si pusieras algunos ejemplos con cadena de caracteres seria la joya :)

en fin te mando mi forma de resolverlo el ejercicio, me decis q hago mal

saludos
En línea

Only two things are infinite, the universe and human stupidity, and I'm not sure about the former : A.E
Horricreu
Wiki

Desconectado Desconectado

Mensajes: 290

¡La verdad os hará libres!


Ver Perfil WWW
Re: [TALLER][C++] Empezando a manejar los punteros
« Respuesta #14 en: 2 Agosto 2010, 00:41 »

excelente lo estuve revisando y esta comprensivo.

Gracias ;D

si pusieras algunos ejemplos con cadena de caracteres seria la joya :)

Ahora pongo alguno.

en fin te mando mi forma de resolverlo el ejercicio, me decis q hago mal

saludos

No sé si entendiste el ejercicio. Ahora modifico la información para que se entienda mejor pero a partir de la palabra: queso. Con esta palabra, dividiéndola, se puede mostrar la frase: eso es queso. Una vez sabes esto, haces un arreglo, penor ejemplo:

Código
char palabra[6] = "queso";

Y un puntero al arreglo:

Código
char *ptr = palabra;

A partir de ahí, vas aumentando la posición de memoria del puntero, para que te muestre la palabra y, puedes modificar el contenido de UN elemento. Igualmente, ahora pongo un ejemplo jugando con los arreglos de caracteres y, seguramente lo entenderás mejor.

Saludos :P
« Última modificación: 2 Agosto 2010, 00:44 por Horricreu » En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines