Autor |
Mensaje |
4WD
Administrador
Edad: 39
Registrado: 07 Sep 2006
Mensajes: 2430
Ubicación: Ingeniero
Carrera: Mecánica
|
|
Bueno, el asunto es así. Estoy con un TP de Numérico y tengo una duda. La voy a plantear porque me interesa la respuesta en Pascal (que es lo que estoy usando). Luego, si quieren, también pueden contarme cómo resolverla en otros lenguajes.
La situación es la siguiente:
Tengo 2 métodos para resolver ecuaciones diferenciales que tienen que trabajar sobre dos funciones distintas. Cada método tenía pensado que fuera una subrutina, y cada función matemática una función en el lenguaje (F1(x) y F2(x)).
Como tengo pocas ganas de escribir mucho código, tenía pensado hacer subrutinas que funcionen para las 2 funciones. El problema es que dentro de la subrutina hay que evaluar la función en distintos puntos, por lo que no puedo pasar como parámetro F1(x0) (o sea, en cierto valor), sino que tengo que pasarle F1 y que dentro de la subrutina lo evalúe donde sea necesario.
La respuesta en C++ creo que es obvia, utilizando punteros, ¿no?: algo así supongo:
Código:
|
M1(param1, param2, int &F1) {
// acá adentro hace algo así
contador = *F1(2);
}
|
La pregunta es cómo hacer esto en Pascal, ya que si no me equivoco no tiene punteros.
Pregunta2 (y de curioso): ¿Cómo hacerlo en Java? (que tampoco hay punteros). Por ahora la única solución (sin prender la IDE) que se me ocurrió fue jugar con el polimorfismo, extendiendo una clase base, de forma que siempre haya un Clase.Eval(x), donde cada Eval es distinta y está sobreescrita según la clase específica, pero a la subrutina le pasaría la clase base antecesora de las dos derivadas.
No estoy seguro, pero se podría intentar hacer algo de esto también en Pascal, ¿no?, porque tienen datos definidos por usuario (símil clases).
Gracias
|
|
|
|
_________________
|
|
|
|
|
Sebastian Santisi
Administrador Técnico
Edad: 42
Registrado: 23 Ago 2005
Mensajes: 17451
|
|
No, eso que estás planteando no son punteros, son punteros a función; la respuesta en C++ sería de la onda de:
Código:
|
M1(param1, param2, int (*F1)(int)) {
// acá adentro hace algo así
contador = F1(2);
}
|
En Pascal también existen los punteros y los punteros a función pero creo que en ningún curso de Algoritmos para Informática los enseñaban (los a función, los punteros comunes sí)... si mal no recuerdo, de haberlos visto alguna vez, se usaba el operador @, pero puedo estar batateándote.
En Java no sé cómo se llamen; si handlers o tengan otro nombre; pero existen. En C# se llaman delegados. En otros lenguajes no hay diferencia entre una variable cualquiera y un puntero a función, simplemente existe la propiedad de callable.
|
|
|
|
_________________
|
|
|
|
|
Sebastian Santisi
Administrador Técnico
Edad: 42
Registrado: 23 Ago 2005
Mensajes: 17451
|
|
|
|
|
Rada
Moderador
Edad: 37
Registrado: 10 Abr 2006
Mensajes: 2728
Ubicación: Caballito
Carrera: Informática
|
|
|
|
|
4WD
Administrador
Edad: 39
Registrado: 07 Sep 2006
Mensajes: 2430
Ubicación: Ingeniero
Carrera: Mecánica
|
|
Pasa que lo quería implementar son punteros a funciones (que usan argumentos).
La ayuda del Pascal me dice que se pudrío todo:
Código:
|
@ with a procedure or function:
You can apply @ to a procedure or a function to produce a pointer to its
entry point. Turbo Pascal does not give you a mechanism for using such a
pointer.
The only use for a procedure pointer is to pass it to an assembly language
routine or to use it in an inline statement.
@ with a method:
You can apply @ to a qualified method identifier to produce a pointer to the
method's entry point.
|
Creo que voy a usar una solución de emergencia:
Desde los métodos llamar a una única función F(x) que en realidad sea un "chooser" según una variable externa al procedimiento.
Sí, estoy violando todas las leyes del encapsulamiento pero si a alguien se le ocurre una mejor idea estoy dispuesto a escucharlo. Por ahora, Pascalito no me deja llamar a funciones por sus punteros pasándole argumentos...
|
|
|
|
_________________
|
|
|
|
|
Sebastian Santisi
Administrador Técnico
Edad: 42
Registrado: 23 Ago 2005
Mensajes: 17451
|
|
4WD escribió:
|
Pasa que lo quería implementar son punteros a funciones (que usan argumentos).
La ayuda del Pascal me dice que se pudrío todo:
Código:
|
@ with a procedure or function:
You can apply @ to a procedure or a function to produce a pointer to its
entry point. Turbo Pascal does not give you a mechanism for using such a
pointer.
The only use for a procedure pointer is to pass it to an assembly language
routine or to use it in an inline statement.
@ with a method:
You can apply @ to a qualified method identifier to produce a pointer to the
method's entry point.
|
|
Cuando buscaba el enlace que te había pegado antes me topé con este, lo descarté cuando vi que el FP tenía el tipo ^function; en este tenés un ejemplo de la llamada inline que te dice la ayuda del compilador: http://h71000.www7.hp.com/wizard/wiz_7473.html .
4WD escribió:
|
Creo que voy a usar una solución de emergencia:
Desde los métodos llamar a una única función F(x) que en realidad sea un "chooser" según una variable externa al procedimiento.
|
Jaco en Civil y vos en Mecánica...
Realmente te felicito por la calidad de código; un 95% de la gente hubiera arrancado por el switch. La forma que vos querés usar de punteros a funciones es la forma correcta de hacerlo; pero, lamentablemente Pascal no es más que un lenguaje de enseñanza bastante mal diseñado.
Siempre es molesto cuando una falencia de un lenguaje (cualquiera sea) te limita la expresividad de alguna manera... es la señal de que hay que cambiar de lenguaje (independientemente de que para esta materia te estén exigiendo usarlo).
4WD escribió:
|
Sí, estoy violando todas las leyes del encapsulamiento pero si a alguien se le ocurre una mejor idea estoy dispuesto a escucharlo. Por ahora, Pascalito no me deja llamar a funciones por sus punteros pasándole argumentos...
|
No tenés muchas opciones más; de todos modos, no dejás de encapsular; un módulo sabe hacer una cosa, el otro sabe comportarse como una F(); a un módulo no le importa cómo trabaja el otro... llamar a F() o llamar a (*F)() para el módulo invocante es análogo; le está delegando a otro qué camino elegir. La única diferencia es que con punteros a función esa decisión se toma antes de la invocación al primer método y con el switch se toma al llegar al segundo. En cuanto a eficiencia, es despreciable lo que perdés en el switch comparado con lo que ya estás perdiendo por llamar a una función (de todos modos, si usás Pascal tampoco debería importarte la eficiencia).
|
|
|
|
_________________
|
|
|
|
|
Sebastian Santisi
Administrador Técnico
Edad: 42
Registrado: 23 Ago 2005
Mensajes: 17451
|
|
Sebastian Santisi escribió:
|
En Java no sé cómo se llamen; si handlers o tengan otro nombre; pero existen. En C# se llaman delegados.
|
Esto demuestra mi ignorancia en Java... y también cómo he sido embaucado en C#.
En Java no tenés manera de hacer punteros a método; la solución práctica para implementarlos es:
- Creás una interfase; interfase que tiene el nombre del método que va a hacer la acción y su signature.
- El objeto que va a proveer la funcionalidad implementa esa interfase.
- El método que va a hacer la acción que requiere la funcionalidad encapsulada, recibe un objeto que cumpla la interfase; llegado el momento de operar, llama a ese método.
Eso fue lo que estuve leyendo, y parecería ser standard; creo que es exactamente lo que se le ocurrió a 4WD.
En C# dije que existían los delegados y es cierto, existe el tipo delegate. Yo nunca había entendido por qué eran tan imprácticos; en C o lenguajes derivados si querés hacer un puntero a función sólo le das el nombre a una declaración con al signature de la función o método, nada más. En C# hay que definir un tipo delegado que contiene esa signature y después aclarar que lo que implementás cumple con el mismo... si bien es más elegante, internamente lo está manejando del mismo modo que Java; es simplemente una azucar sintáctica para no tener que hacer la interfase, pero el delegado termina siendo una con otro nombre.
Por suerte hay lenguajes donde jugar con este tipo de cosas es algo implícito de los mismos; lamentablemente, no son comerciales de momento.
|
|
|
|
_________________
|
|
|
|
|
4WD
Administrador
Edad: 39
Registrado: 07 Sep 2006
Mensajes: 2430
Ubicación: Ingeniero
Carrera: Mecánica
|
|
Gracias Sebastián. En realidad en el curso de Griggio te dejan usar lo que quieras (Pascal, Java, C++, Fortran (jeje), Mathlab (sin rutinas de resolución)). Pasa que en el grupo estoy con un chico de Civil, que se defiende bastante bien pero sólo sabe Pascal que es lo que se ve en Computación (creo que sabe más que yo, nunca pude aprender la sintaxis... ). Si no, supongo que me hubiera tirado a la pileta con el Java...
Lo de la llamada inline tiene pinta de despelote y no parece muy legible y elegante... así que creo que vamos a usar al gran switch. Gracias de nuevo por las respuestas.
|
|
|
|
_________________
|
|
|
|
|
|
|
Ver tema siguiente
Ver tema anterior
Podés publicar nuevos temas en este foro No podés responder a temas en este foro No podés editar tus mensajes en este foro No podés borrar tus mensajes en este foro No podés votar en encuestas en este foro No Podéspostear archivos en este foro No Podés bajar archivos de este foro
|
Todas las horas son ART, ARST (GMT - 3, GMT - 2 Horas)
Protected by CBACK CrackerTracker365 Attacks blocked.
|