memoria P. subrutina principal

Anuncio
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
Descargar