TEMA 8
Arrays
Contenidos
8.1 El concepto de array 8.2 Arrays unidimensionales 8.3 Arrays bidimensionales 8.4 Arrays en expresiones
8.5 Lectura y escritura de arrays 8.6 Arrays dinámicos
z Los datos pueden ser:
¿Simples: cada identificador representa una dirección de memoria donde guardar un valor escalar, p.e. un único valor de una variable:
ÈDatos de los tipos entero, real, carácter o lógico.
¿Compuestos: cada identificador representa una dirección de memoria a partir de la cual se guardan varios valores. Guardan varios valores bajo un mismo identificador.
z
Registros: contienen varios datos que pueden ser de distinto tipo.
z
Arrays: contienen varios datos todos del mismo tipo.
8.1 El concepto de array
Array
z Es una colección de datos todos del mismo tipo y agrupados bajo el mismo identificador (nombre del array).
z Los datos o elementos de un array pueden ser de tipo:
¿
INTEGER
¿
REAL
¿
CHARACTER
¿
LOGICAL
¿
REGISTRO
z Según su dimensión, los arrays se clasifican en:
¿
Arrays unidimensionales (también llamados vectores o listas)
¿
Arrays bidimensionales (también llamados matrices o tablas)
Arrays unidimensionales
¿Sólo tienen una dimensión
¿Consisten en una lista de variables todas del mismo tipo
¿Se accede a cada una mediante una expresión que viene dada por el nombre del array y entre paréntesis, un índice (su posición en el array):
Nombre_array(índice)
Array unidimensional cuyo nombre es A.Contiene 10 elementos reales
A(10) 10
9 8 7 . i . . 2 1
2.2 9.2 0.4 1.1 6.4 9.3 2.0 A
A(1) A(2)
A(i)
A(8) Acceso a las componentes índice
Identificador Expresión entera
Arrays bidimensionales
7 6 . i . 2 1
…
… ...
… ...
…
…
…
… ...
… ...
…
…
9.0 2.2
3.7
…
…
…
5.5 2.2
… 9.0 6.4
1.3 2.2
… 9.0 6.4
2.9 6.4
… 6.4 6.4
B
B(6,1) B(i,j) B(2,1) Acceso a las
componentes:
¿Tienen dos dimensiones (fila y columna)
¿Consisten en una matriz de variables todas de un mismo tipo.
¿Se accede a cada una mediante una expresión que viene dada por el nombre del array, y entre paréntesis y separados por coma, dos índices (el de fila y el de columna), que indican su posición en el array:
Nombre_array(índice_fila, índice_col)
Array bidimensional B, de 7x5 elementos reales
Índice
de fila 1 j 5
Índice de columna
Identificador Expresión entera
Expresión entera
Utilidad de los Arrays
Son útiles (y en muchas ocasiones imprescindibles) cuando en un programa hay varios elementos del mismo tipo y que se procesan igual: si se realiza una misma instrucción (u operación) sobre cada elemento, basta con escribir dicha instrucción una sola vez y repetirla para cada elemento (mediante una instrucción de repetición).
Ejemplo:
z Dado un programa que maneje los 100 salarios de 100 empleados. Con datos simples tendríamos que utilizar 100 variables reales:
REAL::salario1,salario2,...,salario100
Con arrays bastaría con declarar 1 único vector o array de 100 elementos reales, que contenga los 100 salarios.
z Si hay que calcular un incremento del salario del 4% para cada empleado, en lugar de realizar 100 veces el mismo cálculo, repito 100 veces la instrucción (que escribo una sola vez) mediante una instrucción de repetición.
Utilidad de los arrays
salarios
salarios(100) salarios(i) salarios(2) salarios(1)
2500.00 1500.00 2000.00 1000.00 1
2 .
i
.
100
Utilidad de los arrays
z Ejemplo: Una constructora construye un bloque de 7 plantas y en cada planta 3 viviendas (Vivienda vendida: .TRUE. / Vivienda no vendida: .FALSE.)
z Con datos simples tendríamos que utilizar 7*3=21 identificadores diferentes
z Con arrays bastaría con declarar un array 7 x 3 de dimensión 2.
Utilidad de los arrays
.false.
.true.
.true.
.true.
.false.
.true.
.true.
.true.
.false.
.false.
.false.
.true.
.false.
.true.
.true.
.true.
.false.
.true.
.true.
.false.
.true.
1 2 3 4 5 6 7
1 2 3
Filas: Columnas:
CasasVendidas(5,3)
Indice de fila Indicede col
Ejemplo: array bidimensional de 7x3 Componentes denominado CasasVendidas
8.2. Arrays unidimensionales
(Declaración, acceso a las componentes y recorrido)
Declaración
z La sintaxis general de declaración de un array unidimensional es:
TIPO, DIMENSION(num_componentes):: nombre_array TIPO: Es el tipo de los datos que contiene el array
(INTEGER, REAL, CHARACTER, LOGICAL o REGISTRO).
num_componentes : es la longitud del vector, el número máximo de datos que caben en el array. Debe ser una expresión entera. Indica el espacio que hay que reservar en la memoria principal para albergar el vector.
Nombre_array : es el identificador o nombre del array.
Debe ser un identificador válido de Fortran .
Ejemplos de declaración
!Declaración de un tipo:
TYPE tipo_persona INTEGER:: dni
CHARACTER (LEN = 30):: nombre CHARACTER:: nacionalidad END TYPE tipo_persona
!Ejemplos de declaración de arrays
REAL, DIMENSION(3) :: u, v !reserva espacio en la memoria
!para dos arrays de 3 reales
!cada uno.
LOGICAL, DIMENSION(7) :: CasasVendidas
INTEGER, DIMENSION(20) :: Notas !contiene 20 elem. enteros CHARACTER(len=20),DIMENSION(30)::nombre
CHARACTER(len=20),DIMENSION(30)::apellido1 TYPE (tipo_persona), DIMENSION(100)::alumnos
Acceso a los elementos de un array
z Se accede a los diferentes elementos de un array a través del nombre del array seguido de un número entero entre paréntesis llamado índice que indica la posición a la que se quiere acceder:
z Ejemplo:
z El índice puede venir dado por cualquier expresión entera.
15.0 4.5 3.0
u
u(3) = u(1)*5
a = 2 !a es variable entera u(2*a-2) = 4.5
u(1) = 3.0
índice
1 2 3z El acceso a los elementos de un array sirve para poder usar cada elemento como si fuera una variable, y puede hacerse en cualquier expresión del programa. Ejemplos:
1. Asignación del resultado de una expresión a un elemento de un array:
nombre_array(índice) = expresión 2. Lectura de un elemento de un array
Read*, nombre_array(índice)
2. Uso de un elemento de in array en una expresión:
nombre_var = nombre_array(índice)
Ejemplo:
character(len = 30), dimension(11)::nombres_jugadores character(len=30):: nombre_descalificado
nombres_jugadores(7) = ‘Raúl’ !Escritura en el array nombre_descalificado = nombres_jugadores(7) !Lectura del array
Recorrido por los elementos de un array 1D
z Se realiza un recorrido por los elementos de un array para procesarlos realizando la misma operación repetidamente con todos o con algunos de sus elementos, por ejemplo para:
ÈLeer de teclado el valor de cada elemento ÈEscribir cada elemento en la pantalla ÈUtilizar cada elemento en una expresión ÈProcesar cada elemento,
ÈBuscar un elemento en un array
ÈBuscar la posición de un elemento en un array ÈSumar los elementos de un array
ÈContar el número de veces que aparece un elemento en un array, etc…
z Para recorrer un array se utiliza una instrucción de
repetición en la que se repite una instrucción donde variando
el índice (posición del elemento en el array) en cada repetición,
se recorre el array pasando por los elementos deseados.
Recorrido por los elementos de un array 1D
INTEGER:: indice
INTEGER, DIMENSION(15) :: vector
z
Ejemplo: lectura de los elementos del vector elemento a elemento, p.e. para cuando el usuario escribe cada uno en una línea distinta y hay que usar un read para leer cada elemento:
PRINT*,‘Teclee 15 datos, cada uno en una línea’
DO indice = 1, 15
READ*,vector(indice) !Con cada read hay salto de línea END DO
NOTA: Los elementos de un array también se pueden leer sin realizar un recorrido por todos ellos, p.e. cuando el usuario los introduce a través de teclado todos en la misma línea y separados por espacios o por comas. En este caso todos los elementos pueden leerse con un único read:
PRINT*,‘Teclee 15 datos en la misma línea’
READ*, vector
Recorrido por los elementos de un array 1D
z
Ejemplo: calcular la nota media a partir de dos parciales para todos los alumnos de una clase de 80 alumnos. Las notas de cada parcial se hallan en sendos arrays nota1 y nota2 de 80 elementos. Guárdense las notas finales en el array final de 80 elementos.
INTEGER, PARAMETER::NUM_ALUMNOS=80
REAL, DIMENSION(NUM_ALUMNOS)::nota1,nota2,final INTEGER:: i
...
! Se asignan valores a nota1 y nota2
…
! Se recorren los arrays variando el índice desde la posición 1 hasta la
! posición NUM_ALUMNOS para procesar cada elemento:
DO i = 1,NUM_ALUMNOS
final(i) = (nota1(i)+nota2(i))/2 END DO
Recorrido por los elementos de un array 1D
Media de los elementos almacenados en un array de longitud 10:
Ejercicio:
Modifíquelo para que la lectura de los elem.
se realice en una subrutina.
Ejemplo
z Programa que pregunta las bases y las alturas de 10 rectángulos y las guarda en sendos arrays.
Posteriormente calcula las superficies de los
rectángulos, las guarda en un array, y las escribe en la pantalla.
PROGRAM areas_rectangulos IMPLICIT NONE
INTEGER, PARAMETER:: NUM_RECTANGULOS = 10
REAL, DIMENSION(NUM_RECTANGULOS):: bases, alturas, areas
CALL leer_lados(bases, alturas, NUM_RECTANGULOS)
CALL calcular_areas_rectangulos(bases, alturas, areas, NUM_RECTANGULOS) CALL escribir resultados(areas, NUM_RECTANGULOS)
END PROGRAM areas_rectangulos
SUBROUTINE leer_lados(bases, alturas, N) IMPLICIT NONE
INTEGER, INTENT(in):: N !Debe declararse antes de usarlo en la siguiente declarac.
REAL, DIMENSION(N), INTENT(out):: bases, alturas INTEGER::i
DO i=1,N
PRINT*, ‘Escriba la base y la altura del rectángulo’, i, ‘:’
READ*, bases(i), alturas(i) END DO
END SUBROUTINE leer_lados
!**************************************************************
SUBROUTINE calcular_areas_rectangulos(bases, alturas, areas, N) IMPLICIT NONE
INTEGER, INTENT(in):: N
REAL, DIMENSION(N), INTENT(in):: bases, alturas REAL, DIMENSION(N), INTENT(out):: areas INTEGER::i
DO i=1,N
areas(i) = bases(i)*alturas(i) END DO
END SUBROUTINE calcular_areas_rectangulos
!**************************************************************
SUBROUTINE escribir resultados(areas, N) IMPLICIT NONE
INTEGER, INTENT(in):: N
REAL, DIMENSION(NUM_RECTANGULOS):: bases, alturas, areas INTEGER::i
DO i=1,N
PRINT*, ‘El área del rectángulo ‘, i, ‘es:’, areas(i) END DO
END SUBROUTINE escribir_resultados
Acceso a los elementos de un array de registros
!Declaración de tipo TYPE tipo_persona
CHARACTER(LEN=50):: nombre CHARACTER:: nacionalidad REAL:: salario
END TYPE tipo_persona
!Declaración de un array de elementos de tipo tipo_persona TYPE(tipo_persona), dimension(100):: empleados
!Inicialización de la nacionalidad de los 10 primeros
! empleados a ‘e’ (española):
DO i = 1, 10
empleados(i)%nacionalidad = ‘e’
END DO
Acceso a los elementos de un array de registros (continúa):
!Lectura de nombres y salarios DO i=1, 100
PRINT*, ‘Escriba el nombre y el salario del empleado ’, i READ*, empleados(i)%nombre, empleados(i)%salario END DO
!Subida del salario un 4% a todos los empleados
DO i=1, 100
empleados(i)%salario = empleados(i)%salario + &
& empleados(i)%salario *4 / 100 END DO
Búsqueda de un elemento en un array
INTEGER FUNCTION posicion_elemento (A, num_elementos, elemento) IMPLICIT none
! Función que busca un elemento entero en un array. Si lo encuentra, devuelve como
! resultado la 1ª posición donde lo halla, y si no encuentra el elemento en el
! array, da como resultado cero (0)
! Declaración de argumentos:
INTEGER, INTENT(IN):: num_elementos !Número de elementos del array A INTEGER, INTENT(IN), DIMENSION(num_elementos)::A !array
INTEGER, INTENT(IN):: elemento !Elemento a buscar en el array.
!Declaración de variables locales
LOGICAL:: encontrado ! Indica si se encuentra el elemento.
INTEGER:: i
encontrado = .false. ! Se inicializa a .false. (todavía no lo ha encontrado) posicion_elemento = 0 ! Cuando encuentre el elemento tomará el valor de la
! posición donde se halla i=1
DO WHILE ((.NOT.encontrado).and. (i<=num_elementos)) IF (A(i) == elemento) THEN
encontrado = .true.
posicion_elemento = i END IF
i = i+1 END DO
END FUNCTION posicion_elemento
8.3. Arrays bidimensionales
(Declaración, acceso a las componentes y recorridos)
Declaración
z La sintaxis general de declaración de arrays bidimensionales es:
TIPO,DIMENSION(numfilas,numcolumnas)::nombrearray TIPO: Es el tipo de datos que contendrá el array (INTEGER,
REAL, CHARACTER, LOGICAL o REGISTRO).
numfilas, numcolumnas : son el número de filas y de columnas de datos que contendrá el array,
respectivamente. Deben ser expresiones enteras.
nombrearray : es el identificador de la colección o array.
Debe ser identificador válido en Fortran 90.
Ejemplos
de declaración (2D)
REAL, DIMENSION(3,3) :: matriz1, matriz2 LOGICAL, DIMENSION(7,3):: CasasVendidas INTEGER, DIMENSION(20,3) :: Notas
CHARACTER(len=20),DIMENSION(30,5)::nombres
!Array para guardar 6 medidas de contaminación
!cada mes del año:
REAL, DIMENSION(12,6)::medidas !reserva espacio para 12x6
!reales.
…
…
…
…
…
…
…
…
…
…
…
… 1 … . . . . . 11 12
1 …….. 5 6
medidas(2,6)
Acceso a los elementos de un array (2D)
z Se accede a los diferentes elementos de un array a través del nombre de la colección seguido de dos números enteros entre paréntesis que indican la fila y columna del elemento al que se quiere acceder:
z Ejemplo:
3.1 5.0 1.0
15.3 4.5 3.0
5.2 5.5 73.0 velocidades
velocidades (3,2) = 3.1
velocidades (2,3) = 5.5
velocidades(1,1) = 3.
Acceder a una posición de un array (2D)
Acceso a elementos de un array como si fueran variables:
1. Asignación del resultado de una expresión al elemento de un array de la fila fil y columna col :
nombre_array(fil,col) = expresion Ej: medidas(2,6)= 6.3
2. Lectura de un elemento del array procedente del teclado:
READ*, nombre_array(fil, col)
2. Asignación de un valor guardado en la fila fil y columna col, a una variable de nombre nombre_var:
nombre_var = nombre_array(fil,col) Ej: real:: medida
medida = medidas(2,6)
Recorrido por los elementos de un array 2D
z Recorridos por filas:
DO fil=1,numero_filas DO col=1,numero_columnas
...nombre_array(fil,col)...
END DO END DO
z
Se fija el número de fila y se recorren todas las columnas.
Se repite esta operación para cada fila.
z
Ejemplo:
Leer 12 elem. y almacenarlos en el array A en el orden que resulta al recorrer el array por filas:PRINT*,‘Escriba 12 elem de la matriz, cada uno en una línea y por orden de filas’
DO i = 1,3 DO j = 1,4
READ*, a(i,j) END DO
END DO
!El usuario escribe cada elemento en una línea
Recorrido por los elementos de un array 2D
zRecorridos por columnas:
DO col=1,numero_columnas DO fil=1,numero_filas
...nombre_array(fil,col)...
END DO END DO
zSe fija el número de columna y se recorren todas las filas. Se repite esta
operación para cada columna.
zEjemplo: Leer 12 elem. y almacenarlos en el array A en el orden que resulta al recorrer el array por columnas:
INTEGER, DIMENSION(3,4)::a
PRINT*,‘Escriba 12 elem de la matriz, cada uno en una línea, por orden de columnas’
DO j = 1,4 DO i = 1,3
READ*, a(i,j) END DO END DO
!El usuario escribe cada elemento en una línea
Recorrido por los elementos de un array 2D
z Ejemplos de recorridos: imprimir por pantalla los elementos de una matriz 3x6 por orden de filas
INTEGER i,j
INTEGER, DIMENSION(3,6) :: matriz ...
! Imprimimos matriz por pantalla DO i = 1,3
DO j = 1,6
Print*,’Elemento fila’,i,’columna’,j, Print*,matriz(i,j)
END DO
END DO
Recorrido por los elementos de un array 2D
z Ejemplos de recorridos: pedir por teclado los elementos de una matriz siguiendo el orden de las filas:
DO i=1,n_filas print*,’fila: ‘,i DO j=1,n_columnas
print*,’dame el elemento de la fila: ’, i, columna: ’,j read*,B(i,j)
END DO END DO
8.4. Arrays en expresiones
Arrays en expresiones
z Cualquier expresión en Fortran puede contener arrays como operandos, si estos tienen el mismo tamaño.
z Ejemplo: si definimos a, b y c así:
REAL, DIMENSION(20):: A, B, C INTEGER, DIMENSION(3,4):: E, F Son expresiones válidas:
-A + 3.0*B 2.0*E - 5.0*F
Asignación a matrices
z Las expresiones anteriores pueden asignarse a otros arrays, siempre que tengan el mismo tamaño.
z Ejemplo 1: si definimos A, B y C así:
real, dimension(20)::A, B, C
A = 8 !Los 20 elem. de A toman valor 8.
B = 0 !Todos los elem. de B toman valor 0.
c=-a+3.0*b*C equivale a:
DO i=1,20
c(i)=-a(i)+3.0*b(i)*C(i)
END DO
Asignación a matrices
z
Ejemplo:
REAL, DIMENSION(10, 5):: a, b INTEGER:: i, j
b = 30.0 !Asigna a todos los elem. de b el valor 30.0
!La instrucción:
a = sin(b)
! asigna a cada elemento de a el seno de su
! correspondiente elemento en b.
! Es equivalente a:
DO i=1,10 DO j=1,5
a(i,j)= sin(b(i,j)) END DO
END DO
Submatrices
Es posible tratar submatrices como si fueran matrices, en expresiones. Se denotan mediante el nombre de la matriz a la que pertenecen, y entre paréntesis y separados por comas, los rangos del índice de fila y del índice de columna que abarca la submatriz en la matriz, respectivamente.
El rango de variación de un índice se denota mediante el valor inicial del índice, seguido de dos puntos y del valor final. Los índices inicial y final vienen dados por expresiones enteras.
Integer, parameter:: long = ___, long1 = ___, long2 = ____
Integer, dimension(long):: vector Integer, dimension(long1, long2):: matriz Integer:: n1, n2, m1, m2
Vector(n1:n2) !Es el subvector contenido en el vector, que
!va de las posiciones n1 a la n2 del vector y
!cuya longitud es n2-n1+1. Se puede tratar en
!expresiones como si fuese un vector.
Matriz(n1:n2, m1:m2) !Es la submatriz contenida en la
! matriz que va desde las filas n1 a la
! n2 y desde las columnas m1 a la m2.
! Se puede tratar en expresiones como
! si fuese una matriz.
n1
..
n2
m1 …. m2 n1 … n2
8.5 Lectura y escritura de arrays
Disposición de los arrays en la memoria
z
Arrays 1D: sus elementos se almacenan de forma consecutiva, por orden de su posición en el array:
Ej:
integer, dimension(5):: A
A(1)
A(5) A(4) A(3) A(2)
MP A
Direcciónz
Arrays 2D: sus elementos se almacenan de forma consecutiva, siguiendo orden por columnas:
Ej:
Integer, dimension(2,3)::B
B(1,1)
B(2,3) B(1,3) B(2,2) B(1,2) B(2,1)
MP B
direcciónA(1)
A(5) A(4) A(3) A(2)
A
Array Disposición en MP
B(2,3) B(2,2) B(2,1)
B(1,3) B(1,2) B(1,1)
B
Array
Disposición en MP
Lectura y escritura de arrays 1D
Integer, dimension(n):: vector
LECTURA DE UN ARRAY 1D MEDIANTE UNA INSTRUCCIÓN SIMPLE read*, vector !lee los n primeros elementos que
!se introducen desde teclado y los
!almacena en las n posiciones de la MP a
!partir del array, es decir, los almacena
!por ese orden en el array.
Se pueden introducir los n elementos en la misma línea separados por comas o blancos.
ESCRITURA DE UN ARRAY 1D MEDIANTE UNA INSTRUCCIÓN SIMPLE print*, vector !escribe los n elementos del array en la misma
!línea en el orden en que están almacenados en MP.
z También podemos leer y escribir elemento a elemento, en cuyo caso habrá que construir una estructura de repetición.
Lectura y escritura de arrays 2D
Integer, dimension(n,m):: matriz
LECTURA DE UN ARRAY 2D MEDIANTE UNA INSTRUCCIÓN SIMPLE read*, matriz !lee los nxm primeros elementos que
!se introducen desde teclado y los
!almacena en las nxm posiciones de la MP a
!partir del array, es decir, los almacena
!por orden de columnas en el array. Conviene decir al
!usuario que introduzca los elementos de la matriz por
!columnas.
Se pueden introducir los nxm elementos en la misma línea separados por comas o blancos.
ESCRITURA DE UN ARRAY 2D MEDIANTE UNA INSTRUCCIÓN SIMPLE print*, matriz !escribe los nxm elementos del array en la misma
!línea en el orden en que están almacenados en MP, es decir,
!por columnas.
También podemos leer y escribir elemento a elemento, en cuyo caso habrá que construir una estructura de repetición.
Ejemplos
z Pedir al usuario que teclee los elementos de una matriz B, 3x4 por columnas, y calcular la suma de los elementos de la columna 2:
INTEGER, DIMENSION(3,4):: b INTEGER:: i, j, suma
PRINT*, ‘Teclee los elementos de B en una fila y por columnas’
READ*, b
suma = 0 j = 2 DO i = 1, 3
suma = suma + b(i,j) END DO
PRINT*, ‘La suma de los elementos de la columna ’, j, ‘es: ’ suma
Ejemplos
z
Sumar todos los elementos de una fila cuyo índice se pregunta al usuario:
INTEGER, DIMENSION(3,4):: b INTEGER:: i, j, suma
PRINT*, ‘Teclee los elementos de B en una fila y por columnas’
READ*, b
PRINT*, ‘¿De qué fila desea calcular la suma?’
READ*, i Suma = 0 DO j = 1, 4
suma = suma + b(i, j) END DO
Ejemplos
z
Sumar todos los elementos de la matriz:
INTEGER, DIMENSION(3,4):: b INTEGER:: i, j, suma
PRINT*, ‘Teclee los elementos de B en una fila y por columnas’
READ*, b
suma = 0 DO i = 1, 3
DO j = 1, 4
suma = suma + b(i, j) END DO
END DO
Ejemplos
z Suma de los elementos de cada fila de una matriz:
INTEGER, DIMENSION(3,4):: b INTEGER:: i, j, suma
PRINT*, ‘Teclee los elementos de B en una fila y por columnas’
READ*, b
DO i = 1,3 suma_fila = 0 DO j = 1,4
suma_fila = suma_fila + b(i,j) END DO
PRINT*, ‘La suma de los elementos de la fila ‘, i , ‘es: ‘, suma_fila END DO
Ejemplos
integer, parameter::n = 3 integer, parameter::m = 2 integer, dimension(n)::lista real, dimension(n,m)::tabla
Print*, ‘Escriba los’, n,’ elementos de la lista’
Read*, lista
Print*, ‘Escriba los’,n*m,’ elementos de la tabla por columnas’
Read*, tabla Print*, ‘Lista:’
Print*, lista Print*, ‘tabla:’
Print*, tabla Ejemplo de ejecución:
Escriba los 3 elementos de la lista 6 5 4
Escriba los 6 elementos de la tabla por columnas 6 5 4 3 2 1
Lista:
6 5 4 Tabla:
6 5 4 3 2 1
lista
4 5 6
tabla
1 2 3 4 5 6
Ejemplos
integer, parameter:: n = 3 integer, parameter:: m = 2 integer, dimension(n):: lista real, dimension(n,m):: tabla integer::i,j
!Lectura de los elementos cada uno en una línea
Print*, ‘Escriba los’, n,’ elementos de la lista, cada uno en una línea’
Do i=1,n Read*, lista(i) End do
!Lectura de los elementos de la matriz con cada uno en una línea
Print*, ‘Escriba los’,n*m,’ elementos de la tabla por filas cada uno en una línea’
do i=1,n do j=1,m
Read*, tabla(i,j) end do end do
!Lectura de los elementos de la matriz con cada uno en una línea Print*, ‘Escriba los’,n*m,’ elementos de la tabla por columnas’
do j=1,m do i=1,n
Read*, tabla(i,j) end do end do
!Escritura de los elementos de la lista con cada uno en una línea:
Do i=1,n print*, lista(i) End do
!Escritura de los elementos de la tabla por filas con cada uno en una línea do i=1,n
do j=1,m print*, tabla(i,j) end do
end do
z Escritura de los elementos de una matriz con todos los elementos de cada fila en una línea:
integer, dimension(n, m):: matriz integer::i,j
do i = 1, n
print*, matriz(i, 1:m) !Acceso a subtablas end do
Salida por pantalla:
1 2 3 4 5 6 7 8 9
integer, dimension(4,3):: a integer:: i, j
Print*, ‘Escriba cada fila de la matriz en una línea’
! p.ej.: 6 5 2 <INTRO>
! 4 3 2 <INTRO>
! 0 0 1 <INTRO>
! 1 0 0 <INTRO>
DO i = 1, 4
READ*, a(i,1:3) !mediante acceso a subtablas END DO
Consejos para la programación con arrays
zEs conveniente declarar las dimensiones del array con una constante no literal. Ejemplo:
INTEGER, PARAMETER::long = 80
REAL, DIMENSION(long)::nota1,nota2,final
Arrays como argumentos
! Al enviar un array como argumento a un subprograma, conviene enviar además otro argumento:
! el tamaño del array. Ejemplo:
INTEGER, PARAMETER:: NUM_ELEMENTOS = 100, F=30, C=2 REAL, DIMENSION(NUM_ELEMENTOS):: a
REAL, DIMENSION(F,C):: b .
CALL leer_datos(a, NUM_ELEMENTOS, b, F, C) .
!*********************************************
SUBROUTINE leer_datos(lista, longitud, matriz, num_filas, num_columnas) INTEGER, INTENT(IN):: longitud, num_filas, num_columnas
! Antes de declarar los arrays deben estar declarados los tamaños, para que estos sean
! conocidos a la hora de usarlos:
REAL, DIMENSION(longitud), INTENT(OUT):: lista
REAL, DIMENSION(num_filas, num_columnas), INTENT(OUT):: matriz .
. .
! Así conseguiremos que el subprograma que recibe el array pueda reutilizarse para arrays de
! cualquier tamaño.
! Del mismo modo, también es útil enviar como argumento la longitud de las cadenas de
! caracteres.
Ejemplo
z Programa que calcula la traza de una matriz 3x3 (suma de los elementos de la diagonal principal):
PROGRAM ej_traza IMPLICIT NONE
INTEGER, PARAMETER:: N = 3 INTEGER, DIMENSION(N, N):: matriz REAL, EXTERNAL:: traza INTEGER::i DO i=1, n
PRINT*, ‘fila: ‘: i READ*, matriz(i, 1:n) END DO
PRINT*, ‘La traza es: ‘, traza(matriz, n) END PROGRAM ej_traza
!___________________________________________
REAL FUNCTION traza(matriz, lado) Implicit none
INTEGER, INTENT(IN):: lado
INTEGER, DIMENSION(lado, lado), INTENT(IN):: matriz INTEGER::contador
REAL:: suma suma = 0.0 DO contador = 1, lado
suma = suma + matriz(contador, contador) END DO
traza = suma END FUNCTION traza
8.6. Arrays dinámicos
Arrays dinámicos
z Los arrays con los que hemos trabajado hasta ahora son arrays estáticos: su tamaño se fija en tiempo de compilación (o diseño) y no varía a lo largo de la ejecución del programa (utilización estática de la memoria). Ejemplo:
real, dimension (20)::notas z Si se declaran arrays de un número fijo de
elementos se tienen los siguientes inconvenientes:
zSi en algún momento en la ejecución del programa hay más elementos, no hay espacio reservado para almacenarlos
zSi hay menos, se está desaprovechando memoria
Arrays dinámicos
z Fortran 90 permite reservar memoria de forma dinámica, es decir, en tiempo de ejecución, en función de las necesidades que surgen a lo largo de la ejecución.
z Para ello debemos utilizar arrays dinámicos, siguiendo estos 3 pasos:
1.
Se declara el array con el atributo ALLOCATABLE, sin dar información sobre su tamaño, que se definirá más tarde. Sintaxis:
!Array dinámico 1D:
Tipo, dimension(:), ALLOCATABLE::
nombre_vector
!Array dinámico 2D:
Tipo, dimension(:,:), ALLOCATABLE::
nombre_matriz
DEALLOCATE
2. Se utiliza la sentencia ALLOCATE dentro del programa para definir el tamaño deseado para el array. Se debe realizar este paso antes de trabajar con el array. Sintaxis:
ALLOCATE(nombre_vector(longitud))
ALLOCATE(nombre_matriz(num_filas, num_columnas)) 3. Una vez se ha utilizado un array dinámico, si ya no se
necesita más, se puede liberar la memoria que ocupa mediante la sentencia DEALLOCATE. Sintaxis:
DEALLOCATE(nombre_vector) DEALLOCATE(matriz)
Arrays dinámicos 1D
REAL, DIMENSION(:), ALLOCATABLE::nombre_vector INTEGER::n
. .
! Durante el programa:
print*, ‘Indique el tamaño del vector’
read*,n
ALLOCATE(nombre_vector(n))
! Luego n es el tamaño de nombre_vector .
. . .
DEALLOCATE(numbre_vector)
Arrays dinámicos 2D
REAL, DIMENSION(:,:), ALLOCATABLE::matriz INTEGER::n,m
. .
! Durante el programa:
print*, ‘Filas de la matriz: ’ read*,n
print*, ‘Columnas de la matriz: ’ read*,m
ALLOCATE(matriz(n,m))
! Luego n es el tamaño de nombre_vector
.
. .
DEALLOCATE(matriz)
Ejemplo
z Programa que calcula la traza de una matriz cuadrada cuyo tamaño se pide al usuario (suma de los elementos de la diagonal principal):
PROGRAM ej_traza IMPLICIT NONE
INTEGER, DIMENSION(:,:), ALLOCATABLE:: matriz REAL, EXTERNAL:: traza
INTEGER::i, n
PRINT*, ‘¿Cuál es número de filas de la matriz cuadrada?’
READ*, n
ALLOCATE(matriz(n,n)) DO i=1, n
PRINT*, ‘fila: ‘: i READ*, matriz(i, 1:n) END DO
PRINT*, ‘La traza es: ‘, traza(matriz, n) DEALLOCATE(matriz)
END PROGRAM ej_traza
!___________________________________________
REAL FUNCTION traza(matriz, lado) Implicit none
INTEGER, INTENT(IN):: lado
INTEGER, DIMENSION(lado, lado), INTENT(IN):: matriz INTEGER::contador
REAL:: suma suma = 0.0 DO contador = 1, lado
suma = suma + matriz(contador, contador) END DO
traza = suma END FUNCTION traza
Ejemplo
Cálculo de la media de los elementos de un vector a cuyo tamaño n se pregunta al usuario.
PROGRAM media_reales IMPLICIT none
REAL, DIMENSION(:), ALLOCATABLE:: a INTEGER:: n
REAL, EXTERNAL:: media
PRINT*, ¿Cuántos elementos tiene el vector?
READ*, n
ALLOCATE(a(n)) !reserva n celdas en la MP para n reales CALL leer_vector(a, n)
PRINT*, ‘La media de los elementos del vector es: ‘, media(a,n) DEALLOCATE(a) !libera la memoria ocupada por el vector a END PROGRAM media_reales
!*****************************************************************************
SUBROUTINE leer_vector(a, n) IMPLICIT NONE
INTEGER, INTENT(IN):: n REAL, DIMENSION(n), INTENT(OUT):: a
PRINT*, ‘Introduzca ‘, n, ‘números reales separados por blancos o por comas’
READ*, a
END SUBROUTINE leer_vector
!*****************************************************************************
REAL FUNCTION media(a, n) IMPLICIT NONE INTEGER, INTENT(IN):: n REAL, DIMENSION(n), INTENT(IN):: a INTEGER:: i, suma
suma = 0 DO i=1, n
suma = suma + a(i) END DO
media = suma/n END FUNCTION media