tipos de dados estruturados - fenix.tecnico.ulisboa.pt · ficha - armazena elementos de tipos...

31
1 João Miguel da Costa Sousa 248 Tipos de dados estruturados Tipos de dados intrínsecos em Fortran INTEGER REAL COMPLEX CHARACTER LOGICAL É possível definir tipos (estruturas) ou fichas. Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) Número (inteiro) Nota exame (real) Nota projecto (real) Nota final (inteiro) João Miguel da Costa Sousa 249 Tipos estruturados Definição de tipos estruturados (fichas) ____________________________________________________________________ Forma: TYPE nome_tipo declaracao 1 declaracao 2 ... declaracao k END TYPE nome_tipo O nome_tipo é um identificador em Fortran; Cada declaracao i declara um ou mais componentes da estrutura deste tipo. Objectivo: declara tipo estruturado (ficha) cujos componentes são declarados em declaracao 1 , …, declaracao k . Estas definições são efectuadas na zona de especificações do programa.

Upload: vuxuyen

Post on 26-Jan-2019

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

1

João Miguel da Costa Sousa 248

Tipos de dados estruturados

� Tipos de dados intrínsecos em Fortran� INTEGER

� REAL

� COMPLEX

� CHARACTER

� LOGICAL

� É possível definir tipos (estruturas) ou fichas.� Ficha - armazena elementos de tipos diferentes� Exemplo: ficha de aluno de IP contém:

� Nome (cadeia de caracteres)� Número (inteiro)� Nota exame (real)� Nota projecto (real)� Nota final (inteiro)

João Miguel da Costa Sousa 249

Tipos estruturados

Definição de tipos estruturados (fichas)____________________________________________________________________

Forma:

TYPE nome_tipo

declaracao1declaracao2

...

declaracaok

END TYPE nome_tipo

� O nome_tipo é um identificador em Fortran;� Cada declaracaoi declara um ou mais componentes da

estrutura deste tipo.� Objectivo: declara tipo estruturado (ficha) cujos componentes são

declarados em declaracao1, …, declaracaok. Estas definições são efectuadas na zona de especificações do programa.

Page 2: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

2

João Miguel da Costa Sousa 250

Exemplos de fichas

� Exemplo 1: ficha de alunoTYPE Ficha_Aluno

CHARACTER(20) :: Nome

INTEGER :: Numero

REAL :: Exame, Projecto

INTEGER :: NotaFinal

END TYPE Ficha_Aluno Aluno1 Aluno2 Nome Nome Numero Numero Exame Exame Projecto Projecto NotaFinal NotaFinal

� Exemplo 2: ponto no espaço 2-DTYPE Ponto2D

REAL :: X, Y

END TYPE Ponto2D

João Miguel da Costa Sousa 251

Declaração de estruturas

Declaração de estruturas____________________________________________________________________

Forma:

TYPE(nome_tipo) :: lista_identificadores

� Objectivo: declara os identificadores que serão os nomes das estruturas cujos componentes são declarados na definição do tipo nome_tipo .

� Exemplo: estruturas dos tipos definidos no Ex. 1 e no Ex. 2 anteriores:

TYPE(Ficha_Aluno) :: Aluno1, Aluno2

TYPE(Ficha_Aluno), DIMENSION(50) :: Alunos

ou:TYPE(Ficha_Aluno):: Alunos(50)

TYPE(Ponto2D) :: Ponto1, Ponto2

Page 3: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

3

João Miguel da Costa Sousa 252

Construtores de fichas

Forma:nome_tipo(lista_componentes)

� Exemplo 1:Ponto2D(2.5, 3.2)

� é um valor do tipo Ponto2D e pode ser atribuida a P:P = Ponto2D(2.5, 3.2)

� Declaração da constante Centro:TYPE(Ponto2D), PARAMETER :: Centro = Ponto2D(2.5, 3.2)

� Declaração da constante Centro:TYPE(Ponto2D), PARAMETER :: Centro = Ponto2D(2.5, 3.2)

...

A = 1.1

P = Ponto2D(A, 2*A)

� Exemplo 2:Aluno1 = Ficha_Aluno(“J. Silva”, 10000, 15., 17., 16)

Alunos(1) = Aluno1

João Miguel da Costa Sousa 253

Acesso a componentes de fichas

� Componentes individuais são acedidos por variáveis qualificadas dadas por:� Nome da estrutura e� Nome do componente,� juntos pelo selector de componente: “%”:

nome_estrutura%nome_componente

� Exemplos:� P%X é o primeiro componente da estrutura P do tipo Ponto2D, e P%Y é o

segundo componente. � Alunos(1)%Nome é o primeiro componente da estrutura Alunos(1) do tipo

Ficha_Aluno, etc.

Aluno1%Nome = “Jose Silva”

READ(*, *) Aluno1%Nome

PRINT(*, *) Aluno1%Nome

Aluno1%Nome(1:1) = “J”

Page 4: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

4

João Miguel da Costa Sousa 254

Estruturas encadeadas

� Os componentes de um tipo podem ser de qualquer tipo; mesmo de outra estrutura.

� Exemplo:TYPE Ponto2D

REAL :: X, Y

END TYPE Ponto2D

TYPE Circulo

TYPE(Ponto2D) :: Centro

REAL :: Raio

END TYPE Circulo

TYPE(Circulo) :: C

� declara C que é uma variável do tipo Circulo e tem dois componentes, onde o primeiro é do tipo Ponto2D, e o segundo do tipo REAL.

C = Circulo(Ponto2D(2.5, 3.2), 10.0)

� representa um círculo de raio 10.0 e centrado em (2.5, 3.2). � O valor de C%Centro%X é de 2.5.

João Miguel da Costa Sousa 255

Processamento e atribuições

� E/S de estruturas tem de ser efectuada componente a componente

� Exemplos: leitura e escrita da variável Aluno do tipo Ficha_Aluno, e atribuição por componentes.

READ(*, *) Aluno%Nome, Aluno%Numero, Aluno%Exame, &

Aluno%Projecto, Aluno%NotaFinal

WRITE(*, ‘(1X, “Nome: ”, A)’) Aluno%Nome

WRITE(*, ‘(1X, “Numero: ”, I5)’) Aluno%Numero

WRITE(*, ‘(1X, “Exame: ”, F6.1)’) Aluno%Exame

WRITE(*, ‘(1X, “Projecto: ”, F6.1)’) Aluno%Projecto

