Sunteți pe pagina 1din 63

Autor: Ing. William W.

Chauca Nolasco

Arreglos (vectores, matrices, .)


Un arreglo es un grupo de variables o constantes, todas del mismo tipo
referenciadas con un mismo nombre.
.

a(1)

a(2)

a(3)

a(4)

a(5)

a(6)

..

arreglo
Cada valor individual se llama elemento
El subndice indica la posicin particular dentro del arreglo.
El subndice es un ENTERO.
Es til para aplicar un algoritmo a un gran nmero de datos a travs de
ciclos
Ejemplo
DO i=1,100
a(i)=sqrt(a(i))
END DO

Declaracin de los Arreglos


Los arreglos tienen que ser declarados antes de ser utilizados para que el
compilador guarde lugar en la memoria segn el tipo y nmero de elementos
que contiene.
Ejemplo
REAL, DIMENSION (100) : : a
Cuando se define la variable CHARACTER se tiene que tener en cuenta la
longitud de caracteres y elementos
Ejemplo
CHARACTER(10), DIMENSION (12) : : mes
Los arreglos pueden ser declarados con ms de un subndice , por lo tanto
pueden tener 2 o ms dimensiones.
El nmero de dimensiones se llama rango (rank).
El nmero de elementos de cada dimensin se llama extensin (extent).
La combinacin del rango y la dimensin se llama forma (shape) .
El nmero de elementos declarados en el arreglo tamao (size)
Arreglos constantes: sus elementos son ctes.
Pueden definirse entre /
Ejemplo
(/1, 2, 3, 4, 5/)

Inicializacin de los arreglos


Los elementos de los arreglos son variables ordinarias y tienen que ser inicializadas
antes de ser usadas. Si no se la inicializa su valor es indefinido.
Pueden ser inicializados:
1. Sentencias de asignacin elemento por elemento
Ejemplos de esta forma de inicializacin:

REAL, DIMENSION(10) : : arreglo


DO i=1,10
arreglo(i) = REAL(i)
END DO

REAL, DIMENSION(10) : : arreglo


arreglo=(/1., 2., 3., 4., 5., 6., 7., 8., 9., 10./)

REAL, DIMENSION(10) : : arreglo


arreglo=0.
! todos los elementos iguales

INTEGER, DIMENSION(10) : : num, cuad


DO i=1,10
num(i)=i + i
cuad(i)= num(i)**2
END DO

2. Inicializacin por sentencias de declaracin


Ejemplos de esta forma de inicializacin:

INTEGER, DIMENSION (5) : : arreglo = (/1, 2, 3, 4, 5 /)

INTEGER, DIMENSION (5) : : arreglo = (/(i, i=1,5)/)

INTEGER, DIMENSION (25) : : arreglo = (/((0, i=1,4), 5*j, j=1,5) /)


0, 0, 0, 0, 5, 0, 0, 0, 0, 10, 0, 0, 0, 0, 15, 0, 0, 0, 0, 20, 0, 0, 0, 0, 25

REAL, DIMENSION (100) : : arreglo =1.0

3. Inicializacin de arreglos con READ


Valores de borde de los arreglos
Normalmente se usan valores de 1 a N
Ejemplo: REAL, DIMENSION (3) : : arr arr(1), arr(2), arr(3)
pero muchas veces resulta til que los subndices tomen otros valores. Para definir
los:
REAL, DIMENSION (imin, imax) : : arr
Ejemplo:
REAL, DIMENSION (5) :: aa
REAL, DIMENSION (-2 : 2) : : bb
REAL, DIMENSION ( 7:11) : : cc
Los 3 arreglos tienen la misma forma (igual dimensin e igual nmero de elementos)

Controlar que el ndice se encuentre dentro de los lmites del arreglo

A(1) A(2) A(3) A(4) A(5) B(1)

Arreglo A

B(2)

B(3)

B(4)

