elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Sigue las noticias más importantes de seguridad informática en el Twitter! de elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..  (Leído 2,281 veces)
digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« en: 10 Febrero 2019, 00:43 am »

Hola amigos..

pues tal como se lee en el título, seguramente me creerán idiota o algo por el estilo (asumo que es muy probable que sea así después de hacer esta pregunta)..

Creí que los punteros tenían un poder enorme en la programación, referencia memoria en vez de valor, supuse que era la opción perfecta para interactuar con muchos datos, pero después de ver que los arreglos y matrices internamente se procesan como punteros (pues son las reglas que conozco al menos de manejar mucha información) no le hallé mas sentido a los punteros, es decir... si tengo :

Código
  1.  
  2. int numero = 5;
  3.  
  4. void ConsultarNumero(){
  5.   cout << "Numero es : " << numero << endl;
  6. }
  7.  
  8. void ModificarNumero(){
  9.    numero = 6;
  10. }
  11.  
  12. void SumarUnoAlNumero(){
  13.     numero++;
  14. }
  15.  
  16.  

En vez de :

Código
  1.  
  2. int main (){
  3.   int * numero = new int;
  4.   *numero = 5;
  5.   consultarNumero(numero);
  6.   modificarNumero(numero, 6);
  7.   sumarUnoAlNumero(numero);
  8.  
  9. }
  10.  
  11. void consultarNumero(int * _numero){
  12.     cout << "El numero es : " << *_numero << endl;
  13. }
  14.  
  15. void modificarNumero(int * _numero, int _nuevoNumero){
  16.    *_numero = _nuevoNumero;
  17. }
  18.  
  19. void sumarUnoAlNumero(int * _numero){
  20.    *_numero++;
  21. }
  22.  
  23.  
  24.  


Como verán, simplemente reemplacé el puntero por una variable global, de todas formas sin puntero estoy accediendo a una variable compartida sin la necesidad de consultar su memoria...

Alguien me podría guiar sobre el uso de punteros?
Gracias de antemano.


En línea

Dungeons & dragons;
dragons.Attack();
EdePC
Moderador Global
***
Desconectado Desconectado

Mensajes: 2.041



Ver Perfil
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #1 en: 10 Febrero 2019, 02:26 am »

Saludos,

- La utilidad de los punteros está más enfoca al uso eficiente de la Memoria, lo que se dice Memoria Dinámica, ya has tocado los temas de Listas Enlazadas, Variables de tamaño variable en tiempo de ejecución, etc.

- Te recomiendo este libro, en su página 155 habla sobre el uso de los Punteros y muchos ejemplos donde demuestra el porqué de su uso:
https://openlibra.com/es/book/fundamentos-de-programacion-con-el-lenguaje-de-programacion-c-ed-2017

Capítulo 12

Memoria Dinámica. Punteros

Hasta ahora, todos los programas que se han visto en capítulos anteriores almacenan su estado
interno por medio de variables que son automáticamente gestionadas por el compilador. Las varia-
bles son creadas cuando el flujo de ejecución entra en el ámbito de su definición (se reserva espacio
en memoria y se crea el valor de su estado inicial), posteriormente se manipula el estado de la varia-
ble (accediendo o modificando su valor almacenado), y finalmente se destruye la variable cuando el
flujo de ejecución sale del ámbito donde fue declarada la variable (liberando los recursos asociados
a ella y la zona de memoria utilizada). A este tipo de variables gestionadas automáticamente por el
compilador se las suele denominar variables automáticas (también variables locales), y residen en
una zona de memoria gestionada automáticamente por el compilador, la pila de ejecución, donde
se alojan y desalojan las variables locales (automáticas) pertenecientes al ámbito de ejecución de
cada subprograma.

Así, el tiempo de vida de una determinada variable está condicionado por el ámbito de su decla-
ración. Además, el número de variables automáticas utilizadas en un determinado programa está
especificado explícitamente en el propio programa, y por lo tanto su capacidad de almacenamiento
está también especificada y predeterminada por lo especificado explícitamente en el programa.
Es decir, con la utilización única de variables automáticas, la capacidad de almacenamiento de
un determinado programa está predeterminada desde el momento de su programación (tiempo de
compilación), y no puede adaptarse a las necesidades reales de almacenamiento surgidas durante
la ejecución del programa (tiempo de ejecución). (1)