WRITE(*, ‘(1X, “Nota Final: ”, I4)’) Aluno%NotaFinal

Aluno2%Nome = Aluno%Nome

Aluno2%Numero = Aluno%Numero

Aluno2%Exame = Aluno%Exame

Aluno2%Projecto = Aluno%Projecto

Aluno2%NotaFinal = Aluno%NotaFinal

� Atribuição: variavel_estrutura = expressao_estrutura

� Exemplo: Aluno2 = Aluno

Page 5: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

5

João Miguel da Costa Sousa 256

Estruturas como argumentos

� As estruturas podem ser usadas como argumentos de sub-programas.

� Os parâmetros actuais e formais devem ser do mesmo tipo!

� Exemplo: programa que dados dois pontos calcula a distância entre eles e a recta que passa pelos dois.

� Distância entre 2 pontos P1 com coordenadas (x1, y1) e P2 com coordenadas (x2, y2):

� Recta que passa nos pontos P1 e P2:

2 22 1 2 1( ) ( )x x y y− + −

y mx b= +

2 1

2 1

,y y

mx x

−=

1 1b y m x= −

João Miguel da Costa Sousa 257

Programa: Pontos e linhas (1)

PROGRAM Pontos_e_Linhas

!----------------------------------------------------------------------------------

! Programa que le dois pontos P1 e P2 representados como estruturas, calcula a

! distancia entre P1 e P2 e calcula a equacao da recta unindo os dois pontos.

! Identificadores usados:

! Ponto : ficha representada em 2 dimensoes! P1, P2 : dois pontos a ser processados! Distancia : funcao que calcula distancia entre pontos

! EquacaoRecta : subrotina que calcula a equacao duma recta

! Resposta : resposta do utilizador

!

! Entradas: Coordenadas dos pontos P1 e P2

! Saidas: distancia entre 2 pontos e recta entre eles

!-----------------------------------------------------------------------------------

IMPLICIT NONE

TYPE PontoREAL :: X, Y

END TYPE Ponto

TYPE(Ponto) :: P1, P2CHARACTER(1) :: Resposta

DO

WRITE(*, ‘(1X, A)’, ADVANCE = “NO”) &“ Introduza as coordenadas dos pontos P1 e P2: ”

READ (*, *) P1%X, P1%Y, P2%X, P2%YWRITE(*,‘(1X,2(A,“(”,F5.2,“,”,F5.2,“)”), “ e ”, F5.2)’) &

“Distancia entre ”, P1%X, P1%Y, “ e ”, P2%X, P2%Y, &Distancia(P1, P2)

CALL EquacaoRecta(P1, P2)

Page 6: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

6

João Miguel da Costa Sousa 258

Programa: Pontos e linhas (2)

WRITE(*, ‘(/ 1X, A)’, ADVANCE = “NO”) &

“Mais pontos (S ou N)? ”

READ(*, *) Resposta

IF (Resposta /= “S”) EXIT

END DO

CONTAINS

!--Distancia-----------------------------------------------

! Funcao que calcula a distancia entre os pontos P1 e P2

!

! Aceita: Estruturas P1 e P2 do tipo Ponto

! Retorna: Distancia entre P1 e P2

!----------------------------------------------------------

FUNCTION Distancia(P1, P2)TYPE(Ponto), INTENT(IN) :: P1, P2REAL :: Distancia

Distancia = SQRT((P2%X - P1%X)**2 + (P2%Y - P1%Y)**2)END FUNCTION Distancia

!--EquacaoRecta--------------------------------------------

! Subrotina que calcula a equacao da recta y = mx + b da

! linha que passa nos pontos P1 e P2. Variaveis locais:

! M : declive da recta

! B : interseccao da recta com o eixo dos yy

! Aceita: Estruturas P1 e P2 do tipo Ponto

! Retorna: Escreve equacao da recta que passa em P1 e P2

!----------------------------------------------------------

João Miguel da Costa Sousa 259

Programa: Pontos e linhas (3)

SUBROUTINE EquacaoRecta(P1, P2)TYPE(Ponto), INTENT(IN) :: P1, P2REAL :: M, B

IF (P1%X == P2%X) THENWRITE (*, ‘(1X, A, F5.2)’) “Linha vertical x = ”, P1%X

ELSEM = (P2%Y - P1%Y) / (P2%X - P1%X)B = P1%Y - M * P1%XWRITE (*, ‘(1X, 2(A, F5.2))’) “Equacao da recta e y = ”, M, “x + ”, B

END IFEND SUBROUTINE EquacaoRecta

END PROGRAM Pontos_e_Linhas

� Exemplo de execução:> Introduza as coordenadas dos pontos P1 e P2: 0,0 1,1

> Distancia entre ( 0.00, 0.00) e ( 1.00, 1.00) e 1.41

> Equacao da recta e y = 1.00x + 0.00

>

> Mais pontos (S ou N)? S

> Introduza as coordenadas dos pontos P1 e P2: 1,1 1,5

> Distancia entre ( 1.00, 1.00) e ( 1.00, 5.00) e 4.00

> Linha vertical x = 1.00

>

> Mais pontos (S ou N)? S

> Introduza as coordenadas dos pontos P1 e P2: 3.1,4.2 -5.3,7.2

> Distancia entre ( 3.10, 4.20) e (-5.30, 7.20) e 8.92

> Equacao da recta e y = -0.36x + 5.31

>

> Mais pontos (S ou N)? N

Page 7: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

7

João Miguel da Costa Sousa 260

Exemplo: Tabela de utilizadores

� Pretende-se procurar um utilizador numa base de dados, e verificar a utilização dos seus recursos computacionais. � Um dado ficheiro deverá conter o apelido, nome, número de

identificação, recursos disponíveis e recursos utilizados, i.e.:

Babbage Charles 10101 ADA 7503 8081

Newton Isaac 10102 APPLE 6505 9884

Leibnitz Gottfried 10103 CALC 2501 9374

Fahreneit Freda 10104 FRZ32 2501 7793

Celsius Christine 10105 FRZ0 8501 9191

Tower Lean 10106 PISA 3502 2395

VanderVan Henry 10107 VAN 7501 6859

Yale Harvard 20125 IVY 1501 2770

� Dado um número de utilizador, pretende-se que o programa indique o seu nome, apelido e a percentagem dos recursos disponíveis já utilizados.

João Miguel da Costa Sousa 261

