Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Duda sobre declaración de apuntador

Estas en el tema de Duda sobre declaración de apuntador en el foro de C/C++ en Foros del Web. Buenas tardes, Quiero ver si me pueden ayudar con una duda sobre una declaración de un apuntador dentro de una estructura. La declaración es la ...
  #1 (permalink)  
Antiguo 28/03/2016, 17:22
 
Fecha de Ingreso: marzo-2016
Mensajes: 1
Antigüedad: 8 años, 7 meses
Puntos: 0
Pregunta Duda sobre declaración de apuntador

Buenas tardes,
Quiero ver si me pueden ayudar con una duda sobre una declaración de un apuntador dentro de una estructura.
La declaración es la siguiente:

struct Vector {
double x,y;
double (*pmag)(struct Vector *);
};

La duda es sobre la segunda declaración double y que significa el asterisco después de Vector.

El motivo de esta declaración es para calcular la magnitud de un vector guardando cada una de sus componentes en las variables x e y. se tiene que crear una función mandándola llamar por medio del apuntador *pmag.

Saludos
  #2 (permalink)  
Antiguo 28/03/2016, 20:27
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 22 años
Puntos: 52
Respuesta: Duda sobre declaración de apuntador

Significa que la función a la que apunte tu apuntador debe aceptar un puntero de tipo Vector como parámetro.

Saludos
  #3 (permalink)  
Antiguo 30/03/2016, 12:35
 
Fecha de Ingreso: enero-2014
Mensajes: 60
Antigüedad: 10 años, 10 meses
Puntos: 1
Respuesta: Duda sobre declaración de apuntador

quizas sea lo mismo o este equivocado, pero para mi "double (*pmag)(struct Vector *)" quiere decir que esa estructura tendra un dato double proporcionado por una funcion todavia por determinar (se pasara un puntero a la funcion) que tendra un puntero a una structura de tipo Vector como parametro de esa funcion


Última edición por vizen; 30/03/2016 a las 12:43
  #4 (permalink)  
Antiguo 30/03/2016, 14:28
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 14 años, 5 meses
Puntos: 73
Respuesta: Duda sobre declaración de apuntador

pmag es un puntero a una función que recibe como parámetro un puntero a una estructura de tipo Vector, y devuelve un valor de tipo double.
  #5 (permalink)  
Antiguo 03/04/2016, 02:55
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 8 meses
Puntos: 3
Respuesta: Duda sobre declaración de apuntador

Ya se que la duda fue solucionada pero a mi me surge otra, que diferencia hay entre:
double (*pmag)(struct Vector *);
Y:
double *pmag(struct Vector *);

Según lo que he entendido el primer caso es un puntero a una función que devuelve un double y el segundo seria una función que devuelve un puntero double. Mi duda es que ambos serian prototipos ¿no? ¿como le asignó una función al primer caso? Esto me recuerda mucho a cuando se quiere controlar eventos en una clase y dependiendo de si creamos una función para ese evento se ejecuta o no ya que de primeras el puntero seria NULL y al asignarle una función ya no lo sería.
  #6 (permalink)  
Antiguo 03/04/2016, 06:05
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Duda sobre declaración de apuntador

Si estás trabajando con C++ yo te sugeriría usar std::function para almacenar punteros a funciones. Tiene una sintaxis algo más legible que los viejos punteros a funciones.

Un saludo
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #7 (permalink)  
Antiguo 03/04/2016, 16:29
 
Fecha de Ingreso: abril-2016
Mensajes: 31
Antigüedad: 8 años, 7 meses
Puntos: 5
Respuesta: Duda sobre declaración de apuntador

Cita:
Mi duda es que ambos serian prototipos ¿no?
double (*pmag)(struct Vector *);
declara a la vez que define el puntero a función pmag.

double *pmag(struct Vector *);
declara la función pmag que necesita ser definida en algún lado.

Cita:
¿como le asignó una función al primer caso?
se usan dos formas técnicamente equivalentes, pero
que como siempre algunos prefieren una forma y otros la otra.
Por ejemplo, si tenés una función f declarada como:

double f(Vector* v);
se puede asignar:
Código:
pmag = f; // más común
pmag = &f; // lo mismo pero despierta fanatismos
Te paso un ejemplo simple:
Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. struct Vector {
  4.     double a;
  5.     double b;
  6. };
  7.  
  8. double sumar(Vector* v)
  9. {
  10.     return v->a + v->b;
  11. }
  12.  
  13. double restar(Vector* v)
  14. {
  15.     return v->a - v->b;
  16. }
  17.  
  18. int main ()
  19. {
  20.     double res;
  21.     Vector v{3, 2};
  22.     double (*pmag)(struct Vector*);
  23.     // o double (*pmag)(Vector*); que es lo mismo sin la palabra "struct"
  24.  
  25.     pmag = nullptr; // asigna a pmag el puntero nulo.
  26.  
  27.     pmag = sumar; // asigna a pmag el puntero a sumar()
  28.     res = pmag(&v); // invoca a sumar() a través del puntero pmag
  29.     std::cout << "suma = " << res << '\n';
  30.  
  31.     pmag = restar; // asigna a pmag el puntero a restar()
  32.     res = pmag(&v); // invoca a restar() a través del puntero pmag
  33.     std::cout << "resta = " << res << '\n';
  34. }

