REGISTROS, UNIÕES E
ENUMERAÇÕES
Introdução
Variáveis são usadas para armazenar
informações na memória do computador
Com os tipos básicos de dados pode-se
armazenar informações de tipo inteiro ou
ponto-flutuante
char ch = 'W';
short sol = 25;
int num = 45820;
float taxa = 0.25f;
double peso = 1.729156E5;
Inteiro
Introdução
Porém, com os tipos básicos não é possível
armazenar um conjunto de informações
Como armazenar o peso de 22 jogadores?
A solução é usar vetores:
float p1 = 80.2;
float p2 = 70.6;
float p3 = 65.5; ...
float p21 = 85.8;
float p22 = 91.0;
Criar 22 variáveis diferentes não é a
melhor solução.
Com vetores não é possível armazenar um
conjunto de informações de tipos diferentes
Como armazenar um cadastro completo (nome,
idade, altura, peso, gols, etc.) de 22 jogadores?
A solução é usar registros
char nome[22][80];
unsigned idade[22];
unsigned altura[22];
float peso[22];
unsigned gols[22];
Introdução
Criar vários vetores não é a melhor
Registros
O registro agrupa diversas informações, de
tipos possivelmente diferentes, sob um único identificador
Para solucionar o problema anterior pode-se criar
um registro jogador, onde um jogador possui: Nome, idade, altura, peso, gols , etc.
Na linguagem C o nome de um registro
define um novo tipo de estrutura de dado ou
Registros
Declaração de um registro:
struct jogador {
char nome[40]; float salario; unsigned gols; };
Palavra chave struct Nome do registro
Membros do Registro
Declaração
A declaração do registro não cria variáveis, apenas define que tipo de informações serão armazenadas
Os membros do registro são definidos por instruções de declaração de variáveis
Pode-se usar qualquer tipo, incluindo vetores ou
mesmo outro tipo definido como um registro
A definição de um registro deve ser finalizada
por um ponto e vírgula
struct jogador {
Criação de Variáveis
Após a declaração do registro, pode-se definir
variáveis desse novo tipo:
Em C é obrigatório manter a palavra chave struct
jogador pele; jogador zico; jogador bebeto;
Criação de Variáveis
jogador zico; Endereços de Memória Dados na Memória zico nome salario golsstruct jogador {
Usando Registros
Os campos individuais de um registro são
acessados através do operador membro (.)
struct jogador {
char nome[40]; float salario; unsigned gols; };
jogador zico;
zico.salario = 40000; zico.gols = 300;
zico.nome = "Zico"; // atribuição inválida
Registros
#include <stdio.h>
#include <stdlib.h>
struct jogador {
char nome[40]; float salario; unsigned gols; };
int main() {
jogador a = {"Bebeto", 200000, 600}; jogador b = {"Romário", 300000, 800};
printf("Contratacoes para o proximo ano: %s e %s! \n\n", a.nome, a.nome); printf("Preco da aquisicao: R$ %0.2f .\n\n", (a.salario + b.salario)); printf("Gols em 2010: %u .\n\n", (a.gols + b.gols));
system("pause"); return 0;
Registros
Saída do programa:
Cada membro é tratado como uma variável
do tipo definido na declaração do registro
Contratações para o próximo ano: Bebeto e Romário! Preço da aquisição: R$500000!
Gols em 2010: 1400.
jogador bebeto; // declaração de variável
bebeto // tipo jogador
bebeto.nome // tipo vetor de caracteres
bebeto.salario // tipo float
bebeto.gols // tipo unsigned int
Registros
Tipos definidos pelo programador através de
registros se comportam de forma semelhante
aos tipos ou variáveis básicos da linguagem C:
Registros podem ser passados como argumentos
de funções
void imprimir(jogador ex);
int main() {
jogador bebeto = {"Bebeto", 200000, 600}; imprimir(bebeto);
Registros
Tipos definidos pelo programador através de
registros se comportam de forma semelhante
aos tipos ou variáveis básicos da linguagem C:
Um registro pode ser um tipo de retorno de uma
função
jogador lerDados();
int main() {
jogador bebeto;
bebeto = lerDados(); ...
Registros
Tipos definidos pelo programador através de
registros se comportam de forma semelhante
aos tipos ou variáveis básicos da linguagem C:
Um registro pode ser atribuído a outro de mesmo
tipo usando o operador de atribuição
int main() {
jogador bebeto = {"Bebeto", 200000, 600}; jogador romario;
romario = bebeto; ...
Vetores de Registros
Pelo registro ser semelhante a um tipo básico
de dados, podemos criar vetores de registros
jogador equipe[22]; // cria vetor de 22 jogadores
scanf %s , &equipe[0].nome); /* lê nome, salário e
scanf %f , equipe[0].salario); gols do PRIMEIRO
scanf %u , equipe[0].gols); jogador do time*/
struct jogador {
char nome[40]; float salario; unsigned gols; };
...
0 1 2 3 4 5 6 21
Vetores de Registros
#include <stdio.h>
#include <stdlib.h>
struct jogador {
char nome[40]; float salario; unsigned gols; };
int main() {
jogador equipe[22] = {
{"Bebeto", 200000, 182}, {"Romário", 300000, 178} };
printf("Contrações para o próximo ano %s e %s.\n\n , equipe[0].nome, equipe[1].nome);
printf( Preço da aquisicao : R$ %f \n\n , equipe[0].salario + equipe[1].salario );
system("pause"); return 0;
Vetores de Registros
Saída do programa:
Como equipe é um vetor do tipo jogador,
equipe[0] é um jogador
Contrações para o próximo ano: Bebeto e Romário! Preço da aquisição: R$500000!
jogador potiguar[22]; // declaração do vetor
potiguar // tipo vetor de jogadores
potiguar.nome // inválido, potiguar não é um registro
potiguar[0].nome // tipo vetor de caracteres
potiguar[0].nome[0] // tipo caractere
Declaração de Variáveis
Pode-se combinar a declaração de um
registro com a criação de uma variável:
Pode-se também criar um registro sem nome
struct jogador {
char nome[40]; float salario; }
maradona, zidane;
struct {
char nome[40]; float salario; }
Uniões
Assim como um registro, uma união pode
armazenar diferentes tipos de dados
union identificador {
char ch;
int num; double frac; };
Palavra chave union Nome da união
Membros da união
Uniões
A diferença entre um registro e uma união é
que uma união só armazena um de seus membros por vez
O registro armazena um char, um int e um double
A união armazena um char ou um int ou um
double
union identificador {
char ch;
int num; double frac; };
struct identificador {
char ch;
Uniões
identificador id;
id.ch = 'a'; // char
printf %c , id.ch); // a
id.frac = 3.8; // double
printf %c , id.frac); // 3.8
printf %c , id.ch); // lixo
Endereços de Memória
Dados
id ch num frac
union identificador {
char ch;
Uniões
Um uso para uniões é economizar memória
quando um item pode usar dois ou mais
formatos, mas nunca simultaneamente
union regkey {
int chave;
char codigo[10]; };
struct software {
char nome[40]; regkey serial;
float preco; };
O numero serial do software pode ser uma
Uniões
#include <stdio.h>
union regkey { int chave;
char codigo[8]; };
int main() {
regkey senha;
printf("Qual seu tipo de senha?\n n[1] chave\n [2] código\n Opção: ); int tipo;
scanf( %d , &tipo);
if (tipo == 1) {
printf("Digite sua chave: ; scanf( %d , &senha.chave);
} else {
printf("Digite seu código: ;
scanf( %d , &senha.codigo);
}
system("pause"); return 0;
Uniões
Saída do Programa:
O programador só pode armazenar valores
em um dos membros da união, portanto ele
deve saber que informação foi digitada
Qual seu tipo de senha? [1] chave
[2] código Opção: 1
Enumerações
Uma enumeração consiste em um conjunto
de constantes inteiras, em que cada uma é representada por um nome
A instrução acima faz duas coisas:
Define cores como o nome de um novo tipo
Faz dos nomes verde, amarelo, azul e branco
constantes para os valores 0, 1, 2 e 3
Enumerações
Uma enumeração é uma forma alternativa de
criar constantes simbólicas
Ela é usada quando conhecemos o conjunto
de valores que uma variável pode assumir
// vermelho = 0, amarelo=1, verde=2, azul=3, preto=4 enum cores {vermelho, amarelo, verde, azul, preto};
// masculino = 0, feminino = 1 enum sexo {masculino, feminino};
// on = 0, off = 1 enum chave {on, off};
Enumerações
Se a intenção é criar apenas constantes sem
ter um tipo definido:
Valores podem ser explicitamente definidos
Alguns valores podem ser omitidos:
Valores podem ser repetidos
enum {vermelho, amarelo, verde, azul, preto};
enum bits {um=1, dois=2, quatro=4, oito=8};
enum bigstep {primeiro, segundo=100, terceiro};
Enumerações
Após a definição da enumeração é possível
criar variáveis da seguinte forma:
As únicas atribuições válidas são as de um dos
valores definidos na enumeração
enum cores {vermelho, amarelo, verde, azul, preto}; cores corDoCarro;
corDoCarro = azul; // válido corDoCarro = 2000; // inválido corDoCarro = 3; // inválido
corDoCarro = (cores) 3; // válido, type cast estilo C
Enumerações
#include <stdio.h>
enum mes {Jan=1, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez};
int main() {
mes inicio, fim; // cria variáveis do tipo mês
inicio = Mar; // inicio do semestre
fim = Jun; // fim do semestre
printf("Digite o mês atual: ; int atual;
scanf( %d ,&atual); // lê o mês atual
if (atual >= inicio && atual <= fim)
printf("Você pode trancar disciplinas.\n ; else
printf("Você não pode trancar!\n ;
system("pause"); return 0;
Enumerações
Saída do Programa:
As funções de entrada e saída (cin e cout) não sabem como ler ou mostrar um tipo definido pelo programador
Digite o mês atual: 5
Você pode trancar disciplinas.
printf("Digite o mês atual: ; int atual;
Conclusão
Registros são tipos compostos de dados que:
Reúnem um conjunto de informações,
possivelmente de tipos diferentes, sob um mesmo identificador
Permitem ao programador criar seus próprios
tipos de dados
Funcionam como um tipo básico de dado no que
Conclusão
Uniões são semelhantes a registros mas só armazenam um membro por vez
Elas são usadas para economizar memória
Enumerações são usadas para definir
constantes inteiras
O programador pode usar no código fonte de seu
programa um nome no lugar de um número
São usadas quando o número de valores que uma