Ex: Registo Utiliz. Computadores

PROGRAM Registos_Utilizacao_Computadores

!--------------------------------------------------------------

! Este programa le numeros de identificacao do teclado,

! e procura numa base de dados se esse numero existe, e

! nesse caso retorna informacao sobre esse utilizador.

! Os identificadores usados sao os seguintes:

!

! Tp_Registo_Utilizacao : nome do tipo com informacao

! Nome_Ficheiro : nome do ficheiro com dados

! Estado_Abertura : variavel de estado para OPEN

! Estado_Leitura : variavel de estado para READ

! Utilizadores : tabela do Tp_Registo_Utilizacao

! Num_Utilizadores : numero de utilizadores

! Numero_Procurado : numero de id a procurar

! Localizacao : indice do utilizador procurado

! Encontrado : indica se a id procurada foi

! : ou nao encontrada

! Entradas : Numero_Procurado(teclado), Utilizadores(fich.)

! Saidas : Numero, nome e % de recursos computacionais

! utilizados, ou uma mensagem indicando que o numero

! nao foi encontrado.

!-----------------------------------------------------------------

IMPLICIT NONE

TYPE Tp_Registo_Utilizacao

CHARACTER(15) :: Nome, Apelido

INTEGER :: Numero_Identificacao

CHARACTER(6) :: Palavra_chave

REAL :: Recursos_Usados, Limite_Recursos

END TYPE Tp_Registo_Utilizacao

Page 8: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

8

João Miguel da Costa Sousa 262

Registo Utiliz. Computadores

CHARACTER(20) :: Nome_Ficheiro

TYPE(Tp_Registo_Utilizacao), DIMENSION(20) :: Utilizadores

INTEGER :: Estado_Abertura, Estado_Leitura, i

INTEGER :: Num_Utilizadores, Numero_Procurado, Localizacao

LOGICAL :: Encontrado

! Le o nome do ficheiro com os registos e abre-o

WRITE(*,'(1X, A)',ADVANCE="NO") "Escreva o nome do ficheiro:"

READ (*, *) Nome_Ficheiro

OPEN (10, FILE = Nome_Ficheiro, STATUS = "OLD", &

IOSTAT = Estado_Abertura)

IF (Estado_abertura <= 0) THEN

i = 0

DO

i = i+1

READ(10,*,IOSTAT=Estado_Leitura) Utilizadores(i)%Apelido,&

Utilizadores(i)%Nome, &

Utilizadores(i)%Numero_Identificacao, &

Utilizadores(i)%Palavra_chave, &

Utilizadores(i)%Recursos_Usados, &

Utilizadores(i)%Limite_Recursos

IF (Estado_Leitura<0) EXIT ! Fim do fiheiro

END DO

Num_Utilizadores = i-1

João Miguel da Costa Sousa 263

Registo Utiliz. Computadores

DO ! Procura numero identificacao

WRITE(*,*)

WRITE(*,'(1X,A)',ADVANCE="NO") "Escreva o numero de &

&utilizador (0 para parar): "

READ (*,*) Numero_Procurado

IF (Numero_Procurado /= 0) THEN

CALL Procura_Numero(Utilizadores(1:Num_Utilizadores), &

Numero_Procurado,Encontrado,Localizacao)

IF (Encontrado) THEN

WRITE(*,'(1X, I5, 1X, 2A)') &

Utilizadores(Localizacao)%Numero_Identificacao, &

Utilizadores(Localizacao)%Nome, &

Utilizadores(Localizacao)%Apelido

WRITE(*,'(1X, "utilizou", F5.1, "% de recursos")') &

100.0 * Utilizadores(Localizacao)%Recursos_Usados &

/ Utilizadores(Localizacao)%Limite_Recursos

ELSE

WRITE(*,*) Numero_Procurado, " nao encontrado."

END IF

END IF

! Se utilizador indicar, acaba o ciclo.

IF (Numero_Procurado == 0) EXIT

END DO

ELSE

WRITE(*,*) "Erro na abertura de ficheiro!!"

END IF

Page 9: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

9

João Miguel da Costa Sousa 264

Registo Utiliz. Computadores

CONTAINS

!-Procura_Numero—(...)------------------------------------

SUBROUTINE Procura_Numero(Utilizadores, NumProcurado, Encontrado, Local)

TYPE(Tp_Registo_Utilizacao), DIMENSION(:) :: Utilizadores

INTEGER,INTENT(IN) :: NumProcurado

INTEGER,INTENT(OUT) :: Local

LOGICAL,INTENT(OUT) :: Encontrado

INTEGER :: NumUtilizadores

NumUtilizadores = SIZE(Utilizadores)

Local = 1

Encontrado = .FALSE.

DO

IF ((Local > NumUtilizadores) .OR. Encontrado) EXIT

IF (NumProcurado== &

Utilizadores(Local)%Numero_Identificacao) THEN

Encontrado = .TRUE.

ELSE

Local = Local + 1

END IF

END DO

END SUBROUTINE Procura_Numero

END PROGRAM Registos_Utilizacao_Computadores

João Miguel da Costa Sousa 265

Exemplo de execução

> Escreva o nome do ficheiro: dados.dat

>

> Escreva o numero de utilizador (0 para parar): 10101

> 10101 Charles Babbage

> utilizou 92.8% de recursos

>

> Escreva o numero de utilizador (0 para parar): 10103

> 10103 Gottfried Leibnitz

> utilizou 26.7% de recursos

>

> Escreva o numero de utilizador (0 para parar): 20125

> 20125 Harvard Yale

> utilizou 54.2% de recursos

>

> Escreva o numero de utilizador (0 para parar): 10200

> 10200 nao encontrado

>

> Escreva o numero de utilizador (0 para parar): 10102

> 10102 Isaac Newton

> utilizou 65.8% de recursos

>

> Escreva o numero de utilizador (0 para parar): 0

Page 10: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

10

João Miguel da Costa Sousa 266

Outros tipos de dados

� Tipos de dados parametrizados� Inteiros em Fortran: 32 bits de -2 147 483 648 a +2 147 483 647

� Reais em Fortran: 32 bits -1038 a 1038 aprox. (precisão simples)

� Estes limites podem ser inadequados; podem ser necessária maior ou menor precisão.

� Estas alterações são dadas por tipos de dados parametrizados.

� Tipo COMPLEX� a + bi, onde a e b são números reais e� i2 = -1

