1
Novos Tipos
Novos Tipos
struct
struct
,
,
typedef
typedef
e
e
enum
enum
8. Novos Tipos:
8. Novos Tipos:
struct
struct
,
,
typedef
typedef
e
e
enum
enum
2
Na linguagem C é possível criar
novos
tipos
através
de
estruturas. Uma estrutura é
um conjunto de uma ou mais
variáveis (também chamadas
de campos ou membros),
agrupadas sob um único
nome. As estruturas podem
conter elementos de qualquer
tipo de dados tais como int,
char, float, double, ponteiros,
vetores, matrizes, strings ou
mesmo outras estruturas.
8.1 Novos Tipos:
8.1 Novos Tipos:
struct
struct
Definição
struct Data {
int dia, ano; char mes[20]; };
Exemplo 1
No exemplo abaixo é criada uma estrutura capaz de
armazenar datas com 3 campos (dia, ano e mes)
e cada campo é de um tipo diferente.
3
8.1 Novos Tipos:
8.1 Novos Tipos:
struct
struct
struct Data {
int dia, ano; char mes[20]; };
Nome do novo tipo de variável Campos dia e ano do tipo int
Campo mes do tipo string
Não esquecer do ponto-e-vírgula !
A definição do novo tipo de variável Data (struct Data) indica que a partir daquele momento o compilador passa a conhecer um outro tipo, chamado struct Data, que é composto por dois inteiros e um vetor de 20 caracteres. Ou seja, Data não é uma variável e sim o nome pelo qual é conhecido o novo tipo de dados. Cada um dos elementos de Data é denominada campo.
4 #include<stdio.h>
structData
{int Dia, Ano; char Mes[20];};
main() {
struct Datad1;
printf(“Entre com o dia:”); scanf(“%d”,&d1.Dia); fflush(stdin);
printf(“Entre com o mes:”); gets(d1.Mes);
printf(“Entre com o ano:”); scanf(“%d”,&d1.Ano); printf(“A data digitada e:”); printf(“%d/%s”,d1.Dia,d1.Mes); printf(“/%d\n”,d1.Ano);
}
Exemplo 1 – struct Data
8.1 Novos Tipos:
8.1 Novos Tipos:
struct
struct
No Exemplo 1, a variável d1 é do tipo Data e uma informação pertencente a um dado campo/
membro da estrutura Data é acessada utilizando-se ‘.’:
5 #include<stdio.h>
structData
{int Dia, Ano; char Mes[20];};
main() {
struct Datad1 = {23,67,“Jan”}; printf(“Data inicial e:”);
printf(“%d/%s”,d1.Dia,d1.Mes); printf(“/%d\n”,d1.Ano);
printf(“Entre com o dia:”); scanf(“%d”,&d1.Dia); fflush(stdin);
printf(“Entre com o mes:”); gets(d1.Mes);
printf(“Entre com o ano:”); scanf(“%d”,&d1.Ano); printf(“A data digitada e:”); printf(“%d/%s”,d1.Dia,d1.Mes); printf(“/%d\n”,d1.Ano);
}
Exemplo 2 – Inicialização
8.1 Novos Tipos:
8.1 Novos Tipos:
struct
struct
No Exemplo 2, d1 é inicializado de forma que entre chaves são colocados os valores do membros
da estrutura pela ordem em que foram escritos na definição. Ou
seja, o primeiro valor entre chaves (23) inicia o primeiro campo (Dia) e assim por diante. O Exemplo 2 fornece uma forma
de se inicializar a variável d1 do tipo estrutura Data:
struct Data d1 = {23,67,“Jan”};
6
8.2 Novos Tipos:
8.2 Novos Tipos:
typedef
typedef
A declaração de uma variável do tipo estrutura emprega a palavra reservada struct seguida do nome da estrutura:
struct Data d1;
Uma alternativa é empregar a palavra reservada typedef que estabelece um sinônimo para qualquer conjunto de palavras.
typedef struct Data Dt;
Definindo sinônimo com typedef Declaração da estrutura Data Sinônimo de struct Data Dt d1;
7 Outra alternativa é empregar a palavra reservada typedef ao
mesmo tempo em que é definida a estrutura:
8.2 Novos Tipos:
8.2 Novos Tipos:
typedef
typedef
typedef struct Data {
int Dia, Ano; char Mes[20]; } Dt; main() { Dt d1; d1.Dia = 26; d1.Mes = “Jan”; d1.Ano = 93; }
Typedef define que o sinônimo de struct Data {...} é a palavra Dt.
Não é necessário empregar a palavra struct Data e sim apenas Dt.
8 A seguir são ilustradas as três formas possíveis para declarar
se um novo tipo Data utilizando struct com ou sem typedef: struct Data
{
int Dia, Ano; char Mes[20]; }; main() { struct Data d1; d1.Dia = 26; d1.Mes = “Jan”; d1.Ano = 93;}
8.2 Novos Tipos:
8.2 Novos Tipos:
typedef
typedef
typedef struct Data {
int Dia, Ano; char Mes[20]; } Dt; main() { Dt d1; d1.Dia = 26; d1.Mes = “Jan”; d1.Ano = 93; } struct Data {
int Dia, Ano; char Mes[20]; };
typedef struct Data Dt; main()
{ Dt d1; d1.Dia = 26; d1.Mes = “Jan”; d1.Ano = 93; }
9
8.2 Novos Tipos:
8.2 Novos Tipos:
typedef
typedef
#include<stdio.h> typedef structData
{int Dia, Ano; char Mes[20];} Dt;
main() {
intnDias;
Dt d2, d1 = {23, 67, “Jan”}; printf(“Data inicial e:”);
printf(“%d/%s/%d\n”,d1.Dia,d1.Mes,d1.Ano); d2 = d1;
printf(“Entre com n. de dias:”); scanf(“%d”,&nDias);
d2.dia = d1.dia + nDias; printf(“A nova data e:”);
printf(“%d/%s/%d\n”,d2.Dia,d2.Mes,d2.Ano); }
Exemplo 3 – Atribuições Atribuição de valores
entre estruturas: d2 = d1; Equivale à: d2.Dia = d1.Dia; d2.Mes = d1.Mes; d2.Ano = d2.Ano; Observe que para vetor
e matriz a atribuição é sempre feita por elemento por elemento! Problema: 31/12/1999 -> 32/12/1999 ?
10 Em 1582, Gregório XIII:
Calendário Gregoriano
Nova definição para ano bissexto
3300
1
400
1
100
1
4
1
365
365,242199
≅
+
−
+
−
Cada 4 anos + 1 dia Cada 100 anos - 1 dia Cada 400 anos + 1 dia
8.3 Novos Tipos: fun
11 Em 1582, Gregório XIII:
Calendário Gregoriano
Nova definição para ano bissexto
Se resto(ano/100) é 0 Se (ano/400) é 0 então bissexto; (b) Senão não_bissexto; (c) Senão Se (ano/4) é 0
então bissexto; (a) Senão não_bissexto; (c)
Algoritmo
OBSERVAÇÃO: Subtrair 1 dia do calendário a cada 3300 anos (a) Não divisível por 100 e
divisível por 4.
(b) Divisível por 100 e 400. (c) Os demais anos não são Bissextos.
Ano Bissexto
8.3 Novos Tipos: fun
8.3 Novos Tipos: fun
ç
ç
ões +
ões +
struct
struct
12 #include<stdio.h>
typedef structData {int Dia, Mes, Ano;}Data;
// Protótipos das funções. voidprintData(Data di);
intbissexto(int ano);
Data addDia(Data di, int nDias);
// Função principal. main()
{int nDias;
Data d2, d1 = {31,12,1999}; printf(“Data inicial e:”); printData(d1);
d2 = d1;
printf(“Entre com n. de dias:”); scanf(“%d”,&nDias);
d2 = addDia(d1, nDias); printf(“A nova data e:”); printData(d2);}
Exemplo 4 – Funções + struct
// Função que imprime uma data. voidprintData(Data di)
{ printf(“%d/%d/”, di.Dia,di.Mes); printf(“%d\n”, di.Ano);}
// Função para adicionar dias na data.
Data addDia(Data di, int nDias) { int auxD, TRUE = 1;
auxD = di.Dia + nDias;
while(TRUE) { if(di.Mes == 1 || di.Mes == 3 || di.Mes == 5 || di.Mes == 7 || di.Mes == 8 || di.Mes = 10 || di.Mes == 12) if(auxD <= 31) break;
elseauxD = auxD – 31; Exemplo 4 – Funções + struct
8.3 Novos Tipos: fun
13
else
if(di.Mes == 4 || di.Mes == 6 || di.Mes == 9 || di.Mes == 11)
if(auxD <= 30) break;
else auxD = auxD – 30;
else if(di.Mes == 2)
if(bissexto(di.Ano))
if(auxD <= 29) break;
elseauxD = auxD – 29;
else
if(auxD <= 28) break;
elseauxD = auxD – 28;
// Acréscimo no mês.
di.Mes = di.Mes + 1;
// Verifica se ultrapassa 12 meses. if(di.Mes > 12)
{ di.Ano = di.Ano + 1; di.Mes = 1; }
Exemplo 4 – Funções + struct
} // Fim do while.
di.Dia = auxD;
returndi; }
// Função que verifica se um ano é // bissexto (retorna 1) ou não (0).
intbissexto(int ano) {if (ano % 100 == 0) if(ano % 400 == 0) return1; else return0; else if(ano % 4 == 0) return1; else return0; }
Exemplo 4 – Funções + struct
8.3 Novos Tipos: fun
8.3 Novos Tipos: fun
ç
ç
ões +
ões +
struct
struct
14
8.3 Novos Tipos:
8.3 Novos Tipos:
struct
struct
+ fun
+ fun
ç
ç
ões
ões
#include<stdio.h> typedef structPol
{float v[101]; int n; int init;}Pol;
// Protótipos das funções. voidprintPol(Pol px); Pol initPol(Pol px);
floatcalcPol(Pol px, float x);
// Função principal. main() {Pol p, p2; printf(“Iniciando p:”); p = initPol(p); printf(“\n Mostrando p:”); printPol(p); printf(“p(x=2)=%f\n”,calcPol(p,2)); p2 = p; printf(“\n Mostrando p2:”); printPol(p2); } Exemplo 5 – Polinômio // Função de impressão de px. voidprintPol(Pol px) {int i;
// Se o polinômio foi inicializado.
if(px.init)
{for (i=0; i < px.n; i++)
printf(“\nc[%3d]=%f”,i,px.v[i]); printf(“\n”); } else printf(“Inicialize px ! \n”); } // Função de inicialização de px. Pol initPol(Pol px) { int i; px.init = 1;
printf(“\nInsira grau px <= 100:”); scanf(“%d”,&px.n);
for(i=0; i <= px.n; i++)
{ printf(“Entre com c[%3d]:”,i); scanf(“%f”,&px.v[i]); }
returnpx;}
15
8.3 Novos Tipos:
8.3 Novos Tipos:
struct
struct
+ fun
+ fun
ç
ç
ões
ões
// Função de Cálculo de px. floatcalcPol(Pol px, float x) { inti, n = px.n; floaty; if(n == 1) y = px.v[0]; else {
// Usando algoritmo de horner.
y = px.v[n-1]+px.v[n]*x;
for(i=n-2; i >= 0; i--) y = px.v[i] + x*y; } returny; } Exemplo 5 – Polinômio 16
8.4 Novos Tipos:
8.4 Novos Tipos:
struct
struct
+
+
struct
struct
Problema 1: Construir um programa que armazene e manipule informações de uma usina hidrelétrica, tais como dadas abaixo: Nome Volume
(x)
Polinômio grau 4: Volume x Altura
φφφφ(x)
θθθθ(u) Furnas
Defluência
17
8.4 Novos Tipos:
8.4 Novos Tipos:
struct
struct
+
+
struct
struct
#include<stdio.h> typedef structusinaH {char nome[100]; float x, u;
Pol px, pu;} usinaH;
// Protótipos das funções. voidprintUsinaH(usinaH h); usinaH initUsinaH(usinaH h); floatcalcAltx(usinaH h); // Função principal. main() { usinaH h; float x; printf(“Iniciando usina:”); h = initUsinaH(h);
printf(“\n Mostrando h:”); printUsinaH(h);
printf(“px=%f\n”,calcAltx(h)); }
Programa 1 – Usinas Hidro
// Inicializa os dados de uma usina.
usinaH initUsinaH(usinaH h) { Pol px, pu;
printf(“\n Entre nome da usina:”); gets(h.nome);
printf(“\n Entre com volume:”); scanf(“%f”,&h.x);
printf(“\n Entre com defluencia:”); scanf(“%f”,&h.u);
h.px = initPol(px); h.pu = initPol(pu);
returnh;}
// Imprime dados de uma usina. voidprintUsinaH(usinaH h) {printf(“\n Nome da usina:”);
puts(h.nome);
printf(“\nVolume:%f”,h.x); printf(“\nDefluencia:%f”,h.u); printf(“\n Polx = ”);printPol(h.px); printf(“\n Polu = ”);printPol(h.pu);} Programa 1 – Usinas Hidro
18
8.4 Novos Tipos:
8.4 Novos Tipos:
struct
struct
+
+
struct
struct
// Função que calcula phi(x) // (altura de montante). floatcalcAltx(usinaH h) { floaty; y = calcPol(h.px, h.x); returny; }
Programa 1 – Usinas Hidro
A estrutura usinaH utiliza uma outra estrutura Pol que representa um polinômio,
bem como as funções associadas a manipulação
da estrutura Pol. Observação Importante:
19
8.5 Novos Tipos:
8.5 Novos Tipos:
struct
struct
+ fun
+ fun
ç
ç
ões + vetores
ões + vetores
#include<stdio.h> typedef structData {int D, M, A;} Dt;
typedef structProduto
{char Nome[100]; Data Venda;
floatPreco;} Pd;
// Protótipos das funções. voidprintData(Dt d); voidprintProd(Pd p); Dt initData(void); Pd initProd(void); // Função principal. main() {Pd p[3]; int i;
printf(“Leitura de produtos:”);
for(i=0; i < 3; i++) { p[i] = initProd();
printProd(p[i]);} }
Exemplo 6 – Cadastro
// Função que imprime Data. voidprintData(Dt d)
{printf(“%d/%d/%d”,d.D,d.M,d.A);}
// Função que imprime Produto. voidprintProd(Pd p)
{ printf(“\Resumo Venda:”); printf(“\n Produto: ”); puts(p.Nome);
printf(“Data de venda: ”); printData(p.Venda);
printf(“\n Preco Produto: ”); printf(“R$ %10.2f \n”, p.Preco);}
// Função que inicializa Data.
Dt initData(void) { Dt d;
printf(“DD/MM/AAAA: \n”); scanf(“%d%d%d”,&d.D, &d.M,
&d.A);
returnd;}
Exemplo 6 – Cadastro
20
8.5 Novos Tipos:
8.5 Novos Tipos:
struct
struct
+ fun
+ fun
ç
ç
ões + vetores
ões + vetores
Pd initProd(void) {
Pd p;
printf(“\n---\n”); printf(“\n Nome Produto: ”); gets(p.Nome);
printf(“\n Data da venda ”); p.Venda = initData();
printf(“\n Preco da venda: ”); scanf(“%f”,&p.Preco); printf(“\n---\n”); printf(“\n---\n”); returnp; } Exemplo 6 – Cadastro
21
A palavra enum associa a um
conjunto de nomes valores
inteiros a partir de zero (padrão)
ou a partir de um primeiro valor
fornecido. Se um valor for
fornecido a alguns nomes e não
a outros, o compilador atribui
o próximo valor inteiro aos que
não tiverem valor. Tipos enum
são tratados como inteiros e qq
operação de números inteiros
com eles é válida.
8.6 Novos Tipos:
8.6 Novos Tipos:
enum
enum
Definição
enum Mes
{ Jan = 1, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez
};
Exemplo 7
No exemplo abaixo é criada uma estrutura enum que associa para cada palavra
um valor inteiro.
22
8.6 Novos tipos:
8.6 Novos tipos:
enum
enum
#include <stdio.h>
enummeses {Jan = 1, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez};
main() { int dia;
meses mes; mes = Set;
if(mes == Jan || mes == Mar || mes == Mai || mes == Jul || mes == Ago || mes == Out || mes == Dez) dia = 31; else if(mes == Fev) dia = 28; else dia = 30;
printf(“Numero dias: %d \n”,dia); } Exemplo 7.1 – Enum Mes
#include <stdio.h>
enummeses {Jan = 1, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez};
main() { int dia;
meses mes;
mes = meses(9); // int -> meses ! if(mes == Jan || mes == Mar || mes == Mai || mes == Jul || mes == Ago || mes == Out || mes == Dez) dia = 31; else if(mes == Fev) dia = 28; else dia = 30;
printf(“Numero dias: %d \n”,dia); } Exemplo 7.2 – Enum Mes
23
8.7 Novos tipos: resumo
8.7 Novos tipos: resumo
(ii) A definição de tipos e tipos enumerados facilita a programação e permite melhorar o entendimento do programa. Além disso, estruturas podem ser combinadas
com quaisquer outros tipos de dados tais como int, char, float, vetores, matrizes e inclusive outras estruturas. (i) Assim, como vetores e matrizes permitem agrupar e acessar uma grande quantidade de dados do mesmo tipo sob o nome de uma variável e o uso de índices e colchetes,
estruturas são muito úteis para definir um conjunto de campos de valores para diferentes tipos de dados que podem ser armazenados em uma variável e acessados
através do operador ‘.’. 24