90 likes | 230 Views
Pasaje por esquema de referencia. PROGRAM test REAL : : a, b(4) INTEGER : : next ….. Call sun1 (a, b, next ) …….. End test. Programa de verificación. SUBROUTINE sun1(x, y, i) REAL, INTENT(OUT) : : x REAL, INTENT(IN) : : y(4) INTEGER : : i …………….. END SUBROUTINE sun1. Subrutina.
E N D
Pasaje por esquema de referencia PROGRAM test REAL : : a, b(4) INTEGER : : next ….. Call sun1 (a, b, next) …….. End test Programa de verificación SUBROUTINE sun1(x, y, i) REAL, INTENT(OUT) : : x REAL, INTENT(IN) : : y(4) INTEGER : : i …………….. END SUBROUTINE sun1 Subrutina Cuando se llama a una subrutina el programa principal señala la posición en memoria de cada argumento actual de la lista de argumentos. La subrutina busca los argumentos ficticios en el lugar indicado.→ Pasaje por referencia
Los argumentos reales (programa principal) y ficticias ( subrutinas) tienen que coincidir en número, tipo y orden EJemplo de error Una variable real tomada como entera PROGRAM llamada_ equivocada ! Propósito: ejemplificar un error frecuente ! IMPLICIT NONE REAL : : x= 1. Callarg_erroneo(x) END llamada_ equivocada SUBROUTINE arg_erroneo(i) IMPLICIT NONE INTEGER : : i Write (*,*) “ i=“,i END SUBROUTINE arg_erroneo Al correr el programa el resultado es : i= 1065353216
Pasaje de un arreglo a una subrutina • La subrutina necesita conocer la localización y el tamaño del arreglo • Hay distintas maneras de especificar la longitud de una variable ficticia: • Pasar los limites de cada dimensión del arreglo a la subrutina como argumento en el llamado y declarar el arreglo ficticio a esta longitud → Forma explicita de la variable ficticia • Ej: • SUBROUTINE proceso (dato1, dato2, n, nvalores) • INTEGER, INTENT(IN) : : n, nvalores • REAL, INTENT((IN), DINENSION(n) : : dato1 ! forma explicita • REAL, INTENT((OUT), DINENSION(n) : : dato2 ! forma explicita • ! • DO i= 1, nvalores • dato2(i) = 3* dato1(i) • END DO • END SUBROUTINE proceso Como la dimensión de las variables es conocida por la expresión explicita se puede realizar operaciones entre arreglos o secciones de arreglos.
Ej: SUBROUTINE proceso2 (dato1, dato2, n, nvalores) INTEGER, INTENT(IN) : : n, nvalores REAL, INTENT((IN), DINENSION(n) : : dato1 ! forma explicita REAL, INTENT((OUT), DINENSION(n) : : dato2 ! forma explicita ! dato2(1:nvalores) = 3. * dato1(1: nvalores) END SUBROUTINE proceso2 Otra forma es el asumir el tamaño del arreglo ficticio a través de un *. En este como el compilador no conoce el tamaño del arreglo no puede efectuar operaciones entre arreglos o secciones de los mismos Ej: SUBROUTINE proceso3(dato1, dato2, n, nvalores) INTEGER, INTENT(IN) : : n, nvalores REAL, INTENT((IN), DINENSION(*) : : dato1 ! se asume el tamaño REAL, INTENT((OUT), DINENSION(*) : : dato2 ! se asume el tamaño ! DO i= 1, nvalores dato2(i) = 3* dato1(i) END DO END SUBROUTINE proceso3
Pasando variables “character “ a una subrutina Cuando se utiliza una variable character como argumento ficticio, su longitud es declarada con un *. Si queremos saber la longitud de texto usamos la función intrínseca LEN( ) Ej : SUBROUTINE ejemplo(texto) CHARACTER(len=*), INTENT(IN) : : texto WRITE(*, *) “ la longitud de texto es: “, LEN(texto) END SUBROUTINE ejemplo
Es conveniente usar banderas dentro de una subrutina para no parar el proceso de un programa: Ej: Si restamos 2 números y calculamos la raíz cuadrada. SUBROUTINE proceso (a, b, resultado) IMPLICIT NONE ! Diccionario y declaración de variables REAL , INTENT(IN) : : a, b REAL , INTENT(OUT) : :resultado REAL : : tem ! Auxiliar temporaria tem= a-b IF(tem>=0).then result = SQRT(tem) ELSE WRITE(*, *) “La raiz no se puede calcular” STOP END IF END SUBROUTINE proceso
Si utilizamos banderas SUBROUTINE proceso (a, b, resultado, error) IMPLICIT NONE ! Diccionario y declaración de variables REAL , INTENT(IN) : : a, b REAL , INTENT(OUT) : :resultado INTEGER , INTENT(OUT) : : error ! Aviso de error =1 REAL : : tem ! Auxiliar temporaria tem= a-b IF(tem>=0).then result = SQRT(tem) error= 0 ELSE result=0 error=1 END IF END SUBROUTINE proceso
Compartiendo datos usando módulos MODULE comparto ! ! Propósito: declarar datos compartidos entre subrutinas ! IMPLICIT NONE SAVE INTEGER, PARAMETER : : nvalores = 5 REAL, DINENSION(nvalores) : : valores END MODULE comparto • Un MÓDULO contiene las definiciones y valores iniciales que se quieren compartir entre programas unitario • Un “MODULE” puede ser incluido en un programa a través de la sentencia “USE” • Cada programa que utilice el módulo tiene acceso a los mismos datos • Comienza con MODULE y continua con un nombre de hasta 31 caracteres. • Termina con END MODULE nombre • SAVE garantiza que todos los valores de los datos en el módulo son preservados en distintos procedimientos.
Ej PROGRAM test_modulo ! ! Propósito: ver como se usa el módulo ! USE comparto IMPLICIT NONE REAL, PARAMETER : : PI= 3.14159 Valores = PI * (/1., 2., 3., 4., 5. /) CALL sub1 END PROGRAM test_modulo SUBROUTINE sub1 ! Propósito: ver como se usa el módulo ! USE comparto IMPLICIT NONE Write(*, *) valores END SUBROUTINE sub1