� Tipo CHARACTER� processamento avançado de cadeias de caracteres

João Miguel da Costa Sousa 267

Tipos de dados parametrizados

� Representação de números é aproximada� Reais não são representados exactamente

� Exemplo: equação que retorna sempre 1:

A B AB B

A

A

A

+ − −= =

a f2 2

2

2

2

21

PROGRAM Demo_1

IMPLICIT NONE

REAL :: A, B, C

READ (*, *) A, B

C = ((A + B)**2 - 2.0*A*B - B**2) / A**2

WRITE (*,*) C

END PROGRAM Demo_1

A B C

0.1 888.0 1.0000000 1e-4 888.0 1.001166 1e-5 888.0 1.163585 2e-6 888.0 -1.421085E–02 1.1e-10 888.0 9.616402E+09

Page 11: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

11

João Miguel da Costa Sousa 268

Declaração de tipos parametrizados

Tipos parametrizados____________________________________________________________________

Forma:

especificador_tipo(KIND = numero-tipo) :: lista

ouespecificador_tipo(numero-tipo) :: lista

� o especificador_tipo é em geral:INTEGER

REAL

COMPLEX

LOGICAL

� o numero-tipo é um inteiro positivo (constante) com valor positivo;� os atributos são atributos opcionais;� a lista é uma lista de identificadores.

� Declara que os identificadores na lista têm o tipo e o numero-tipoespecificado.

João Miguel da Costa Sousa 269

Tipos parametrizados (concl.)

� Os números-tipo dependem da máquina e do compilador. Reais mais utilizados:

Tipo NúmeroTipo Descrição REAL 4 Valores com precisão simples com aproximadamente 7

dígitos significativos; armazanados em 32 bits REAL 8 Valores com precisão dupla com aproximadamente 14

dígitos significativos; armazanados em 64 bits

� Exemplo:

REAL(KIND = 4) :: Z

REAL(8), DIMENSION(5,5) :: Beta

� Inteiros em PowerStation:Tipo NúmeroTipo Descrição INTEGER 1 Inteiros de 8 bits: -27 até 27 - 1 INTEGER 2 Inteiros de 16 bits: -215 até 215 - 1 INTEGER 4 Inteiros de 64 bits: -263 até 263 - 1

Page 12: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

12

João Miguel da Costa Sousa 270

Tipo de dados COMPLEX

� Tipo COMPLEX� a + bi, onde a e b são reais. Em Fortran:

(a, b)

� Declarações de complexosCOMPLEX :: A, B

COMPLEX, DIMENSION(10,10) :: Rho

� Operações com complexos� Soma

� Subtração

� Produto

� Divisão

z a bi w c di= + = +e

z w a c b d i+ = + + +( ) ( )

z w a c b d i− = − + −( ) ( )

z w ac bd ad bc i⋅ = − + +( ) ( )

z

w

ac bd

c d

bc ad

c di=

+

+

+−

+2 2 2 2

João Miguel da Costa Sousa 271

Tipo complexo (exemplos)

� Exemplo de operações (C e Z variáveis complexas):C = (6.2, 2.4)

Z = 4.0 * C / 2

� retorna para Z o valor:

(12.4, 4.8)

� Se for atribuída a X do tipo real: X = 4.0 * C/2, retorna o valor 12.4� Se for atribuída a N do tipo inteiro: N = 4.0 * C/2, retorna o valor 12

� Funções complexas intrínsecas:� ABS(z)

� CONJG(z)

� EXP(z)

� AIMAG(z)

� CMPLX(x, y)

� REAL(z)

Page 13: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

13

João Miguel da Costa Sousa 272

Entrada e saída de complexos

� Complexos são lidos como um par de reais ou 2 reaisPROGRAM Demo_2

IMPLICIT NONE

COMPLEX :: X, Y, W, Z, A

READ(*, *) X, Y

READ(*, ‘(2F2.0)’) W

WRITE(*, *) X, Y

WRITE(*, *) W

WRITE(*, 10) X, Y, W

10 FORMAT(1X, F5.2, “ +”, F8.2, “I”)

Z = (X + Y) / (1.0, 2.2)

A = X * Y

WRITE(*, 10) Z, A

END PROGRAM Demo_2

� Entrada de dados:> (3,4), (0.75, -2.23)

> 5 7

� Saída produzida:> ( 3.0000000, 4.0000000) ( 0.7500000, -2.2300000)

> ( 5.0000000, 7.0000000)

> 3.00 + 4.00I

> 0.75 + -2.23I

> 5.00 + 7.00I

> 1.31 + -1.11I

> 11.17 + -3.69I

João Miguel da Costa Sousa 273

O tipo CHARACTER

� Cadeia de caracteres vazia� “” ou ‘’

� Compilador associa cada variável a um endereço em memória. Nomes das variáveis são identificadores.

Declaração de cadeias de caracteres___________________________________________________________

CHARACTER(LEN = n) :: lista

ouCHARACTER(n) :: lista

� Exemplo:CHARACTER(LEN = 15) :: Nome, Apelido

CHARACTER(15) :: Nome

� Em subprogramas os argumentos formais podem ser pré-definidos:CHARACTER(*) :: lista_identificadores

Page 14: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

14

João Miguel da Costa Sousa 274

Operacões com caracteres

� Caracteres podem ser parametrizados:CHARACTER(LEN=n, KIND=num_tipo) :: lista

CHARACTER(n, KIND=num_tipo) :: lista

CHARACTER(n, num_tipo) :: lista

CHARACTER(KIND=num_tipo, LEN=n) :: lista

CHARACTER(KIND=num_tipo) :: lista

� onde o num_tipo especifica o esquema de codificação (ASCII, EBCDIC, etc.) e/ou o tipo de caracteres (Inglês, Português, Russo, etc.)

� Concatenação de caracteres: operador binário dado por //� Exemplo 1

“centi” // “metros” produz:“centimetros”

� Exemplo 2CHARACTER(7) :: UnidadeQuadrada

UnidadeQuadrada = “ quadrados”

“centi” // “metros” // UnidadeQuadrada

produz:“centimetros quadrados”

João Miguel da Costa Sousa 275

Subcadeias de caracteres

� Exemplo: subcadeia dos caracteres 6 a 10 deUnidade = “centimetros”

é dada por:Unidade(6:10) e tem o valor: “metro”

