Você está na página 1de 41

INSTITUTO DE INFORMÁTICA

Universidade Federal de Goiás

Tipo de Dados
Linguagens e Paradigmas de Programação

Prof Bruno Silvestre


brunoos@inf.ufg.br
Registro

2
Registro

● Necessidade dos programas de modelarem coleções com


tipos diferentes
● Agregado de dados onde cada elemento é identificado por
um nome e acessado por um deslocamento
○ Os campos dos registros não são indexados como nos arrays

● Elementos de um registro geralmente são adjacentes na


memória

3
Registro: Definição
COBOL define registro por números de nível

01 EMPLOYEE-RECORD.
02 EMPLOYEE-NAME.
05 FIRST PICTURE IS X(20). 20 Caracteres
05 LAST PICTURE IS X(20).
02 HOURLY-RATE PICTURE IS 99V99. Decimal: ??,??

5
Registro: Definição
● Java e C# usam classes como registros
● C, C++ e C# possuem o tipo struct
● C++: struct é uma pequena variação de classe
● Declaração aninhada de registros em C/C++ (e outras)

struct Employee_Name { struct Employee_Record {


char first[20]; struct Employee_Name name;
char last[20]; double hourly_rate;
}; };
6
Registro: Definição
● Lua usa tabelas Variável
(não tipo)
● JavaScript tem algo semelhante

employee = { employee = {
name = { name : {
first = “Pedro”, first : “Pedro”,
middle = “Alvares”, middle : “Alvares”,
last = “Cabral”, last : “Cabral”,
}, },
hourlyRate = 12.20 hourlyRate : 12.20
} } 7
Referenciando os Campos
● Em geral, usa-se a notação de ponto, começando com as estruturas
mais externas até chegar no campo
○ Employee_Record.Employee_Name.first

● COBOL referencia ao contrário (e com OF)


○ FIRST OF EMPLOYEE-NAME OF EMPLOYEE-RECORD

● Fortran 95 usa o % no lugar do ponto


● Em Lua, pode-se usar o ponto ou índice
○ employee[“name”][“first”] ↔ employee.name.first

8
Operações sobre Registros
● Na atribuição, geralmente os dois tipos devem ser iguais
● Ada permite a comparação de registros (Go?)
● C realiza a cópia de memória entre registros
○ Cuidado com ponteiros!

Segura Não Segura

struct Employee_Name { struct Employee_Name {


char first[20]; char *first;
char last[20]; char *last;
}; };
9
Operações sobre Registros

● COBOL tem uma operação que copia os campos de tipos


de registros diferentes com o mesmo nome
○ Registros com o mesmo propósito, mas ordem diferente
○ Em outras linguagem, deve-se copiar os campos manualmente

10
Operações sobre Registros

01 REGISTRO-01. 01 REGISTRO-02.
02 NAME. 02 NAME.
05 FIRST PICTURE IS X(20). 05 LAST PICTURE IS X(20).
05 LAST PICTURE IS X(20). 05 FIRST PICTURE IS X(20).
02 HOURLY-RATE PICTURE IS 99V99. 02 EMPLOYEE-NUMBER PICTURE IS 99.
02 EMPLOYEE-NUMBER PICTURE IS 99. 02 NET-PAY PICTURE IS 99V99.

MOVE CORREPONDING REGISTRO-01 TO REGISTRO-02.


11
Registro: Implementação
● Campos são armazenados em localizações adjacentes
● Tamanhos dos campos podem variar
● São atribuídos deslocamentos relativo ao início para acesso
ao identificadores

struct Person {
char name[32]; Delocamento: 0 (zero)
int age; Delocamento: 32
char address[32]; Delocamento: 36
};
Obs: a disciplina de Software Básico detalha melhor a definição de estrutura 12
Registro: Implementação
struct Person {
char name[32]; Delocamento: 0 (zero)
int age; Delocamento: 32
char address[32]; Delocamento: 36
};

struct Person p; struct Person p;


p.age = 28; *(&p + 32) = 28;

