• Jueves 2 de Mayo de 2024, 05:19

Autor Tema:  Duda novato punteros  (Leído 3348 veces)

nmaxcom

  • Nuevo Miembro
  • *
  • Mensajes: 20
    • Ver Perfil
Duda novato punteros
« en: Lunes 28 de Septiembre de 2009, 14:34 »
0
Buenas, estoy empezando con C++ leyendo de aquí y de allá y me he atascado con el tema punteros en este manual:

Citar
int *entero;
Debes tener muy claro que "entero" es una variable del tipo "puntero a int", y que
"*entero" NO es una variable de tipo "int".

De acuerdo, una variable puntero sólo almacenará una dirección de memoria a la que apunta. O sea que nunca puede hacer de "contenedor" o de variable normal, nunca almacenará nada que no sea una dirección de memoria, ¿no? Más abajo leo:

Código: C++
  1. int main(){
  2. int*a;
  3. a=new int;
  4. *a=10;
  5. }
  6.  

Acostumbrado a leer cosas tipo a = &variable, en las que se inicia al puntero y hace que apunte a una variable, me surge la duda.
Si *a, por ser puntero, no puede hacer nunca de variable normal sino que en este caso es un puntero de tipo int que debería apuntar a una variable...donde está exactamente el número 10 almacenado? La teoría me dice que "a" sólo está apuntando a una variable de tipo int que contiene el numero 10. Y bien, donde está esa variable? Como se llama?

Gracias!

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Duda novato punteros
« Respuesta #1 en: Lunes 28 de Septiembre de 2009, 16:30 »
0
Cita de: "nmaxcom"
La teoría me dice que "a" sólo está apuntando a una variable de tipo int que contiene el numero 10. Y bien, donde está esa variable? Como se llama?
No existe tal variable. El dato ya lo tienes referenciado por *a. Ten en cuenta que en un computador, los datos se almacenan en la memoria, y ésta no es más que un conjunto de celdas con direcciones. Un puntero es simplemente lo que su nombre indica, un apuntador a una dirección de memoria (en realidad ES una dirección de memoria, igual que todas las variables).

Si quieres realmente entender qué se esconde detrás de un lenguaje de programación de alto nivel (como C y C++), te aconsejo unos cuantos enlaces:

http://en.wikipedia.org/wiki/Von_Neumann_architecture
http://www.springerlink.com/content/978-1-84882-255-9
http://www.intel.com/products/processor/manuals/

nmaxcom

  • Nuevo Miembro
  • *
  • Mensajes: 20
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #2 en: Lunes 28 de Septiembre de 2009, 19:21 »
0
Referenciado...pero donde? Es que no le veo la lógica con lo que he leído. A ver si me puedes ayudar de otra forma:

Por qué esto es incorrecto

Código: C++
  1. int main ()
  2. {
  3.     char *flux;
  4.     *flux = "test";
  5. }
  6.  

Pero en cambio esto no?

Código: C++
  1. int main ()
  2. {
  3.     char *flux = "test";
  4. }
  5.  
  6.  


Y a parte de esto, para no darte tanto la brasa, hay alguna documentación, aunque sea muy extensa, sobre los punteros en C++? Que se centre en el tema de punteros. Por que he mirado incluso algun videotutorial sobre punteros y no me surge ninguna duda, pero con los ejemplos que pone este manual ya me pierdo y veo que me falta mucho por entender.
Por que si no investigo y entiendo la profunda raiz de todas las cosas y el "por qué" no soy captar de pillar ni las más sencillas :P

Muchas gracias

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Duda novato punteros
« Respuesta #3 en: Martes 29 de Septiembre de 2009, 10:24 »
0
Primero, te aclaro una cosilla: en un SO moderno los recursos del ordenador son administrados por el mismo SO. Es decir, las aplicaciones que corren encima del SO necesitan "perdirle" al SO permiso para usar ciertos recursos, que el mismo SO les asigna. Aclarado esto, sigamos.

Código: C
  1. int main ()
  2. {
  3.     char *flux = "test";
  4. }
  5.  
Aquí conviene tener en cuenta cómo funciona un compilador. Al asignar un valor en la misma declaración del puntero (es decir, una asignación estática), el compilador automáticamente reserva la memoria necesaria para la cadena de caracteres. Aquí tienes otro ejemplo de asignación estática:

Código: C
  1. int main ()
  2. {
  3.     char flux[20];
  4. }
  5.  
Reserva un espacio de 20 char.

Sin embargo, aquí:

Código: C
  1. int main ()
  2. {
  3.     char *flux;
  4.     *flux = "test";
  5. }
  6.  