� As primeiras e últimas posições não necessitam de ser especificadas.� Exemplo:

CHARACTER(15) :: Curso, Nome*20

Curso = “Engenharia”

Curso(:3) tem o valor “Eng” eCurso(8:) tem o valor “ria____”,

onde “_” corresponde a um espaço em branco.� A primeira posição deve ser positiva, e a última >= que a primeira, mas não

maior que o comprimento da cadeia de caracteres.� Podem ser efectuadas atribuições a sub-cadeias, modificando parte de uma

cadeia de caracteres.

Page 15: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

15

João Miguel da Costa Sousa 276

Funções com caracteres

� Funções de cadeias para cadeias:� ADJUSTL(cad_caracteres)

� ADJUSTR(cad_caracteres)

� REPEAT(cad_caracteres, n)

� TRIM(cad_caracteres)

� Exemplo:CHARACTER(10) :: Cadeia = “ ABCDE”

� A saída produzida por:WRITE(*, *) “***”, Cadeia, “***”

WRITE(*, *) “***”, ADJUSTL(Cadeia), “***”

WRITE(*, *) “***”, ADJUSTR(Cadeia), “***”

WRITE(*, *) “***”, TRIM(Cadeia), “***”

WRITE(*, *) “***”, REPEAT(Cadeia,3), “***”

� é a seguinte:>*** ABCDE ***

>***ABCDE ***

>*** ABCDE***

>*** ABCDE***

>*** ABCDE ***

>*** ABCDE ABCDE ABCDE ***

João Miguel da Costa Sousa 277

Funções com caracteres (cont.)

� Funções de comprimento:� LEN(cad_caracteres)

� LEN_TRIM(cad_caracteres)

� Exemplo:CHARACTER(10) :: Cadeia = “ ABCDE”

O valor retornado por:LEN(Cadeia) retorna 10, eLEN_TRIM(Cadeia) retorna 6.

� Funções de procura:� INDEX(cadeia1, cadeia2) ou� INDEX(cadeia1, cadeia2, atras)

� SCAN(cadeia1, cadeia2) ou� SCAN(cadeia1, cadeia2, atras)

� VERIFY(cadeia1, cadeia2) ou� VERIFY(cadeia1, cadeia2, atras)

Page 16: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

16

João Miguel da Costa Sousa 278

Exemplo com funções de procura

� Exemplo:CHARACTER(25) :: Unidades = “centimetros e metros”

� A saída produzida por:WRITE(*, *) INDEX(Unidades, “metros”)

WRITE(*, *) INDEX(Unidades, “metros”, .FALSE.)

WRITE(*, *) INDEX(Unidades, “metros”, .TRUE.)

WRITE(*, *) INDEX(Unidades, “cents”)

WRITE(*, *) SCAN(“kilometro”, Unidades)

WRITE(*, *) SCAN(“kilometro”, Unidades, .FALSE.)

WRITE(*, *) SCAN(“kilometro”, Unidades, .TRUE.)

WRITE(*, *) SCAN(“flora”, Unidades)

WRITE(*, *) VERIFY(“kilometro”, Unidades)

WRITE(*, *) VERIFY(“kilometro”, Unidades, .FALSE.)

WRITE(*, *) VERIFY(“kilometro”, Unidades, .TRUE.)

WRITE(*, *) VERIFY(“tenis”, Unidades)

� é a seguinte:> 6

> 6

> 15

> 0

> 2

> 2

> 9

> 3

> 1

> 1

> 3

> 0

João Miguel da Costa Sousa 279

Gestão de memória em tabelas

� Instruções ALLOCATE e DEALLOCATE utilizam memória quando o programa corre.� permitem utilizar apenas a memória necessária� evitam desperdício de memória� eficientes para tabelas com tamanho constante

� Para dados de diferentes tamanhos, quando se varia o tamanho da tabela efectuam-se as seguintes operações:� Uma nova tabela é alocada.� Os elementos da tabela antiga são copiados para a tabela nova.� Os novos elementos são introduzidos na nova tabela.� A tabela antiga é apagada da memória.

� Estas operações demoram bastante tempo!

Page 17: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

17

João Miguel da Costa Sousa 280

Ponteiros

� As tabelas (mesmo alocadas) são estruturas de dados

estáticas.

� Estruturas de dados dinâmicas permitem expandir ou contrair a estrutura durante a execução.� É constituída por uma colecção de elementos, chamados nós ligados

entre si.

� Esta ligação associa a cada nó um ponteiro para o próximo nó da estrutura.

� Exige a necessidade de alocar e aceder à memória durante a execução dum programa.

� Variáveis que apontam para essas localizações em memória: ponteiros.

� Exemplo: Lista ligadaProx Prox ProxDados Dados Dados

XXX YYY ZZZLista

João Miguel da Costa Sousa 281

Listas implementadas em tabelas

� Tabelas podem implementar listas. São ineficientes para:� tamanhos variáveis durante a execução,

� inserir e retirar elementos na lista.

� Cada vez que elementos novos são inseri-dos dever-se-á mover elementos na tabela.

� Exemplo 1: Inserir 42 na lista 23, 25, 34, 48, 61, 89. Os elementos 4 a 6 devem ser deslocados para as posições 5 a 7, para o novo elemento ser introduzido em 4:

� Exemplo 2: Retirar 25 da lista:

23 25 34 48 61 89 ? ... ?

23 25 34 42 48 61 89 ... ?

23 34 42 48 61 89 ? ... ?

23 25 34 42 48 61 89 ... ?

Page 18: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

18

João Miguel da Costa Sousa 282

Listas ligadas

� Contém uma colecção de elementos chamados nós, que contêm:1. um elemento da lista,

2. um ponteiro para o nó seguinte. O acesso ao nó inicial (1º elemento da lista) deve ser mantido.

� Exemplo: lista com nomes Silva, Fonseca e Castro

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

� A variável Lista aponta para o primeiro nó da lista, e o Prox aponta para o próximo nó.

� O símbolo “terra” não aponta para nada, indicando assim o fim da lista (ponteiro vazio ou null pointer).

João Miguel da Costa Sousa 283

Inserção de elementos em listas

� Nas listas ligadas não é necessário mover elementos quando se altera a lista.

� Para inserir um novo elemento na lista:

1. Criar um novo nó. Guardar o valor a inserir no elemento do nó (pressupõe-se que é possível obter nós duma dada fonte, e que estão nós disponíveis)

