Paradigmas de Programação Tipos de Dados Aula 5 Prof.: Edilberto M. Silva http://www.edilms.eti.br Prof. Edilberto Silva / edilms.eti.br
Tipos de Dados Sistema de tipos Tipos de Dados e Domínios Métodos de construção de domínios Tipos primitivos Tipos estruturados Entrada Processamento Saída
Processamento de Dados Processar dados consiste basicamente em: determinar quais são os possíveis dados ( ou entradas); descrever quais são os possíveis resultados ( ou saídas); determinar quais são as transformações ( ou operações) que devem ser efetuadas para que um particular resultado seja uma saída para uma certa entrada. Programa: seqüência de transformações sobre dados
Tipos de dados em LP: para que servem? Um tipo de dados determina a classe de valores que podem ser: armazenados em uma variável passados como parâmetro resultantes de uma expressão; A informação de tipo em uma linguagem de programação é usada para: prevenir ou detectar construções incorretas em um programa determinar os métodos de representação e manipulação de dados no computador.
Tipos de dados em LP: vantagens O conhecimento dos possíveis valores de uma variável é essencial para o entendimento de um algoritmo Saber quais são as operações permitidas possibilita a detecção de vários erros O tradutor, de posse destas informações, pode: determinar o espaço necessário para as variáveis e, como proceder para a implementação das operações e tratamento de exceções
Um pouco de história... FORTRAN conceitos de tipos de dados simples (inteiros, reais) e estruturados (arrays) COBOL dados estruturados como registros LISP dados estruturados como listas ALGOL68 tipos definidos pelo usuário Atualmente: Tipos Abstratos de Dados e Classes
Linguagens de Programação: hierarquia de componentes Tipos de Dados representação e operações Expressões obtenção de valores Comandos controle de fluxo ambientes: abstrações de valores e comandos Unidades unidade de execução Programas
Sistema de Tipos Um sistema de tipos consiste basicamente de: um mecanismo para definição de tipos de dados através de construções da linguagem de programação, tais como constantes, variáveis, parâmetros. um conjunto de regras para determinar a equivalência de tipos, a compatibilidade de tipos e a inferência de tipos, para fins de verificação da validade do uso de tipos em expressões, atribuições e parâmetros. Existem linguagens de programação que não usam um sistema de tipos, sendo conhecidas como linguagens não-tipadas. Exemplo: LISP e Perl
Domínios de valores Domínios são usados para indicar conjuntos de valores Domínio dos inteiros Domínio dos naturais Domínio dos complexos Problemas de representação em computadores: impossibilidade de representar objetos infinitos computadores usam diferentes formas de representação interna Soluções: padronização da representação e descritores de dados (metadados)
Tipos de Dados e Domínios Um domínio representa um conjunto (infinito) de valores Um tipo de dados em LP possui uma representação finita, dependendo da declaração do tipo: int, shortint, longint da implementação da LP: tipo char, representação ASCII, UNICODE é associado a um conjunto de operações para manipular seus valores domínio Tipo de dado: representação e operações
Domínios simples: base para representação de tipos primitivos Domínios simples primitivos: não necessitam de definição explícita Exemplo: domínio dos números reais definidos: seus componentes (ordinais) devem ser especificados por: enumeração: cria novo domínio domínio estação = ( primavera, verão, outono, inverno) restrição: especifica um subdomínio domínio mandato = 2000..2005 domínio simples tipos primitivos e operações
Tipos primitivos em LP São tipos atômicos, indivisíveis, não definidos com base em outros tipos de dados Geralmente refletem a estrutura de hardware, podendo ser mapeados diretamente Associados a um nome, a um conjunto finito de valores e a um conjunto pré-definido de operações Elementos de primeira ordem na maioria das LP: usados como resultado de operações, em e/s, em atribuição, como parâmetros, como valor de retorno
Descrição de tipos em LP Nome: designação do tipo Exemplo: Boolean Valores : domínio de valores Exemplo: lógicos Operações: repertório de operações permitidas Exemplo: negação, conjunção, disjunção. Testes : relações de igualdade, ordem e outros predicados Exemplo: relação de igualdade Constantes: forma de representação Exemplo: True, False
Exemplo em java: tipos primitivos Tipos disponíveis representação do valor boolean (1 bit) variável primitiva char (16 bits) byte(8 bits) short(16 bits), int(32 bits), long(64 bits) float(32 bits), double(64 bits) void Variáveis colocadas diretamente na pilha sem apontador para representação tamanho uniforme em todas as plataformas
Tipos definidos pelo usuário Objetivo principal: legibilidade Mnemônicos associados a tipos existentes Sinonímia: não criam novos tipos de dados; apenas usam identificadores simbólicos. Composição: podem ser combinados com outros tipos de dados. Permitem restrições / enumerações
Tipos definidos pelo usuário: ordinais Definidos por associação ao um domínio de inteiros positivos Restrição: sub-seqüência de um tipo Exemplo de restrição em Pascal: maiusculas= A.. Z ; dias= 1..31; Enumeração: descrição dos elementos Exemplo de enumeração em Pascal type TS = ( verde, vermelho, azul); VetorCor = array [TS] of boolean;
Enumeração: implementação Associação de constantes a valores inteiros Associação implícita Ex. C/C++: enum Cores {vermelho, verde, azul} Associação explícita Ex. C/C++: enum 0 1 2 Romanos {I=1,V=5,X=10,L=50,C=100,D=500,M=1000} Cartas{dois=2,tres,quatro,cinco,seis,sete,oito,nove,dez, valete,dama,reis,as}
Enumeração: simulação em Java Uma interface pode ser usada para implementar constantes, simulando os tipos enumerados existentes em Pascal e C++. public interface Cores{ public final int verde = 0; public final int azul = 1; public final int vermelho = 2; } public class MCores implements Cores{ /* define vetorcor, com os elementos vetorcor[verde], vetorcor[azul] e vetorcor[vermelho]*/ public static boolean[] vetorcor = {false, false, false};..}
Tipos x instâncias Variável: instância concreta de um tipo Tipo: descritor Exemplo em Pascal: definição declaração type Vetor= array [1..5] of boolean; { instanciação } var v1, v2: Vetor; v1 instanciação v2
Tipos definidos por restrição Os tipos definidos por restrição são: considerados subtipos de um tipo base T úteis para aumentar a legibilidade e podem contribuir para a confiabilidade ou eficiência de programas. Exemplo em Pascal type natural = 0.. maxint; var i : integer; s : shortint; n : natural;... n := i ;
Domínios compostos Os domínios compostos resultam de aplicação de métodos para construir novos domínios com base em domínios já existentes domínio simples método domínio composto Estes domínios compostos constituirão os tipos de dados estruturados disponíveis nas linguagens de programação: homogêneos e heterogêneos
Construção de novos domínios Produto cartesiano: faz o produto de T domínios e fornece tuplas ordenadas. Mapeamento finito: aplica uma função no domínio A, para obter um valor de um domínio B. Seqüência : permite construir as seqüências finitas <a1,a2,..an>, formadas por objetos do domínio A. União : faz uma união de domínios A e B, criando alternativas. Conjunto potência: permite a geração de subconjuntos de valores, a partir de um conjunto que é definido como o domínio do tipo.
Tipos estruturados São tipos compostos a partir de outros tipos de dados homogêneos: todos os componentes pertencem ao mesmo tipo: Ex: array heterogêneos: os componentes podem ser de tipos de dados diferentes. Ex. struct, union Operações sobre elementos Operações mais restritas sobre o conjunto domínio composto tipos estruturados e operações
Método de construção X tipos estruturados Produto cartesiano: heterogêneo record/ struct/ class Mapeamento finito: homogêneo array/ map/ vector Seqüência string, arquivo União discriminada: heterogêneo variant record/ union Conjunto potência set
Produto cartesiano O produto cartesiano de n domínios A1, A2,, An, denotado por A1 x A2 x. x An, fornece conjuntos de tuplas ordenadas (a1, a2,, an), onde cada ak, pertence a Ak Exemplo: Sendo A: inteiro e B: real o produto cartesiano AxB fornece uma dupla (a, b) sendo que a pertence ao domínio A e b pertence ao domínio B representável pela dupla (inteiro, real) inteiro X real
Produto cartesiano: registro Exemplo de associação de nomes de campos a uma dupla (inteiro, real): pessoa ( idade : inteiro, peso : real ) nota_fiscal ( quant : inteiro, valor : real) referência: pessoa.idade, pessoa.peso idade pessoa Uma estrutura de registro pode ser representada em uma estrutura hierárquica nome do tipo estruturado corresponde à raiz de uma árvore cada uma das folhas deve ser um tipo primitivo peso
Produto cartesiano: exemplos { Pascal} Racional: record numerador, denominador: integer; end; //C++/Java class Racional { int numerador, denominador; } //C/C++/C# struct Racional { int numerador, denominador; }
Mapeamento finito Seja m uma função de mapeamento e sejam A e B domínios Aplicando a função m em um elemento a do domínio A obtém-se o valor b do contra-domínio B correspondente, representado por b = m(a). A B = { m x ε A m(x) ε B} Exemplo: A= {1,2,3, 4, 5} e B={10, 20, 30} A b = m(a) B 10 20 10 20 30
Mapeamento finito: array Um array representa um tipo de dado correspondente ao modelo de construção: S T = { m x ε S m(x) ε T} sendo S = { verde, vermelho, azul}, T = {true, false} type TS = ( verde, vermelho, azul); VetorCor = array [TS] of boolean; var { instanciação } Cor : VetorCor; begin { referência } {... } Cor [verde] := true; {... } end. true/false true/false true/false
Mapeamento finito em Java Arrays são objetos criados na memória dinâmica (heap) - referências Declaração de arrays int numero[ ]; int[ ] v1,v2; char mc[ ][ ]; Instanciação do array, usando o operador new: numero = new int[5]; str = new String[3]; Declaração, instanciação e inicialização int ncinco[ ] = { 10, 20,10, 20,30 }; ncinco 10 20 10 20 30
Java: arrays com vários subscritos Um array bidimensional é um array de arrays: cada elemento aponta para um array os arrays que formam a segunda dimensão podem ter tamanhos diferentes Exemplos: int b[ ] [ ]; b = new int [2] [ ]; // instanciação de linhas b[0] = new int [5]; // colunas da linha 0 b[1] = new int [3]; // colunas da linha 1
C/C++: implementação O nome do array significa: o nome de uma instância o endereço de memória Exemplo: int a[]={10,20}; cout << a << << \t << *a << \t << a[0] << endl; 0x0064fdbc 10 10 cout << a+1 << \t << *(a+1) << \t << a[1] << endl; 0x0064fdc0 20 20
União (discriminada) Constrói novos domínios a partir da união de outros domínios, fornecendo alternativas Este modelo de construção corresponde ao tipo union em C/C++ e variant record em Pascal Exemplo em C/C++ union Valor { char*s; int i; } Valor s i
União: considerações Todos os membros são alocados a partir do mesmo endereço O acesso ao campo desejado geralmente é feito através de um seletor O tamanho do tipo corresponde ao tamanho do maior membro É um tipo frágil: a linguagem não faz restrição de acesso o programador é responsável pelo valor armazenado
Conjunto potência Sendo S um domínio, o conjunto de todos os subconjuntos dos valores de S é denominado de conjunto potência de S Exemplo: Sendo S = {chá, café}, o conjunto de todos os subconjuntos de S seria: { } {chá} {café} {chá, café} A ordem dos elementos não define novos subconjuntos: o subconjunto {chá, café} equivale a {café, chá}
Seqüência A seqüência define um domínio cujos objetos são seqüências de tamanho indeterminado Uma seqüência consiste de ocorrências de elementos em ordem arbitrária, permitindo repetições. Exemplo : Verbo = seq < 's', 'e', 'r', 'i', 'a' > Seletor de objeto : primeiro(verbo), ultimo(verbo),... Aplicações: strings, arquivos
Strings em Java Strings são objetos da classe String String cor; // associa Tipo x Podem ser atribuídos na declaração String cor = "azul"; cor é a referência a um String "azul" é um objeto do tipo String anônimo Podem ser criados pelo operador new() cor = new String() cor = new String( azul ) cor azul
Strings e arrays de caracteres Arrays de caracteres permitem o mapeamento (indexação) Strings devem oferecer operações para acessar caracteres: charat(...) Conversões podem ser feitas: s3 = new String(charArray) s3 contém todos os caracteres do array chararray a z u l azul