subrutinas subprogramas resueltos raiz programas programación problemas intrinsecas funciones ejemplos cuadrada comandos arcoseno function module fortran fortran90 subroutine

function - subprogramas - raiz cuadrada en fortran



Uso correcto de módulos, subrutinas y funciones en Fortran (3)

Los módulos son siempre lo correcto para usar ;-)

Si tiene un programa F90 muy simple, puede incluir funciones y subrutinas en el bloque ''contains'':

program simple implicit none integer :: x, y x = ... y = myfunc(x) contains function myfunc(x) result(y) implicit none integer, intent(in) :: x integer :: y ... end function myfunc end program

Entonces, la interfaz de las funciones / subrutinas se conocerá en el programa y no será necesario definirla en un bloque de interfaz.

Para programas más complejos, debe mantener todas las funciones / subrutinas en módulos y cargarlas cuando sea necesario. Por lo tanto, no necesita definir interfaces, ya sea:

module mymod implicit none private public :: myfunc contains function myfunc(x) result(y) implicit none integer, intent(in) :: x integer :: y ... end function myfunc end module mymod program advanced use mymod, only: myfunc implicit none integer :: x, y x = ... y = myfunc(x) end program advanced

El módulo y el programa pueden (en realidad deberían) estar en archivos separados, pero el módulo debe compilarse antes del programa real.

Recientemente aprendí sobre los bloques de interfaz cuando agrego una función a mi programa Fortran. Todo funciona bien y ordenadamente, pero ahora quiero agregar una segunda función en el bloque de interfaz.

Aquí está mi bloque de interfaz:

interface function correctNeighLabel (A,i,j,k) integer :: correctNeighLabel integer, intent(in) :: i,j,k integer,dimension(:,:,:),intent(inout) :: A end function function correctNeighArray (B,d,e,f) character :: correctNeighArray integer, intent(in) :: d,e,f character, dimension(:,:,:),intent(inout) :: B end function end interface

Me parece que esta puede no ser la mejor opción.

He investigado las subrutinas, pero no estoy muy seguro de que sea la solución correcta. Lo que estoy haciendo es relativamente simple, y necesito pasar argumentos a la subrutina, pero todas las subrutinas que he visto son a) complicadas (es decir, demasiado complicadas para una función), yb) no toman argumentos, se comportan como si manipularan variables sin que se les pasaran a ellas.

Realmente no he investigado los módulos correctamente, pero por lo que he visto, no es lo correcto.

¿Qué debería usar cuándo y cómo lo hago mejor?


Secundar y extender lo que ya se ha dicho. Es mejor poner sus procedimientos (subrutinas y funciones) en módulos y "usarlos" porque les permite verificar la consistencia automática de las interfaces con poco esfuerzo. Las otras formas tienen inconvenientes. Si define la interfaz con un bloque de interfaz, tiene tres cosas que mantener en lugar de dos: la interfaz, el procedimiento en sí y la llamada. Si haces un cambio, entonces los tres tienen que ser modificados para ser consistentes. Si usa un módulo, solo dos deben ser cambiados. Una razón para usar un bloque de interfaz es si no tiene acceso al código fuente (por ejemplo, una biblioteca precompilada) o si el código fuente está en otro idioma (por ejemplo, está usando el código C a través de la vinculación ISO C).

El inconveniente del enfoque "contiene" es que los procedimientos contenidos heredan todas las variables locales del programa principal ... que no es muy modular y puede ser muy confuso si olvida esta "característica".


las respuestas de alexurba y MSB son correctas y útiles como de costumbre; permítanme dar más detalles sobre un punto: si los módulos son el camino a seguir (y lo son), ¿para qué sirven las interfaces?

Para funciones y subrutinas en módulos, cualquier cosa que use s ese módulo puede ver automáticamente esas interfaces; las interfaces se generan cuando se compila el módulo (esa información, entre otras cosas, va al archivo .mod que se genera al compilar un módulo). Entonces no necesitas escribirlo tú mismo. Del mismo modo, cuando utilizas un subprograma CONTAIN ed (que, de acuerdo con MSB, me resulta más confuso y útil, se los considera mejor como closures o subrutinas anidadas que las subrutinas externas), el programa principal ya puede ''ver'' la interfaz explícitamente y no necesita que lo escriba para eso.

Los bloques de interfaz son para cuando no puede hacer esto, cuando el compilador no puede generar la interfaz explícita para usted o cuando desea algo diferente de lo que se le da. Un ejemplo es cuando se usa la interoperabilidad de C-Fortran en Fortran 2003. En ese caso, el código de Fortran se enlaza con alguna biblioteca de C (por ejemplo) y no tiene forma de generar una interfaz fortran correcta para la rutina C para usted. hágalo usted mismo, escribiendo su propio bloque de interfaz.

Otro ejemplo es cuando ya conoce las interfaces para las subrutinas, pero cuando quiere crear una nueva interfaz para "esconder" las subrutinas detrás, por ejemplo, cuando tiene una rutina que opera en (digamos) enteros, y una en reales , y desea poder invocar el mismo nombre de rutina en cualquiera de ellos y dejar que el compilador lo resuelva según los argumentos. Dichos constructos se denominan rutinas genéricas y existen desde Fortran 90. En ese caso, se crea una interfaz explícitamente para esta nueva rutina genérica y se enumeran las interfaces con las rutinas "reales" dentro de ese bloque de interfaz.