Arreglo B

Si se utiliza el A(6) puede conducir a errores. Los compiladores FORTRAN


tienen opcin bounds cheking para controlar los valores que toma el ndice
Las constantes con nombre y la declaracin de arreglos
Se utiliza para cambiar de manera simple el tamao de los arreglos.
Ej:
INTEGER, PARAMETER : : tama=1000
REAL : : arre1(tama)
REAL : : arre2(2*tama)
REAL : : arre3(tama,tama)

Buena costumbre: declarar el tamao de los arreglos usando


PARAMETER y realizar cambios rpidamente.

Usando arreglos completos o un subconjunto


a

VALOR

VALOR

VALOR

a(1)

1.

b(1)

5.

c(1)

6.

a(2)

2.

b(2)

6.

c(2)

8.

a(3)

3.

b(3)

7.

c(3)

10.

a(4)

4.

b(4)

8.

c(4)

12.

PROGRAM suma_arreglos
IMPLICIT NONE
INTEGER : : i
REAL, DIMENSION (4) : : a=(/ 1., 2., 3., 4./)
REAL, DIMENSION (4) : : b=(/ 5., 6., 7., 8./)
REAL, DIMENSION (4) : : c, d
! Elemento por elemento
DO i=1,4
c(i)= a(i)+b(i)
END DO
! Suma en forma conjunta todos los elementos de los arreglos
d= a+b
!
! Escribo los resultados
PRINT*, c
DO i=1,4
PRINT*, c(i)
END DO
PRINT*, d , d
END PROGRAM suma_arreglos

Impresin
c
6.0
d
6.0

8.0
8.0

10.0
10.0

12.0
12.0

! La operacin puede hacerse si y solo si ambos arreglos tienen la misma forma


(igual nmero de dimensiones y el mismo nmero de elementos en cada
dimensin, (igual rango e igual extensin)) conforme
Los escalares son conformes con los arreglos:
REAL, DIMENSION (4) : : a=(/1., 2., 3., 4./), c
REAL : : b=10
c=b*a
El arreglo c ser 10., 20., 30., 40.
Tambin se puede realizar estas operaciones con funciones intrnsecas
elementales. Las ms comunes:
ABS, SIN, COS, EXP y LOG
REAL, DIMENSION (4) : : a=(/-1., 2., -3., 4./), c
c= ABS(a)
El arreglo c ser 1., 2., 3., 4.