2. Ligar o novo nó à lista. Podem existir 2 casos:� o nó é acrescentado no início da lista;

� o nó é inserido no meio da lista.

Page 19: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

19

João Miguel da Costa Sousa 284

Exemplo: inserção em listas

� Exemplo 1: inserir o nome Reis no início da lista� Criar um nó com o nome Reis. O ponteiro NovoPont aponta para este nó.

� O nó é inserido na lista, com a sua ligação a apontar para o primeiro nó na lista; o Prox de NovoPont aponta para o mesmo que Lista:

ProxDados

ReisNovoPont

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

� Ao ponteiro Lista é atribuído NovoPont:

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

ProxDados

ReisNovoPont

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

ReisNovoPont

João Miguel da Costa Sousa 285

Exemplo 2: inserção em listas

� Exemplo 2: inserir nome Ramos após Fonseca, onde PontPredé o ponteiro predecessor:

� Criar um nó com o nome Ramos (como anteriormente):

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontPred

ProxDados

RamosNovoPont

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontPred

Page 20: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

20

João Miguel da Costa Sousa 286

Exemplo 2: inserção em listas

� Prox de NovoPont igual a Prox de PontPred

� Prox de PontPred igual a NovoPont:

ProxDados

RamosNovoPont

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontPred

ProxDados

RamosNovoPont

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontPred

João Miguel da Costa Sousa 287

Apagar elementos de listas

� Tal como na inserção existem 2 casos:1. apagar o primeiro elemento da lista;

2. apagar um elemento com um predecessor.

� Exemplo: para apagar o nome Silva no início da lista basta passar Lista para o segundo nó.

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontAux

� Atribui a PontAux o ponteiro Lista.

Page 21: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

21

João Miguel da Costa Sousa 288

Apagar elementos de listas

� Atribui a Lista o Prox de PontAux.

� Ponteiro PontAux enviado para pilha de livres.

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontAux

Prox ProxDados Dados

Fonseca CastroLista

PontAux

João Miguel da Costa Sousa 289

Apagar elementos de listas

� Exemplo 2: apagar o nome Fonseca da lista inicial.

� Atribui ao ponteiro PontAux o ponteiro Prox de PontPred.

� Atribui a Prox de PontPred o ponteiro Prox de PontAux.

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontPred PontAux

� Coloca o ponteiro PontAux na pilha de ponteiros disponíveis.

Prox Prox ProxDados Dados Dados

Silva Fonseca CastroLista

PontPred PontAux

Prox ProxDados Dados

Silva CastroLista

PontPred PontAux

Page 22: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

22

João Miguel da Costa Sousa 290

Ponteiros em Fortran

Variáveis do tipo ponteiro_____________________________________________________________________________________________________________________

Forma:

tipo, lista-atributos, POINTER :: var_ponteiro

� Declara a variável var_ponteiro, usada para aceder a localizações em memória.

� A variável tem um dado tipo onde os atributos podem ser guardados.

� Exemplo 1: Um ponteiro para cadeias de caracteres é definido como:CHARACTER(10), POINTER :: PontCadeia

� Esta variável só pode ser utilizada para aceder a localizações em memória com 10 caracteres.

� Exemplo 2TYPE :: Info_Inventario

INTEGER :: Numero

REAL :: Preco

END TYPE Info_Inventario

TYPE(Info_Inventario), POINTER :: PontInventario

João Miguel da Costa Sousa 291

Criação de ponteiros

Instrução ALLOCATE_______________________________________________________________________________________

Forma:

ALLOCATE(ponteiro)

� Exemplo: ALLOCATE(PontCadeia)

� O ponteiro PontCadeia “aponta” para uma localização em memória, chamada alvo, com uma cadeia de caracteres (e.g. “computador”)

PontCadeia Computador

� Estados de associação de ponteiros:1. Indefinido - estado inicial após declaração.2. Associado - quando aponta para um alvo.

ponteiro ?

3. Vazio - null pointer; não aponta para nada.

ponteiro

Page 23: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

23

João Miguel da Costa Sousa 292

Associação de ponteiros

� Função de teste ASSOCIATEDASSOCIATED(ponteiro)

� Retorna .TRUE. se o ponteiro está associado e .FALSE. caso contrário. O ponteiro não pode estar indefinido.

� Comando NULLIFYNULLIFY(ponteiro)

� Torna o ponteiro vazio. A localização em memória não é acessível.

� Programa dispõe de uma pilha de memória disponível. Instrução ALLOCATE executa:1. Retira um bloco de memória livre da pilha.2. Aloca esse espaço ao programa executável.

� Pilha de memória é limitada:ALLOCATE(lista, STAT = variavel-inteira)

DEALLOCATE(lista, STAT = variavel-inteira)

João Miguel da Costa Sousa 293

Atribuição de ponteiros

Forma: ponteiro1 => ponteiro2

� O ponteiro1 tem a mesma associação do ponteiro2. O valor anterior de ponteiro1 não é acessível, a não ser que estivesse outro ponteiro a apontar para a mesma localização.

� Antes da atribuição:ponteiro1

ponteiro2

ponteiro3

� Após a atribuição ponteiro1 => ponteiro2:

� Exemplo:CHARACTER(8), POINTER :: PontCadeia, PontTemp

� onde PontTemp aponta para “software” e PontCadeia aponta para “hardware”. Qual o resultado da instrução:

PontTemp => PontCadeia ?

ponteiro1

ponteiro2

ponteiro3

Page 24: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

24

João Miguel da Costa Sousa 294

Expressões com ponteiros

� Regra básica: Quando um ponteiro associado aparece numa expressão, é utilizado directamente o valor para o qual está a apontar.

� Exemplo:CHARACTER(10), POINTER :: PontCadeia

CHARACTER(10) :: Produto = “Computador”

PontCadeia = Produto ePontCadeia = “Computador”

� retornam:PontCadeia Computador

WRITE(*, *) PontCadeia eIF PontCadeia(2:4) == “omp” THEN

WRITE(*, *) PontCadeia

END IF

� imprimem:> Computador

PontTemp = PontCadeia

PontCadeia Computador

PontTemp Computador

João Miguel da Costa Sousa 295

Implementação de listas ligadas

� é definida como:TYPE Lista_Nos

INTEGER :: Dados

TYPE(Lista_Nos), POINTER :: Proximo

END TYPE Lista_Nos

