Вы находитесь на странице: 1из 13

8/11/2009

Linguagens de Programação Conceitos e Técnicas

Valores e Tipos de Dados

Prof. Jairo Francisco de Souza

Introdução

Evolução:

As primeiras LPs tinham um conjunto muito reduzido de TDs;

Fortran pré-90’s: matrizes (arrays) para implementar listas encadeadas e árvores binárias;

COBOL: tipo estrutura para registros de informações e especificação da precisão de tipos decimais.

PL/I: acrescentou muitos TDs (primitivos ou pré-definidos). Especificação para precisão de inteiros e reais.

Algol 68: inovou com um conjunto reduzido de TDs básicos e operações de definição de estruturas de dados pelo programador.

ADA 83: tipos de dados abstratos (definidos pelo usuário)

Linguagens de Programação

3

Tipos Primitivos

Não são definidos usando outro TD

ser

Não

podem

decompostos

em

simples

valores

mais

Costumam ser definidos na implementação da LP

Sofrem influência direta do hardware

Podem ser usados para definir TD estruturados

Categorias de TD primitivos:

Numéricos

Booleanos

Caracter

Linguagens de Programação

5

Introdução • Tipo de dados (TDs): conjunto de valores (de dados) e de operações pré-definidas
Introdução
• Tipo de dados (TDs): conjunto de valores (de dados)
e de operações pré-definidas sobre esses valores;
• Importância dos TDs nas LPs:
– Os conceitos do mundo real (universo de discurso ou
espaço do problema) devem ser representados através de
valores e operações da LP (espaço representacional);
– Quanto mais próxima estiver a LP do espaço do problema,
melhor (menor o “gap conceitual”);
– Isso
determina
a
aplicabilidade
da
LP
aos
diferentes
domínios de aplicação.
2
Linguagens de Programação

Introdução