13
Array VS Registro

● Arrays e registros são de certa forma relacionados e cobrem duas


necessidades distintas das aplicações
○ Arrays são geralmente empregados para agrupar tipos idênticos

○ Registros são usados quando o conjunto de dados é heterogêneo

● Acesso aos dados do registro são eficientes pois os identificadores são


normalmente estáticos

16
União

18
Tipo União
● A variável armazena diferente tipos de valores em
diferentes momentos da execução
○ Alocar memória suficiente
100 101 102 103

union exemplo { ue
char c; 100 101 102 103

int i; ue.c
}; 100 101 102 103

union exemplo ue; ue.i

19
Tipo União
● Exemplo: linguagens dinâmicas podem utilizar union para
representar variáveis

x = 123 /* Union of all Lua values


x = true */
x = “hello world” typedef union {
GCObject *gc;
x = function() … end
void *p;
x={} lua_Number n;
int b;
} Value;
20
Tipo União
● Em algumas linguagens não há garantia de verificação de
tipos. O desenvolvedor é responsável em saber o que está
armazenado
○ Uniões livres

● Em outras, é colocada uma tag na união para saber o que ela


está guardando
○ Uniões discriminadas

21
Uniões Livres
● C e C++ não proveem uma forma de verificar o tipo em
uniões
int i;
short s;
union exemplo { union exemplo var;
short curto;
int inteiro; var.string[0] = 'u';
var.string[1] = 'v';
char string[10]; var.string[2] = 'a';
}; var.string[3] = '\0';

i = var.inteiro;
s = var.curto;
22
Uniões Discriminadas
● Para garantir a verificação de tipo, algumas linguagens
incluem um identificador

23
Uniões Discriminadas: 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 Rectangle => Side1, Side2: Integer;
when Triangle => Leftside, Rightside: Integer;
Angle: Float;
end case;
end record;
24
Uniões Discriminadas: Ada

fig : Figure(Rectangle);

fig := (
Filled => True,
Color => Blue,
Form => Rectangle,
Side1 => 12,
Side2 => 3
);

fig.Diameter := 3.0; Erro


25
Ponteiro

26
Tipo Ponteiro
● As variáveis do tipo ponteiro têm como valores:
○ A faixa de endereço de memória
○ Ou um valor nil (ou null)

● Provê uma forma de gerenciar armazenamento dinâmico


○ Heap → variáveis anônimas manipuladas por ponteiros
○ Então, ponteiros referenciam variáveis e não valores

● Promove a flexibilidade: sem ponteiros e alocação


dinâmica, é necessário limitar a quantidade de
armazenamento (na compilação)
27
Operações com Ponteiros
● Operações mais comuns com ponteiros
○ Atribuição e derreferenciação

● Atribuição de um endereço a um ponteiro


○ Endereço da alocação dinâmica
■ Em C, temos malloc(); em C++/Java, o operador new
○ Endereço de outra variável
■ Linguagens oferecem operador ou função para extrair o
endereço
■ Por exemplo: ptr = &var;
28
Operações com Ponteiros
● Derreferenciar um ponteiro é usá-lo como indireção para
recuperar o valor e não o endereço
● C/C++ usam o '*' como operador

29
Ponteiro para Registro
● C/C++ usam duas notações struct Person {
○ (*ptr).field char name[32];
int age;
○ ptr->field
char address[32];
● Ada e Go possuem };
derreferenciação implícita
○ O '.' é usando tanto para registro com struct Person *p;
para ponteiro p = malloc(sizeof(struct Person));

p->age = 28;
(*p).age = 28;

30
Problema com Ponteiros
● Dangling Reference
○ Ponteiro mantém referência para uma área de memória que já foi desalocada

int *ptr;
int *vet = malloc(1024);
ptr = vet;
free(vet);
ptr[2] = 3; // ????

31
Problema com Ponteiros
● Dangling Reference

/* Usa vet como inteiros */


int *vet = malloc(1024*sizeof(int));
int *ptr = vet;
free(vet);

