View
1.007
Download
9
Category
Preview:
Citation preview
Programação de Computadores Profª Ms. Engª Elaine Cecília Gatto
Unidade 6: Estruturas, Uniões, Enumerações e Tipos Definidos pelo Usuário
Curso de Bacharelado em Engenharia de Computação
Universidade do Sagrado Coração – USC
Bauru/SP
Uniões
• Uma união é um tipo de dado derivado com membros que compartilham o mesmo espaço de armazenamento.
• Para diferentes situações em um programa, algumas variáveis podem não ser relevantes, mas outras variáveis o são, de modo que uma união compartilha o espaço em vez de desperdiçar armazenamento em variáveis que não são mais usadas.
• Os membros de uma união podem ser de qualquer tipo de dado.
Uniões
• O número de bytes usados para armazenar uma união precisa ser, pelo menos, o suficiente para manter o maior membro.
• Na maior parte dos casos, as uniões contêm dois ou mais tipos de dados.
• Apenas um membro e, portanto, um tipo de dado, pode ser referenciado a cada vez.
• É de responsabilidade do programador garantir que os dados em uma união sejam referenciados com o tipo apropriado.
Declarações de Uniões
• Uma união é declarada com a palavra-chave union no mesmo formato de uma estrutura.
union numero {
int x;
double y;
}
• A declaração acima indica que número é um tipo union com os membros int x e double y.
• A declaração da união normalmente é colocada no cabeçalho e incluída em todos os arquivos-fonte que usam o tipo união.
Declarações de Uniões
• Assim como a declaração de struct, uma declaração de union simplesmente cria um novo tipo.
• Colocar uma declaração de union ou struct fora de uma função não cria uma variável global.
• Uma union é o meio pelo qual um pedaço de memória é tratado ora como uma variável de um certo tipo, ora como outra variável de outro tipo.
• Uniões podem ser usadas para poupar memória.
• Uma struct aloca um espaço diferente de memória para cada membro.
Operações que podem ser realizadas em uniões
• As operações que podem ser realizadas em uma união são as seguintes:
• Atribuição de uma união a outra união do mesmo tipo;
• Coleta do endereço (&) de uma variável de união;
• Acesso dos membros da união usando o operador de membro da estrutura e o operador de ponteiro da estrutura;
• As uniões não podem ser comparadas com os operadores == e != pelos mesmos motivos pelos quais as estruturas não podem ser comparadas.
Inicialização de uniões em declarações
• Em uma declaração, uma união pode ser inicializada com um valor do mesmo tipo que o primeiro membro da união.
• Por exemplo, com a união anterior, a declaração
union número valor = { 10 };
• é uma inicialização válida de uma variável de união valor, pois a união é inicializada com um int, mas a declaração seguinte (double) truncaria a parte de ponto flutuante do valor inicializador, e normalmente produziria uma advertência do compilador:
union número valor = { 1.43 };
Demonstração de Uniões
• O programa a seguir usa a variável VALUE do tipo UNION NUMBER para exibir o valor armazenado na união como um INT e um DOUBLE.
• A saída do programa depende da implementação.
• A saída do programa mostra que a representação interna de um valor DOUBLE pode ser muito diferente da representação de INT.
• Uniões são tipos de dados que armazenam um único membro por vez.
• Os membros de uma union representam os diversos tipos de dados que ela pode conter.
Demonstração de Uniões
#include <stdio.h>
union number{
int x;
double y;
};
int main(void) {
union number value; //declara a variável de union
//coloca um inteiro na union
value.x = 100;
printf( “ %s \n %s \n %s \n %d \n \n %s \n %f \n”,
“Coloca um valor no membro inteiro”,
“e mostra os dois membros.”,
“int:”, value.x,
“double:”, value.y);
Demonstração de Uniões
// coloca um double na mesma union
value.x = 100.0;
printf( “ %s \n %s \n %s \n %d \n \n %s \n %f \n”,
“Coloca um valor no membro de ponto flutuante”,
“e mostra os dois membros.”,
“int:”, value.x,
“double:”, value.y);
return 0;
}
Demonstração de Uniões
TYPEDEF com UNION
typedef union {
char str[30];
int i;
float f;
} Numero;
Numero x; //cria a variável do tipo union
union Numero {
char str[30];
int i;
float f;
} x; //cria a variável
TYPEDEF com UNION
union Numero {
char str[30];
int i;
float f;
} x, y, z;
//cria várias variáveis
union {
char str[30];
int i;
float f;
} x; //cria a variável
Uniões de Estruturas
• Uma união pode ter membros de qualquer tipo, até mesmo estruturas ou outras uniões.
• Uma união pode ser membro de uma estrutura.
Uniões de Estruturas
#include <stdio.h>
#include <stdlib.h>
int main(void) {
struct doisint {
int n1;
int n2;
};
union intflo {
struct doisint x;
float f;
} unex;
printf("sizeof(union intflo) = %d \n", sizeof(union intflo));
unex.x.n1 = 734;
unex.x.n2 = 333;
printf("unex.x.n1 = %d \n", unex.x.n1);
printf("unex.x.n2 = %d \n", unex.x.n2);
unex.f = 325.22;
printf("unex.f = %.2f \n", unex.f);
system("PAUSE");
return 0;
}
Uniões de Estruturas
Operador SIZEOF
#include <stdio.h> #include <stdlib.h> union Numero { char str[32]; int i; float f; } x; int main(void) { printf("%d \n", sizeof(union Numero)); fflush(stdout); printf("%d \n", sizeof(x)); fflush(stdout); system("PAUSE"); return 0; }
Operador SIZEOF
• Uma variável de um tipo union tem o tamanho do maior membro.
• Para verificar isso, usa-se o operador SIZEOF
• O operador SIZEOF opera sobre o nome de um tipo de dado ou sobre o nome de uma variável e resulta o seu tamanho em bytes.
Constantes de Enumeração
• Uma enumeração, introduzida pela palavra-chave enum, é um conjunto de constantes de enumeração inteiras, representadas por identificadores.
• Os valores em um enum começam com zero, a menos que haja outras especificações, e são incrementados por 1.
• Exemplo:
enum months {
jan, fev, mar, abr, mai, jun, jul, ago, set, out, nov, dez
};
Constantes de Enumeração
• Essa enumeração cria um novo tipo, em que os identificadores são definidos como os inteiros de 0 a 11, respectivamente.
• Para numerar os meses de 1 a 12, use a seguinte enumeração:
enum months {
jan = 1, fev, mar, abr, mai, jun, jul, ago, set, out, nov, dez; }
• Como o primeiro valor nessa enumeração é explicitamente definido como 1, os valores restantes serão incrementados a partir de 1 resultando nos valores de 0 a 11.
Constantes de Enumeração
• Os identificadores em uma enumeração precisam ser exlusivos.
• O valor de cada constante em uma enumeração pode ser definido explicitamente pela declaração que atribui um valor ao identificador.
• Vários membros de uma enumeração podem ter o mesmo valor constante.
• Tipos enumerados são usados quando conhecemos o conjunto de valores que uma variável pode assumir.
• A variável desse tipo é sempre INT.
Constantes de Enumeração #include <stdio.h> enum months { JAN = 1, FEV, MAR, ABR, MAI, JUN, JUL, AGO, SET, OUT, NOV, DEZ }; int main(void) { //pode conter qualquer um dos 12 meses enum months month; //inicializa array de ponteiros const char *monthName[] = {"", "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"}; //loop pelos meses for( month=JAN; month <= DEZ; month++){ printf(" %2d %11s \n", month, monthName[month]); fflush(stdout); } return 0; }
Constantes de Enumeração
Usando TYPEDEF com ENUM
#include <stdio.h> typedef enum { JAN = 1, FEV, MAR, ABR, MAI, JUN, JUL, AGO, SET, OUT, NOV, DEZ } Mes; int main() { Mes m1, m2, m3; m1 = ABR; m2 = JUN; m3 = m2 - m1; if(m1 < m2){ printf(" \n M3 = %d \n", m3); printf(" \n m1 < m2 = %d \n", (m1<m2)); fflush(stdout); } return 0; }
DICA: Função ATOI() e ATOF()
• Função atoi(): recebe o endereço de uma string como argumento e o converte para um valor inteiro. Caso a string não contenha um número válido, ela retornará zero. Espaços em branco iniciais são ignorados.
• Função atof(): recebe o endereço de uma string como um argumento e o converte em um valor double. Caso a string não contenha um número válido, ela retornará zero. Espaços em branco iniciais são ignorados.
DICA: Função EXIT()
• Permite o término imediato do programa e passa o controle ao sistema operacional.
• A função exit() finaliza o programa.
• O seu argumento é um número inteiro que é retornado ao sistema operacional e pode ser acessado por meio do subcomando ERRORLEVEL de um programa .BAT.
• O arquivo .BAT pode conter uma linha como IF ERRORLEVER 1 GOTO ERR1, o que provoca uma mudança de operação, dependendo do valor de retorno indicado pelo término do programa.
• O zero costuma ser usado para indicar o término normal do programa.
Exemplo #include <stdio.h> #include <stdlib.h> #include <string.h> union Numero { char str[30]; int i; float f; }; union Numero x; enum DataType { StrType, IntType, FloatType } Tipo;
void StrTipo(char n[]){ Tipo = StrType; strcpy(x.str,n); } void FloatTipo(float n){ Tipo = FloatType; x.f = n; } void IntTipo(int n){ Tipo = IntType; x.i = n; }
Exemplo void Print(){ switch(Tipo){ case StrType: printf(" Str = %s \n", x.str); fflush(stdout); break; case IntType: printf(" Int = %d \n", x.i); fflush(stdout); break; case FloatType: printf(" Float = %.2f \n", x.f); fflush(stdout); break; } }
int main(){ float y = 34.56; int z = 345; StrTipo("VVB - Treinamento de Pessoal"); Print(); IntTipo(z); Print(); FloatTipo(y); Print(); //system("PAUSE"); return 0; }
Exemplos
Uniões Anônimas
• Uniões anônimas são uniões definidas sem a especificação do nome do tipo.
Uniões Anônimas #include <stdio.h> #include <stdlib.h> #include <string.h> enum DataType { StrType, IntType, FloatType }; typedef struct { enum DataType Tipo; union{ char str_valor[30]; int int_valor; float float_valor; }; } UniaoLiteral;
void Print(UniaoLiteral); int main(){ UniaoLiteral A; A.Tipo=StrType; strcpy(A.str_valor, "VVB - Treinamento de Pessoal"); Print(A); A.Tipo=FloatType; A.float_valor=34.56; Print(A); A.Tipo=IntType; A.int_valor=345; Print(A); return 0; }
Uniões Anônimas void Print(UniaoLiteral x){
switch(x.Tipo){
case StrType:
printf(" Str = %s \n", x.str_valor);
break;
case IntType:
printf(" Int = %d \n", x.int_valor);
break;
case FloatType:
printf(" Float = %.2f \n", x.float_valor);
break;
}
}
Operadores sobre bits
• Computadores representam internamente todos os dados como sequencias de bits;
• Os bits podem assumir o valor 0 ou o valor 1;
• Na maioria dos sistemas, uma sequencia de 8 bits forma um byte – unidade de armazenamento padrão para uma variável do tipo char;
• Outros tipos de dados são armazenados em números maiores de bytes;
• Os operadores sobre bits são usados para manipular os bits de operandos inteiros;
• Os inteiros sem sinal normalmente são usados com o os operadores sobre bits;
Operadores sobre bits
• Os operadores sobre bits são:
• Comparação dos dois operandos bit a bit:
• And (&)
• OR inclusivo ( | )
• OR exclusivo ( ^ )
• Deslocamento à esquerda ( < < )
• Deslocamenteo à direita ( > > )
• Complemento ( ~ )
• Ser capaz de operar no nível dos bits é especialmente importante quando o programa deve atuar diretamente no hardware da máquina.
Operadores sobre bits
AND Os bits são definidos como 1 no resultado, se os bits correspondentes em ambos os operandos forem 1.
OR inclusivo Os bits são definidos como 1 no resultado, se pelo menos um dos bits correspondentes em amobs os operandos for 1.
OR exclusivo Os bits são definidos como 1 no resultado, se exatamente um dos bits correspondentes em ambos os operandos for 1.
Deslocamento à esquerda
Desloca os bits do primeiro operando à esquerda pelo número de bits especificado pelo segundo operando: preenche a partir da direita com zero (0) bits.
Deslocamento à direita
Desloca os bits do primeiro operando à direita pelo número de bits especificado pelo segundo operando: o método de preenchimento a partir da esquerda depende da máquina.
Complemento de um
Todos os bits 0 são definidos como 1, e todos os bits 1 são definidos como 0.
Exibição de um inteiro sem sinal em bits
• Ao usar os operadores sobre bits, é útil imprimir valores em sua representação binária para ilustrar os efeitos exatos desses operadores.
• O programa a seguir imprime um inteiro sem sinal em sua representação binária em grupos de 8 bits cada.
• Os inteiros sem sinal são armazenados, neste exemplo, em 4 bytes ou 32 bits de memória.
Exibição de um inteiro sem sinal em bits #include <stdio.h>
void displayBits (unsigned value); //protótipo da função
int main(void) {
unsigned x;
printf(“Digite um inteiro sem sinal: ”);
scanf(“%u”, &x);
displayBits(x); //chama a função
return 0;
}
//função: mostra bits de um valor inteiro sem sinal
void displayBits(unsigned value) {
unsigned c; //contador
Exibição de um inteiro sem sinal em bits //declara displayMask e desloca 31 bits à esquerda
unsigned displayMask = 1 << 31;
printf(“%10u = ”, value);
//percorre os bits
for( c=1; c<=32; c++) {
putchar(value & displayMask ? ‘1’ : ‘0’);
value <<= 1; //desloca valor à esquerda em 1
if( c%8 == 0) { //gera espaço após 8 bits
putchar(‘ ’);
}
}
putchar(‘ \n ’);
}
Exibição de um inteiro sem sinal em bits
Exibição de um inteiro sem sinal em bits • A função displayBits usa o operador AND sobre bits para
combinar a variável VALUE com a variável DISPLAYMASK.
• Frequentemente, o operador AND sobre bits é usado como um operando chamado MÁSCARA – um valor inteiro com bits específicos definidos como 1.
• As máscaras são usadas para ocultar alguns bits em um valor enquanto seleciona outros bits.
• Na função DISPLAYBITS, a variável máscara DISPLAYMASK recebe o valor 1 << 31 (10000000 00000000 00000000 00000000)
Exibição de um inteiro sem sinal em bits • O operador de deslocamento à esquerda desloca o valor 1 a
partir do bit de baixa ordem – mais à direita – para o bit de alta ordem – mais à esquerda – em DISPLAYMASK, e preenche bits 0 a partir da direita.
• A linha putchar(value & displayMask ? ‘1’ : ‘0’); determina se 1 ou 0 deve ser impresso para o bit mais à esquerda da variável VALUE.
• Quando VALUE e DISPLAYMASK são combinados usando &, todos os bits, exceto o bit de alta ordem na variável VALUE, são mascarados – ocultados – pois qualquer bit que passe por AND com 0 gera 0.
Exibição de um inteiro sem sinal em bits • O operador de deslocamento à esquerda desloca o valor 1 a
partir do bit de baixa ordem – mais à direita – para o bit de alta ordem – mais à esquerda – em DISPLAYMASK, e preenche bits 0 a partir da direita.
• A linha putchar(value & displayMask ? ‘1’ : ‘0’); determina se 1 ou 0 deve ser impresso para o bit mais à esquerda da variável VALUE.
• Quando VALUE e DISPLAYMASK são combinados usando &, todos os bits, exceto o bit de alta ordem na variável VALUE, são mascarados – ocultados – pois qualquer bit que passe por AND com 0 gera 0.
Exibição de um inteiro sem sinal em bits • Se o bit mais à esquerda for 1, VALUE & DISPLAYMASK será
avaliado como um valor diferente de zero – verdadeiro – e 1 será impresso – caso contrário, 0 será impresso.
• A variável VALUE é, então, deslocada um bit à esquerda pela expressão VALUE <<= 1 – isso equivale a VALUE = VALUE << 1.
• Essas etapas são repetidas para cada bit na variável UNSIGNED VALUE.
• Cuidado: usar o operador lógico AND (&&) para o operador AND SOBRE BITS (&) e vice-versa consiste em um erro.
Imprimindo um caracter em binário
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned char bit0: 1;
unsigned char bit1: 1;
unsigned char bit2: 1;
unsigned char bit3: 1;
unsigned char bit4: 1;
unsigned char bit5: 1;
unsigned char bit6: 1;
unsigned char bit7: 1;
} Bits;
typedef union {
unsigned char ch;
Bits x;
} Binario;
int main (void){
Binario B;
printf("Digite um caractere: ");
fflush(stdout);
B.ch = getchar();
printf("O caractere digitado é: %c \n", B.ch);
printf("O valor em binário correspondente é: ");
printf("%d", B.x.bit7);
printf("%d", B.x.bit6);
printf("%d", B.x.bit5);
printf("%d", B.x.bit4);
printf("%d", B.x.bit3);
printf("%d", B.x.bit2);
printf("%d", B.x.bit1);
printf("%d", B.x.bit0);
//system("PAUSE");
return 0;
}
Imprimindo um caracter em binário
Operador and: & e &=
• É um operador binário que executa um AND com cada par de bits dos operandos.
• Cada bit do resultado é 1 somente quando os dois bits operandos são 1; em qualquer situação, o resultado é zero.
• O operador bit a bit AND é normalmente usado para testar se um bit particular está ligado ou desligado.
• O processo de teste funciona, pois se operarmos o bit a ser testado com 1, o resultado será verdadeiro somente se esse bit estiver ligado.
BIT 1 BIT 2 BIT & BIT2
0 0 0
1 0 0
0 1 0
1 1 1
Operador or: | e |=
• É um operador binário que executa um OR com cada par de bits dos operandos.
• Cada bit do resultado é zero somente quando os dois bits operandos são zero; em qualquer outra situação, o resultado é um.
• O operador bit a bit OR é normalmente usado para ligar um bit particular.
• O processo funciona, pois, se operarmos o bit a ser ligado com 1, o resultado será verdadeiro sempre.
BIT 1 BIT 2 BIT 1 | BIT 2
0 0 0
1 0 1
0 1 1
1 1 1
Operador xor: ^ e ^=
• É um operador binário que executa um XOR com cada par de bits dos operandos.
• Cada bit do resultado é 1 somente quando os dois bits operandos são diferentes; quando são iguais, o resultado é zero.
• O operador bit a bit XOR é normalmente usado para inverter o status de um bit.
BIT 1 BIT 2 BIT 1 | BIT 2
0 0 0
1 0 1
0 1 1
1 1 0
Operador de complemento: ~ e ~= • O operador de complemento opera um único operando;
resulta um valor com todos os bits invertidos.
• A aplicação do operador ~ duas vezes no mesmo operando resulta sempre o número original.
• Exemplo:
int main (){
unsigned char ch;
while((ch=getch()) != ‘X’)
printf(“%c”, ~ch);
system(“PAUSE”);
return 0;
}
Operador de deslocamento esquerdo: << e <<= • Trata-se de um operador binário, mas que age somente no
operando da esquerda.
• Executa um deslocamento para a esquerda, conforme o número de posições especificado no segundo operando.
• Toda vez que empurramos um bit à esquerda estaremos multiplicando o número por dois.
X <<= 1; //é o mesmo que x*=2;
X <<= 2; //é o mesmo que x*=4;
• Exemplo:
Operador de deslocamento esquerdo: << e <<= int palavra () {
unsigned int n = ~0;
int i;
for( i=0; n; i++)
n <<= 1;
return i;
}
int main(){
int t = palavra();
printf(“O tamanho da palvra dessa máquina é %d bits. \n”, t);
system(“PAUSE”);
return 0;
}
Operador de deslocamento esquerdo: >> e >>= • É um operador binário, mas que age somente no operando da
esquerda.
• Executa um deslocamento para a direita, conforme o número de posições especificado no segundo operando.
• Toda vez que empurramos um bit à direita estaremos dividindo o número por 2.
X >>= 1; //é o mesmo que x /= 2
X >>= 2; //é o mesmo que x /= 4
Operadores de atribuição sobre bits
&= Operador de atribuição sobre bits AND.
|= Operador de atribuição sobre bits OR inclusivo.
^= Operador de atribuição sobre bits OR exclusivo.
<<= Operador de alinhamento à esquerda com atribuição.
>>= Operador de alinhamento à direita com atribuição.
Precedência e associatividade de operadores
Operadores Associatividade Tipo
() [] . Esquerda para a direita Mais alto
+ - ++ -- | & * ~sizeof (tipo) Direita para a direita Unário
* / % Esquerda para a direita Multiplicativo
+ - Esquerda para a direita Aditivo
<< >> Esquerda para a direita Deslocamento
< <= > >= Esquerda para a direita Relacional
== != Esquerda para a direita Igualdade
& Esquerda para a direita AND sobre bits
^ Esquerda para a direita OR sobre bits
| Esquerda para a direita OR sobre bits
&& Esquerda para a direita AND lógico
|| Esquerda para a direita OR lógico
?: Direita para a direita Condicional
= += -= *= /= |= ^= <<= >>= %= Direita para a direita Atribuição
, Esquerda para a direita vírgula
Campos de Bits
• C permite que o número de bits de um membro UNSIGNED ou INT de uma estrutura ou união armazenado, seja especificado pelo programador.
• Campos de bits permitem uma utilização da memória mais competente, armazenando dados no número mínimo de bits exigido.
• Os membros de campo de bit DEVEM ser declarados como INT ou UNSIGNED.
Campos de Bits
struct bitCar {
unsigned face : 4;
unsigned suit : 2;
unsigned color : 1;
}; //jogo de cartas
• Um campo de bit é declarado ao se colocar um nome de membro UNSIGNED ou INT seguido por um sinal de dois-pontos ( : ) e uma constante inteira representando a largura do campo.
• A constante que representa a largura precisa ser um inteiro entre 0 e o número total de bits usados para armazenar um INT inclusive em seu sistema.
Campos de Bits
• O membro face é armazenado em 4 bits, o membro suit é armazenado em 2 bits e o membro color é armazenado em 1 bit.
• O número de bits é baseado no intervalo de valores desejado para cada membro da estrutura.
• 4 bits podem armazenar valores no intervalo de 0 a 15;
• 2 bits podem armazenar valores no intervalo 0 a 3;
• 1 bit pode armazenar um valor apenas, ou 0 ou 1.
Campos de Bits
• O membro face armazena as cartas de ÁS até Rei;
• O membro suit armazena as cartas:
• Ouros = 0
• Copas = 1
• Paus = 2
• Espadas = 3
• O membro color armazena as cartas vermelho ou preto.
Campos de Bits
• Membros de campo de bit das estruturas são acessados exatamente como qualquer outro membro da estrutura.
• É possível especificar um campo de bit não nomeado para ser usado como preenchimento na estrutura.
Exemplo 1
//converte hexadecimal para binário #include <stdio.h> #include <stdlib.h> #include <math.h> int palavra(); int main(){ int t, j, num, bit; unsigned int mask; while(1){
t = palavra(); //1 no bit mais significativo e zero nos outros mask = pow(2, t-1); printf(" \n Digite um número em hexadecimal: "); fflush(stdout); scanf("%x", &num); printf("Binário de %04x é: ", num); fflush(stdout); for( j=0; j<t; j++){
Exemplo 1
bit = (mask & num) ? 1 : 0; printf("%d", bit); fflush(stdout); if(((j+1)%8) == 0){ printf("--"); fflush(stdout); } mask >>= 1; } } system("PAUSE"); return 0; }
int palavra(){ unsigned int n=~0; int i; for( i=0; n; i++){ n <<= 1; } return i; }
Exercícios
1. Forneça a definição de cada uma das estruturas e uniões a seguir:
a) Estrutura ESTOQUE que contém o array de caracteres NOMEPECA[30], o inteiro NUMPECA, o PRECO em ponto flutuante, o inteiro QUANTIDADE e o inteiro PEDIDO.
b) Dados de união que contem char C, short S, long B, float F e double D.
c) Uma estrutura chamada ENDERECO, que contém os arrays de caracteres RUA[25], CIDADE[20], ESTADO[2] e CEP[8].
d) A estrutura ALUNO que contém os arrays NOME[15] e SOBRENOME[15] e a variável ENDRESIDENCIA do tipo struct ENDEREÇO da parte (c)
e) A estrutura TESTE que contém 16 campos de bit com larguras de 1 bit. Os nomes dos campos de bit são as letras de A até P.
Exercícios
2. Crie a UNIÃO integer com membros char c, short s, int i e long b. Escreva um programa que aceite valores do tipo char, shor, int e long e armazene os valores em variáveis de união do tipo union integer. Cada variável de união deve ser impressa com um char, um short, um int e um long. Os valores são impressos corretamente?
3. Crie a UNIÃO pontoFlutuante com membros float f, double d e long double x. Escreva um programa que aceite valores do tipo float, double e long double e armazene os valores em variáveis de união do tipo union pontoFlutuante. Cada variável de união deve ser impressa com um float, um double e um long double. Os valores são impressos corretamente?
Exercícios
4. Escreva um programa que desloque para a direita uma variável inteira de 4 bits. O programa deverá imprimir o inteiro em bits antes e depois da operação de deslocamento. Seu sistema coloca zeros e uns nos bits vagos?
5. Escreva um programa que desloque para a esquerda uma variável inteira de 4 bits. O programa deverá imprimir o inteiro em bits antes e depois da operação de deslocamento. Seu sistema coloca zeros e uns nos bits vagos?
6. Escreva uma estrutura para conter três membros do tipo int chamados hora, min e seg. Atribua o nome tempo a essa estrutura.
Exercícios
6. Escreva uma estrutura para armazenar dados de um estacionamento. Ela deve ser capaz de armazenar o número da chapa do carro, a marca, a hora de entrada e a hora de saída do estacionamento. Utilize dois membros do tipo tempo, definidos no exercício anterior, para as horas de entrada e saída.
7. Escreva uma instrução que defina um tipo enumerado chamado FRUTAS com nomes pera, maçã, figo, manga e uva. Declare duas variáveis do tipo FRUTAS de nomes Arvore e Feirante e atribua a elas os valores FIGO e UVA, respectivamente. Qual o valor numérico de árvores e feirante?
Exercícios
8. Escreva uma instrução que defina um tipo enumerado chamado RIO com nomes AMAZONAS, NILO, OBI, NIGER e PARANA. De a esses cinco nomes os valores 7.025, 6.6070. 5.5150, 4.184 e 4.025 respectivamente.
9. Crie uma estrutura para armazenar livros de uma biblioteca. A estrutura deve armazenar o título do livro, autor, o número do registro e o preço. O preço deve ser implementado por meio de uma união anônima com um membro para dólar e um membro para reais.
10. Escreva uma estrutura para descrever um mês do ano. A estrutura deve ser capaz de armazenar o nome do mês, a abreviação em três letras, o número de dias e o número do mês.
Exercícios
11. Declare uma matriz externa de 12 estruturas descritas na questão anterior e inicialize-a com os dados de um ano não bissexto. Escreva uma função que recebe o número do mês como argumento e retorna o total de dias do ano até aquele mês. Escreva um programa que solicite ao usuário dia, mês e ano. O mês pode ser numero, seu nome ou sua abreviação. Imprima o total de dias do ano até o dia digitado.
12. Crie uma estrutura para descrever restaurantes. Os membros devem armazenar o nome, o endereço, o preço médio e o tipo de comida. Crie uma matriz de estruturas e escreva um programa que utilize uma função para solicitar os dados de um elemento da matriz e outra para listar todos os dados.
13. Crie uma estrutura com o nome DIETA, para armazenar o nome de uma comida, o peso de uma porção e o número de calorias. Escreva um programa semelhante ao do exercício anterior.
Recommended