memoria P. principal subrutina Programa de verificación Subrutina

Transcripción

memoria P. principal subrutina Programa de verificación Subrutina
Pasaje por esquema de referencia
Programa de
verificación
Subrutina
PROGRAM test
REAL : : a, b(4)
INTEGER : : next
…..
Call sun1 (a, b, next)
……..
End test
SUBROUTINE sun1(x, y, i)
REAL, INTENT(OUT) : : x
REAL, INTENT(IN) : : y(4)
INTEGER : : i
……………..
END SUBROUTINE sun1
memoria
P.
principal
subrutina
001
a
x
002
b(1)
y(1)
003
b(2)
y(2)
004
b(3)
y(3)
005
b(4)
y(4)
006
next
i
007
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.
Call arg_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

Documentos relacionados