Para que sirven los Punteros?

Iniciado por ..:ALT3RD:.., 16 Octubre 2011, 15:45 PM

0 Miembros y 1 Visitante están viendo este tema.

..:ALT3RD:..

Buenas  :D

ando liado con los estudios asi que desde hace una semana no toco C++ y hoy quería empezar con los punteros ya que según dicen es algo imprescindible en C++. Vi un video sobre punteros en el que explicaban que un puntero es un tipo de variable que contiene una direccion en la memoria. Seguidamente te explicaban como declarar estos punteros y como se usan y para que. Tambien te hacian un pequeño ejercicio.
He usado el buscador pero no he encontrado nada que me aclaré, lo que quiero saber es para que sirven realmente los punteros.
Repito ya se que son un tipo de variable que contiene una direccion en la memoria, pero quiero ejemplos reales de para que se podrian usar y tambien quiero saber a que se debe su importancia.Otra cosa que no entiendo es porque dicen que es tan dificil, yo lo vi como una lección mas de C++, seguramente luego me trague mis palabras pero a simple vista me pareció fácil.


Un salu2!
"Mañana sabrás que hoy no sabes nada"

El_Java

Uno de los ejemplos más comunes para el uso de punteros es el paso de datos extremadamente grandes como argumento de una función.
Imagina que tienes un dato muy grande, y que quieres pasarlo a una función, como ya sabes, los argumentos cuando se pasan se copian, por lo que se puede decir que son dos variables distintas, al tener que copiarlas gastas más memoria.
Para solucionar esto, pasas como argumento un puntero al dato tan grande que quieres pasar, por lo que actúas directamente en el dato.
Un ejemplo:
Código (cpp) [Seleccionar]

void func (long long* dato){
    //dato es un puntero al dato tan grande;
}

int main(){
   long long dato;
   ...
   func(&dato); //Pasas la direccion de dato
   ...
   return 0;
}


Hay muchas más aplicaciones, pero esta es una de las más sencillas.

Pd. me gusta tu avatar ;)

..:ALT3RD:..

Digamos en resumen que sirven para optimizar el programa no?


PD: Y a mi el tuyo  :silbar: Bueno supongo que no es raro encontrar dos avatares de Ubuntu en un foro de Informatica   ;D ;D
"Mañana sabrás que hoy no sabes nada"

El_Java

#3
Pienso que eso es generalizar demasiado, pero se puede decir que sí que sirven para eso.
Tambien se usan para moverte estructuras dinamicas (TLA, creo que era), para el poliformismo de clases, para pasar cualquier argumento haciendo un casting (void *), etc...

rir3760

Aclaro que lo siguiente es en relación a C, la mayoría también aplica a C++ pero tienen sus diferencias así que, cuidado.

Una de las razones, como ya te comento El_Java, es para evitar la copia del argumento. Siguiendo su ejemplo otra ventaja es la posibilidad (mediante indireccion) de modificarlo. Sin embargo C++ agrego las referencias que solucionan ambos problemas.

Otra razón es la capacidad de indicar el uso de una función en particular (en C++ son los famosos predicados). Ya que los objetos y las funciones son entidades distintas la única forma de indicar una función es mediante un puntero a esta.

El mejor ejemplo en la biblioteca estándar de C son las funciones bsearch y qsort, como sus nombres lo indican la primera busca y la segunda ordena cualquier tipo de array. El problema es el método de comparación, ya que dependiendo del tipo se debe realizar una comparación distinta. Ello se soluciona con el paso de un puntero a función.

Un ejemplo de qsort para ordenar un array de enteros:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define NUM_ELEM 16

int fn_cmp(const void *p, const void *q);

int main(void)
{
   int i, num[NUM_ELEM];
   
   srand((unsigned) time(NULL));
   
   printf("Array sin ordenar:");
   for (i = 0; i < NUM_ELEM; i++){
      num[i] = rand() % NUM_ELEM;
      printf("%3d", num[i]);
   }
   puts("");
   
   /* Ordenar el array de forma ascendente (menor a mayor) */
   qsort(num, (size_t) NUM_ELEM, sizeof(num[0]), fn_cmp);
   
   printf("Array ordenado:   ");
   for (i = NUM_ELEM; i > 0; i--)
      printf("%3d", num[i - 1]);
   puts("");
   
   return EXIT_SUCCESS;
}

int fn_cmp(const void *p, const void *q)
{
   int a = *(int *) p;
   int b = *(int *) q;
   
   if (a < b)
      return -1;
   else if (a == b)
      return 0;
   else
      return 1;
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

..:ALT3RD:..

Me va quedando mas claro, Un salu2 y Gracias  ;)
"Mañana sabrás que hoy no sabes nada"

pucheto

Cita de: ..:ALT3RD:.. en 16 Octubre 2011, 15:45 PM
He usado el buscador pero no he encontrado nada que me aclaré, lo que quiero saber es para que sirven realmente los punteros.
Los punteros sirven para las estructuras que manejan memoria de forma dinamica, ese es su principal objetivo.
( busca codigo de una 'lista enlazada' y te va a quedar mas claro ).

Cita de: ..:ALT3RD:.. en 16 Octubre 2011, 15:45 PM
Otra cosa que no entiendo es porque dicen que es tan dificil, yo lo vi como una lección mas de C++, seguramente luego me trague mis palabras pero a simple vista me pareció fácil.
Los punteros son muy mentirosos, el problema no es el puntero en si, sino el manejo de memoria de forma manual. Hay estructuras de datos cuyos objetos tienen ciclos de vida bien definidos y muy claros, pero hay otros que no, donde resulta muy dificil saber si un objeto sigue en uso o ya se puede liberar la memoria que tiene asignada.
Otro problema de los punteros es que al producirse una excepción, podrias perder las referencias a algunos objetos y terminarias con 'memory leaks'. Inclusive codigo que parece totalmente seguro, puede llegar a producir excepciones que uno no espera.

Por ahora tomatelo con soda, mira tranqui y anda avanzando, mas adelante van a empezar a aparecer los problemas con punteros y vas a ir conociendo algunos enfoques clasicos para resolverlos ( como por ej los smart pointers ).