Subconjunto de un arreglo
Para utilizar una seccin del arreglo se especifican los ndices :
inicio:fin:incremento
subndice triple
Ej :
INTEGER, DIMENSION : : arre(/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
El subconjunto arre( 1:10: 2)
arre(1), arre(3), arre(5), arre(7) y arre(9)
1, 3, 5, 7 y 9
inicio
valor del ndice inicial del subconjunto
fin
valor del ndice final del subconjunto
Incremento
incremento a travs de los ndices del arreglo.
Si falta:
inicio 1
fin fin del arreglo
incremento 1
Ej:

INTEGER :: i=3, j=7


REAL, DIMENSION (10) :: a (/1., -2., 3., -4., 5., -6., 7., -8., 9., -10./)
a(:) todos los elementos
a( i: j) del tercer elemento al sptimo ( 3., -4., 5., -6., 7)
a(i: j: i) del tercer elemento al sptimo saltando de a 3 (3., -6.)
a(i: j: j) del tercer elemento al sptimo saltando de a 7 (3.)
a(i:) del tercer elemento al final (3., -4., 5., -6., 7., -8., 9., -10)
a(j:) del sptimo elemento al final (7., -8., 9., -10)
a(: : i) todos los elementos saltando 3 (1., -4., 7., -10.)

Subindice vector especifica uno a uno los elementos del arreglo a ser usados
en el clculo.
Ej:
INTEGER, DIMENSION (5): : vec =(/1, 6, 4, 1, 9/)
REAL, DIMENSION (10) : : a (/1., -2., 3., -4., 5., -6., 7., -8., 9., -10./)
a(vec ) es el arreglo [1., -6., -4., 1., 9.]

Entradas y salidas
PRINT*, a(1), a(2), a(3), a(4)
Con DO implcito

PRINT*, (a(i), i=1,4)


Imprime los valores de a(1), a(2), a(3) y a(4)
Usando Write:
WRITE( unidad , format) (var1, var2, . Indice= icomienzo, ifin. incre)
READ ( unidad , format) (var1, var2, . Indice= icomienzo, ifin. incre)
Dentro del write se pueden incluir tareas
Ej:
WRITE( *, * ) (i, 2*i, 3*i, i= 1,3)
Imprime 1 2 3 2 4 6 3 6 9

Ciclos anidados
WRITE(*,*) ((i, j, j= 1, 3), i= 1, 3)
PRINT*, ((i, j, j= 1, 3), i= 1, 3)
Primero varia j y luego i
1
1
1
2
1
3
2
1
2
2
2
3
3
1
3
2
3
3
Los DO implcitos son muy importantes cuando se trabaja con arreglos que
tienen dos o mas dimensiones.

ARREGLOS
BIDIMENSIONALES

Inicializacin de arreglos de 2 variables


INTEGER , DIMENSIN (4, 3) : : ini
DO i=1, 4
DO j= 1,3
ini(i, j) = j
END DO
END DO

i=1

i=2

i=3

i=4

j=1

j=2

j=3

Ini es de 4x3

Pero si inicializamos con:


(/1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3/)

Ini es de 1x12

Aunque los 2 arreglos tienen el mismo numero de elementos, no tienen la misma


forma y no pueden ser usados en la misma operacin. Para transformalo est la
funcin intrnseca RESHAPE
Ej

ini= RESHAPE ((/1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3/), (/4, 3/)

Convierte al vector 1X12 en una matriz de 4X3 la cual es asignada a ini:

INTEGER, DIMENSION (4,3) : : ini (4,3)=&


RESHAPE ((/1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3/), (/4, 3/)
Buena costumbre:
Cuando se trabaja con matrices conservar su forma. Leerlas y
escribirlas con DO o DO implcitos y al realizar operaciones
programas mas entendibles.

Matrices y subconjuntos de matrices


Se puede realizar operaraciones aritmticas con dos matrices cuando son
conformes o una es un escalar
Ej

a=

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

Para realizar un subconjunto de la matriz a

a(1, : ) = [ 1 2 3 4 5 ]

6
a( : , 1)=

11
16
21

a(1: 3, 1: 5: 2) =

10

11

13

15

Arreglos de mas de 2 dimensiones


Ej 2x2x2
A(1,1,1)

A(2,1,1)

A(1,2,1)

A(2,2,1)

A(1,1,2)

A(2,1,2)

A(1,1,2) A(1,2,2)
A(1,1,1) A(1,2,1)
A(2,1,1)

A(2,1,2)

A(2,2,2)

A(2,2,1)

Enmascarar : la construccin WHERE

Ej: Queremos calcular el logaritmo a una matriz


DO i=1, ifin
DO j=1, jfin
logval(i,j)= log(valor(i,j))
END DO
END DO

A(1,2,2)

A(2,2,2)

Otra forma:
logva= log (valor)
Pero no se tuvo en cuenta si exista algn valor negativo o un 0 para la cual la funcin
LOG no es vlida.
Para evitar ese error se debera programar:
DO i=1, ifin
DO j=1, jfin
IF(valor(i,j) >0.) then
logval(i, j) = LOG(valor(i,j))
ELSE
logval(i, j) = -99999.
END IF
END DO
END DO
A esta asignacin se le dice enmascarar
En FORTRAN 90 existe una funcin que realiza esta asignacin: WHERE
[nombre] WHERE ( mask_exp)
Sentencias de asignacin del arreglo !Bloque 1
ELSEWHERE [nombre]
Sentencias de asignacin del arreglo !Bloque 2
END WHERE [nombre]

Si la expresin mask_exp es verdad se ejecuta el Bloque 1, en caso contrario se


ejecuta el Bloque 2.
Ej

WHERE (valor>0)
logval=LOG(valor)
ELSEWHERE
logval=-99999.
ENDWHERE

El FORTRAN 95 agrega una clausula mas al WHERE


[nombre] WHERE ( mask_exp1)
Sentencias de asignacin del arreglo !Bloque 1
ELSEWHERE ( mask_exp2) [nombre]
Sentencias de asignacin del arreglo !Bloque 2
ELSEWHERE [nombre]
Sentencias de asignacin del arreglo !Bloque 3
END WHERE [nombre]

En los FORTRAN 90/95 tambin es vlido


WHERE(mask_exp) sentencia de asignacin del arreglo

Analizar un conjunto de datos de entrada cuyo rango se debe encontrar entre


-1000 y 1000. Si un valor no esta dentro de este intervalo asignarle el valor del
lmite inferior o superior segn sea su signo.

Usando DO e IF

Usando WHERE

ALLOCATABLE ARRAYS
Hasta ahora el tamao de los arreglos que hemos utilizado fue declarado junto
con el nombre de la variable.
Ej:

INTEGER , DIMENSIN (4, 3) : : ini

Esto se denomina STATIC MEMORY ALLOCATION. El espacio en memoria para


almacenar el contenido del arreglo es siempre el mismo a lo largo de todo el
programa.
En algunos casos, esto puede resultar inconveniente si hay algn arreglo que
interviene en nuestro programa del que no conocemos a priori el tamao que va a
tener. Para salvar este problema generalmente se definen arreglos muy grandes
que eventualmente permitan ajustarse a muchas situaciones, pero esto puede ser
ineficiente si no utilizamos el tamao completo de las variables ya que estamos
usando mucha memoria.
Para resolver este problema, se introdujo la DYNAMIC MEMORY ALLOCATION
que permite definir el tamao de un arreglo durante la ejecucin del programa. Esto
hace que podamos adaptar los tamaos de los arreglos al problema especfico que
estamos resolviendo en cada caso.

Para permitir que el tamao de un arreglo sea asignado durante la ejecucin del
Programa el atributo ALLOCATABLE en la declaracin de las variables.

REAL, ALLOCATABLE, DIMENSION(:) :: X ! La variable X tiene una sola dimensin


Este atributo le dice al programa que el tamao de X no ser determinado en el
momento de la declaracin sino ms adelante. Si bien no hay que especificar el
tamao, si las dimensiones, esto lo hacemos colocando un : .
REAL, ALLOCATABLE, DIMENSION(:,:) :: X !En este otro caso X tiene 2 dimensiones.
Para lograr asignarle un espacio en la memoria y poder utilizar a la variable X
disponemos de la sentencia ALLOCATE.
ALLOCATE ( X(10,20))
Esta sentencia le indica al programa que reserve un espacio de 10 filas por 2
columnas en la memoria para la variable X. A partir de este momento podemos utilizar
la variable X como lo hacamos antes.

ALLOCATE(X(N,M)) ! Esto tambin es vlido si N y M son 2 INTEGER.


Para liberar el espacio que est ocupado por la variable X en la memoria
DEALLOCATE

DEALLOCATE ( X )
IMPORTANTE despus de haber hecho esto no podremos acceder ms a la
variable X, su contenido se ha perdido.

EJEMPLO: Escribir y compilar el siguiente programa, ejecutarlo mirando como


vara la memoria utilizada por el sistema con el monitor del sistema de windows.

PROGRAM verifica
REAL, ALLOCATABLE, DIMENSION(:,:) :: X

WRITE(*,*)"Antes de asignar a X espacio en memoria, presione enter"


READ(*,*)

ALLOCATE(X(50000,1000))
WRITE(*,*)"X ya est en la memoria de la mquina, presione enter"

READ(*,*)
DEALLOCATE(X)
WRITE(*,*)"X fue eliminado de la memoria de la mquina"
STOP
END PROGRAM verifica

El FORTRAN da la posibilidad de subdividir las tareas de un programa complejo en


partes simples y claras . Procedimientos Externos
SUBRUTINAS
Subprogramas
FUNSIONES

VENTAJAS
Testeo independiente: un subprograma que puede ser compilado
independientemente. Puede ser probado separadamente y elimina fuente de errores
en programas largos.(programa unitario).
Cdigo re-usable: en muchos casos hay procedimientos o clculos que deben
usarse reiteradamente en diferentes programas o en el mismo. Los subprogramas
permiten acceder al calculo sin programarlo reiteradamente.

Asla efectos: Las variables que pueden ser cambiadas por el procedimiento
son aquellas que figuran en la lista de argumentos. Si existe un error puede slo
estar en esos argumentos.

SUBROUTINES
SUBROUTINE nombre (lista de argumentos)

Seccin de declaracin
..
Seccin de ejecucin
..
RETURN
END SUBROUTINE [nombre]

La lista de argumentos son variables o arreglos que son pasados y llamados


desde el programa principal. (argumentos ficticios (dummy))
Cuando un programa llama a la subrutina , el programa suspende su ejecucin y se
ejecuta la subrutina hasta que en esta se encuentra con RETURN o END
SUBROUTINE la ejecucin vuelve al programa principal a la sentencia posterior a
la llamada a la subrutina.

El llamado del desde el programa:


CALL nombre_de _la_subrutina( lista de argumentos)

La lista de argumentos con que el programa llama a la subrutina (argumentos


actuales) tiene que ser del mismo tipo que las declaradas en ella y guardar el
mismo orden (argumentos ficticios (dummy ))

Atributo INTENT
Declara el tipo de las variables ficticias:
INTENT (IN)
El argumento ficticio es usado solo para entrada de datos de
la subrutina
INTENT (OUT)
El argumento ficticio es usado solo para salida de datos de la
subrutina
INTENT (INOUT) El argumento ficticio es usado solo para entrada de datos
en la subrutina y devolver los resultados al llamado del programa.

Ejemplo
SUBROUTINE hipotenusa (lon1, lon2, hipote)
! Proposito: Calcular la hipotenusa a partir de los catetos del triangulo rectngulo
IMPLICIT NONE
! Diccionario y declaracin de variables
REAL , INTENT(IN) : : lon1 ! longitud del lado 1
REAL , INTENT(IN) : : lon2 ! longitud del lado 2
REAL , INTENT(OUT) : : hipote
! longitud de la hipotenusa
REAL : : tem
! Variable Auxiliar temporaria
! Calculo de la hipotenusa
tem= lon1**2 + lon2**2
hipote= SQRT(tem)
RETURN
END SUBROUTINE hipotenusa

Los argumentos ficticios son usados para pasar los datos a la subrutina asi que
ellos son declarados como valores de entrada INTENT(IN) . El argumento ficticio
hipotenusa es un real determinado en la subrutina asi que tiene que ser
declarado como variable de salida INTENT(OUT) .

La variable tem est definida dentro de la subrutina y no pasa al programa


principal. Este tipo de variables que son inaccesibles desde el programa principal
se llaman variables locales.
La sentencia RETURN es opcional ya que cuando la subrutina se encuentra con un
END SUBROUTINE vuelve al programa principal. RETURN es necesaria cuando se
quiere retornal al programa principal antes de finalizar la subrutina.
Para testear la subrutina hay que utilizar un simple programa que verifique su
funcionamiento antes de utilizarla dentro de un programa complejo.

Ejemplo:
PROGRAM test_hiotenusa
! Proposito: verificar la subrutina hipotenusa
!
IMPLICIT NONE
! Diccionario y declaracin de variables
REAL : : L1
! longitud del lado 1
REAL : : L2
! longitud del lado 2
REAL : : hipote
! longitud de la hipotenusa
PRINT* , test de la subrutina hipotenusa
PRINT* Entre la longitud del cateto1 y cateto 2
READ * , L1, L2
CALL hipotenusa( L1, L2, hipote)
PRINT*, Visualizo el resultado de la hipotenusa
PRINT*, La longitud de la hipotenusa es:, hipo
END PROGRAM test_hiotenusa

test de la subrutina hipotenusa


Entre la longitud del cateto1 y cateto 2
34
Visualizo el resultado de la hipotenusa
La longitud de la hipotenusa es:
5.000000
Press any key to continue

NOTAR: los argumentos actuales con que llamamos a la subrutina son


distintos de aquellos que se pusieron en la definicin d la subrutina
(argumentos ficticios).
Esto significa que en el llamado a la subrutina se asigna:
lon1 L1
lon2 L2
hipotenusa hipote

Ej : escribir el programa ordenar utilizando una subrutina que ordene.

PROGRAM lee_ordena_escribe
!Leer, ordenar e imprimir una serie de valores en forma
ascendente
IMPLICIT NONE
INTEGER, PARAMETER::ndatos=6 ! nmero de datos
INTEGER::i
! ndice
REAL, DIMENSION(ndatos):: arr
! Arreglo a ser ordenado
print*,"El numero de datos :",ndatos
PRINT*,"Entre los valores de la serie"
READ*,(arr(i),i=1,ndatos)
PRINT 10,(arr(i),i=1,ndatos)
!LLAMA A LA SUBRUTINA
CALL ORDENAR(arr,ndatos)
!Imprimo
PRINT*," la serie ordenada es"
PRINT 10,arr
10 format(1x,6(f4.1,1x))
END PROGRAM lee_ordena_escribe

SUBROUTINE ordenar(a,nvalores)
IMPLICIT NONE
INTEGER,INTENT(IN)::nvalores ! nmero de datos
REAL,DIMENSION(nvalores),INTENT(INOUT)::a ! Arreglo a ser ordenado
INTEGER::i,j
! ndices
INTEGER::iguardo
! ndice del menor valor
REAL::tem
! Variable temporal para hacer el intercambio
Todo: DO i=1,nvalores-1
!encuentro el menor valor desde a(i) hasta a nvalores
Iguardo=i
min: DO j=i+1,nvalores
IF(a(j)<a(iguardo)) THEN
iguardo= j
END IF
END DO min
F(i /= iguardo) THEN !a(Iguardo) tiene el menor valor as que intercambio con a(i) si i /= iguardo
tem= a(i)
a(i)=a(iguardo)
a(iguardo)=tem
ENDIF
END DO todo
END SUBROUTINE ordenar

Pasaje por esquema de referencia

Programa de
verificacin

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

002

b(1)

y(1)

003

b(2)

y(2)

004

b(3)

y(3)

005

b(4)

y(4)

006

next

007

Cuando se llama a una subrutina el programa principal seala la posicin 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 nmero, tipo y orden
EJemplo de error
Una variable real tomada como entera
PROGRAM llamada_ equivocada
! Propsito: ejemplificar un error frecuente
!
IMPLICIT NONE
REAL : : x= 1.
Call arg_erroneo(x)
END llamada_ equivocada
SUBROUTINE arg_erroneo(i)
IMPLICIT NONE
INTEGER : : i
Print*, 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 localizacin y el tamao del arreglo
Hay distintas maneras de especificar la longitud de una variable ficticia:
Pasar los limites de cada dimensin 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 dimensin de las variables es conocida por la expresin 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 tamao del arreglo ficticio a travs de un *. En este


como el compilador no conoce el tamao 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 tamao
REAL, INTENT((OUT), DINENSION(*) : : dato2 ! se asume el tamao

!
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 funcin intrnseca LEN( )
Ej :

SUBROUTINE ejemplo(texto)
CHARACTER(len=*), INTENT(IN) : : texto
PRINT*, la longitud de texto es: , LEN(texto)
RETURN
END SUBROUTINE ejemplo

Es conveniente usar banderas dentro de una subrutina para no parar el proceso


de un programa:
Ej: Si restamos 2 nmeros y calculamos la raz cuadrada.

SUBROUTINE proceso (a, b, resultado)


IMPLICIT NONE
! Diccionario y declaracin 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
PRINT*, 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 declaracin 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 mdulos


MODULE comparto
!
! Propsito: declarar datos compartidos entre subrutinas
!
IMPLICIT NONE
SAVE
INTEGER, PARAMETER : : nvalores = 5
REAL, DINENSION(nvalores) : : valores
END MODULE comparto

Un MDULO contiene las definiciones y valores iniciales que se quieren


compartir entre programas unitario
Un MODULE puede ser incluido en un programa a travs de la sentencia
USE
Cada programa que utilice el mdulo 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 mdulo son
preservados en distintos procedimientos.

Ej
PROGRAM test_modulo
!
! Propsito: ver como se usa el mdulo
!
USE comparto
IMPLICIT NONE
REAL, PARAMETER : : PI= 3.14159
Valores = PI * (/1., 2., 3., 4., 5. /)
CALL sub1
END PROGRAM test_modulo
SUBROUTINE sub1
! Propsito: ver como se usa el mdulo
!
USE comparto
IMPLICIT NONE
PRINT*, valores
END SUBROUTINE sub1

Qu es un MODULE?
Los modules son una forma eficiente de intercambiar informacin entre diferentes
programas y subprogramas.
Tambin permiten agrupar funciones y subrutinas que operan sobre los mismos
datos en paquetes o tool boxes que pueden ser fcilmente utilizados por
diferentes programas

Podemos utilizar modules para intercambiar datos entre diferentes unidades de


un mismo programa. Por ejemplo entre diferentes subrutinas, sin la necesidad de
estar pasndolos como argumentos.
Definimos un MODULE donde definimos el valor de diferentes constantes tiles.

MDULO DE PROCEDIMIENTOS
Los mdulos tambin pueden contener subrutinas y funciones MDULO
DE PROCEDIMIENTOS
PROCEDIMIENTOS son compilados como parte del modulo.
Se ponen disponible a travs de USE
Estn precedidos por CONTAINS Le indica al compilador que siguen
sentencias de procediendo.
Ej:

MODULE mi_sub
(declaracin de los datos)
REAL,
.
CONTAINS
SUBROUTINE sub (a, b, c, x, error)
IMPLICIT NONE
REAL, DIMENSION (3), INTENT(IN) : : a
REAL, INTENT(IN) : : b, c
REAL, INTENT(OUT) : : x
LOGICAL, INTENT(OUT) : : error

END SUBROUTINE sub


END MODULE mi_sub

La subrutina incluida en el modulo puede ser usada con el CALL


Ej
PROGRAM prog_principal
USE mi_sub
IMPLICIT NONE

CALL sub(a, b, c, x, error)


.
END PROGRAM prog_principal

El programa principal queda de esta forma.

Otro ejemplo

Programa principal que utiliza el modulo que me permite utilizar funciones


trigonomtricas que toman el argumento en grados en lugar de radianes.

Parte de la salida del programa anterior sera:

Value of PI = 3.1415925
x = -180.deg sin(x) = 8.742277657E-8 cos(x) = -1.
x = -170.deg sin(x) = -0.173648298 cos(x) = 0.98480773
x = -160.deg sin(x) = -0.342020214 cos(x) = -0.939692616
x = -150.deg sin(x) = -0.50000006 cos(x) = -0.866025388
x = -140.deg sin(x) = -0.642787635 cos(x) = -0.766044438
x = -130.deg sin(x) = -0.766044438 cos(x) = -0.642787635
x = -120.deg sin(x) = -0.866025388 cos(x) = -0.50000006

PUBLIC / PRIVATE

SINTAXIS:
PUBLIC :: name1 , name2 , name3

PRIVATE :: name4 , name5 , name6


En este caso, las variables / procesos name1, name2 y name3 podrn ser
accedidos por cualquier unidad que utilice el MODULE mediante la sentencia
USE.

Mientras que las variables / procesos name4, name5, name6 solo podrn ser
utilizadas dentro del MODULE pero no estarn disponibles para otras unidades
que utilicen el MODULE.

PASANDO PROCEDIMIENTOS A OTROS PROCEDIMIENTOS


Tanto funciones como subrutinas pueden ser pasados como argumentos
Ej :

PROGRAM : : test
REAL, EXTERNAL : : fun1, fun2
REAL : : x, y, salida
..
CALL evaluar( fun1, x, y, salida)
CALL evaluar( fun1, x, y, salida)
END PROGRAM : : test
****************************************
SUROUTINE evaluar( fun, a, b, resultado)
REAL , EXTERNAL : : fun
REAL, INTENT(IN) : : a, b
REAL , INTENT (OUT) resultado
resultado= b * fun(a)
END SUROUTINE evaluar

fun1 y fun2 funciones definidas por el usuario


EXTERNAL Le comunica al compilador que en vez de una variable, el
argumento es una funcin compilada separadamente.

Puede ser una sentencia de declaracin o una sentencia


REAL, EXTERNAL : : fun1, fun2
o
EXTERNAL fun1, fun2
Si se usa esta ltima opcin tiene que usarse antes del llamado por la subrutina
Ej:

REAL, FUNCTION valor_medio (fun, val_1, val_ fin, n)


! Propsito: calcular el promedio de fun
!
! Diccionario y declaracin de variables
REAL, EXTERNAL : : fun
! Funcin a ser evaluada
REAL, INTENT(IN) : : val_1
! Primer valor en el rango
REAL, INTENT(IN) : : val_fin
!ltimo valor en el rango
INTEGER, INTENT(IN) : : n
!
REAL : : DELTA
INTEGER : : i
REAL : : sum
!
delta= (val_fin - val_1) / REAL(n - 1)

! Calculo la suma
sum=0
DO i=1,n
sum = sum + func (REAL( i 1 )* delta)
END DO
! Saco el promedio
valor_medio = sum / REAL(n)
END FUNCTION valor_medio

PROGRAM test_ valor medio


! Propsito: evaluar la funcin valor_medio
IMPLICIT NONE
! Diccionario y declaracin de variables
REAL, EXTERNAL : : mi_funcin ! Funcin a ser evaluada
REAL, INTENT(IN) : : valor_medio ! Valor medio de la funcin
REAL : : medio
! promedio de la funcin
medio = valor_medio (mi_funcion, 0., 1., 101)
WRITE( *, * ) mi funcin, medio
END PROGRAM test_ valor medio

REAL FUNCTION mi_funcion(x)


IMPLICIT NONE
REAL, INTENT(IN)
mi_funcion =3* x
END FUNCTION mi_funcion

ROL DE CLASES FINALES PRACTICAS Y EXMENES


1.- 18 DE NOVIEMBRE - REPASO DE ARREGLOS SUBRUTINAS Y MODULO
2.- 25 DE NOVIEMBRE ARCHIVOS Y DATOS DERIVADOS

3.- 02 DE DICIEMBRE - EXAMEN FINAL


4.- 09 DE DICIEMBRE EXAMEN SUSTITUTORIO

S-ar putea să vă placă și