O documento discute diferentes tipos de dados, incluindo primitivos como inteiros e caracteres, e tipos definidos pelo usuário como matrizes e registros. Ele explica como cada tipo é representado e operado em linguagens de programação, além de questões de projeto relacionadas a cada tipo.
2. 0. Tópicos
Introdução
Tipos de Dados Primitivos
◦ Inteiro
◦ Ponto‐flutuante
◦ Decimal
◦ Booleano
◦ Caractere
◦ Tipos Cadeia de Caracteres
Tipos Definidos pelo Usuário
◦ Tipos Matriz
◦ Matrizes Associativas
◦ Tipos Registro
◦ Tipos União
◦ Tipos Ponteiro
3. 1. Introdução
Um tipo de dado define uma coleção de dados
e um conjunto de operações pré‐definidas
sobre esses dados
Um descritor é um conjunto de atributos de
uma variável
Um objeto representa uma instância de um tipo
de dado abstrato definido pelo usuário
Uma questão fundamental de projeto:
◦ Quais operações são fornecidas para variáveis do tipo
e como elas são especificadas?
4. 2. Tipos de Dados Primitivos
Tipos de dados não‐definidos em termos de
outros tipos são chamados tipos de dados
primitivos
Praticamente todas as linguagens de
programação oferecem um conjunto de tipos
de dados primitivos
Alguns tipos de dados primitivos são reflexos do
hardware
◦ Por exemplo: os inteiros
Outros exigem um pequeno suporte de
software para sua implementação
5. 2.1. Tipo Inteiro
Quase sempre um reflexo do hardware
◦ Assim, seu mapeamento é trivial
Muitos computadores suportam
diferentes tamanhos para inteiros
Em Java, diferentes tamanhos para
inteiros
◦ byte, short, int, long
7. 2.3. Decimal
Para aplicações comerciais (moeda)
◦ Essencial para COBOL
◦ C# oferece um tipo de dado decimal
Armazena um número fixo de dígitos decimais
Vantagem
◦ Precisão
Desvantagens
◦ Faixa de valores restrita
◦ Desperdício de memória
8. 2.4. Booleano
Mais simples de todos
Faixa de valores
◦ Dois elementos, um para “true” e um para
“false”
Pode ser implementado como bits, mas
geralmente são como bytes
◦ Vantagem: legibilidade
9. 2.5. Caractere
Armazenados como codificações
numéricas
O código mais usado: ASCII
Uma alternativa, codificação de 16‐bit:
Unicode
◦ Inclui caracteres da maioria das linguagens
naturais
◦ Usado em Java
◦ C# e JavaScript também suportam Unicode
10. 2.6. Cadeia de Caracteres
Valores consistem em seqüências de
caracteres
Questões de projeto:
◦ É um tipo primitivo ou apenas um tipo
especial de vetores de caracteres?
◦ As cadeias devem ter tamanho estático ou
dinâmico?
11. 2.6. Cadeia de Caracteres
Operações típicas:
◦ Atribuição e cópia
◦ Comparação (=, >, etc.)
◦ Concatenação
◦ Referências a subcadeias
◦ Pattern matching
12. 2.6. Cadeia de Caracteres
C e C++
◦ Não primitivo
◦ Usam vetores char e uma biblioteca de funções que
oferecem operações (string.h)
SNOBOL4 (uma linguagem de manipulação de
cadeias)
◦ Primitivo
◦ Muitas operações, incluindo pattern matching
elaborados
Java
◦ Primitivo através da classe String
13. 2.6. Cadeia de Caracteres
Opções de Tamanho da Cadeia
◦ Estático
COBOL, FORTRAN 90, Pascal, Ada e Java classe
String
◦ Tamanho dinâmico limitado: C e C++
Um caractere especial é usado para indicar o final
da cadeia,em vez de manter seu tamanho
◦ Dinâmico (sem máximo): SNOBOL4, Perl,
JavaScript
◦ Ada suporta todas as opções acima
14. 2.6. Cadeia de Caracteres
Avaliação
◦ São importantes para a capacidade de escrita
de uma linguagem
◦ Como um tipo primitivo com tamanho
estático, não é caro
Por que não usá‐las?
◦ Tamanho dinâmico é mais flexível
Mas o custo compensa?
15. 2.6. Cadeia de Caracteres
Implementação
◦ Tamanho estático
descritor em tempo de compilação
◦ Tamanho dinâmico limitado
Podem exigir um descritor em tempo de execução
para armazenar tanto o tamanho máximo como o
tamanho atual (mas não em C e C++)
◦ Tamanho dinâmico
Exigem um descritor em tempo de execução
Exigem um gerenciamento de armazenagem mais
complexo
Alocação e desalocação
16. 3. Tipos definidos pelo usuário
Um tipo ordinário é aquele cuja faixa de
valores possíveis pode ser associada ao
conjunto dos números inteiros positivos
◦ Tipos Enumeração
◦ Tipos Subfaixa
Exemplos de tipos ordinários em Java
◦ integer
◦ char
◦ boolean
17. 3.1. Tipos Enumeração
Todos os valores possíveis, os quais se
tornam constantes simbólicas, são
enumerados na definição
Exemplo C#
◦ enum dias {seg, ter, qua, qui, sex, sab, dom};
18. 3.1. Tipos Enumeração
Questões de projeto
◦ Deve‐se permitir que um literal constante
apareça em mais de uma definição de tipo e,
se assim for, como o tipo de uma ocorrência
desse literal é verificado no programa?
◦ É possível fazer coerção de valores de
enumeração para inteiros?
19. 3.1. Tipos Enumeração
Avaliação
◦ Vantagens em termos de legibilidade
Não é necessário codificar uma cor como um
número
◦ Vantagens em termos de confiabilidade
Operações (não permite adicionar cores)
Nenhum variável de enumeração será assinalada
para valores fora de sua faixa
20. 3.2. Tipos Subfaixa
É uma subsequência de um ordinal
◦ Exemplo: 12..18 é uma subfaixa dos inteiros
Projeto em Ada
type Days is (mon, tue, wed, thu, fri, sat, sun);
subtype Weekdays is Days range mon..fri;
subtype Index is Integer range 1..100;
Day1: Days;
Day2: Weekday;
Day2 := Day1;
21. 3.2. Tipos Subfaixa
Avaliação
◦ Legibilidade
Informam ao leitor que as variáveis podem
armazenar apenas uma faixa de valores
◦ Confiabilidade
A atribuição de um valor a uma variável fora de sua
faixa pode ser detectado pelo compilador como
sendo um erro
22. 3.3. Tipos Matriz
Uma matriz é um agregado homogêneo
de dados cujo elemento individual é
identificado por sua posição no agregado
em relação ao primeiro.
23. 3.3. Tipos Matriz
Quais tipos são legais para os subscritos?
As expressões de subscrito nas referências a
elementos são verificados quanto à faixa?
Quando as faixas de subscrito são vinculadas?
Quando a alocação da matriz se desenvolve?
Quantos subscritos são permitidos?
Matrizes podem ser inicializadas quando têm
seu armazenamento alocado?
Quais tipos de fatiamento são permitidos, se for
o caso?
24. 3.3. Tipos Matriz
Índices (ou subscritos) fazem
mapeamento para elementos
◦ array_name(index_value_list) → element
Sintaxe do Índice
◦ FORTRAN, PL/I e Ada usam parênteses
Ada usa parênteses para mostrar uma uniformidade
entre matrizes e chamadas de funções, pois ambos
são mapeamentos
◦ Outras linguagens usam colchetes
25. 3.3. Tipos Matriz
Tipos dos Índices
◦ FORTRAN, C: apenas inteiros
◦ Pascal: qualquer tipo ordinário
inteiro, Boolean, Char, enumeração
◦ Ada: inteiro ou enumeração (incluindo
Boolean e Char)
◦ Java: apenas inteiros
◦ C, C++, Perl e Fortran não especificam faixa
para checagem
◦ Java, ML e C# especificam a checagem da
faixa
26. 3.3. Tipos Matriz
Vinculações de Subscritos e Categorias de
Matrizes
◦ Matriz Estática
As faixas de subscrito estão estaticamente
vinculadas e a alocação de armazenamento é
estática (feita antes da execução)
Vantagem: eficiência
◦ Matriz Fixa Dinâmica na Pilha
Faixas de subscrito são estaticamente vinculadas,
mas a alocação é feita no momento da declaração
durante a execução
Vantagem: eficiência de espaço
27. 3.3. Tipos Matriz
Vinculações de Subscritos e Categorias de
Matrizes
◦ Matriz Dinâmica na Pilha
Faixas de subscritos estão dinamicamente
vinculadas e a alocação de armazenamento é
dinâmica (feita durante a execução)
Vantagem: flexibilidade (o tamanho de uma matriz
não precisa ser conhecido antes da sua utilização)
◦ Matriz Dinâmica no Monte
A vinculação das faixas dos índices e a alocação são
dinâmicas e podem mudar várias vezes
Vantagem: flexibilidade (matrizes podem crescer ou
encolher durante a execução do programa)
28. 3.3. Tipos Matriz
Vinculações de Subscritos e Categorias de
Matrizes
◦ Matrizes C e C++ que incluem static são
estáticas
◦ Matrizes C e C++ sem static são fixas
dinâmicas na pilha
◦ Matrizes Ada podem ser dinâmicas na pilha
◦ C e C++ também oferecem matrizes dinâmicas
(malloc e free)
◦ Perl e JavaScript suportam matrizes dinâmicas
29. 3.3. Tipos Matriz
Inicialização de Matrizes
◦ Algumas linguagens permitem a inicialização
no momento em que o armazenamento é
alocado
Exemplos: C, C++, Java e C#
int list [] = {4, 5, 7, 83}
Cadeias de caracteres em C e C++
char name [] = “freddie”;
Matrizes de strings em C e C++
char *names [] = {“Bob”,“Jake”,“Joe”];
Java inicialização de objetos String
String[] names = {“Bob”, “Jake”, “Joe”};
30. 3.3. Tipos Matriz
Operações com Matrizes
◦ APL permite poderosas operações para
matrizes, como também operadores unários
Exemplo: inverte os elementos das colunas
◦ Ada permite atribuição e concatenação de
matrizes
◦ FORTRAN oferece operações elementares
pois são operações entre pares de elementos
de matriz
Exemplo: operador + entre duas matrizes resulta
em uma matriz que é a soma dos pares de
elementos das duas matrizes
31. 3.3. Tipos Matriz
Fatias
◦ Uma fatia (slice) de uma matriz é alguma
subestrutura desta
◦ Fatias são úteis em linguagens que possuem
operadores sobre matrizes
32. 3.3. Tipos Matriz
Fatias: Exemplos
Fortran 95
Integer, Dimension (10) ::Vector
Integer, Dimension (3,3) :: Mat
Integer, Dimension (3,3,3) :: Cube
Vector (3:6) é um vetor de 4 elementos
34. 3.3. Tipos Matriz
Acessando Matrizes (multidimensionais)
◦ Duas maneiras comumente usadas
Ordem da linha maior (por linhas)
Usado na maioria das linguagens
Ordem da coluna maior (por colunas)
Usando em Fortran
35. 3.3. Tipos Matriz
Acessando Matrizes (multidimensionais)
◦ Exemplo de matriz
3 4 7
6 2 5
1 3 8
◦ Ordem da linha maior (por linhas)
3,4,7,6,2,5,1,3,8
◦ Ordem da coluna maior
3,6,1,4,2,3,7,5,8
36. 3.3. Tipos Matriz
Localizando um elemento em uma matriz
multidimensional
◦ location (a[i,j]) = address of a[row_lb,col_lb] + (((I - row_lb)*n)
+ (j - col_lb)) * element_size
37. 3.4. Matrizes Associativas
Uma matriz associativa é um conjunto
não‐ordenado de elementos indexados
por um número igual de valores
chamados chaves
◦ Chaves definidas pelos usuários devem ser
armazenadas
Questões de projeto
◦ Qual é a forma de referência dos elementos?
◦ O tamanho de uma matriz associativa é
estático ou dinâmico?
38. 3.4. Matrizes Associativas
Em Perl
◦ Nomes começam com %; literais são
delimitados por parênteses
%hi_temps = ("Mon"=>77, "Tue"=>79, “Wed”=>65, …);
◦ Os nomes de variáveis escalares iniciam-se
com $
$hi_temps{"Wed"} = 83;
Elementos podem ser removidos
delete $hi_temps{"Tue"};
39. 3.5. Tipos Registro
Um registro é um agregado
possivelmente homogêneo de elementos
de dados
Cada elemento individual é identificado
por seu nome
Questões de projeto
◦ Qual é a forma sintática das referências a
campos?
◦ São permitidas referências elípticas?
40. 3.5. Tipos Registro
Definições de Registro
◦ COBOL usa números para aninhar registros;
outras linguagens usam definições recursivas
01 EMP-REGISTER.
02 EMP-NAME.
05 FIRST PIC X(20).
05 MID PIC X(10).
05 LAST PIC X(20).
02 HOURLY-RATE PIC 99V99.
41. 3.5. Tipos Registro
Definição de Registros em Ada
type Emp_Rec_Type is record
First: String (1..20);
Mid: String (1..10);
Last: String (1..20)Last: 20);
Hourly_Rate: Float;
end record;
Emp_Rec: Emp_Rec_Type;
42. 3.5. Tipos Registro
Referências a Campos do Registro
◦ A maioria das linguagens usam um ponto na
notação
Emp_Rec.Name
◦ Referências elípticas (exemplo em Pascal)
empregado.nome := ‘Bob’;
empregado.idade := 42;
empregado.salario := 23750;
with empregado do
begin
nome := ‘Bob’;
idade := 42;
salario := 23750.0;
end;
43. 3.5. Tipos Registro
Avaliação e comparação com matrizes
◦ O projeto de registros é direto e, seu uso,
seguro
◦ Registros são usados quando os dados
formam uma coleção heterogênea
44. 3.6. Tipos União
Uma união é um tipo que pode
armazenar diferentes valores de tipo
durante a execução do programa
Questões de projeto
◦ A verificação de tipos deve ser exigida?
Note que qualquer verificação de tipos deve ser
dinâmica.
45. 3.6. Tipos União
Discriminantes vs. Uniões Livres
◦ Fortran, C e C++ oferecem construções de
união que não suportam verificação de tipos
na linguagem
A união nessas linguagens são chamadas de uniões
livres
◦ A verificação de tipos em uniões exige que
cada construtor de união inclua um indicador
de tipo, chamado discriminante
Suportado por Pascal e por Ada
46. 3.6. Tipos União
Em Ada
type Shape is (Circle, Triangle, Rectangle);
type Colors is (Red, Green, Blue);
type Figure (Form: Shape) is record
Filled: Boolean;
Color: Colors;
case Form is
when Circle => Diameter: Float;
when Triangle =>
Leftside, Rightside: Integer;
Angle: Float;
when Rectangle => Side1, Side2: Integer;
end case;
end record;
47. 3.6. Tipos União
Estrutura de um registro variante
Uma união discriminada de três variáveis de forma
48. 3.6. Tipos União
Avaliação
◦ Construções potencialmente inseguras
Não permitem verificação de tipos das referências a
uniões
Um dos motivos pelos quais FORTRAN, Pascal, C e
C++ não são fortemente tipificadas
◦ Java e C# não suportam uniões
Reflexo da crescente motivação por linguagens de
programação mais seguras
49. 3.7. Tipos Ponteiro
Um tipo ponteiro é aquele em que as
variáveis têm uma faixa de valores que
consistem em endereços de memória e
um valor especial, nil
Oferece o poder de endereçamento
indireto
Oferece uma alternativa para gerenciar
endereçamento dinamicamente
50. 3.7. Tipos Ponteiro
Questões de projeto de ponteiros
◦ Quais são o escopo e o tempo de vida de
uma variável de ponteiro?
◦ Qual é o tempo de vida de uma variável
dinâmica no monte?
◦ Os ponteiros são restritos quanto ao tipo de
valor para o qual eles apontam?
51. 3.7. Tipos Ponteiro
Operações com Ponteiros
◦ Duas operações fundamentais
Atribuição e desreferenciamento
◦ Atribuição é usada para fixar o valor de uma
variável de ponteiro em um endereço útil
◦ Desreferenciamento referencia o valor da
célula de memória (não apenas o endereço)
Dereferenciamento pode ser implícito ou explícito
C++ usa uma operação explícita *
j = *ptr
j terá o valor alocado em ptr
53. 3.7. Tipos Ponteiro
Problemas com Ponteiros
◦ Ponteiros Pendurados (Dangling pointers)
Um ponteiro que contém o endereço de uma
variável dinâmica no monte desalocada
◦ Variáveis dinâmicas no monte perdidas
Uma variável dinâmica no monte alocada não mais
acessível ao programa usuário (geralmente
chamada de lixo)
Ponteiro p1 é ajustado para apontar para uma variável
dinâmica no monte recém‐criada
Mais tarde, ponteiro p1 é ajustado para outra variável
dinâmica no monte recém‐criada
Vazamento de memória
54. 4. Resumo
Os tipos de dados de uma linguagem são uma grande
parte daquilo que determina o seu estilo e seu uso
Os tipos de dados primitivos da maioria das linguagens
imperativas incluem os tipos numérico, caractere e
booleano
Os tipos enumeração e a subfaixa definidos pelo usuário
são convenientes e aumentam a legibilidade e a
confiabilidade dos programas
Matrizes e registros estão presentes na maioria das
linguagens de programação
Ponteiros são usados para dar flexibilidade de
endereçamento e para controlar o gerenciamento de
armazenamento dinâmica