La gestión de memoria dinámica surge como un mecanismo para que el propio programa, du-
rante su ejecución (tiempo de ejecución), pueda solicitar (alojar) y liberar (desalojar) memoria
según las necesidades surgidas durante una determinada ejecución, dependiendo de las circuns-
tancias reales de cada momento de la ejecución del programa en un determinado entorno. Esta
ventaja adicional viene acompañada por un determinado coste asociado a la mayor complejidad
que requiere su gestión, ya que en el caso de las variables automáticas, es el propio compilador el
encargado de su gestión, sin embargo en el caso de las variables dinámicas es el propio programa-
dor el que debe, mediante código software, gestionar el tiempo de vida de cada variable dinámica,
cuando debe ser alojada y creada, como será utilizada, y finalmente cuando debe ser destruida
y desalojada. Adicionalmente, como parte de esta gestión de la memoria dinámica por el propio
programador, la memoria dinámica pasa a ser un recurso que debe gestionar el programador, y se
debe preocupar de su alojo y de su liberación, poniendo especial cuidado y énfasis en no perder
recursos (perder zonas de memoria sin liberar y sin capacidad de acceso).

1 En realidad esto no es completamente cierto, ya que en el caso de subprogramas recursivos, cada invocación
recursiva en tiempo de ejecución tiene la capacidad de alojar nuevas variables que serán posteriormente desalojadas
automáticamente cuando la llamada recursiva finaliza.


En línea

digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #2 en: 10 Febrero 2019, 03:04 am »

Saludos,

- La utilidad de los punteros está más enfoca al uso eficiente de la Memoria, lo que se dice Memoria Dinámica, ya has tocado los temas de Listas Enlazadas, Variables de tamaño variable en tiempo de ejecución, etc.

- Te recomiendo este libro, en su página 155 habla sobre el uso de los Punteros y muchos ejemplos donde demuestra el porqué de su uso:
https://openlibra.com/es/book/fundamentos-de-programacion-con-el-lenguaje-de-programacion-c-ed-2017

Capítulo 12

Memoria Dinámica. Punteros

Hasta ahora, todos los programas que se han visto en capítulos anteriores almacenan su estado
interno por medio de variables que son automáticamente gestionadas por el compilador. Las varia-
bles son creadas cuando el flujo de ejecución entra en el ámbito de su definición (se reserva espacio
en memoria y se crea el valor de su estado inicial), posteriormente se manipula el estado de la varia-
ble (accediendo o modificando su valor almacenado), y finalmente se destruye la variable cuando el
flujo de ejecución sale del ámbito donde fue declarada la variable (liberando los recursos asociados
a ella y la zona de memoria utilizada). A este tipo de variables gestionadas automáticamente por el
compilador se las suele denominar variables automáticas (también variables locales), y residen en
una zona de memoria gestionada automáticamente por el compilador, la pila de ejecución, donde
se alojan y desalojan las variables locales (automáticas) pertenecientes al ámbito de ejecución de
cada subprograma.

Así, el tiempo de vida de una determinada variable está condicionado por el ámbito de su decla-
ración. Además, el número de variables automáticas utilizadas en un determinado programa está
especificado explícitamente en el propio programa, y por lo tanto su capacidad de almacenamiento
está también especificada y predeterminada por lo especificado explícitamente en el programa.
Es decir, con la utilización única de variables automáticas, la capacidad de almacenamiento de
un determinado programa está predeterminada desde el momento de su programación (tiempo de
compilación), y no puede adaptarse a las necesidades reales de almacenamiento surgidas durante
la ejecución del programa (tiempo de ejecución). (1)