Sólo declaras un puntero, pero no reservas la memoria (que debes pedir al SO). Es decir, sólo reservas la memoria para el puntero (32 bits por ejemplo), pero no para la cadena "test" (6 caracteres, 6 bytes). Tendrías primero que pedírsela al SO:

Código: C
  1. int main ()
  2. {
  3.     char *flux;
  4.     int len;
  5.     // Tamaño de la cadena
  6.     len = strlen("test");
  7.     // Reservamos la memoria (tamaño de cadena + 1)
  8.     flux = malloc(len+1);
  9.     // Ponemos la memoria a 0
  10.     memset(flux, 0, len+1);
  11.     // Copiamos la cadena en la memoria reservada
  12.     strcpy(flux, "test");
  13. }
  14.  
malloc() es el equivalente en C de new en C++, pero para tipos que no son clases (como char*). De todas formas, en C++ es aconsejable usar la clase string en vez de char* y utilizar siempre punteros a clases.

Ten en cuenta que el manejo de punteros nos da más control sobre qué estamos haciendo, pero también convierte tareas aparentemente sencillas en bastante más tediosas que en otros lenguajes de más alto nivel, que abstraen este tipo de detalles. Sin embargo, con tener más control podemos hacer que nuestro código corra más rápido que código generado automáticamente.

Cita de: "nmaxcom"
hay alguna documentación, aunque sea muy extensa, sobre los punteros en C++?
Los punteros en C++ son idénticos a los de C. Yo siempre aconsejo documentación en inglés porque suele ser mucho más completa y más fácilmente accesible:

http://www.google.es/search?client=fire ... gle+Search

Cualquier duda, no dudes en postear, pa eso estamos ;)

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #4 en: Martes 29 de Septiembre de 2009, 10:38 »
0
No; el problema aca no es de memoria:
Código: C++
  1. int main ()
  2. {
  3.   char *flux;
  4.   *flux = "test";
  5. }
  6.  

El problema es que no podes asignarle a un caracter un puntero a cadena, *flux esta desreferenciando el puntero al primer caracter al que apunta flux (indefinido). Esto es perfectamente valido:

Código: C++
  1. int main ()
  2. {
  3.   char *flux;
  4.   flux = "test";
  5. }
  6.  

Lo normal es que el compilador ponga esa cadena en la seccion de datos de solo lectura.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Duda novato punteros
« Respuesta #5 en: Martes 29 de Septiembre de 2009, 10:58 »
0
Cierto, Eternal Idol, disculpad los dos mi despiste  :wacko:

nmaxcom

  • Nuevo Miembro
  • *
  • Mensajes: 20
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #6 en: Martes 29 de Septiembre de 2009, 14:59 »
0
Cita de: "Eternal Idol"
El problema es que no podes asignarle a un caracter un puntero a cadena

Pero cuando hago char *flux = "test"; también estoy asignando a un caracter un puntero a cadena no? Y el compilador no se queja  :huh:  De hecho esta expresión es equivalente a char flux[] = "test";, ¿no? Por eso se parecen tanto punteros a arrays tengo entendido.

Muchas gracias a los dos. Con la explicación de m0skit0 he aclarado muchas cosas pero con la correcion de Eternal me he vuelto a perder  :P

He escogido este link cplusplus.com/doc/tutorial/pointers/ que tiene muy buena pinta y cuando vuelva por la tarde a ver si me da tiempo de leerlo y me queda claro el tema punteros. También me conseguí bajar el Principles and Practice Using C++ de Stroustrup. Es una locura de tocho (1200 páginas!!) pero he leído buenas críticas, lo conocéis? Qué os parece para mi? No digo que tenga la ilusa intención de leermelas todas pero... ^_^

Con lo rápido que había avanzado desde 0 hasta aquí y el encasquillamiento que he cogido con el tema punteros jeje

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #7 en: Martes 29 de Septiembre de 2009, 15:47 »
0
No, no es lo mismo, lo mismo es lo que te mostre justo debajo.

En uno estas asignando al PUNTERO la direccion de la cadena, en el otro intentas asignar a un caracter la direccion de la cadena.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

r0d

  • Miembro activo
  • **
  • Mensajes: 37
  • Nacionalidad: fr
    • Ver Perfil
    • http://r0d.developpez.com/index-es.php
Re: Duda novato punteros
« Respuesta #8 en: Martes 29 de Septiembre de 2009, 16:10 »
0
Es por eso que en C++ no se usa char*, que es C, sino la clase std::string.
La clase string resuelve todos estos problemas de sintaxis, de gestión de la memoria, etc.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #9 en: Martes 29 de Septiembre de 2009, 16:35 »
0
En realidad no:

Código: C++
  1. std::string *flux;
  2. *flux = "test";
  3.  