� Construção de uma lista ligadaTYPE(Lista_Nos), POINTER :: ListaNumeros, PontTemp

ALLOCATE(PontTemp)

PontTemp%Dados = 1550

PontTemp%Proximo => ListaNumeros

ListaNumeros => PontTemp

� Para construir toda a lista, a primeira instrução seria:NULLIFY(ListaNumeros)

Prox Prox ProxDados Dados Dados

1550 1723 1996ListaNumeros

Page 25: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

25

João Miguel da Costa Sousa 296

Listas ligadas

� Percorrer uma lista ligada, escrevendo todos os seus elementosPontActual => ListaNumeros

DO

IF (.NOT. ASSOCIATED(PontActual)) EXIT ! Fim da lista

WRITE (*, *) PontActual%Dados

PontActual => PontActual%Proximo

END DO

� Inserir elemento no meio da listaALLOCATE(PontTemp, STAT = EstadoAlocacao)

PontTemp%Dados = ElementoNovo

� Inserir elemento entre PontPred e PontActual:PontTemp%Proximo => PontActual

PontPred%Proximo => PontTemp

João Miguel da Costa Sousa 297

Apagar elementos em listas ligadas

� Apagar elementos na lista� Apagar elementos no início da lista

PontActual => Lista

Lista => PontActual%Proximo

DEALLOCATE(PontActual)

� Apagar o elemento apontado por PontActual precedido por PontPredmeio da listaPontPred%Proximo => PontActual%Proximo

DEALLOCATE(PontActual)

Page 26: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

26

João Miguel da Costa Sousa 298

Aplicação: Endereços Internet

� Protocolos de comunicação� TCP (Transmission Control Protocol)� IP (Internet Protocol)

� TCP/IP identification endereços únicos na Internet. � Exemplo:

dem.ist.utl.pt

� endereço do Dep. Eng. Mecânica do IST

� Os 4 campos correspondem a:host.subdomain.subdomain.rootdomain

� Estes endereços são dados por inteiros:193.136.128.2

João Miguel da Costa Sousa 299

Problema: Acesso à Internet

� Uma porta de acesso é um sistema de ligação entre duas redes de computadores.� Exemplo: ligação de uma Universidade com a Internet.� Cada vez que um estudante acede à WWW o seu endereço TCP/IP é

guardado num ficheiro.

� Problema: O administrador do sistema pretende verificar periodicamente quem e quantas vezes acedeu à Internet.

� Solução:� Entrada: O ficheiro contendo os endereços TCP/IP� Saída: Uma lista com os diferentes endereços e o número de vezes que

aparecem no ficheiro� Existem 232 possibilidades de endereços, logo uma estrutura estática, tal

como uma tabela, não é eficiente.

Page 27: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

27

João Miguel da Costa Sousa 300

Algoritmo: Acesso à Internet

� Identificadores� NomeFicheiro – nome do ficheiro� Endereco – o endereço TCP/IP� ListaEnderecos – lista ligada de endereços

Algoritmo

� Este algoritmo encontra endereços TCP/IP gravados num ficheiro eo número de vezes que ocorrem.

� Entrada: NomeFicheiro – ficheiro contendo os endereços TCP/IP.� Saída: Lista com os endereços e o número de vezes que aparecem

no ficheiro.1. Lê o nome do ficheiro e abre-o para leitura. Se o ficheiro não fôr

aberto acaba o programa.2. Inicializa a ListaEnderecos como lista vazia.

João Miguel da Costa Sousa 301

Algoritmo: Acesso à Internet (2)

3. Repete o seguinte:a) Lê um endereço do ficheirob) Se existe erro de leitura escreve mensagem de erro.c) Caso contrário:d) Se não há mais endereços termina o ciclo.e) Caso contrário:

i. Procura na ListaEnderecos se Endereco está contido na lista.ii. Se endereço já existe

Incrementa contador desse Endereco

Caso contrárioInsere novo endereço na lista, com contador a 1.

4. Atravessa ListaEnderecos e escreve cada TCP/IP e o valor do seu contador.

Page 28: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

28

João Miguel da Costa Sousa 302

Programa: Enderecos_Internet

PROGRAM Enderecos_Internet

!--------------------------------------------------------------------------------------

! Este programa le enderecos TCP/IP de um ficheiro e produz uma lista de enderecos

! distintos indicando quantas vezes esses enderecos aparecem no ficheiro.

! Variáveis usadas:

!

! Nome_Ficheiro : nome do ficheiro com enderecos

! Estado_Abertura : variavel de estado para OPEN

! Estado_Leitura : variavel de estado para READ

! Endereco : endereco lido do ficheiro

! ListaEnderecos : ponteiro para o primeiro no da

! Lista de enderecos

!

! Subrotinas utilizadas para processar listas:

! Adiciona_Lista, Procura, Enderecos_saida

!

! Entradas : NomeFicheiro(teclado), Enderecos (ficheiro)

! Saidas : Lista com enderecos distintos e numero de ocorrencias.

!---------------------------------------------------------------------------------------

IMPLICIT NONE

!Definicao do tipo no-endereco

TYPE Lista_No

CHARACTER(15) :: Endereco_TCP_IP !Dados endereco

INTEGER :: Contador !Contador desse endereco

TYPE(Lista_No), POINTER :: Prox !Ponteiro para prox. no

END TYPE Lista_No

João Miguel da Costa Sousa 303

Programa: Enderecos_Internet

CHARACTER(15) :: Endereco, Nome_Ficheiro*20

INTEGER :: Estado_Abertura, Estado_Leitura

TYPE(Lista_No), POINTER :: ListaEnderecos

! Le o nome do ficheiro com os registos e abre-o

WRITE(*,'(1X, A)',ADVANCE="NO") "Escreva o nome do ficheiro:"

READ (*, *) Nome_Ficheiro

OPEN (10, FILE = Nome_Ficheiro, STATUS = "OLD", &

IOSTAT = Estado_Abertura)

IF (Estado_abertura > 0) THEN

WRITE(*, *) “*** Ficheiro de enderecos invalido ***”

ELSE

!Cria uma lista de enderecos vazia

NULLIFY(ListaEnderecos)

!Le enderecos do ficheiro ate ao fim do ficheiro

DO

READ(10,*,IOSTAT=Estado_Leitura) Endereco

IF (Estado_Leitura<0) EXIT ! Fim do ficheiro

CALL Adiciona_a_Lista(ListaEnderecos,Endereco)