La gestión de memoria dinámica surge como un mecanismo para que el propio programa, du-
rante su ejecución (tiempo de ejecución), pueda solicitar (alojar) y liberar (desalojar) memoria
según las necesidades surgidas durante una determinada ejecución, dependiendo de las circuns-
tancias reales de cada momento de la ejecución del programa en un determinado entorno. Esta
ventaja adicional viene acompañada por un determinado coste asociado a la mayor complejidad
que requiere su gestión, ya que en el caso de las variables automáticas, es el propio compilador el
encargado de su gestión, sin embargo en el caso de las variables dinámicas es el propio programa-
dor el que debe, mediante código software, gestionar el tiempo de vida de cada variable dinámica,
cuando debe ser alojada y creada, como será utilizada, y finalmente cuando debe ser destruida
y desalojada. Adicionalmente, como parte de esta gestión de la memoria dinámica por el propio
programador, la memoria dinámica pasa a ser un recurso que debe gestionar el programador, y se
debe preocupar de su alojo y de su liberación, poniendo especial cuidado y énfasis en no perder
recursos (perder zonas de memoria sin liberar y sin capacidad de acceso).

1 En realidad esto no es completamente cierto, ya que en el caso de subprogramas recursivos, cada invocación
recursiva en tiempo de ejecución tiene la capacidad de alojar nuevas variables que serán posteriormente desalojadas
automáticamente cuando la llamada recursiva finaliza.

Gracias por tu respuesta!

Entonces los punteros están enfocados a ser utilizados en casos donde se requiera solicitar memoria dinámica, por ejemplo la dimensión personalizada de una matriz o arreglo.. verdad?..  y en que otros ámbitos se puede usar?
saludos!
En línea

Dungeons & dragons;
dragons.Attack();
CalgaryCorpus


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #3 en: 10 Febrero 2019, 16:17 pm »

Hay otras situaciones en que los punteros tambien son utiles y muestran su poderio.

Los punteros pueden guardar direcciones de memoria de otras zonas que no has pedido explicitamente, y leer o escribir alli informacion o datos que tu quieras.

Las funciones de tu programa tambien tienen direcciones de memoria y un puntero puede guardar esa direccion y luego ir e invocar esa funcion. Puedes usar esto para, en una clase por ejemplo, hacer que un codigo sirva para multiples propositos, pues la funcionalidad se "inyecta" hacia otra, parecido al patron de dicen~o Strategy.
No es necesario realmente una clase para este uso, una funcion tambien puede recibir como parametro a un puntero a una funcion, para hacer algo parecido a lo mencionado previamente, por ejemplo, la funcion qsort recibe como tercer parametro la direccion de memoria de una funcion
e.g. http://www.cplusplus.com/reference/cstdlib/qsort/
En línea

Aqui mi perfil en LinkedIn, invitame un cafe aqui
Loretz

Desconectado Desconectado

Mensajes: 117


Ver Perfil
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #4 en: 10 Febrero 2019, 17:15 pm »

El uso de punteros en C++ es algo muy excepcional, en los últimos 10 años ya casi nadie en el mundo real usa punteros.

No se usa new, (no se usa delete) se usan smart pointers (std::unique_ptr y std::shared_ptr).

Es más, siempre que se puede elegir entre una variable en la stack (pila, variables de duración automática) o en memoria libre, probablemente la mejor opción sea la stack.

En las funciones de tu ejemplo, en la primera deberías haber pasado una copia del numero; en la segunda y la tercera deberías haber pasado una referencia.

Código:
void consultarNumero(int _numero) {
    cout << "El numero es : " << _numero << endl;
}

void modificarNumero(int& _numero, int _nuevoNumero) {
    _numero = _nuevoNumero;
}

void sumarUnoAlNumero(int& _numero) {
    _numero++;
}

int main() {
    int numero = 5;

    consultarNumero(numero);
    modificarNumero(numero, 6);
    sumarUnoAlNumero(numero);
}



Un caso común en el que suele preferirse un puntero es cuando se necesita interactuar con alguna librería en C, o pasar como parámetro el puntero crudo de un smart pointer, sin transferir el ownership y sabiendo que el tiempo de vida del objeto está manejado por quién invoca la función. También podría pasarse una referencia, pero si el parámetro puede ser nulo no irá una referencia, irá un puntero. Ejemplo:

Código:
struct ObjetoMuyPesado {
    static inline const string BibliotecaDeAlejandria { "Empezando por el catálogo ... " };
    size_t size() const { return BibliotecaDeAlejandria.max_size(); }
};

void cuantosBytes(ObjetoMuyPesado* biblio) {
    if (!biblio)
        throw std::runtime_error("quemada");

    std::cout << "La biblioteca de Alejadnria tiene "
        << biblio->size() << " bytes\n";
}