Saludos!

P.D: y por favor, a los aconsejadores compulsivos les voy a pedir que tomen esto como una forma rápida y simple de responder a un par de preguntas, no pretendo hacer una próxima librería para las boost ni espero que nadie vaya a quere ampliar o mantener esto en el futuro, así que por favor no se molesten, cuando necesite un consejo voy a saber pedirlo solito
  #8 (permalink)  
Antiguo 04/04/2016, 01:59
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Duda sobre declaración de apuntador

Cita:
Iniciado por enrieto Ver Mensaje
P.D: y por favor, a los aconsejadores compulsivos les voy a pedir que tomen esto como una forma rápida y simple de responder a un par de preguntas, no pretendo hacer una próxima librería para las boost ni espero que nadie vaya a quere ampliar o mantener esto en el futuro, así que por favor no se molesten, cuando necesite un consejo voy a saber pedirlo solito
Más del 90% de las preguntas que se exponen en este foro las realiza gente que está aprendiendo a programar ya que las dudas de más nivel suele acabar en foros tipo stackoverflow (y en inglés para ser más precisos). Dado el gran volumen con un nivel bajo yo, personalmente, veo productivo intentar enseñar buenas prácticas que, todo sea dicho, los profesores suelen omitir, como evitar el uso de variables globales, evitar el uso de using namespace en las cabeceras, controlar los ciclos de vida de la memoria dinámica, entender que los objetos locales se pueden crear en la pila en vez de usar siempre new, las ventajas de usar referencias en vez de punteros y cosas así.

Los comentarios que se hagan sobre tu código no van dirigidos exclusivamente a tí si no a cualquiera que lea el hilo... si se personalizan con tu nombre es debido a comentarios que has realizado al respecto y poco más.

Yo personalmente celebro que seas de la gente que sabe buscarse la vida, pero no por ello has de privar a gente menos preparada que tu del derecho a tener diferentes puntos de vista para poder opinar en el futuro por sí mismos.

Por otro lado y venida a cuenta lo complicado que puede resultar la sintaxis de un puntero a función hemos de saber que tenemos disponible std::function. ¿Ventajas de std::function? Para mi las principales son una sintaxis algo más clara y que no hay que usar punteros, lo cual elimina la ambigüedad de los punteros a función. Además, dado que std::function está bastante optimizado, lo normal es que el overhead al usar dicha función sea nulo o despreciable.

Tampoco penséis que std::function es perfecto. Con funciones sobrecargadas da problemas, aunque hay soluciones para este problema puntual.

Código C++:
Ver original
  1. #include <iostream>
  2. #include <string>
  3. #include <functional>
  4. #include <algorithm>
  5.  
  6. std::string ABinario(int numero)
  7. {
  8.     std::string toReturn;
  9.  
  10.     while( numero != 0 )
  11.     {
  12.       // & es un operador binario. XXXXXXY & 1 = XXXXXXY & 0000001 = Y
  13.       // Es una forma de obtener el bit menos significativo
  14.       int digito = (numero & 1);
  15.      
  16.       // Convertimos
  17.       toReturn += (digito == 1)? '1' : '0';
  18.      
  19.       // Eliminamos el digito que acabamos de procesar
  20.       // desplazando todos los bits a la derecha
  21.       numero >>= 1;
  22.     }
  23.    
  24.     // Es necesario invertir la cadena para que el resultado sea correcto
  25.     std::reverse(toReturn.begin(), toReturn.end());
  26.    
  27.     return toReturn;
  28. }
  29.  
  30. std::string AHexadecimal(int numero)
  31. {
  32.     char tabla[] = "0123456789ABCDEF";
  33.    
  34.     std::string toReturn;
  35.  
  36.     while( numero != 0 )
  37.     {
  38.       // Obtenemos los 4 bits menos significativos
  39.       int byte = (numero & 0xF);
  40.  
  41.       // Convertimos
  42.       toReturn += tabla[byte];
  43.      
  44.       // Eliminamos los 4 bits que acabamos de procesar
  45.       numero >>= 4;
  46.     }
  47.    
  48.     // Como después vamos a invertir la cadena, insertamos la secuencia
  49.     // de inicio en orden inverso.
  50.     toReturn += "x0";
  51.    
  52.     // Es necesario invertir la cadena para que el resultado sea correcto
  53.     std::reverse(toReturn.begin(), toReturn.end());
  54.    
  55.     return toReturn;
  56. }
  57.  
  58. int main()
  59. {
  60.     // function almacenará punteros a funciones que retornan un string
  61.     // y que aceptan un único argumento de tipo int
  62.     // Al ser una clase, por lo que dispone de constructor, no es necesario
  63.     // hacer una inicialización a nullptr para evitar problemas.
  64.     std::function<std::string(int)> func;
  65.    
  66.     func = ABinario;
  67.     std::cout << func(145) << std::endl;
  68.    
  69.     func = AHexadecimal;
  70.     std::cout << func(145) << std::endl;
  71. }

El ejemplo únicamente es compilable a partir del estándar C++11, que data del 2011 para que os hagáis una idea.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #9 (permalink)  
Antiguo 05/04/2016, 09:26
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 8 meses
Puntos: 3
Respuesta: Duda sobre declaración de apuntador

Muy interesante, gracias.

Etiquetas: apuntadores, estructuras
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:12.