La situacion es la misma, accedemos a un puntero indefinido e incluso compila ...

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

r0d

  • Miembro activo
  • **
  • Mensajes: 37
  • Nacionalidad: fr
    • Ver Perfil
    • http://r0d.developpez.com/index-es.php
Re: Duda novato punteros
« Respuesta #10 en: Martes 29 de Septiembre de 2009, 17:39 »
0
lo que queria decir, es que usando un string, no se necesita usar un puntero
Código: Text
  1. std::string flux="test";
  2.  
o
Código: Text
  1. std::string flux("test");
  2.  
he aprendido c++ con las frases: "nunca un puntero en un tipo nativo" y "una referencia cuando puedes, un puntero cuando no es posible hacerlo de otra manera" es por eso que... bueno, es otra manera de ver las cosas, pero al final es igual. El unico es que hay que hacerlo bien ;)

nmaxcom

  • Nuevo Miembro
  • *
  • Mensajes: 20
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #11 en: Martes 29 de Septiembre de 2009, 18:01 »
0
Cita de: "Eternal Idol"
En realidad no:

Código: C++
  1. std::string *flux;
  2. *flux = "test";
  3.  

La situacion es la misma, accedemos a un puntero indefinido e incluso compila ...


¡Exacto! ¡Ahí viene mi quebradero de cabeza!

No sólo me interesa aprender C++ (me limitaria a usar string como decís y fuera), también quiero entender plenamente conceptos tan importantes como me parece que lo es este, así como poder comprender programas en C original.

r0d

  • Miembro activo
  • **
  • Mensajes: 37
  • Nacionalidad: fr
    • Ver Perfil
    • http://r0d.developpez.com/index-es.php
Re: Duda novato punteros
« Respuesta #12 en: Martes 29 de Septiembre de 2009, 19:05 »
0
ha vale, habia mal entendido el asunto. Disculpas.  :nosweat:

nmaxcom

  • Nuevo Miembro
  • *
  • Mensajes: 20
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #13 en: Martes 29 de Septiembre de 2009, 22:16 »
0
Bueno, la verdad es que ese link de cplusplus me ha aclarado mucho, creo que ya lo tengo claro el por qué. ¿Ha quedado alguna duda en el aire? xD

Sobre el libro no habéis dicho nada..

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Duda novato punteros
« Respuesta #14 en: Miércoles 30 de Septiembre de 2009, 18:51 »
0
Cita de: "nmaxcom"
También me conseguí bajar el Principles and Practice Using C++ de Stroustrup. Es una locura de tocho (1200 páginas!!) pero he leído buenas críticas, lo conocéis? Qué os parece para mi?
Lo siento, ni idea de cuál es...

Cita de: "nmaxcom"
Con lo rápido que había avanzado desde 0 hasta aquí y el encasquillamiento que he cogido con el tema punteros jeje
Eso es sencillamente porque no sabes qué se esconde detrás del telón... Lo que te dije más arriba: si quieres saber el porqué de las cosas, hay que empezar por entender cómo funcionan las cosas a nivel de hardware. Porque al fin y al cabo, el software siempre corre en un cacho de chatarra  ;)

nmaxcom

  • Nuevo Miembro
  • *
  • Mensajes: 20
    • Ver Perfil
Re: Duda novato punteros
« Respuesta #15 en: Jueves 1 de Octubre de 2009, 00:06 »
0
Cita de: "m0skit0"
Eso es sencillamente porque no sabes qué se esconde detrás del telón... Lo que te dije más arriba: si quieres saber el porqué de las cosas, hay que empezar por entender cómo funcionan las cosas a nivel de hardware. Porque al fin y al cabo, el software siempre corre en un cacho de chatarra  ;)

Pues intentaré ir rascando poco a poco. Ahora ya sé un poco de la memoria y del por qué de la imprecision de float. En alguno de los tochos de libros que empiezo a leer van soltando alguna cosilla.

Hice primero de ingeniria informatica (lo tuve que dejar por motivos laborales) y la asignatura que mejor llevaba era física y la que peor estructura de computadores. Parece que me equivoqué de carrera jias jias. Nah ahora en serio, me llama mucho la atención la programación, a ver hasta donde llego.

Cuanto llevas con C/C++ ? Lo autoaprendiste?

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Duda novato punteros
« Respuesta #16 en: Jueves 1 de Octubre de 2009, 11:45 »
0
Cita de: "nmaxcom"
Cuanto llevas con C/C++ ?
Casi 10 años ya (cómo pasa el tiempo  :P )

Cita de: "nmaxcom"
Lo autoaprendiste?
Sí, pero no empecé a aprender a programar con ello, sino que lo aprendía cuando ya sabía un poco de BASIC y Pascal.