char *str = malloc(1024*sizeof(char));


ptr[2] = 3; // ????

32
Problema com Ponteiros
● Dangling Reference
○ A área de memória foi realocada para outra variável

/* Usa vet como inteiros */


int *vet = malloc(1024*sizeof(int));
Mesma posição
de memória
int *ptr = vet;
free(vet);

char *str = malloc(1024*sizeof(char));


ptr[2] = 3; // ????
Problema com Ponteiros

● Vazamento de memória
int *vet = malloc(1024);
● Área de memória alocada e que
vet = malloc(1024);
não é mais acessível por nenhuma free(vet);
variável (ponteiro)

34
Ponteiros em C/C++
● Flexíveis, pois podem apontar para qualquer
variável, independentemente de onde ela foi alocada
(pilha, head, global)
○ De fato, pode apontar para qualquer lugar da memória
○ Nota: Ada permite que os ponteiros apontem somente para
o heap
● Operador '*' para derreferenciação do ponteiro e '&'
para recuperar o endereço de uma variável
35
Ponteiros em C/C++

int main() {
int *ptr;
int var = 10;
ptr = &var;
???
ptr = var;
return 0;
}

36
Ponteiros em C/C++
● Permite a realização de aritmética com ponteiros
○ Semântica diferente de números

● Deslocamento depende do tipo do ponteiro


○ Interessante para manipulação de arrays

int vet[10]; Aponta para vet[0]


int *ptr = vet;
ptr = ptr + 3; Desloca em 12 bytes
37
Ponteiros em C/C++
typedef int (*Incremento)(int);

int dobro(int i) { return 2*i; }

int triplo(int i) { return 3*i; }

void run(Incremento f) {
● Permite apontar para funções int v = 100;
v = f(v);
}

int main() {
Incremento f = dobro;
run(f);
}

38
Tipo Referência
● Similar a um ponteiro, mas está associado com valores em memória
e objetos, não endereços
● Em C++, referência é um ponteiro constante, geralmente usado em
parâmetro de funções e métodos
○ Implicitamente derreferenciado
○ Deve ser inicializado na definição int result = 0;
○ Utiliza o símbolo '&' na definição int &ptr = result;
● Java usa referência não constantes para objetos
ptr = 3;
result = 5;
39
Verificação
de Tipo

40
Verificação de Tipo
● Verificação garante que as operações e os operandos são
compatíveis
○ Compatível → é legal segundo o operador ou é legal converter implicitamente de
acordo com as regras da linguagem

● A verificação pode ser:


○ Estática: se a amarração do tipo da variável é dado na compilação
○ Dinâmica: se o tipo da variável pode mudar durante a execução do programa
● Células de memória que armazenam diferentes valores complicam a
verificação de tipo
○ union de C (uniões livres)

41
Tipagem Forte
● Uma linguagem é fortemente tipada se os erros de tipos são sempre
detectados

● Isso implica na identificação do uso incorreto de variáveis e valores,


seja durante a compilação ou execução
○ Todas as expressões têm tipos bem definidos

42
Tipagem Forte

● Haskell e ML são fortemente tipadas

● C e C++ não são fortemente tipados

○ Exemplo: union quebra a verificação de tipo

● Java e C#: mais fortes que C/C++, mas cast explícito pode gerar erros

● Coerção de valores também atrapalha a verificação

43
Equivalência de Tipos
● Compatibilidade de tipos define quais tipos são aceitáveis para as operações
● Para tipos escalares as regras são simples e rígidas, mas para tipos
estruturados ou definidos pelo usuários, as regras podem ser complexas
○ Como fazer coerção nos tipos estruturados?

● Define-se então o conceito de equivalência


○ Nome: os nomes dos tipos devem ser iguais

○ Estrutura: as estruturas dos tipos devem ser iguais

44
Resumo
● Tipo Registro
● Tipo União
○ Uniões Livres
○ Uniões Discriminadas

● Tipo Ponteiro
○ Tipo Referência

● Verificação de Tipo

45

Você também pode gostar