Capítulo VII – Tipos
Enumerativos e Estruturas
7.1 – Tipos enumerativos
7.2 – A necessidade de estruturas
7.3 – Manipulação dos campos de uma estrutura
7.4 – Campos alternativos
7.4 – Campos Alternativos
7.4.1 – Utilidade de campos alternativos

Seja o cadastramento dos moradores de um prédio

Para todo morador são registrados: o nome, o andar, o
número do apartamento e a idade

Conforme a idade, outras informações são registradas
Morador:

nome, andar, número do apartamento, idade

Zero a 3 anos: número de mamadeiras tomadas por dia

4 a 11 anos: escolaridade, número de brinquedos que
possui;

12 a 17 anos: escolaridade, número de livros que já leu,
passatempo predileto

18 anos ou mais: escolaridade, profissão, se é ou não
casado(a), caso seja casado(a), o nome do cônjuge e o
número de filhos

A seguinte struct poderia ser usada:
struct morador {
char Nome[30], Escolaridade[10], Passatempo[15],
Profissao[15], NomeConjuge[30];
int andar, numapartamento, idade,
numeromamadeiras, numbrinquedos,
numlivros, numfilhos;
logic casado;
};

Nenhum morador usaria todos os campos: desperdício de
memória
Solução: Campos Alternativos

Campos Alternativos: campos de uma variável que
compartilham um mesmo espaço de memória

A variável não será do tipo struct, mas sim do tipo union

No exemplo dos moradores do prédio, o mesmo espaço de
memória pode ser compartilhado por:




nummamadeiras
Escolaridade, numbrinquedos
Escolaridade, numlivros, Passatempo
Escolaridade, Profissao, casado, NomeConjuge,
numfilhos




nummamadeiras
Escolaridade, numbrinquedos
Escolaridade, numlivros, Passatempo
Escolaridade, Profissao, casado, NomeConjuge,
numfilhos

Os campos desse espaço a serem utilizados dependem da
idade do morador

O tamanho total desse espaço é o maior dentre aqueles
ocupados pelas quatro alternativas
7.4.2 – A declaração union

Sejam as seguintes declarações:
union valor {
int valint; double valreal; char valchar;
};
union valor val;
Val

A variável val é do tipo union valor

Os campos valint, valreal e valchar compartilham o mesmo
espaço de memória

Então, essa variável pode guardar alternativamente, num
dado momento, um inteiro, um real ou um caractere
valint/valreal/valchar
union valor {
int valint; double valreal; char valchar;
Val
};
union valor val;
valint/valreal/valchar

O espaço por ela ocupado é o de um double, pois dentre os
tipos dos três campos, double é o que ocupa maior espaço

Tal como nas declarações enum e struct, a variável val
poderia ser declarada das seguintes formas alternativas:
union valor {
int valint;
double valreal;
char valchar;
} val;
ou
typedef union valor valor;
union valor {
int valint;
double valreal;
char valchar;
};
valor val;
typedef union valor valor;
Val
union valor {int valint; double valreal; char valchar;}; Exemplo: seja o trecho
valor val;
de programa à
val.valint = 4455;
esquerda
valint/valreal/valchar
printf ("1) valint = %d, valreal = %lf, valchar = %c",
Os mesmos 8 bytes
val.valint, val.valreal, val.valchar);
(64 bits) estão
val.valreal = 4455.68;
sendo vistos de
printf ("\n\n2) valint = %d, valreal = %lf, valchar = %c", formas diferentes
val.valint, val.valreal, val.valchar);
val.valchar = '*';
printf ("\n\n3) valint = %d, valreal = %lf, valchar = %c",
val.valint, val.valreal, val.valchar);
No vídeo
1) valint = 4455, valreal = 0.000000, valchar = g
2) valint = 343597384, valreal = 4455.680000, valchar = H
3) valint = 343597354, valreal = 4455.680000, valchar = *
7.4.3 – Estruturas com campos alternativos

Campos alternativos são muitíssimo usados dentro de
estruturas

São frequentes os casos em que o valor de algum campo de
uma estrutura determina quais os outros campos da mesma
serem preenchidos em seguida