int main() {
    auto biblio = std::make_unique<ObjetoMuyPesado>();
    cuantosBytes(biblio.get());
}

Cuando eres un principiante te esfuerzas por entender y aprender a usar punteros, es natural, supongo. Cuando ya crees que has aprendido, te sientes orgulloso y quieres mostrar el mundo que sabes usar punteros. Cuando has aprendido algo no usas punteros.

« Última modificación: 10 Febrero 2019, 17:25 pm por Loretz » En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #5 en: 10 Febrero 2019, 19:40 pm »

Por lo que veo C++ ha cambiado mucho; pero en C, un lenguaje mucho más fiel a sus orígenes sí son necesarios los punteros pues el tratamiento de la memoria sigue estando en manos del programador.

Por otra parte si te alejas del modelo de memoria protegido de los uP modernos y sus sistemas operativos y programas para modos reales, uC y estas historias, puedes acceder directamente a diferentes zonas de memoria; así puedes cambiar datos directamente en la memoria de vídeo, acceder a los datos que te proporcionan los sensores y periféricos mapeados en memoria y hacer diferentes cosas que los lenguajes sin punteros no pueden hacer.
En línea

Loretz

Desconectado Desconectado

Mensajes: 117


Ver Perfil
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #6 en: 10 Febrero 2019, 20:38 pm »

Por lo que veo C++ ha cambiado mucho; pero en C, un lenguaje mucho más fiel a sus orígenes sí son necesarios los punteros pues el tratamiento de la memoria sigue estando en manos del programador.

Por otra parte si te alejas del modelo de memoria protegido de los uP modernos y sus sistemas operativos y programas para modos reales, uC y estas historias, puedes acceder directamente a diferentes zonas de memoria; así puedes cambiar datos directamente en la memoria de vídeo, acceder a los datos que te proporcionan los sensores y periféricos mapeados en memoria y hacer diferentes cosas que los lenguajes sin punteros no pueden hacer.

MAFUS; el C++ usa punteros, es el programador de C++ el que ya casi no usa más "punteros crudos", punteros del estilo C.

string, vector, list, unique_ptr, referencias, ... en el fondo son (tienen) punteros, sólo que se usan de manera más segura y eficiente.

No importa cuántos archivos haya en el proyecto, cuántos programadores han estado ahí durante años, en C++ un memory leaks es una rara avis. Y es el programador quien decide el uso de la memoria libre, cuándo tomarla, cuando liberarla, eso siempre fue así. Y con las referencias a rvalues viene también la semántica de move.

Por ejemplo, aprovechando que se mencionó más arriba; nadie usaría qsort en C++, la std::sort de C++ pude ser 10 veces más rápida para hacer lo mismo (no es posible exagerar el énfasis, 10 veces más rápida). https://www.geeksforgeeks.org/c-qsort-vs-c-sort/

En línea

digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Llevo 1 año estudiando C++ aprox., y aún no hallo sentido a los punteros..
« Respuesta #7 en: 11 Febrero 2019, 00:24 am »

Gracias por las respuestas, tendré que enfocarme en qué y cuando usar punteros, lo que pasa es que en mi afán de querer usarlos, cometo errores, típicamente cuando aprendo algo nuevo, me dan ganas de usar ese algo a la fuerza, y no debería pensar asi..

saludos.
En línea

Dungeons & dragons;
dragons.Attack();
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
conexion wifi 10km aprox
Materiales y equipos
carlos35 4 9,344 Último mensaje 27 Abril 2008, 17:37 pm
por novata24
Sobremesa de 750€ aprox.
Hardware
pemortes 8 6,682 Último mensaje 24 Mayo 2011, 00:50 am
por Artikbot
Facebook no quiere recompensar a hacker que halló error en plataforma
Noticias
Mister12 4 2,454 Último mensaje 22 Agosto 2013, 17:31 pm
por topomanuel
Windows se ralentiza por 20 minutos (aprox)
Windows
ߣ@î§ 7 3,817 Último mensaje 29 Diciembre 2014, 03:08 am
por ߣ@î§
El robot Curiosity halló indicios de agua salada en Marte
Foro Libre
El_Andaluz 9 2,590 Último mensaje 17 Abril 2015, 14:55 pm
por Orubatosu
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines