• No se han encontrado resultados

TEMA 8. Arrays. Array. Contenidos. 8.1 El concepto de array. Los datos pueden ser:

N/A
N/A
Protected

Academic year: 2021

Share "TEMA 8. Arrays. Array. Contenidos. 8.1 El concepto de array. Los datos pueden ser:"

Copied!
16
0
0

Texto completo

(1)

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)

(2)

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

(3)

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 Indice

de 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 .

(4)

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 3

z 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.

(5)

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

(6)

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

(7)

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.

(8)

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

(9)

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

(10)

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ón

z

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ón

A(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

(11)

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

(12)

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

(13)

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.

(14)

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

(15)

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

(16)

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

Referencias

Documento similar

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

[r]

[r]

SECUNDARIA COMPRENDE LOS

Dado que el régimen de los poderes de emergencia afecta a la democracia, a los derechos fundamentales y humanos, así como al Estado de derecho, el control de

Primeros ecos de la Revolución griega en España: Alberto Lista y el filohelenismo liberal conservador español 369 Dimitris Miguel Morfakidis Motos.. Palabras de clausura

La conclusión que extrae Moeschler 9 en la revisión de varios estudios es que aunque la RM es una técnica útil en el diagnóstico de la DI/RGD, no es un estudio obligatorio en