Você está na página 1de 8

Estruturas de Dados

Para se criar uma estrutura usa-se o comando struct. Sua forma geral :
struct nome_do_tipo_da_estrutura
{
tipo_1 nome_1;
tipo_2 nome_2;
...
tipo_n nome_n;
};
O nome_do_tipo_da_estrutura o nome para a estrutura. Dentro da estrutura definimos as
variveis que queremos utilizar. Quando criamos struct como se crissemos um novo tipo
dados.
Vamos criar uma estrutura de endereo:
struct tipo_endereco {
char rua [50];
int numero;
char bairro [20];
char cidade [30];
char sigla_estado [3];
long int CEP;
};
Vamos agora criar uma estrutura chamada ficha_pessoal com os dados pessoais de uma
pessoa:
struct ficha_pessoal
{
char nome [50];
long int telefone;
struct tipo_endereco endereco;
};
Vemos, pelos exemplos acima, como declarar uma estrutura e que uma estrutura pode fazer
parte de outra.
Vamos agora utilizar as estruturas declaradas na seo anterior para escrever um programa
que preencha uma ficha.
#include <stdio.h>
#include <string.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;
tipo_endereco endereco;
};
void main()
{
ficha_pessoal ficha;
strcpy(ficha.nome, "Luiz Osvaldo Silva");
ficha.telefone = 4921234;
strcpy(ficha.endereco.rua, "Rua das Flores");
ficha.endereco.numero = 10;
strcpy(ficha.endereco.bairro, "Cidade Velha");
strcpy(ficha.endereco.cidade, "Belo Horizonte");
strcpy(ficha.endereco.sigla_estado, "MG");
ficha.endereco.CEP = 31340230;
system("pause");
}
O programa declara uma varivel ficha do tipo ficha_pessoal e preenche os seus dados.
Vetores/Matrizes de estruturas
Uma estrutura como qualquer outro tipo de dado no C. Podemos, portanto, fazer vetores e
matrizes de estruturas.
Vamos ver como ficaria a declarao de um vetor de 100 fichas pessoais:
struct ficha_pessoal fichas [100]; //vetor de 100 posies
Poderamos ento acessar a segunda letra da sigla de estado da dcima terceira ficha fazendo:
fichas[12].endereco.sigla_estado[1]; //buscando a segunda letra do
vetor de char
Union
Uma declarao union determina uma nica localizao de memria onde podem estar
armazenadas variveis de tipos diferentes. A declarao de uma union semelhante
declarao de uma estrutura:
union <identificador>{
<tipo> campo_1;
<tipo> campo_2;
...
<tipo> campo_n;
};
Como exemplo, vamos considerar a seguinte unio:
union angulo{
int graus;
float radianos;
};
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 definida na estrutura da union.
Elaborar um programa que exiba o ngulo em GRAUS ou em RADIANOS dependendo da
escolha do usurio.
#include <stdio.h>
#include <stdlib.h>
#define GRAUS 'G'
#define RAD 'R'
union angulo{
int graus;
float radianos;
};
void main() {
union angulo ang;
char op;
printf("\nNumeros em graus ou radianos? ");
scanf("%c", &op);
if (op == GRAUS)
{
printf("Digite um valor inteiro: ");
scanf("%i", &ang.graus);
printf("\nAngulo: %d\n", ang.graus);
}
else
{
if (op == RAD)
{
printf("Digite um valor real: ");
scanf("%f", &ang.radianos);
printf("\nAngulo: %f\n", ang.radianos);
}
else
printf("\nEntrada invalida!!\n");
}
system("pause");
}
Temos que ter muita ateno nos tipos de dados que estamos trabalhando ao utilizar union.
Veja o exemplo abaixo:
#include <stdio.h>
#include <stdlib.h>
union numero{
char ch;
int i;
float f;
};
void main()
{
union numero n;
n.i = 123;
printf("%f\n", n.f);
system("pause");
}
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.
Enum
Uma enum (enumerao) um tipo definido pelo usurio (programador) que consiste em
constantes do tipo int nomeadas. Numa enumerao enum podemos dizer ao compilador
quais os valores que uma determinada varivel pode assumir.
Sua forma geral :
enum <identificador> {
<lista_de_valores>
};
Vamos considerar o seguinte exemplo:
enum dias_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:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
enum dias_da_semana{
segunda, terca, quarta, quinta, sexta, sabado, domingo
};
void main()
{
enum dias_da_semana d1, d2;
d1 = sexta;
d2 = segunda;
if (d1 == d2)
{
printf("O dia eh o mesmo!\n");
}
else
{
printf("Sao dias diferentes!\n");
}
system("pause");
}
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.
A palavra enum define um conjunto de nomes (cada um deles com um valor inteiro), enumera
esses nomes a partir de zero (default) ou, como no exemplo a seguir, a partir do primeiro valor
fornecido:
enum dias_semana {
domingo=1, segunda, terca, quarta, quinta, sexta, sabado
};
Posso fazer:
M1 = domingo;
M2 = terca;
No posso fazer:
M1 = fevereiro; // no pode passar item no listado no enum.
Operaes permitidas:
M3 = M2 - M1;
Constante x Enum
Um jeito tradicional de se declarar constantes em C++ o seguinte:
#define BRASIL 0
#define ITALIA 1
#define PORTUGAL 2
#define ALEMANHA 3
E eis a maneira de fazer o mesmo utilizando enum:
enum Paises{
BRASIL,
ITALIA,
PORTUGAL,
ALEMANHA
};
E declarar uma varivel desse tipo com:
enum Paises pais;
Em um enum igual a esse acima, a primeira constante recebe o valor 0 e as subsequentes
recebem o valor da constante anterior mais 1. Ou seja, BRASIL 0, ITALIA 1, PORTUGAL 2 e
ALEMANHA 3.
Podemos tambm atribuir valores manualmente s constantes como a seguir:
enum Paises{
BRASIL = 2,
ITALIA, //ITALIA igual a 3 (2 + 1)
PORTUGAL = 1,
ALEMANHA //ALEMANHA igual a 2 (1 + 1)
};
Como podemos perceber no exemplo anterior, a mesma regra se aplica para enum com
valores manuais, o que no tiver um valor explicitamente inserido receber o valor do anterior
somado em 1. Percebemos tambm que podem haver constantes com o mesmo valor (BRASIL
== ALEMANHA == 2).
Arquivos:Para trabalhar com a manipulao de arquivos, necessrio utilizarmos um ponteiro de
arquivo". Esse ponteiro ir ser utilizado como referncia na manipulao dos nossos arquivos.
Podemos declarar um ponteiro de arquivo da seguinte maneira: FILE *p;//p ser o ponteiro para
um arquivo
Fopen() Esta a funo de abertura de arquivos. Seu prottipo :
FILE *fopen (char *nome_do_arquivo, char *modo_de_abertura);
O nome_do_arquivo determina qual arquivo dever ser aberto. Este nome deve ser vlido no
sistema operacional que estiver sendo utilizado. O modo_de_abertura diz funo fopen()
que tipo de uso voc vai fazer do arquivo, podendo ser:
"r" Abre um arquivo para leitura, "r+" Abre um arquivo para leitura e escrita "rt" Abre um arquivo texto para
leitura, "rb" Abre um arquivo binrio para leitura,"r+b" Abre um arquivo binrio para leitura e escrita, "r+t" Abre
um arquivo texto para leitura e escrita
"w" Cria um arquivo para escrita ;"wt" Cria um arquivo texto para escrita, "wb" Cria um arquivo binrio para
escrita,"w+" Cria um arquivo para leitura e escrita, "w+b" Cria um arquivo binrio para leitura e escrita, "w+t" Cria
um arquivo texto para leitura e escrita
"a+" Acrescenta dados ou cria uma arquivo para leitura e escrita;"a+b" Acrescenta dados ou cria uma arquivo
binrio para leitura e escrita;"at" Acrescenta dados no fim do arquivo texto;"a+t" Acrescenta dados ou cria uma
arquivo texto para leitura e escrita
Poderamos ento, para abrir um arquivo binrio, escrever:
FILE *fp;
fp = fopen("exemplo.txt", "w+");
if (!fp)// testa se o arquivo foi aberto com sucesso.
printf("Erro na abertura do arquivo.");
Gravando/Lendo estruturas de dados em arquivos utilizaremos as funes
fread() e fwrite(). Para isso, precisamos trabalhar com arquivos binrios. A diferena aqui est no
modo de abertura do arquivo que iremos utilizar:
wb: cria um arquivo binrio para gravao. Se o arquivo j existir, limpa seu contedo e recomea a
gravao a partir do incio;
rb: abre um arquivo binrio para leitura;
rb+: abre um arquivo em modo binrio para atualizao (leitura e escrita);
ab+: abre um arquivo binrio para leitura e gravao, adicionando dados ao final do arquivo. Se o
arquivo no existir ser criado.
fwrite(&buffer, tamanho_estrutura, qtde_de_estruturas, nome_ponteiro);\\grava a struct
fread(&buffer, tamanho_estrutura, qtde_de_estruturas, nome_ponteiro); le a struct,onde:
buffer: passamos o endereo da varivel da estrutura que contm os dados que sero armazenados
no arquivo quando utilizamos fwrite e o endereo da varivel da estrutura onde queremos que as
informaes retornadas do arquivo sejam armazenadas ;
tamanho_estrutura: tamanho da estrutura de dados que ser armazenada ou recuperada.
Normalmente, utilizamos o comando sizeof() para auxiliar;
qtde_de_estuturas: quantas estruturas estamos armazenando ou recuperando por vez;
nome_ponteiro: nome do ponteiro de arquivo onde iremos armazenar ou recuperar as
informaes.
rewind()Retorna a posio corrente do arquivo para o incio. Sintaxe: rewind (nome_ponteiro);
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
struct livro
{
char titulo[50], autor[50];
int cod_livro;
float preco;
};
livro recebe_livro();
void exibe_livro(livro l);
void main()
{
livro l;
char resp;
FILE *arquivo;
arquivo = fopen("livros.dat", "ab+");
if (!(arquivo))
{
printf("Erro! Impossivel abrir o arquivo!\n");
exit(1);
}
printf("CADASTRO DE LIVROS\n");
do
{
l = recebe_livro();
if (fwrite(&l, sizeof(l), 1, arquivo) != 1)
break;
printf("\nCadastrar mais um livro?");
fflush(stdin);
scanf("%c", &resp);
} while (resp != 'n' && resp != 'N');
fclose(arquivo);
system("pause");
system("cls");
printf("LIVROS CADASTRADOS NO ARQUIVO\n");
arquivo = fopen("livros.dat", "rb");
if (!(arquivo))
{
printf("Erro! Impossivel abrir o arquivo!\n");
exit(1);
}
while (fread(&l, sizeof(l), 1, arquivo) == 1){
exibe_livro(l);
}
fclose(arquivo);
system("pause");
}
livro recebe_livro()
{
livro l;
printf("\nTitulo do livro........: ");
fflush(stdin);
gets(l.titulo);
printf("Autor do livro.........: ");
fflush(stdin);
gets(l.autor);
printf("Codigo do livro........: ");
scanf("%i", &l.cod_livro);
printf("Preco do livro.........: ");
scanf("%f", &l.preco);
return l;
}
void exibe_livro(livro l)
{
printf("\nTitulo do livro........: %s\n", l.titulo);
printf("Autor do livro.........: %s\n", l.autor);
printf("Codigo do livro........: %i\n", l.cod_livro);
printf("Preco do livro.........: %f\n", l.preco);
}
exit()
Aqui abrimos um parnteses para explicar a funo exit() cujo prottipo :
void exit(int codigo_de_retorno);
Esta funo aborta a execuo do programa. Pode ser chamada de qualquer ponto no
programa e faz com que o programa termine e retorne, para o sistema operacional, o
cdigo_de_retorno. A conveno mais usada que um programa retorne zero no caso de um
trmino normal e retorne um nmero no nulo no caso de ter ocorrido um problema.
A funo exit() se torna importante em casos como alocao dinmica e abertura de
arquivos, pois pode ser essencial que uma determinada memria seja alocada ou que um
arquivo seja aberto. Poderamos reescrever o exemplo da seo anterior usando agora o
exit() para garantir que o programa executar se o arquivo no for aberto:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
int abre_arquivo(FILE *fp);
void main()
{
FILE *fp=0;
int retorno;
retorno = abre_arquivo(fp);
if (retorno == 0)
printf("Arquivo aberto com sucesso!\n");
else
printf("Erro na abertura do arquivo!\n");
system("pause");
}
int abre_arquivo(FILE *fp)
{
fp = fopen("exemplo.txt", "w+");
if (!fp)
exit(1);
return 0;
}
Quando abrimos um arquivo devemos fech-lo. Para tanto devemos usar a funo fclose():
fclose(<ponteiro_arquivo>);
importante que se perceba que se deve tomar o maior cuidado para no "perder" o ponteiro
do arquivo. "Perder" neste caso seria atribuir um valor de um outro ponteiro qualquer ao
ponteiro de arquivo (perdendo assim o valor original). utilizando este ponteiro que vamos
poder trabalhar com o arquivo. Se perdermos o ponteiro de um determinado arquivo no
poderemos nem fech-lo. O ponteiro p passado funo fclose() determina o arquivo a ser
fechado. A funo retorna zero no caso de sucesso.
feof()
feof ("File End Of file") indica o fim de um arquivo. s vezes, necessrio verificar se um
arquivo chegou ao fim. Para isto podemos usar a funo feof(). Ela retorna no-zero se o
arquivo chegou ao EOF, caso contrrio retorna zero.
feof (<nome_ponteiro_arquivo>);
Toda vez que estamos trabalhando com arquivos, h uma espcie de posio atual no arquivo.
Esta posio, gerenciada pelo compilador, a posio de onde ser lido ou escrito o prximo
caracter. Normalmente, num acesso sequencial a um arquivo, no temos que mexer nesta
posio, pois quando lemos um caractere a posio no arquivo automaticamente atualizada.
fputc()
Escreve um caracter no arquivo:
fputc(<caracter>, <nome_ponteiro_arquivo>);
fgetc()
Retorna um caracter lido do arquivo:
fgetc (<nome_ponteiro_arquivo>);
fprintf()
A funo fputc permite gravar apenas caracteres de um arquivo.
Para gravar outros tipos de dados, devemos usar a funo fprintf(). Essa funo muito
semelhante funo printf() que sempre trabalhamos. A diferena agora que precisamos
especificar o arquivo onde os dados sero gravados.
fprintf(<nome_ponteiro_arquivo>, <%tipo_informacao>, <informacao>);
Exemplo
A seguir apresentado um programa onde vrias operaes com arquivos so realizadas.
Primeiro o arquivo aberto para a escrita, e imprime-se algo nele. Em seguida, o arquivo
fechado e novamente aberto para a leitura. Verifique o exemplo:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
FILE *p;
char c, str[30], frase[80] = "Este e um arquivo chamado: ";
int i;
/* Le nome e extensao para o arquivo a ser aberto: */
printf("\n\nEntre com nome.extensao para o arquivo: ");
gets(str);
/* Caso ocorra algum erro na abertura do arquivo
o programa aborta automaticamente */
if (!(p = fopen(str, "w")))
{
printf("Erro! Impossivel abrir o arquivo!\n");
exit(1);
}
/* Se nao houve erro, imprime no arquivo e depois o fecha...*/
strcat(frase, str);
for (i = 0; frase[i] != '\0'; i++)
fputc(frase[i], p);
fclose(p);
/* abre novamente para a leitura e imprime na tela
o texto do arquivo. */
p = fopen(str, "r");
while (!feof(p))
{
c = fgetc(p);
printf("%c", c);
}
/* fecha novamente o arquivo aberto*/
fclose(p);
printf("\n");
system("pause");
}

Você também pode gostar