END DO

END IF

CALL Escreve_Enderecos(ListaEnderecos)

Page 29: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

29

João Miguel da Costa Sousa 304

Subrotina: Adiciona_a_Lista

CONTAINS

!------------------------------------------------------------------------------------

! Esta subrotina verifica se Endereco ja se encontra na lista ligada (utilizando

! Procura). Se nao, Endereco e acrescentado no inicio da lista. Se sim, o contador

! e incrementado de 1 elemento. Variaveis locais:

! EstadoAlocacao : estado da instrucao OPEN

! PontLocal : pont. para o no com Endereco, ou vazio

! Esta_na_Lista : indica se Endereco se encontra na

! ListaEnderecos

!

! Recebe: ListaEnderecos e Endereco

! Retorna: ListaEnderecos modificada

!-------------------------------------------------------------------------------------

SUBROUTINE Adiciona_a_Lista(ListaEnderecos,Endereco)

TYPE(Lista_No), POINTER :: ListaEnderecos

CHARACTER(*), INTENT(IN) :: Endereco

TYPE(Lista_No), POINTER :: PontLocal

INTEGER :: EstadoAlocacao

LOGICAL :: Esta_na_Lista

IF (.NOT. ASSOCIATED(ListaEnderecos)) THEN !Lista vazia

ALLOCATE(ListaEnderecos, STAT = EstadoAlocacao)

IF (EstadoAlocacao /= 0) THEN

WRITE(*, *) “*** Nao ha memoria disponivel! ***”

ELSE

ListaEnderecos%Endereco_TCP_IP = Endereco

ListaEnderecos%Contador = 1

NULLIFY(ListaEnderecos%Prox)

END IF

João Miguel da Costa Sousa 305

Subrotinas de Enderecos_Internet

ELSE !Lista nao vazia; determina se Endereco ja existe

CALL Procura_em_Lista(ListaEnderecos,Endereco, &

PontLocal,Esta_na_Lista)

IF (Esta_na_Lista) THEN ! Incrementa contador de um

PontLocal%Contador = PontLocal%Contador + 1

ELSE !Cria um novo no e insere-o no inicio da lista

ALLOCATE(PontLocal, STAT = EstadoAlocacao)

IF (EstadoAlocacao /= 0) THEN

WRITE(*, *) “*** Nao ha memoria disponivel! ***”

ELSE

PontLocal%Endereco_TCP_IP = Endereco

PontLocal%Contador = 1

PontLocal%Prox => ListaEnderecos

ListaEnderecos => PontLocal

END IF

ENDIF

ENDIF

END SUBROUTINE Adiciona_a_Lista

!----------------------------------------------------------------------------------

! Esta subrotina procura na ListaEnderecos por um no contendo Endereco. Se este

! endereco for encontrado, o ponteiro PontLocal aponta para o no com Endereco, e

! Esta_na_Lista retorna verdadeiro; caso contrario PontLocal e vazio (NULL) e

! Esta_na_Lista falso.

!

! Recebe: ListaEnderecos e Endereco

! Retorna: PontLocal, Esta_na_Lista

!--------------------------------------------------------------------------------------

SUBROUTINE Procura_em_Lista(ListaEnderecos, Endereco, PontLocal, Esta_na_Lista)

Page 30: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

30

João Miguel da Costa Sousa 306

Subrotina: Procura_em_Lista

SUBROUTINE Procura_em_Lista(ListaEnderecos, Endereco, PontLocal, Esta_na_Lista)

TYPE(Lista_No), POINTER :: ListaEnderecos, PontLocal

CHARACTER(*), INTENT(IN) :: Endereco

LOGICAL, INTENT(OUT) :: Esta_na_Lista

PontLocal => ListaEnderecos

Esta_na_Lista = .FALSE.

! Percorre a lista ate encontrar endereco ou ate ao fim

DO

IF(Esta_na_Lista .OR. .NOT. ASSOCIATED(PontLocal)) EXIT

! Endereco nao encontrado ou fim da lista termina ciclo

IF (PontLocal%Endereco_TCP_IP == Endereco) THEN

Esta_na_Lista = .TRUE.

ELSE ! Procura no proximo elemento

PontLocal => PontLocal%Prox

END IF

END DO

END SUBROUTINE Procura_em_Lista

João Miguel da Costa Sousa 307

Subrotina: Enderecos_Saida

!----------------------------------------------------------------------------------

! Esta subrotina escreve o conteudo da lista ligada apontada por ListaEnderecos.

! Imprime o endereco e o contador de cada no.

! Variveis locais:

! PontAux : ponteiro que percorre a lista

!

! Recebe: ListaEnderecos

! Saida: Escreve endrecos e contador nos nos

!------------------------------------------------------------------------------------

SUBROUTINE Escreve_Enderecos(ListaEnderecos)

TYPE(Lista_No), POINTER :: ListaEnderecos, PontAux

PontAux => ListaEnderecos

WRITE(*, *)

WRITE(*, *) "Enderecos de Internet"

WRITE(*, *)

WRITE(*, *) " Endereco Contador "

WRITE(*, *) "------------------------------"

! Escreve informacao nos nos ate ao fim da lista

DO

IF (.NOT. ASSOCIATED(PontAux)) EXIT

WRITE(*,‘1X, A, 4X, I4’) PontAux%Endereco_TCP_IP, PontAux%Contador

PontAux => PontAux%Prox

END DO

END SUBROUTINE Escreve_Enderecos

END PROGRAM Enderecos_Internet

Page 31: Tipos de dados estruturados - fenix.tecnico.ulisboa.pt · Ficha - armazena elementos de tipos diferentes Exemplo: ficha de aluno de IP contém: Nome (cadeia de caracteres) ... Estado_Leitura

31

João Miguel da Costa Sousa 308

Resultados

� Ficheiro exfic.dat:128.159.4.20

123.111.222.33

100.1.4.31

34.56.78.90

120.120.120.120

128.159.4.20

123.111.222.33

123.111.222.33

77.66.55.44

100.1.4.31

123.111.222.33

128.159.4.20

� Exemplo de execução:> Escreva o nome do ficheiro: exfic.dat

>

> Endereco Contador

> ---------------------------

> 77.66.55.44 1

> 120.120.120.120 1

> 34.56.78.90 1

> 100.1.4.31 2

> 123.111.222.33 4

> 128.159.4.20 3