29. Enumerações e uniões Outline Contexto - DIMAp

Transcrição

29. Enumerações e uniões Outline Contexto - DIMAp
Outline
29. Enumerações e uniões
1
Enumerações
2
Uniões
DIM0321
2015.1
DIM0321
29. Enumerações e uniões
2015.1
1 / 18
DIM0321
29. Enumerações e uniões
2015.1
2 / 18
Contexto
1
Enumerações
Muitas vezes o conjunto de valores aceitáveis para uma variável é restrito
2
Uniões
Exemplo
lógico: verdadeiro/falso
sexo: homem/mulher
tipo de peça de xadrez: peão, cavalo, bispo, torre, rei, dama
DIM0321
29. Enumerações e uniões
2015.1
3 / 18
DIM0321
29. Enumerações e uniões
2015.1
4 / 18
Codificação
Sintaxe / declaração
1
2
3
4
Codificação com tipos de base
5
6
Por exemplo, inteiros (peão = 1, cavalo = 2, bispo = 3, . . . )
7
8
Abordagem difícil de compreensão.
9
Não é possível saber que vai ter apenas n valores.
10
O significado dos valores não é transparente.
12
11
13
14
16
18
19
20
21
A representação concreta usa uma sequência automática de números
naturais.
23
24
26
27
28
29. Enumerações e uniões
2015.1
4
5
6
7
8
9
10
11
12
13
20
21
22
23
24
25
}
4
5
6
29. Enumerações e uniões
2015.1
6 / 18
#include <stdio.h>
typedef enum {
NEGATIVO,
POSITIVO
} sinal_t;
7
8
9
10
11
12
13
14
15
16
17
18
printf( "Primeiro dia da semana: %i\n", primeiro_dia );
printf( "Ultimo dia da semana: %i\n", ultimo_dia );
printf( "Hoje = %i\n", dia_semana );
printf( "Amanha = %i\n", ++dia_semana );
dia_semana = SABADO;
printf( "Outro dia da semana = %i\n", dia_semana );
return 0;
19
20
21
22
23
24
25
26
27
DIM0321
// É possível atribuir valores diferentes do padrao 0,1,2,3,...
DIM0321
3
17
19
typedef enum cor {
PRETO , // = 0
BRANCO = 2,
AMARELO , // = 3
VERMELHO = 9
} cor_t;
2
enum dia primeiro_dia = DOMINGO;
enum dia ultimo_dia = SABADO;
18
typedef enum sexo {
HOMEM = 4,
MULHER = 3
} sexo_t;
1
14
16
// Podemos usar typedef
Exemplo
#include <stdio.h>
int main(void)
{
enum dia
{
DOMINGO,
SEGUNDA,
TERCA,
QUARTA,
QUINTA,
SEXTA,
SABADO
} dia_semana = QUARTA;
15
typedef enum peca peca_t;
5 / 18
Exemplo
3
enum logico { // Declaração no momento da declaração do enum
V,
F
} booleano, primos[100];
22
25
2
p;
17
Tipo especial de variável que deve conter um número restrito de valores
distintos
1
{ // O tipo enum é tratado como um inteiro
// 0
// 1
// 2
// 3
// 4
// 5
15
Enumeração
DIM0321
enum peca
PEAO,
CAVALO,
BISPO,
TORRE,
REI,
DAMA
};
enum peca
29. Enumerações e uniões
2015.1
7 / 18
typedef struct {
sinal_t sinal;
unsigned int numerador;
unsigned int denominador;
} racional_t;
int main(void)
{
3
racional_t x = { POSITIVO, 2, 5 };
4
racional_t y = { NEGATIVO, 1, 2 };
5
racional_t z = mult_racional(x, y);
6
imprime_racional(x);
void imprime_racional(racional_t r)
7
printf(" * ");
{
8
imprime_racional(y);
printf("%c", r.sinal == POSITIVO ? ’+’ : ’-’);
9
printf(" = ");
printf("%u/%u", r.numerador, r.denominador);
10
imprime_racional(z);
}
11
return 0;
12 }
racional_t mult_racional(racional_t r1, racional_t r2)
{
racional_t resultado;
resultado.sinal = (r1.sinal == r2.sinal ? POSITIVO : NEGATIVO);
resultado.numerador = r1.numerador * r2.numerador;
resultado.denominador = r1.denominador * r2.denominador;
return resultado;
}
DIM0321
1
2
29. Enumerações e uniões
2015.1
8 / 18
Contexto
1
Enumerações
2
Uniões
Sistemas com pouco espaço de memória disponível: em certos casos
precisamos economizar espaço de memória alocado desnecessariamente em
registros.
Em outros casos precisamos criar estruturas contendo uma mistura de
diferentes tipos em um único campo. Ex: Conjunto de números inteiros e de
números de ponto flutuante armazenados em um único vetor.
DIM0321
29. Enumerações e uniões
2015.1
DIM0321
9 / 18
União
29. Enumerações e uniões
2015.1
10 / 18
Sintaxe / declaração
Definição
De um novo tipo / muito parecido a um registro. Só o primeiro campo pode ser
inicializado na declaração.
Tipo especial de registro
Ele armazena apenas um dos valores de seus campos na memória.
1
O compilador aloca espaço suficiente apenas para o maior dos campos, em
3
termos de bytes alocados. Todos os campos compartilham o mesmo espaço na
memória. A atribuição de um valor a um dos campos também altera os valores
dos outros campos.
struct s { char c; int i; } = 5 bytes
union u { char c; int i; } = 4 bytes
DIM0321
29. Enumerações e uniões
2
4
5
6
11 / 18
union num v[5];
7
8
typedef union num num_t;
9
10
2015.1
union num {
int i;
float f;
};
num_t n;
DIM0321
29. Enumerações e uniões
2015.1
12 / 18
Exemplo
Exemplo
1
2
3
4
5
1
2
#include <stdio.h>
#define MAX 100
3
4
5
6
7
10
11
12
13
14
15
7
8
typedef enum {
TIPO_INT,
TIPO_DOUBLE
} tipo;
8
9
6
9
10
11
12
13
typedef struct {
tipo tipo;
union {
int i;
double d;
} uniao;
} mixnum;
14
15
16
17
18
19
20
21
22
23
24
25
DIM0321
1
int main(void)
{
int i, soma = 0, inteiro = 0, real = 0;
double produto = 1.;
mixnum numero[MAX];
for (i = 0; i < MAX; i++) {
scanf("%i", &numero[i].tipo);
if (numero[i].tipo == TIPO_INT)
scanf("%i", &numero[i].uniao.i);
else
scanf("%lf", &numero[i].uniao.d);
}
for (i = 0; i < MAX; i++) {
if (numero[i].tipo == TIPO_INT) {
soma += numero[i].uniao.i;
inteiro = 1;
} else {
produto *= numero[i].uniao.d;
real = 1;
}
}
if (inteiro) printf("Soma dos inteiros: %i\n", soma);
if (real) printf ("Produto dos reais: %g\n", produto);
return 0;
}
29. Enumerações e uniões
2015.1
2
3
4
5
1
2
3
4
6
7
8
9
5
6
7
8
9
10
10
typedef struct {
sinal_t sinal;
unsigned int numerador;
unsigned int denominador;
} racional_t;
11
12
13
14
15
16
11
12
13
14
15
16
typedef union {
unsigned int natural;
int inteiro;
racional_t racional;
} num_t;
17
18
19
20
21
22
23
24
25
26
13 / 18
União / bit-field
typedef enum {
NEGATIVO,
POSITIVO
} sinal_t;
DIM0321
#include <stdio.h>
int main(void)
{
num_t num1, num2, num3, num4;
printf("sizeof (unsigned int) = %lu\n"
"sizeof (int) = %lu\n"
"sizeof (double) = %lu\n"
"sizeof (sinal_t) = %lu\n"
"sizeof (racional_t) = %lu\n"
"sizeof (num_t) = %lu\n",
sizeof(unsigned int), sizeof(int),
sizeof(double), sizeof(sinal_t),
sizeof(racional_t), sizeof(num_t));
num1.natural = 1;
num2.inteiro = 1;
num4.racional.sinal = POSITIVO;
num4.racional.numerador = 1;
num4.racional.denominador = 1;
printf("sizeof (num1) = %lu\n"
"sizeof (num2) = %lu\n"
"sizeof (num3) = %lu\n"
"sizeof (num4) = %lu\n",
sizeof(num1), sizeof(num2),
sizeof(num3), sizeof(num4));
return 0;
}
29. Enumerações e uniões
2015.1
14 / 18
2015.1
16 / 18
Exercício
O que faz esse trecho de código ?
1
#include <stdio.h>
1
2
3
4
5
6
7
8
9
10
typedef union {
float f;
struct {
unsigned mantissa : 23;
unsigned exponent : 8;
unsigned sign : 1;
} parts;
} myfloat;
3
4
5
6
7
8
9
10
11
11
12
13
14
15
16
17
18
19
20
13
14
15
16
17
18
19
20
21
22
29. Enumerações e uniões
typedef union {
struct { /*
unsigned
unsigned
unsigned
unsigned
};
unsigned int
} color_t;
registro anônimo que não declara campo */
char blue;
char green;
char red;
char alpha;
value;
12
int main(void)
{
myfloat f;
scanf("%f", &f.f);
printf("correct mantissa : %u\n", f.parts.mantissa);
printf("correct exponent : %u\n", f.parts.exponent);
return 0;
}
DIM0321
#include <stdio.h>
2
2015.1
15 / 18
int main( void )
{
color_t color;
scanf( "%u", &color.value );
printf( "%hhu\n", color.alpha );
printf( "%hhu\n", color.red );
printf( "%hhu\n", color.green );
printf( "%hhu\n", color.blue );
return 0;
}
DIM0321
29. Enumerações e uniões
Referências
Perguntas ?
Precisões
[KR88] 6 (6.8, 6.9)
[Bac13] 8.2, 8.3
André Backes, Linguagem C completa e descomplicada, Elsevier, 2013.
Brian W. Kernighan and Dennis M. Ritchie, The (ANSI) C Programming
Language, 2nd ed., Prentice Hall Professional Technical Reference, 1988.
http://dimap.ufrn.br/~richard/dim0321
DIM0321
29. Enumerações e uniões
2015.1
17 / 18
DIM0321
29. Enumerações e uniões
2015.1
18 / 18

Documentos relacionados

Lista03 Extra

Lista03 Extra 6. Escreva uma função transporMatriz que receba por parâmetro uma matriz 4 × 5 e outra matriz 5 × 4. A função deve transpor a matriz 4 × 5 e armazenar os resultados na matriz 5 × 4. 7. Utiliza...

Leia mais

Estruturas Auto-Referenciadas e Ficheiros

Estruturas Auto-Referenciadas e Ficheiros • #include • char *fgets(char *line, int maxline, FILE *fp) Lê linha (incluindo \n) do ficheiro fp. Em caso de EOF ou

Leia mais