TD`s

definidos

vantagens:

pelo

usuário

trazem

muitas

Nomes significativos no espaço do problema (diminuição do “gap conceitual”);

Aumenta o poder da verificação de tipo;

Facilita a manutenção dos programas

Cardinalidade

Quantidade de valores possíveis para o TD

Por exemplo: cardinalidade do tipo boolean é 2.

Linguagens de Programação

4

Tipo Inteiro

Corresponde a um intervalo do conjunto dos números inteiros

Sinalizados e não-sinalizados (p.ex: C++ e C#)

Vários tipos inteiros numa mesma LP

Normalmente,

intervalos

são

definidos

na

implementação do compilador

Em JAVA, o intervalo de cada tipo inteiro é estabelecido na definição da própria LP

Linguagens de Programação

6

8/11/2009

Tipos Inteiros em JAVA

Tipo Tamanho (bits) Início Fim byte 8 -128 127 short 16 -32768 32767 int 32
Tipo
Tamanho
(bits)
Início
Fim
byte
8
-128
127
short
16
-32768
32767
int
32
-2.147.483.648
2.147.483.647
long
64
-9223372036854775808
9223372036854775807

Linguagens de Programação

7

Tipo Inteiro

Representação de inteiros

Complemento a um

O negativo de um número é dado pelo seu complemento (sua negação bit a bit – bitwise NOT)

Em 8 bits, sobram 7 para a magnitude. Assim, é possível representar de -127 a +127

e

Duas

formas

de

representar

o

Zero:

00000000

(+0)

11111111 (-0)

Exemplo: Número -5 = (NOT) 1101 = 0010.

Para somar dois números, é necessário “carregar” 1:

11111110 (-1) complemento a um

+ 00000010 (+2) complemento a um 1 00000000 (0) resposta errada 1 (+1) “carregando” 1

00000001 (1) resposta correta

Linguagens de Programação

Usado no algoritmo de verificação (checksum) do IPv4,

ICMP, UDP, TCP.

9

Tipo Ponto (ou vírgula) Flutuante

Modela os números reais em uma representação finita e utilizando o sistema de numeração binário;

Consequência: conseguem representar somente aproximações

Número π ou e: aproximação devido à representação finita

Número decima 0,1: aproximação devido à utilização do sistema binário

Problemas de compatibilidade com aplicações financeiras.

LPs normalmente incluem dois tipos de ponto flutuante: float e double

Linguagens de Programação

11

Tipo Inteiro

Representação de inteiros

Sinal-magnitude

1 bit para sinal e os demais para a magnitude (número)

Em 8 bits, sobram 7 para a magnitude. Assim, é possível representar de -127 a +127

Duas formas de representar o Zero: 00000000 (+0) e 10000000 (-0)

Exemplo: Número -5 = 1101

Linguagens de Programação

8

Exemplo: Número -5 = 1101 Linguagens de Programação 8 Tipo Inteiro • Representação de inteiros –

Tipo Inteiro

Representação de inteiros

Complemento a dois (mais comum)

O negativo de um número é dado pelo seu complemento (sua negação bit a bit – bitwise NOT) somado de 1.

Em 8 bits, sobram 7 para a magnitude. Assim, é possível representar de -128 a 127

Zero: única representação (00000000). Não é preciso “carregar” 1

Exemplo: Número -5 = (NOT) 1101 + 1= 0010 + 1 = 0011.

Método prático:

Encontre o primeiro 1.

Inverta o bit de todos os números anteriores ao primeiro 1. Binário 0101001 1010111 (complemento a 2) Binário 0101100 1010100 (complemento a 2)

Linguagens de Programação

10

100 (complemento a 2) – Linguagens de Programação 1 0 Tipo Ponto Flutuante • A representação

Tipo Ponto Flutuante

A representação interna de um PF se divide em parte fracionária e expoente (como na notação científica);

Caracterização: precisão (números de bits na parte fracionária) e faixa de valores representáveis (fração e expoente)

expoente fração
expoente
fração

bit de sinal

8 bits

23 bits

Padrão IEEE 754 - Precisão Simples

expoente fração 11 bits 52 bits bit de sinal
expoente
fração
11 bits
52 bits
bit de sinal

Padrão IEEE 754 - Precisão Dupla

Linguagens de Programação

12

8/11/2009

Tipo Decimal

• Armazena um número fixo de dígitos decimais

– COBOL possui

– Representação BCD (Binary coded decimal) 0000 0010 0010 0011 0011 0000 1000 0110 0111
– Representação BCD (Binary coded decimal)
0000 0010
0010 0011
0011 0000
1000 0110
0111 1001
1000 0011
4 bytes
sinal
7 casas inteiras
2 bytes
4 casas decimais

1 sinal

Não usa notação científica

Ocupa mais espaço de memória

Pra armazenar o número 18 em BCD, ocupa-se 8 bits. Em binário, somente 5.

Operações são realizadas por hw ou emuladas por sw

Faixas restritas de valores (não são usados expoentes)

Linguagens de Programação

13

Linguagens de Programação
Linguagens de Programação
15
15

Tipo Caractere

Tipo String

Valores correspondem a uma seqüência de caracteres

Não existe consenso sobre como devem ser tratadas

Tipo primitivo em Fortran 95.

Vetor de caracteres em C e C++

Operações em strings: concatenação, substring, padrões

Operação (nativas) de casamento de padrões

Fornecido por algumas linguagens como SNOBOL, PERL, JavaScript

Exemplo em SNOBOL4:

ALPHA = “ABCDEFGHIJKLMNOPQRSTUVWXUZ” READ INSTR = INPUT INSTR “C” | (LEN(6) BREAK(ALPHA) (“INTEGER” | “FUNCTION” | “SUBROUTINE”)) :S(READ)

Exemplo em Perl (expressões regulares):

$String =~ /\d+\,?d*|\,0\d+/

Linguagens de Programação

17

Tipo Caractere

Armazenados como códigos numéricos

Tabelas

ASCII (American Standard Code for Information Interchange): 8 bits

ISO 8859-1 (ADA 95): 8 bits. Extensão da ASCII. Caracteres acentuados e gregos

UNICODE (Java, JavaScript, C#): 16 bits. Caracteres da maioria das linguagens naturais, como do Japão, Sérvia, Tailândia, Rússia, etc.

PASCAL e MODULA 2 oferecem o tipo char

Em C, o tipo primitivo char é classificado como um tipo inteiro

char d; char *p, *q; d = 'a' + 3;

Linguagens de Programação

14

Tipo Caractere Linguagens de Programação
Tipo Caractere
Linguagens de Programação

16

Tipo String

Tamanho dos strings (da menor para a maior flexibilidade e do menor para o maior overhead de execução):

Fixo: strings de tamanho estático (Java -classe String)

Variável até um limite máximo: strings de tamanho dinâmico limitado (C, C++);

Variável sem limite máximo: strings de tamanho dinâmico (SNOBOL,JavaScript,Perl);

Em Ada 95: String -fixo; Bounded_String - variável com limite máximo; Unbounded_String (variável sem limite máximo)

Avaliação:

Não justifica LPs atuais não terem um TD primitivo para cadeias de caracteres (ou pelo menos através de uma biblioteca-padrão da LP);

O custo de se ter cadeias de caracteres sem limite de tamanho é alto; normalmente, estão disponíveis apenas em LPs interpretadas

Implementação:

Na maioria dos casos: via software;

Strings com tamanho variável sem limite máximo: lista encadeada (no heap) ou bloco contíguo de memória.

Linguagens de Programação

18

8/11/2009

Tipo Booleano

Tipo mais simples

Possui apenas dois valores

C não

dado booleano, mas

qualquer expressão numérica pode ser usada como

condicional

possui

o

tipo

de

Valores zero verdadeiro Valores = zero falso

Abordagem de C pode provocar erros

if (c += 1) x = 10;

• JAVA inclui o tipo de dado boolean

Linguagens de Programação

19

Tipo Enumerado

São TDs ordinais com todos os valores possíveis elencados como constantes nomeadas, na sua definição;

Exemplo em C++:

enum dias {Seg,Ter,Qua,Qui,Sex,Sab,Dom}; dias meuDiaPref = Dom, seuDiaPref= Seg;

As constantes nomeadas (enumeradas) são tipicamente associadas

(mas também podem ser

implicitamente aos inteiros 0, 1,

associadas a qualquer outro literal inteiro na definição);

Em LPs sem essa categoria de TD, os programadores podem simulá-los com valores inteiros. Em Fortran 77:

INTEGER VERMELHO, AZUL DATA VERMELHO, AZUL/0, 1/

Problema: nenhuma verificação de tipo específica é realizada (p.ex:

será possível somar duas cores!)

Linguagens de Programação

21

Tipo Enumerado

Em Ada:

Literais sobrecarregados (overloaded literals): constantes enumeradas que aparecem em mais de uma declaração de TD no mesmo ambiente de referenciamento;

O tipo do literal é determinado pelo contexto de sua utilização:

aCor= verde; (verde é considerado do tipo Cor) oSinal= verde; (verde é considerado do tipo Sinal)

Não tem coerção para o TD int

Em Java 5.0 (2004):

Todos os TDs enumeração são implicitamente subclasses da classe predefinida Enum.

Não tem coerção para qualquer outro TD;

Linguagens de Programação

23

Tipo Enumerado

São TDs ordinais com todos os valores possíveis elencados como constantes nomeadas, na sua definição;

Exemplo em C++:

enum dias {Seg, Ter,Qua,Qui,Sex,Sab, Dom}; dias meuDiaPref = Dom, seuDiaPref= Seg;

As constantes nomeadas (enumeradas) são tipicamente

associadas implicitamente aos inteiros 0, 1,

podem ser associadas a qualquer outro literal inteiro na

definição);

(mas também

Linguagens de Programação

20

Tipo Enumerado

C e Pascal foram as duas primeiras LPs mais populares a incluir um TD enumeração;

Em C++ (exemplo):

enum cores {vermelho, azul, verde, amarelo, preto}; cores minhaCor = azul; suaCor = vermelho;

Usa internamente os valores inteiros 0, 1,

constantes enumeradas (default);

para representar as

O

programador

enumerada;

pode

atribuir

outro

valor

inteiro

a

cada

constante

Tem coerção para o TD int (e portanto, as constantes enumeradas podem

ser utilizadas em qualquer expressão numérica):

minhaCor++ é válido! (se minhaCor tiver valor azul, após a execução desta instrução, passará a ter valor verde)

Não tem coerção de outro TD para um TD enumerado:

minhaCor= 4; não é válido

Uma constante enumerada só pode aparecer em uma única definição de

TD (no mesmo ambiente de referenciamento);

Linguagens de Programação

22

Tipo Enumerado

Em C#:

Como em C++, exceto que constantes ou variáveis de TD enumeração nunca sofrem coerção para o TD int;

Avaliação:

Os TDs enumeração trazem ganhos em legibilidade e confiabilidade;

Legibilidade: nomes × valores;

Confiabilidade: Ada, C# e Java 5.0 > C++ > C

Linguagens de Programação

24

8/11/2009

Tipos Subfaixas

• É uma subseqüência contígua de um TD ordinal;

• Introduzido pelo Pascal;

• Exemplo (Ada):

typeDias is(Seg, Ter,Qua,Qui,Sex,Sab, Dom); subtypeDiasSemanaisDias rangeSeg Sex;

subtypeIndexisIntegerrange1

100;

(uma das utilizações

mais comuns: índices de arrays)

Dia1: Dias; Dia2:DiasSemana; Dia2 := Dia1; (válido, a menos que o valor de Dia1 seja Sab ou Dom)

Linguagens de Programação

25

Tipos Subfaixas

Implementação dos TDs ordinais enumeração e subfaixa:

TDs enumeração são usualmente implementados como inteiros (sem restrições sobre o conjunto de valores e operações, não há ganho de confiabilidade);

TDs subfaixa são implementados exatamente como seus TDs-pai, exceto que a verificação de “valor dentro da faixa” deve ser implicitamente incluída pelo compilador em cada atribuição de uma variável ou expressão a uma variável subfaixa.

Isso é custoso (gasto de memória e tempo de execução), mas normalmente considera-se que compensa.

Linguagens de Programação

27

Produto Cartesiano

• Combinação de valores de tipos diferentes em tuplas (b,c) (b,d) (b,e) x= a b
• Combinação de valores de tipos diferentes em tuplas
(b,c)
(b,d)
(b,e)
x= a
b
c
d
e
(a,c)
(a,d)
(a,e)
S
T
S x T
29
Linguagens de Programação

Tipos Subfaixas

Avaliação:

Os TDs subfaixa trazem ganhos em legibilidade e confiabilidade;

Legibilidade: deixam claro que variáveis estão restritas a certas faixas de valores;

Confiabilidade: a atribuição de um valor fora da faixa é detectada como erro;

Linguagens de Programação

26

Tipos Compostos

Tipos compostos são aqueles que podem ser criados a partir de tipos mais simples

registros, vetores, listas, arquivos

Entendidos em termos dos conceitos

produto cartesiano, uniões, mapeamentos, conjuntos potência e tipos recursivos

Cardinalidade

número de valores distintos que fazem parte do tipo

Linguagens de Programação

28

Produto Cartesiano

São produtos cartesiano os registros de PASCAL, MODULA 2, ADA e COBOL e as estruturas de C

Registros são agregados possivelmente heterogêneos identificados por nome

struct nome { char primeiro [20]; char meio [10]; char sobrenome [20];

}

struct empregado { struct nome nfunc; float salario; } emp;

Linguagens de Programação

30

8/11/2009

Produto Cartesiano • Uso de seletores emp.nfunc.meio • Inicialização em C struct data { int
Produto Cartesiano
• Uso de seletores
emp.nfunc.meio
• Inicialização em C
struct data { int d, m, a; };
struct data d = { 7, 9, 1999 };
• Em LPs orientadas a objetos, produtos cartesianos são
definidos a partir do conceito de classe
– JAVA só tem class
• Cardinalidade
#(S1 x S2 x
x Sn) = #S1x #S2x
x #Sn
31
Linguagens de Programação

Uniões

Consiste na união de valores de tipos distintos para formar um novo tipo de dados

Podem ser livres ou disjuntas

Linguagens de Programação

33

Uniões Livres

Uniões

Pode haver interseção entre o conjunto de valores dos tipos que formam a união

Disponíveis no FORTRAN, C e C++ (union)

Há possibilidade de violação no sistema de tipos

union medida { int centimetros; float metros;

};

union medida medicao; float altura;

medicao.centimetros=180;

altura = medicao.metros; printf("\n altura : %f metros\n", f);

Linguagens de Programação

35

Produto Cartesiano

Implementação

Os campos dos registros são armazenados em posições adjacentes de memória;

O endereçamento dos campos é feito a partir do endereço de início de registro acrescido de um offset;

mostra

ao

A figura

lado

a

forma geral do

descritor

de

um

registro

em

tempo de

compilação;

Linguagens de Programação

a forma geral do descritor de um registro em tempo de compilação; Linguagens de Programação 3

32

Uniões Livres

Uniões

– Pode haver interseção entre o conjunto de valores dos tipos que formam a união
– Pode haver interseção entre o conjunto de valores dos
tipos que formam a união
a
b
c
b
c
d
a
b
c
d
S T
S + T
34
Linguagens de Programação

Uniões

Uniões Livres: implementação

Reserva de espaço de memória capaz de armazenar o maior espaço necessário

101010010110100 101010010110100

centímetros

Cardinalidade

metros

dependente

das

possíveis

interseções

existentes entre os conjuntos de valores dos componentes

Linguagens de Programação

36

8/11/2009

Uniões Disjuntas

Uniões

não há interseção entre o conjunto de valores dos tipos que formam a união

registros variantes de PASCAL, MODULA 2 e ADA e a union de ALGOL 68 , redefines do COBOL

TYPE Representacao = (decimal, fracionaria); Numero = RECORD CASE Tag: Representacao OF decimal: (val: REAL); fracionaria: (numerador, denominador: INTEGER); END;

Valores possíveis para Numero:

 

(

,

decimal(-0,33),

,

decimal(1.5),

)

 

U

(

,

fracionario(-1,3),

,

fracionario(4,6),

)

Linguagens de Programação

37

Uniões

Uniões • Exemplo em Pascal type forma = (circulo, triangulo, retangulo); cores = (vermelho, verde, azul);

Exemplo em Pascal

type forma = (circulo, triangulo, retangulo); cores = (vermelho, verde, azul); figura = record preenchido : Boolean; cor: cores; case aspecto : forma of

circulo: (diamentro : real); triangulo: (lado_esquerdo : integer; lado_direito : integer; angulo : real); retangulo: (lado1 : integer; lado2 : integer)

end; var minha_figura : figura;

case minha_figura.aspecto of circulo: writeln(‘É um círculo; seu diâmetro é: ‘, minha_figura.diametro); triangulo: writeln(‘É um triângulo; seus lados são: ‘, minha_figura.lado_esquerdo, minha_figura.lado_direito);

Obs: repare o uso conjunto de produto cartesiano e uniões no código Pascal

Linguagens de Programação

39

Mapeamentos

• Tipos de dados cujo conjunto de valores corresponde a todos os possíveis mapeamentos de
• Tipos de dados cujo conjunto de valores corresponde a todos
os possíveis mapeamentos de um tipo de dados S em outro T
a
a
u
u
b
b
v
v
c
c
S
S
T
T

Cardinalidade: #(S T) = (#T) #S

Linguagens de Programação

41

 

Uniões

 

Uniões Disjuntas

 

Cardinalidade #(S 1 + S 2 +

+ S n ) = #S 1 + #S 2

+ #S n

 
+ + + & & & + + + & & & a b c
+ +
+
&
&
&
+ +
+
&
&
&
a b
c
d
e
f
a b
c
d
e
f
S
T
S + T
 
 

Linguagens de Programação

 

38

 

Uniões

 

Avaliação

 

Uniões

são

construções

potencialmente

inseguras

em

 

muitas LPs

 
 

Elas constituem um dos motivos pelos quais Fortran, Pascal, C e C++ não são fortemente tipadas, pois não permitem a verificação de tipo na referência a uniões;

Proporcionam flexibilidade de programação

 

LPs como Java

e

C# não

tem

o

TD

união (reflexo da confiabilidade da

 

preocupação crescente

com

a

linguagem);

 
 

Linguagens de Programação

 

40

 

Mapeamentos Finitos

 

O conjunto domínio é finito

 

Vetores e matrizes

 

array S OF T;

 

(S T)

 

A: array [1

 

50]

of char;

A: ([1,50] char)

 
a z d r s … f h w o
a
z
d
r
s
f
h
w
o
 

1

2

3

4

5

47

48

49 50

O conjunto índice deve ser finito e discreto (inteiros)

 

Verificação de Índices em C (falta de confiabilidade) e JAVA (perda de eficiência)

int v[7]; V[13] = 198;

 
 

Linguagens de Programação

 

42

8/11/2009

Categorias de Vetores

Categoria Tamanho Tempo de Alocação Local de Exemplos de Vetor Definição Alocação Estáticos Fixo
Categoria
Tamanho
Tempo de
Alocação
Local de
Exemplos
de Vetor
Definição
Alocação
Estáticos
Fixo
Compilação
Estática
Base
FORTRAN 77
Semi-
Fixo
Compilação
Dinâmica
Pilha
PASCAL, C,
Estáticos
MODULA 2
Semi-
Fixo
Execução
Dinâmica
Pilha
ALGOL 68,
Dinâmicos
ADA, C
Dinâmicos
Variável
Execução
Dinâmica
Monte
APL, PERL
43
Linguagens de Programação
 

Categorias de Vetores

 

Semidinâmicos

 
 

Vantagem: aumenta a flexibilidade para o programador

 

void f (int n) { int x[n]; }

 

Dinâmicos (APL)

 
 

Vantagem: flexibilidade para o programador

 

Desvantagem: redução da eficiência e possível redução da confiabilidade

A (2 A (2

3

4)

3

4

15)

 

Linguagens de Programação

45

 

Vetores Semi-dinâmicos

 

Exemplo em C:

Exemplo em C++:

 

void f (int a) {

void f (int a) {

int *p; p = (int *) malloc (a * sizeof(int)); p[0] = 10; free(p)

int *p; p = new int[a]; p[0] = 10; delete[] p;

}

}

 

Exemplo em Java:

 
 

void f (int a) {

 

int p[]; p = new int[a]; p[0] = 10;

 

}

Linguagens de Programação

47

Categorias de Vetores

Estáticos (C)

Vantagem: eficiência, pois não requerem alocação e desalocação de memória.

Desvantagem: consomem mais memória do que o necessário, visto que vetores usados apenas em algumas regiões do programa têm de ficar alocados durante toda a execução.

void f () { static int x[10]; }

Semi-Estáticos (C)

Vantagem: Mais econômicos pois só alocam memória no bloco necessário do programa

Desvantagem: Redução da eficiência, pois é preciso alocar e desalocar memória.

void f () { int x[10];

}

Linguagens de Programação

44

Vetores Semi-dinâmicos

Podem ser implementados em C, C++ e JAVA através do monte

Necessário alocar nova memória e copiar conteúdo quando vetor aumenta de tamanho

É encargo do programador controlar alocação e cópia. Em C e C++, o programador deve controlar desalocação também. Isso torna a programação mais complexa e suscetível a erros

Linguagens de Programação

46

Vetores Multidimensionais • Elementos são acessados através da aplicação de fórmulas posição mat [i] [j]
Vetores Multidimensionais
• Elementos são acessados através da aplicação de
fórmulas
posição mat [i] [j] =
endereço de mat [0][0] + i × tamanho da linha + j × tamanho
do elemento =
endereço de mat
[0][0]
+
(i
×
número de colunas + j)
×
tamanho do elemento
48
Linguagens de Programação

8/11/2009

Vetores Multidimensionais

Na maioria das LPs, as matrizes são regulares

Mesmo número de colunas em todas as linhas

Em JAVA vetores multidimensionais são vetores unidimensionais cujos elementos são outros vetores

int [] [] a = new int [5] []; for (int i = 0; i < a.length; i++) { a [i] = new int [i + 1];

}

O mesmo efeito pode ser obtido em C com o uso de ponteiros para ponteiros

Linguagens de Programação

49

Vetores Multidimensionais

Operações

Uma operação de array é aquela que afeta o array como um todo;

Exemplos em Ada:

Atribuição (de um array a outro array);

Concatenação (de dois vetores; de um escalar com um vetor);

Comparação entre arrays;

São o “coração” da linguagem APL (a LP mais poderosa para processamento de matrizes). Por exemplo:

A + B (se A e B forem matrizes, calcula a sua soma);

ФV inverte os elementos de V;

ФM inverte as linhas de M;

M transpõe a matriz M (as linhas se tornam colunas e vice-versa);

Possui operadores especiais (formas funcionais). Por exemplo, o operador produto interno (.): A +.× B (soma do produto interno de A e B).

Linguagens de Programação

51

Mapeamentos Através de Funções

Uma função implementa um mapeamento ST através de um algoritmo

O conjunto S não necessita ser finito

O conjunto de valores do tipo mapeamento ST são todas as funções que mapeiam o conjunto S no conjunto T

Valores do mapeamento [int boolean] em JAVA

boolean positivo (int n) { return n > 0;

}

Outros valores do mapeamento: impar, par, primo

Linguagens de Programação

53

 

Vetores Multidimensionais

Cardinalidade

 

int mat [5][4];

Conjunto de valores

 

{0, …, 4} x {0, …, 3} int

 

(#int) # ({0, …, 4} x {0,

, 3}) =

(#int) (# {0, …, 4} x #{0,

, 3}) =

(#int) 5 x 4 = (#int) 20

 

Linguagens de Programação

50

 

Arrays associativos

Um array associativo é uma coleção desordenada de elementos de dados que são indexados por um número igual de valores denominados chaves;

Cada elemento de um array associativo é um par (chave, valor).

Exemplo em Perl:

 

%salarios = (“Pedro” => 7500, “Jose” => 2500, “Maria” => 3400);

São denominados também de hashes porque na implementação seus elementos são armazenados e recuperados com funções hash;

 

Linguagens de Programação

52

 

Mapeamentos Através de Funções

C utiliza o conceito de ponteiros para manipular endereços de funções como valores

int impar (int n){ return n%2; } int negativo (int n) { return n < 0; } int multiplo7 (int n) { return !(n%7); } int conta (int x[], int n, int (*p) (int) ) { int j, s = 0; for (j = 0; j < n; j++) if ( (*p) (x[j]) ) s++; return s;

}

main() { int vet [10]; printf ("%d\n", conta (vet, 10, impar)); printf ("%d\n", conta (vet, 10, negativo)); printf ("%d\n", conta (vet, 10, multiplo7));

}

 

Linguagens de Programação

54

8/11/2009

 

Conjuntos Potência

 

Tipos

de

dados

cujo

conjunto

de valores

corresponde a todos os possíveis subconjuntos que

podem ser definidos a partir de um tipo base S

ϕS = {s | s S}

 
{} {a} {b} {c} {a, b} a b c {a, c} {b, c} {a, b,
{}
{a}
{b} {c}
{a, b}
a b c
{a, c}
{b, c}
{a, b, c}
S
ϕS
 

Linguagens de Programação

 

55

 

Conjuntos Potência

 

Poucas LPs oferecem. Muitas vezes de forma restrita

PASCAL:

TYPE Carros = (corsa, palio, gol); ConjuntoCarros = SET OF Carros; VAR Carro: Carros; CarrosPequenos: ConjuntoCarros; BEGIN Carro:= corsa; CarrosPequenos := [palio, gol];

/*atribuicao*/

CarrosPequenos:= CarrosPequenos + [corsa]; /*uniao*/

 

CarrosPequenos:= CarrosPequenos * [gol];

/*intersecao*/

if Carro in CarrosPequenos

THEN

 

/*pertinencia*/

if CarrosPequenos >= [gol, corsa] THEN

/*contem*/

 

Linguagens de Programação

 

57

Conjuntos Potência • LPs que não possuem tipos conjunto necessitam criar abstrações de dados para
Conjuntos Potência
• LPs que não possuem tipos conjunto necessitam criar
abstrações de dados para os implementar.
• Programação mais trabalhosa e menos eficiente
• C: não possui tipos conjuntos, mas fornece operações bit a bit
que facilitam a implementação através de vetores
• Em LPs orientadas a objetos, é comum a existência de uma
classe Set
• Java e Smalltalk
• Contudo,
nem
todas
as
operações
de
conjuntos
costumam
ser
disponibilizadas
59
Linguagens de Programação
Conjuntos Potência • Cardinalidade #ϕS = 2 #S • Operações básicas Pertinência Contém Está contido
Conjuntos Potência
• Cardinalidade
#ϕS = 2 #S
• Operações básicas
Pertinência
Contém
Está contido
União
Diferença
Diferença simétrica
Interseção
56
Linguagens de Programação
Conjuntos Potência • Em Pascal só é permitido construir conjuntos de tipos discretos primitivos pequenos
Conjuntos Potência
• Em
Pascal
é
permitido
construir
conjuntos
de
tipos
discretos primitivos pequenos
• Conjuntos são implementados como cadeias de bits
• Restrições de PASCAL visam permitir implementação eficiente
VAR S: SET OF [ 'a
'h' ];
BEGIN
S := ['a', 'c', 'h'] + ['d'];
END;
['a', 'c','d',
'h' ]
['a', 'c',
'h' ]
[
'd'
]
=
S
1 0 1 1 0 0 0 1
1 0 1 0 0 0 0 1
OR
0 0 0 1 0 0 0 0
58
Linguagens de Programação

Tipos Recursivos

Tipos recursivos são tipos de dados cujos valores são compostos por valores do mesmo tipo

R ::= < parte inicial > R < parte final >

Tipo Lista ::= Tipo Lista Vazia | (Tipo Elemento x Tipo Lista)

A cardinalidade de um tipo recursivo é infinita

Isto é verdade mesmo quando o tipo do elemento da lista é finito

O conjunto de valores do tipo listas é infinitamente grande (não podendo ser enumerado) embora toda lista individual seja finita

Linguagens de Programação

60

8/11/2009

Tipos Recursivos • Tipos recursivos podem ser definidos a partir de ponteiros ou diretamente Em
Tipos Recursivos
Tipos recursivos podem ser definidos a partir de
ponteiros ou diretamente
Em C
struct no {
int elem;
struct no* prox;
Em C++
class no {
int elem;
no* prox;
Em JAVA
class no {
int elem;
no prox;
};
};
};
61
Linguagens de Programação

Tipos Ponteiros

#define nil 0 typedef struct no* listaint; struct no { int cabeca; listaint cauda;

}; listaint anexa (int cb, listaint cd) { listaint l; l = (listaint) malloc (sizeof (struct no)); l->cabeca = cb; l->cauda = cd; return l;

}

void imprime (listaint l) { printf("\nlista: "); while (l) { printf("%d ",l->cabeca); l = l->cauda;

}

} Linguagens de Programação

63

Tipos Ponteiros

Derreferenciamento implícito (Fortran 90, ALGOL68)

INTEGER, POINTER :: PTR PTR = 10 PTR = PTR + 10

Derreferenciamento explícito (C++, C, PASCAL)

int *p; *p = 10; *p = *p + 10;

Exemplo de desreferenciamento explícito (em C++, utilizando o operador *): sendo ptr uma variável ponteiro,

j = *ptr (pela figura ao lado, podemos concluir que este comando fará com que j receba o valor 206).

Linguagens de Programação

figura ao lado, podemos concluir que este comando fará com que j receba o valor 206).

65

 

Tipos Ponteiros

Não se restringe a implementação de tipos recursivos embora seja seu uso principal

Ponteiro é um conceito de baixo nível relacionado com a arquitetura dos computadores

O conjunto de valores de um tipo ponteiro são os endereços de memória e o valor nil

Proporcionam flexibilidade ao programador

PL/I: Primeira LP de alto nível a incluir variáveis ponteiro

 

Linguagens de Programação

62

 

Tipos Ponteiros: Operações

Atribuição

 

int *p, *q, r; // dois ponteiros para int e um int

 

q

= &r;

// atribui endereco de r a q

p

= q;

// atribui endereco armazenado em q a p

Alocação

int* p = (int*) malloc (sizeof(int));

 

Desalocação

 

free(p);

Linguagens de Programação

64

Tipos Ponteiros • Aritmética (C) – Se p aponta para uma área de memória de
Tipos Ponteiros
• Aritmética (C)
– Se p aponta para uma área de memória de 2 bits, então p++ desloca 2
bits adiante na memória
p++;
++p;
p = p + 1;
p--;
--p;
p = p - 3;
• Indexação (C)
Atalho para sintático para a combinação da operação de adição em
ponteiro com a operação de derreferenciamento
x
= p[3]; equivale a *(p + 3)
66
Linguagens de Programação

8/11/2009

Ponteiros Genéricos

Podem apontar para qualquer tipo

int f, g; void* p;

f

= 10;

p

= &f;

g

= *p;

// erro: ilegal derreferenciar ponteiro p/ void

Servem para criação de funções genéricas para gerenciar memória

Servem para criação de estruturas de dados heterogêneas (aquelas cujos elementos são de tipos distintos)

Linguagens de Programação

67

Problemas Com Ponteiros

 

Objetos Pendentes

int* p = (int*) malloc (10*sizeof(int)); int* q = (int*) malloc (5*sizeof(int));

p = q;

// área apontada por p torna-se inacessível

Provoca vazamento de memória

 

Referências Pendentes

int* p = (int*) malloc(10*sizeof(int)); int* q = p;

free(p);

// q aponta agora para área de memória desalocada

int* p; *p = 0; p não foi alocado, então aponta para uma área desconhecida

 

Linguagens de Programação

69

 

Ponteiros - ADA

Aliviou o problema de ponteiros pendurados:

 

A variável apontada é implicitamente desalocada na saída do escopo do seu ponteiro;

Com isso os programadores são induzidos a não fazer desalocação explícita;

Não resolve completamente, pois os programadores ainda podem fazer desalocação explicita utilizando Unchecked_Deallocation;

Não resolve o problema de variáveis perdidas;

 
 

Linguagens de Programação

71

 

Problemas Com Ponteiros

 

O TD Ponteiro tende a reduzir a confiabilidade das LPs que o incluem

Baixa Legibilidade

 

p->cauda = q;

Inspeção

simples

não

permite

determinar

qual

estrutura

está

sendo

atualizada e qual o efeito

 

Possibilitam violar o sistema de tipos

 

int

i, j = 10;

 

int* p = &j;

// p aponta para a variável inteira j // p pode não apontar mais para um inteiro // valor imprevisível atribuído a i

 

p++; i = *p + 5;

 

Linguagens de Programação

 

68

 

Problemas Com Ponteiros

 

Referências Pendentes

 
 

main() { int *p, x;

 
 

x

= 10;

if

(x) { int i; p = &i;

}

// p continua apontando para i, que não existe mais

 
 

}

 

Linguagens de Programação

 

70

 

Ponteiros – C e C++

 

Manipulação de ponteiros muito flexível (p. ex:

aritmética de ponteiros) – e perigosa!

 

Um ponteiro em C e C++ pode apontar para qualquer posição de memória, e não apenas para variáveis do heap (como é o caso de Ada);

Ponteiros podem apontar para funções, o que é utilizado para passar funções como parâmetros para outras funções;

Não oferece qualquer solução para os problemas de ponteiros e objetos pendentes;

 

Linguagens de Programação

 

72

8/11/2009

Ponteiros – Avaliação

O efeito do uso livre de ponteiros nas LPs já foi comparado ao uso de goto’s:

O goto aumenta o conjunto das instruções que podem ser executadas após ele;

O ponteiro aumenta o conjunto de células de memória que podem ser referenciadas por uma variável;

Hoare (1973), sobre ponteiros: “Sua introdução em LPs de alto-nível tem sido um passo para trás, do qual talvez jamais possamos nos recuperar”;

Linguagens de Programação

73

Tipo Referência em Java

Estende o conceito de variável-referência do C++, possibilitando assim a substituição completa de ponteiros;

Objetivo: aumentar a confiabilidade da linguagem;

Diferença fundamental: enquanto que C++ referencia endereços de memória, Java referencia instâncias de classes (objetos);

Características:

Não faz sentido a aritmética de variáveis-referência;

É possível atribuir um novo valor (endereço de uma nova instância da classe) a uma variável-referência;

Todas as instâncias de classes em Java são referenciadas através de variáveis-referência (aliás, isso é a única forma de uso desse tipo de variável);

Linguagens de Programação

75

Tipo Referência em Java e C#

Java resolveu o problema de referências denpentes, já que toda desalocação é implícita;

O problema de variáveis perdidas (lixo) é resolvido, em parte, pelo coletor de lixo;

Em C#:

Inclui ambas as formas de variáveis-referência: de C++ e de Java;

Desencoraja vigorosamente o uso de variáveis-referência a la C++ (todo método que as utiliza deve ser declarado com o modificador unsafe);

Essas variáveis-referência foram incluídas em C# para permitir que programas feitos na linguagem possam interoperar com código C e C++;

Linguagens de Programação

77

Tipo Referência em C++

É

ponteiro

derreferenciado

um

constante,

sempre

implicitamente

É inicializado com o endereço de alguma variável na sua declaração

O derreferenciamento implícito impede a atribuição ao endereço da variável referência;

int res = 0;

int& ref = res;

// ref passa a referenciar res

ref = 100;

// res passa a valer 100

Linguagens de Programação

74

passa a valer 100 Linguagens de Programação 7 4 Tipo Referência em Java • Exemplo: String

Tipo Referência em Java

Exemplo:

String str1; (str1 é uma variável-referência, já que String é uma classe Java; é inicializada com null)

str1 = “Este é um string Java”; (str1 aponta p/ o

objeto da classe String)

Todas as variáveis de tipos não primitivos em Java são variáveis-referência.

Linguagens de Programação

76

variáveis-referência. Linguagens de Programação 7 6 Hierarquia de Tipos Tipos Primitivos Compostos Inteiros

Hierarquia de Tipos

Tipos
Tipos
Linguagens de Programação 7 6 Hierarquia de Tipos Tipos Primitivos Compostos Inteiros Enumerados Recursivos
Primitivos Compostos Inteiros Enumerados Recursivos Strings Caracteres Ponto Flutuantes Uniões Conjuntos
Primitivos
Compostos
Inteiros
Enumerados
Recursivos
Strings
Caracteres
Ponto Flutuantes
Uniões
Conjuntos Potência
Booleanos
Decimais
Mapeamentos
Produtos Cartesianos
Intervalos
Ponteiros
Finitos
Funções
Livres
Disjuntas

Linguagens de Programação

78