Seja a seguir o exemplo visto dos moradores de um prédio
Declarações dos tipos utilizados:
cadastro Cad;
// Cad é do tipo cadastro onde
struct cadastro {
int nmor; morador Moradores[10];
};
typedef struct cadastro cadastro;
Moradores
nmor
morador
morador
morador
morador
morador
morador
morador
morador
morador
morador
Cad
typedef struct morador morador;
struct morador {
char Nome[30]; int andar, nap, idade;
infoadicionais InfoAdic;
};
Moradores
nmor
morador
morador
morador
morador
morador
morador
morador
morador
morador
morador
Cad
O tipo morador
char - [30]
int
int
int
infoadicionais
Nome
andar
nap
idade
InfoAdic
O tipo morador
char - [30]
int
int
int
infoadicionais
Nome
andar
nap
idade
InfoAdic
typedef union infoadicionais infoadicionais;
union infoadicionais {
infozeroa3 Info03; info4a11 Info411;
info12a17 Info1217; info18oumais Info18;
};
O tipo infoadicionais
infozeroa3 / info4a11 / info12a17 / info18oumais
Info03 / Info411 / Info1217 / Info18
O tipo infoadicionais
infozeroa3 / info4a11 / info12a17 / info18oumais
Info03 / Info411 / Info1217 / Info18
typedef struct infozeroa3 infozeroa3;
struct infozeroa3 {int nmamads;};
O tipo infozeroa3
int
nmamads
typedef struct info4a11 info4a11;
struct info4a11 {escolaridade esc; int nbrinq;};
O tipo info4a11
escolaridade
int
esc
nbrinq
O tipo infoadicionais
infozeroa3 / info4a11 / info12a17 / info18oumais
Info03 / Info411 / Info1217 / Info18
O tipo info12a17
escolaridade
int
char - [20]
esc
nlivros
Passatempo
typedef struct info12a17 info12a17;
struct info12a17 {
escolaridade esc; int nlivros;
char Passatempo[20];
};
O tipo infoadicionais
infozeroa3 / info4a11 / info12a17 / info18oumais
Info03 / Info411 / Info1217 / Info18
O tipo info18oumais
escolaridade
char - [20]
char - [30]
esc
Profissao
Conjuge
char
int
ehcasado nfilhos
typedef struct info18oumais info18oumais;
struct info18oumais {
escolaridade esc; char Profissao[20], Conjuge[30];
char ehcasado; int nfilhos;
};
A seguir, um programa
completo
#include <stdio.h>
#include <stdlib.h>
/* Declaracoes dos diversos tipos */
typedef enum escolaridade escolaridade;
enum escolaridade {nenhuma, basica, media, superior};
typedef struct infozeroa3 infozeroa3;
struct infozeroa3 {int nmamads;};
typedef struct info4a11 info4a11;
struct info4a11 {escolaridade esc; int nbrinq;};
typedef struct info12a17 info12a17;
struct info12a17 {
escolaridade esc; int nlivros;
char Passatempo[20];
};
typedef struct info18oumais info18oumais;
struct info18oumais {
escolaridade esc; char Profissao[20], Conjuge[30];
char ehcasado; int nfilhos;
};
typedef union infoadicionais infoadicionais;
union infoadicionais {
infozeroa3 Info03; info4a11 Info411;
info12a17 Info1217; info18oumais Info18;
};
typedef struct morador morador;
struct morador {
char Nome[30]; int andar, nap, idade;
infoadicionais InfoAdic;
};
typedef struct cadastro cadastro;
struct cadastro {
int nmor; morador Moradores[10];
};
/* Cabecalho e declaracoes das variaveis */
int main () {
cadastro Cad;
int i; char c;
/* Inicio da entrada de dados */
printf ("CADASTRO DE MORADORES DE UM PREDIO");
printf ("\n\nNumero de moradores: "); scanf ("%d", &Cad.nmor);
for (i = 0; i < Cad.nmor; i++) {
/* Leitura das informacoes comuns a cada morador */
printf ("\n\nMorador n.o %d:", i+1);
printf ("\n\tNome: "); setbuf (stdin, NULL);
gets (Cad.Moradores[i].Nome);
printf ("\tAndar: "); scanf ("%d", &Cad.Moradores[i].andar);
printf ("\tApto: "); scanf ("%d", &Cad.Moradores[i].nap);
printf ("\tIdade: "); scanf ("%d", &Cad.Moradores[i].idade);
/* Leitura das informacoes dos moradores com idade de zero a 3 anos */
if (Cad.Moradores[i].idade >= 0 && Cad.Moradores[i].idade <= 3) {
printf ("\tNumero de Mamadeiras: ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info03.nmamads);
}
/* Leitura das informacoes dos moradores com idade de 4 a 11 anos */
else if (Cad.Moradores[i].idade >= 4 && Cad.Moradores[i].idade <= 11) {
printf ("\tEscolaridade ");
printf ("(0 - Nenhuma, 1 - Basica, 2 - Media, 3 - Superior): ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info411.esc);
printf ("\tNumero de Brinquedos: ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info411.nbrinq);
}
/* Leitura das informacoes dos moradores com idade de 12 a 17 anos */
else if (Cad.Moradores[i].idade>=12 && Cad.Moradores[i].idade<=17) {
printf ("\tEscolaridade ");
printf ("(0 - Nenhuma, 1 - Basica, 2 - Media, 3 - Superior): ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info1217.esc);
printf ("\tNumero de Livros Lidos: ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info1217.nlivros);
printf ("\tPassatempo Predileto: ");
setbuf (stdin, NULL);
gets (Cad.Moradores[i].InfoAdic.Info1217.Passatempo);
}
/* Leitura das informacoes dos moradores com idade de 18 anos ou mais */
else {
printf ("\tEscolaridade ");
printf ("(0 - Nenhuma, 1 - Basica, 2 - Media, 3 - Superior): ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info18.esc);
printf ("\tProfissao: ");
setbuf (stdin, NULL);
gets (Cad.Moradores[i].InfoAdic.Info18.Profissao);
printf ("\tEh casado? (s/n): ");
c = Cad.Moradores[i].InfoAdic.Info18.ehcasado = getche ();
if (c == 's' || c == 'S') {
printf ("\n\tNome do conjuge: "); setbuf (stdin, NULL);
gets (Cad.Moradores[i].InfoAdic.Info18.Conjuge);
printf ("\tNumero de Filhos: ");
scanf ("%d", &Cad.Moradores[i].InfoAdic.Info18.nfilhos);
}
else printf ("\n");
}
}
/* Listagem das informacoes digitadas */
printf ("\nListagem dos Moradores:\n");
for(i = 0; i < Cad.nmor; i++) {
/* Informacoes comuns */
printf("\n%d) Nome: %-21s; Andar: %4d; Apto: %5d; Idade: %4d", i+1,
Cad.Moradores[i].Nome, Cad.Moradores[i].andar,
Cad.Moradores[i].nap, Cad.Moradores[i].idade);
/* Moradores de zero a 3 anos */
if (Cad.Moradores[i].idade >= 0 && Cad.Moradores[i].idade <= 3) {
printf ("\n\tMamadeiras: %d;",
Cad.Moradores[i].InfoAdic.Info03.nmamads);
}
/* Moradores de 4 a 11 anos */
else if (Cad.Moradores[i].idade >= 4 && Cad.Moradores[i].idade <= 11) {
printf ("\n\tEscolaridade: %d; Brinquedos: %d",
Cad.Moradores[i].InfoAdic.Info411.esc,
Cad.Moradores[i].InfoAdic.Info411.nbrinq);
}
/* Moradores de 12 a 17 anos */
else if (Cad.Moradores[i].idade>=12 && Cad.Moradores[i].idade<=17) {
printf ("\n\tEscolaridade: %d; Livros: %d; Passatempo: %s",
Cad.Moradores[i].InfoAdic.Info1217.esc,
Cad.Moradores[i].InfoAdic.Info1217.nlivros,
Cad.Moradores[i].InfoAdic.Info1217.Passatempo);
}
/* Moradores de 18 anos ou mais */
else {
printf ("\n\tEscolaridade %d; Profissao %s; Casado: %c;",
Cad.Moradores[i].InfoAdic.Info18.esc,
Cad.Moradores[i].InfoAdic.Info18.Profissao,
Cad.Moradores[i].InfoAdic.Info18.ehcasado);
c = Cad.Moradores[i].InfoAdic.Info18.ehcasado;
if (c == 's' || c == 'S') {
printf ("\n\tConjuge: %s, Filhos: %d",
Cad.Moradores[i].InfoAdic.Info18.Conjuge,
Cad.Moradores[i].InfoAdic.Info18.nfilhos);
}
}
}
/* Fechamento da tela */
printf ("\n\n"); system ("pause"); return 0;
}
Exercícios 7.4:
1) Seja o programa ao
lado contendo
estruturas e campos
alternativos. Mostrar
o que será escrito no
vídeo pela sua
execução.
#include <stdio.h>
#include <stdlib.h>
typedef char str2[2]; typedef char str4[4];
struct ss {str2 x[4]; str4 y[2];};
typedef struct ss ss; typedef char str16[16];
typedef char str8[8];
union uu {ss a; str16 b; str8 c;} uniao;
int main () {
str16 palavra = "ABCDEFGHIJKLMNOP";
str8 numero = "12345678";
int i, j;
for (i=0; i<16; i++) uniao.b[i] = palavra[i];
for (i=0; i<8; i++) uniao.c[i] = numero[i];
for (i=0; i<4; i++) {
for (j=0; j<2; j++)
printf ("%c%c",
uniao.a.x[i][j],
uniao.a.y[j][i]);
printf ("\n");
}
printf ("\n\n"); system ("pause");
return 0;
}
Download

CES-10 Teoria Cap 7-b