Escolar Documentos
Profissional Documentos
Cultura Documentos
struct rotulo
{
membros_da_estrutura;
};
A instruo acima define uma estrutura chamada rotulo que pode conter
diversos membros, os quais podem ser do mesmo tipo ou podem ser de tipos
diferentes;
Exemplos de Definio de Estruturas:
structhora
{
inthoras;
intminutos;
intsegundos;
};
structdata
{
chardia[2];
charmes[2];
charano[4];
};
structrotuloinstancia1,instancia2,...;
A instruo acima declara instancias da estrutura chamada rotulo, isto ,
variveis cujo formato definido pela estrutura denominada rotulo;
structrotulo
{
membros_da_estrutura;
}instancia1,instancia2,...;
Exemplos de Declarao de Estruturas:
//declaraoemseparado
structhora
{
inthoras;
intminutos;
};
//podehaveroutras
//instrucoesaqui
structhorainicio,fim;
//declaraojuntoc/definio
structdata
{
chardia[2];
charmes[2];
charano[4];
}data_nasc,data_atual;
//nestecasoadeclaracaodeve
//virlogoaposadefinicao
//definiodaestruturaHORA
structhora
{
inthoras;
intminutos;
};
//podehaveroutrasinstrucoesaqui
//declaraodasinstnciasINICIOeFIM
structhorainicio,fim;
//usodosmembrosdaestruturaatravsdainstanciaINICIO
inicio.horas=10;
inicio.minutos=35;
//usodosmembrosdaestruturaatravsdainstanciaFIM
2
fim.horas=inicio.horas;
fim.minutos=49;
Ainda com relao ao uso dos membros de uma estrutura, possvel copiar
informaes entre estruturas de mesmo formato, como no exemplo abaixo:
//osdadoscontidosnosmembrosdaestruturaINICIOso
//passadosacadaumdosmembrosdaestruturaFIM
fim=inicio;
1.3. Estruturas que contm Estruturas
Uma estrutura pode conter outras estruturas dentro de si formando um
agrupamento de variveis mais complexos e interessantes. Vejamos isto
atravs de um exemplo:
Exemplos de Estruturas que contm Estruturas:
//definiodaestruturaCOORDquecompostade
//duascoordenadasnumplanocartesiano(XeY)
structcoord
{
intx;
inty;
};
//definioedeclaraodaestruturaRETANGULOcomposta
//dedoisconjuntosdecoordenadasXeY
structretangulo
{
structcoordsuperior_esquerdo;
structcoordinferior_direito;
}caixa;
//usodosmembrosdaestruturadainstanciaCAIXA
caixa.superior_esquerdo.x=0;
caixa.superior_esquerdo.y=10;
caixa.inferior_direito.x=100;
caixa.inferior_direito.y=200;
//estesdadospodemserinterpretadoscomoumconjunto
//deduascoordenadasXeYnoplanocartesianopara
//formaremumacaixaretangular
O resultado da atribuio acima pode ser representado da seguinte forma:
CAIXA
SUPERIOR_ESQUERDO
X
0
Y
10
INFERIOR_DIREITO
X
100
Y
200
47:printf(\nAreadoretngulode%ldunidades.,area);
48:}
//definiodaestruturaALUNOcontendo2vetores
structaluno
{
charnome[10];
floatnota[3];
};
//declaraodeumainstnciadaestruturaALUNO
structalunoZEZINHO;
A estrutura definida acima poderia ser representada da seguinte forma:
zezinho.nome[7]
zezinho.nome
zezinho.nota
zezinho.nota[2]
Para acessar os membros da estrutura, usa-se as mesmas
manipulao de vetores:
instrues de
zezinho.nota[2] = 10;
zezinho.nome[1] = J;
Exemplo de programa com estrutura que contm vetores:
01:/*Demonstraumaestruturaquecontemmatrizescomo
02:membros*/
03:#include<stdio.h>
04:
05:/*Defineedeclaraumaestruturaparaconterosdados,
06:cujosmembrossaoumavariavelfloateduasmatrizeschar
07:
08:structdados{
09:floatquantia;
10:charnome[30];
11:charsnome[30];
12:}reg;
13:
14:main()
15:{
16:/*Recebeosdadosdoteclado.*/
17:
18:printf(Digiteonomeeosobrenomedodoador,\n);
19:printf(separadosporumespaco:);
20:scanf(%s%s,reg.nome,reg.snome);
21:
22:printf(\nDigiteaquantiadoada:);
23:scanf(%f,®.quantia);
24:
25:/*Exibeasinformacoes.*/
26:/*Nota:%.2fespecificaumvalordepontoflutuante
27: /* que deve ser impresso com dois algarismos a
direita*/
28:/*dopontodecimal.*/
29:
30:/*Exibeosdadosnatela*/
31:
32: printf(\nO doador %s %s deu $%.2f., reg.nome,
reg.snome,reg.quantia);
33:
34:}
1.5. Vetores de Estruturas
Os Vetores de estruturas so ferramentas de programao poderosas. Significa
que, partindo de uma estrutura definida, pode-se ter um vetor onde cada
elemento uma estrutura deste tipo.
Por exemplo, supondo uma estrutura como declarada abaixo:
structdados_pessoa
{
charnome[10];
charsobrenome[12];
charfone[8];
};
Esta estrutura poderia ser representada da seguinte forma:
7
estrutura
dados_pessoa
nome
sobrenome
fone
Para definir uma matriz a partir desta estrutura poderia ser usada, por
exemplo, a seguinte definio:
struct dados_pessoa cliente[5];
cliente[0]
nome
sobrenome
fone
cliente[1]
nome
sobrenome
fone
cliente[2]
nome
sobrenome
fone
cliente[3]
nome
sobrenome
fone
cliente[4]
nome
sobrenome
fone
01:*Demonstraousodematrizesdeestruturas*/
02:
03:#include<stdio.h>
04:#definetam5
05:
06:main()
07:{
08:structdados_aluno
09:{
10:charnome[15];
11:floatmedia;
12:intano_nasc;
13:}aluno[tam];
8
14:
15:intx;
16:
17:/*Recebeosdadosdoteclado.*/
18:
19:for(x=0;x<tam;x++)
20:{
21:printf("\nDigiteonomedo%io.aluno:",x+1);
22:scanf("%s",aluno[x].nome);
23:printf("Digiteamdiadestealuno:");
24:scanf("%f",&aluno[x].media);
25:printf("Digiteoanodenascimentodestealuno:");
26:scanf("%i",&aluno[x].ano_nasc);
27:}
28:
29:/*Exibeosdadosnatela*/
30:
31:printf("\n\tNomes\tMedias\tIdades");
32:
33:for(x=0;x<tam;x++)
34:{
35:
printf("\n\t%s\t%.2f\t
%i",aluno[x].nome,aluno[x].media,
2001aluno[x].ano_nasc);
36:}
37:
38:}
1.6. Inicializando Estruturas
As estruturas podem ser inicializadas ao serem declaradas. O procedimento
semelhante ao adotado para inicializar vetores: coloca-se um sinal de
igualdade aps a declarao da estrutura seguido de uma lista de valores
separados por vrgula e delimitados por chaves. Por exemplo:
structvenda
{
charcliente[10];
charitem[10];
floatquantidade;
}ultima_venda={Fulano,Rebimboca,10.5};
No caso de uma estrutura que contenha outras estruturas como membros, os
valores de inicializao devem ser listados em ordem. Esses valores sero
armazenados nos membros da estrutura na ordem em que os membros esto
structcliente
{
charempresa[20];
charcontato[15];
};
structvenda
{
structclientecomprador;
charitem[10];
floatquantidade;
}primeira_venda={{IndstriaAcme,Fulano},
Rebimboca,
10.5
};
No caso de um vetor de estrutura, os dados de inicializao fornecidos sero
aplicados, pela ordem, s estruturas do vetor. Por exemplo:
structcliente
{
charempresa[20];
charcontato[15];
};
structvenda
{
structclientecomprador;
charitem[10];
floatquantidade;
}diaria[10]={
{/*Dadosparadiaria[0]*/
{IndstriaAcme,Fulano},
Rebimboca,
10.5
}
{/*Dadosparadiaria[1]*/
{ABCLtda.,Beltrano},
Parafuseta,
5.6
}
{/*Dadosparadiaria[2]*/
{Cia.XYZ,Cicrano},
Treco,
17.0
10
}
};
No exemplo acima, apenas os trs primeiros elementos da matriz de estrutura
diaria receberam informaes. Os demais elementos no foram inicializados.
1.7. Passando estruturas para funes
No exemplo temos o seguinte comando:
strcpy(ficha.nome,"LuizOsvaldoSilva");
Neste comando um elemento de uma estrutura passado para uma funo.
Podemos tambm passar para uma funo uma estrutura inteira. Veja a
seguinte funo:
voidPreencheFicha(structficha_pessoalficha)
{
...
}
Como vemos acima fcil passar a estrutura como um todo para a funo.
Devemos observar que, como em qualquer outra funo no C, a passagem da
estrutura feita por valor. A estrutura que est sendo passada, vai ser copiada,
campo por campo, em uma varivel local da funo PreencheFicha. Isto
significa que alteraes na estrutura dentro da funo no tero efeito na
varivel fora da funo. Mais uma vez podemos contornar este pormenor
usando ponteiros e passando para a funo um ponteiro para a estrutura.
2. Estruturas e Ponteiros
Pode-se usar ponteiros como membros de estruturas e tambm declarar
ponteiros que apontem para estruturas.
2.1. Ponteiros como membros de Estruturas:
Para usar um ponteiro como membro de uma estrutura, para declar-los
precedidos do operador de indireo (*), tal como na declarao comum de
ponteiros. Por exemplo:
structfinanciamento
{
int*valor;
float*juros;
}fin_automovel;
Estas instrues declaram uma estrutura denominada financiamento que
11
fin_automovel.valor=&custo_total;
fin_automovel.juros=&taxa;
Tambm pode-se usar o operador de indireo para acessar o valor das
variveis apontadas por estes ponteiros:
printf(\nValor:%d,*fin_automovel.valor);
tot=*fin_automovel.valor+*fin_automovel.juros;
2.2. Ponteiros para Strings como Membros de Estruturas:
O uso mais comum de ponteiros como membros de estruturas o de ponteiros
para strings, como no exemplo abaixo:
structmensagem
{
char*msg1;
char*msg2;
}observacao;
Tal como no uso comum de ponteiros para strings, pode-se inicializ-lo
diretamente com um string, como abaixo:
observao.msg1=Primeiramensagemdeobservao;
observao.msg2=Segundamensagemdeobservao;
Desta mesma forma, os ponteiros que so membros de estruturas podem ser
usados em qualquer lugar em que um ponteiro normal poderia ser usado. Por
exemplo:
printf(%s%s,observao.msg1,observao.msg2)
puts(observao.msg1);
puts(observao.msg2);
2.3. Ponteiros para strings x vetores de char em Estruturas:
Tanto o uso de ponteiros para strings quanto o uso de matrizes para o tipo char
so usados para armazenar um string dentro de uma estrutura.
Definio de Ponteiros para strings x vetores do tipo char:
structmsg
{
12
charp1[20];
char*p2;
}obs;
/*atribuiodevalores*/
strcpy(obs.p1,Primeiramensagem);
strcpy(obs.p2,Segundamensagem);
/*impressodosvalores*/
puts(obs.p1);
puts(obs.p2);
Observe que a forma de uso tanto de ponteiros para strings quanto de vetores
para o tipo char idntico. Assim, a diferena entre ambos consiste
basicamente em:
Ao definir uma estrutura que contenha uma matriz do tipo char, todas as
instncias desse tipo de estrutura contero espao de armazenagem
para o tamanho especificado.
Alm disso, com o uso de matrizes para o tipo char, o tamanho do string
estar limitado ao tamanho especificado e no poder armazenar um
nmero de caracteres maior na estrutura.
Exemplo: limitao no uso de matrizes para o tipo char:
//definioedeclarao
structnome_completo
{
charprenome[10];
charsobrenome[10];
}cliente;
//podehaveroutrasinstruesaqui
strcpy(cliente.prenome,Escolstica);
/*stringmaiorquematrizprovocarerros*/
strcpy(cliente.sobrenome,Silva);
/*stringmenorquematrizdesperdciodememria*/
O uso de ponteiros para strings impede que tais problemas venham a ocorrrer.
Vantagens do uso de ponteiros para strings no lugar de matrizes do tipo char:
Cada instncia da estrutura conter apenas o espao de armazenagem
necessrio para o prprio ponteiro;
Os strings propriamente ditos sero armazenados em qualquer outra
parte da memria (no h necessidade de se saber onde);
No h restrio ao tamanho do string nem haver espao ocioso;
Cada ponteiro da estrutura pode apontar para um string de qualquer
tamanho;
13
/*definioedeclaraodaestrutura*/
structproduto
{
intcodigo;
charnome[10];
}prod1;
/*declaraodeumponteiroparaestaestrutura*/
structproduto*p_prod;
/*inicializaodoponteiro*/
p_prod=&prod1;
/*atribuiodevaloratravsdaindireo*/
(*p_prod).codigo=100;//prod1.codigo=100;
strcpy((*p_prod).nome,"Rebimboca");
/*operador(.)temprioridadesobre(*)*/
/*impressodosvaloresatravsdaindireo*/
printf("%d\n",(*p_prod).codigo);
printf("%s\n",(*p_prod).nome);
puts((*p_prod).nome);
Outra forma de acessar membros da estrutura atravs de ponteiros com o
uso do operador de acesso a membro (->) como mostrado a seguir:
printf("%d\n",p_prod>codigo);
puts(p_prod>nome);
p_prod>codigosimilara(*p_prod).codigo
14
structproduto
{
intcodigo;
charnome[10];
}prod[100];
/*declaraodeumponteiroparaestaestrutura*/
structproduto*p_prod;
p_prod=&prod[0];//p_prod=prod;
//usandoamatrizprod
for(i=0;i<100;i++)
{
printf(Digiteocdigodo%ioproduto:);
scanf(%d,&prod[i].codigo)
printf(Digiteonomedo%ioproduto:);
scanf(%s,prod[i].nome)
}
//usandooponteirop_prod
for(i=0;i<100;i++)
{
printf(Digiteocdigodo%ioproduto:);
scanf(%d,&p_prod>codigo)
printf(Digiteonomedo%ioproduto:);
scanf(%s,p_prod>nome)
p_prod++;
}//nofinal,oponteiroestarapontandopara
//ofimdamatriz(umendereoapsoltimo)
Ponteiros e Vetores de Estruturas
01:/*Demonstraaprogressaoatravesdeuniamatrizde
02:/*estruturasusandoanotacaodeponteiros.*/
03:
04:#include<stdio.h>
05:
06:#defineMAX4
07:
08:/*Defineumaestrutura,depoisdeclaraeinicializa*/
09:/*umamatrizcontendo4estruturas.*/
10:
11:structpeca{
12:intnumero;
15
13:charnome[10];
14:}dados[MAX]={1,Smith,
15:2,Jones,
16:3,Adams,
17:4,Wilson
18:};
19:
20:/*Declaraumponteirop/otipopecaeumavariavelde
contagem*/
21:
22:structpeca*p_peca;
23:intcontagem;
24:
25:main()
26:{
27: /*Inicializaoponteiroparaoprimeiroelementoda
matriz*/
28:
29:p_peca=dados;
30:
31:/*Fazumloopatravesdamatriz,incrementandoo
32:/*ponteiroacadaiteracao.*/
33:
34:for(contagem=0;contagem<MAX;contagem++)
35:{
36:printf(\nNoendereco%d:%d%s,p_peca,p_peca>numero,
p_peca>nome);
37:p_peca++;
38:
39:}
40:
41:}
16
07:structdados{
08:floatquantia;
09:charnome[30];
10:charsnome[30];
11:}reg;
12:
13:/*Oprottipodafuno:Afunonotemvalorde
14:/*retornoeaceitacomonicoargumentoumaestruturado
tipodados.*/
15:
16:voidprint_reg(structdadosx);
17:
18:main()
19:{
20:/*Recebeosdadosdoteclado.*/
21:
22:printf(Digiteonomeeosobrenomedodoador,\n);
23:printf(separadosporumespao:);
24:scanf(%s%s,reg.nome,reg.snome);
25:
26:printf(\nDigiteaquantiadoada:);
27:scanf(%f,®.quantia);
28:
29:/*Chamaafunoqueexibeosdados.*/
30:
31:print_reg(reg);
32:}
33:
34:voidprint_reg(structdadosx)
35:{
36:printf(\nOdoador%s%sdeu$%.2f.,x.nome,x.snome,
x.quantia);
37:}
Digite o nome e o sobrenome do doador, separados por um espao: Carlos
Silva Digite a quantia doada: 1000.00
O doador Carlos Silva deu $1000.00.
structficha_pessoal*p;
17
structficha_pessoalficha;
structficha_pessoal*p;
p=&ficha;
A segunda alocando memria para
malloc():
#include<stdlib.h>
struct tipo_endereco
{
char rua [50];
int numero;
char bairro [20];
char cidade [30];
char sigla_estado [3];
long int CEP;
};
struct ficha_pessoal
{
char nome [50];
long int telefone;
struct tipo_endereco endereco;
};
main()
{
structficha_pessoal*p;
inta=10;
/*Faremosaalocacaodinamicade10fichaspessoais*/
p=(structficha_pessoal*)malloc(a*sizeof(struct
ficha_pessoal));
p[0].telefone=3443768;/*Exemplodeacesso
aocampotelefonedaprimeirafichaapontadaporp*/
free(p);
}
H mais um detalhe a ser considerado. Se apontarmos o ponteiro p para uma
estrutura qualquer (como fizemos em p = &ficha; ) e quisermos acessar um
elemento da estrutura poderamos fazer:
18
(*p).nome
Os parnteses so necessrios, porque o operador . tem precedncia maior
que o operador * . Porm, este formato no muito usado. O que comum de
se fazer acessar o elemento nome atravs do operador seta, que formado
por um sinal de "menos" (-) seguido por um sinal de "maior que" (>), isto :
-> . Assim faremos:
p>nome
A declarao acima muito mais fcil e concisa. Para acessarmos o elemento
CEP dentro de endereco faramos:
p>endereco.CEP
3. Declarao Union
Uma declarao union determina uma nica localizao de memria onde
podem estar armazenadas vrias variveis diferentes. A declarao de uma
unio semelhante declarao de uma estrutura:
unionnome_do_tipo_da_union
{
tipo_1nome_1;
tipo_2nome_2;
...
tipo_nnome_n;
}variveis_union;
Como exemplo, vamos considerar a seguinte unio:
unionangulo
{
floatgraus;
floatradianos;
};
Nela, temos duas variveis (graus e radianos) que, apesar de terem nomes
diferentes, ocupam o mesmo local da memria. Isto quer dizer que s
gastamos o espao equivalente a um nico float. Unies podem ser feitas
tambm com variveis de diferentes tipos. Neste caso, a memria alocada
corresponde ao tamanho da maior varivel no union. Veja o exemplo:
#include<stdio.h>
#defineGRAUS'G'
#defineRAD'R'
19
unionangulo
{
intgraus;
floatradianos;
};
voidmain()
{
unionanguloang;
charop;
printf("\nNumerosemgrausouradianos?(G/R):");
scanf("%c",&op);
if(op==GRAUS)
{
ang.graus=180;
printf("\nAngulo:%d\n",ang.graus);
}
elseif(op==RAD)
{
ang.radianos=3.1415;
printf("\nAngulo:%f\n",ang.radianos);
}
elseprintf("\nEntradainvalida!!\n");
}
Temos que tomar o maior cuidado pois poderamos fazer:
#include<stdio.h>
unionnumero
{
charCh;
intI;
floatF;
};
main(void)
{
unionnumeroN;
N.I=123;
printf("%f",N.F); /*Vaiimprimiralgoquenaoe'
necessariamente123...*/
return0;
}
20
O programa acima muito perigoso pois voc est lendo uma regio da
memria, que foi "gravada" como um inteiro, como se fosse um ponto
flutuante. Tome cuidado! O resultado pode no fazer sentido.
4. Enumeraes
Numa enumerao podemos dizer ao compilador quais os valores que uma
determinada varivel pode assumir. Sua forma geral :
enumnome_do_tipo_da_enumerao{lista_de_valores}lista_de_variveis;
enumdias_da_semana{segunda,terca,quarta,quinta,sexta,
sabado,domingo};
O programador diz ao compilador que qualquer varivel do tipo
dias_da_semana s pode ter os valores enumerados. Isto quer dizer que
poderamos fazer o seguinte programa:
#include<stdio.h>
enumdias_da_semana{segunda,terca,quarta,quinta,sexta,
sabado,domingo};
main(void)
{
enumdias_da_semanad1,d2;
d1=segunda;
d2=sexta;
if(d1==d2)
{
printf("Odiaeomesmo.");
}
else
{
printf("Sodiasdiferentes.");
}
return0;
}
Voc deve estar se perguntando como que a enumerao funciona. Simples.
O compilador pega a lista que voc fez de valores e associa, a cada um, um
nmero inteiro. Ento, ao primeiro da lista, associado o nmero zero, o
segundo ao nmero 1 e assim por diante. As variveis declaradas so ento
variveis int.
21
5. O Comando typedef
O comando typedef permite ao programador definir um novo nome para um
determinado tipo. Sua forma geral :
typedefantigo_nomenovo_nome;
Como exemplo vamos dar o nome de inteiro para o tipo int:
typedefintinteiro;
Agora podemos declarar o tipo inteiro.
O comando typedef tambm pode ser utilizado para dar nome a tipos
complexos, como as estruturas. As estruturas criadas podem ser definidas
como tipos atravs do comando typedef.
#include<stdio.h>
typedefstructtipo_endereco
{
charrua[50];
intnumero;
charbairro[20];
charcidade[30];
charsigla_estado[3];
longintCEP;
}TEndereco;
typedefstructficha_pessoal
{
charnome[50];
longinttelefone;
TEnderecoendereco;
}TFicha;
voidmain(void)
{
TFicha*ex;
...
}
Veja que no mais necessrio usar a palavra chave struct para declarar
variveis do tipo ficha pessoal. Basta agora usar o novo tipo definido TFicha.
22
Exerccios
1. Escreva um programa fazendo o uso de struct's. Voc dever criar uma
struct chamada Ponto, contendo apenas a posio x e y (inteiros) do ponto.
Declare 2 pontos, leia a posio (coordenadas x e y) de cada um e calcule a
distncia entre eles. Apresente no final a distncia entre os dois pontos.
2. Seja a seguinte struct que utilizada para descrever os produtos que esto
no estoque de uma loja :
structProduto{
charnome[30]; /*Nomedoproduto*/
intcodigo; /*Codigodoproduto*/
doublepreco; /*Precodoproduto*/
};
a) Escreva uma instruo que declare uma matriz de Produto com 10 itens de
produtos;
b) Atribua os valores "Pe de Moleque", 13205 e R$0,20 aos membros da
posio 0 e os valores "Cocada Baiana", 15202 e R$0,50 aos membros da
posio 1 da matriz anterior;
c) Faa as mudanas que forem necessrias para usar um ponteiro para
Produto ao invs de uma matriz de Produtos. Faa a alocao de memria de
forma que se possa armazenar 10 produtos na rea de memria apontada por
este ponteiro e refaa as atribuies da letra b;
d) Escreva as instrues para imprimir os campos que foram atribudos na letra
c.
3. Criar uma estrutura com 3 tipos diferentes, implementar as seguintes
situaes:
Entrada de dados:
a) Atribuio de valores;
b) Leitura de valores;
c) Atravs de uma funo.
Sada de Dados:
a) Impresso no programa principal;
b) Atravs de uma funo.
4. Para a estrutura anterior, utilizar um vetor de estrutura.
5. Ainda para a estrutura anterior, utilizar alocao dinmica.
23
Bibliografias principais:
- Apostila de Linguagem C da UFMG disponvel na internet em
http://ead1.eee.ufmg.br/cursos/C/
- SCHILDT, H. C Completo e Total. 3 ed. So Paulo: Makron Books Ltda, 1996.
827 p.
- DEITEL, H.M. & DEITEL, P.J. Como Programar em C. Rio de Janeiro: LTC Livros
Tcnicos e Cie
- Notas de aula da professora Luciana.
24