You are on page 1of 104

Programao 2

Snia Virginia Alves Frana

Recife, 2009

Universidade Federal Rural de Pernambuco


Reitor: Prof. Valmar Corra de Andrade
Vice-Reitor: Prof. Reginaldo Barros
Pr-Reitor de Administrao: Prof. Francisco Fernando Ramos Carvalho
Pr-Reitor de Extenso: Prof. Paulo Donizeti Siepierski
Pr-Reitor de Pesquisa e Ps-Graduao: Prof. Fernando Jos Freire
Pr-Reitor de Planejamento: Prof. Rinaldo Luiz Caraciolo Ferreira
Pr-Reitora de Ensino de Graduao: Prof. Maria Jos de Sena
Coordenao de Ensino a Distncia: Prof Marizete Silva Santos
Produo Grfica e Editorial
Capa e Editorao: Allyson Vila Nova, Rafael Lira, Italo Amorim e Marcella Almeida
Reviso Ortogrfica: Marcelo Melo
Ilustraes: Diego Almeida e Glaydson da Silva
Coordenao de Produo: Marizete Silva Santos

Sumrio
Apresentao.........................................................................................5
Conhecendo o Volume 3.......................................................................6
Captulo 1 Armazenamento de Dados em Vetores..........................8
1.1 O que so vetores?.......................................................................8
1.2 Declarao de Vetores..................................................................9
1.3 Referncia a elementos de vetor................................................. 11
1.4 Inicializao de vetores...............................................................13
1.5 Leitura de elementos para o vetor...............................................15
1.6 Impresso dos elementos de um vetor........................................22
1.7 Tamanho de um vetor e segmentao de memria....................27
1.8 Passando vetores como parmetros de funes........................28
Captulo 2 Armazenamento de Dados em Registros.....................35
2.1 O que so registros?...................................................................35
2.2 Declarao de um Registro.........................................................36
2.3 Acessando os campos do registro...............................................39
2.4 Vetor de registro..........................................................................40
2.5 Acessando os campos do vetor de registro.................................42
2.6 Usando vetor de registro.............................................................43

Captulo 3 Armazenamento de Dados em Arquivos......................61


3.1 O que so arquivos?....................................................................61
3.2 Comandos para manipular arquivos binrios..............................64
3.3 Implementao das operaes bsicas em um arquivo..............76
Consideraes Finais........................................................................102
Conhecendo a Autora........................................................................104

Apresentao
Caro(a) aluno(a),
Seja bem-vindo (a) ao terceiro mdulo da disciplina Programao II. Neste mdulo,
vamos dar mais um passo no nosso aprendizado sobre a linguagem de programao
C.
Nos dois volumes anteriores, aprendemos os comandos bsicos do C, a utilizar
as estruturas de controle (seleo e repetio) e a modularizar nossos programas em
mdulos ou funes. Com estes assuntos, adquirimos a capacidade de desenvolver
programas mais elaborados.
Neste livro, ns vamos aprender novas formas de armazenar nossos dados. Com os
vetores e registros, poderemos manusear um volume maior de dados, de forma facilitada.
Outro assunto muito importante que ser abordado neste volume o armazenamento de
dados em arquivos. Atualmente, ao terminar a execuo do programa, todos os dados
que foram digitados so perdidos. Com o armazenamento de dados em arquivos, isto
no acontece. Assim, iremos desenvolver programas com operaes como: cadastro de
elementos, remoo, alterao, consultas, listagens, etc.
Continuem resolvendo as questes propostas no final de cada captulo, alm de
executar buscas na Internet, visando um maior aprofundamento de cada assunto. Ao final
deste mdulo, teremos a capacidade de resolver questes com operaes presentes
nos principais sistemas de controle do mercado, como por exemplo: sistema de controle
de estoque, sistema de controle de cliente, etc. Vamos comear mais uma nova etapa
no conhecimento da linguagem de programao C?
Bons estudos!
Professora Snia Virginia Alves Frana

Programao 2

Conhecendo o Volume 3
Neste terceiro volume, vocs iro encontrar o mdulo 03 da
disciplina: Programao II. Este volume est estruturado em trs
captulos, que sero estudados ao longo de 15h/aula. Para facilitar
seus estudos, veja a organizao deste volume.
Captulo 1: Armazenamento de Dados em Vetores
Carga Horria do Captulo 1: 5 h/aula
Objetivos do Captulo 1: Apresentar o uso de vetores para o
armazenamento de dados.
Contedo Programtico do Captulo 1
Definio de vetores;
Declarao, leitura e escrita de dados em vetores;
Passagem de vetores como parmetros de funes;
Captulo 2: Armazenamento de Dados em Registros
Carga Horria do Captulo 2: 5 h/aula
Objetivos do Captulo 2: Apresentar o uso de registros para o
armazenamento de dados.
Contedo Programtico do Captulo 2
Definio de registros;
Declarao, leitura e escrita de dados em registros;
Vetor de registro;
Captulo 3: Armazenamento de Dados em Arquivos
Carga Horria do Captulo 3: 5 h/aula
Objetivos do Captulo 3: Apresentar os principais comandos para
o armazenamento de dados em arquivos. Com os arquivos, os dados
manipulados no programa podem ser armazenados definitivamente.
Contedo Programtico do Captulo 3
Definio de arquivos;
6

Programao 2

Ponteiros;
Comandos para manipulao de dados em arquivos;
Ao final de cada captulo vocs encontraro:
A seo Atividades e Orientaes de Estudo: que contm
exerccios para a fixao do assunto estudado, alm de
indicao de fruns de discusso.
A seo Conhea Mais: que contm dicas de sites e livros
que devem ser lidos para ampliar os seus conhecimentos.
A seo Vamos Revisar?: que apresenta um resumo dos
principais tpicos abordados no captulo.

Programao 2

Captulo 1 Armazenamento de
Dados em Vetores
Vamos conversar sobre o assunto?
Neste terceiro volume, vamos aprender novas formas de armazenar
nossos dados. Comearemos aprendendo como armazenar os dados
em vetores. Com os vetores, ns podemos armazenar um grande
conjunto de dados, facilitando o acesso e manuseio dos mesmos. Os
dados so a alma de um programa. Assim, a manipulao dos dados
de forma mais adequada e facilitada, trar ganhos para o programa e
para o programador. Vamos continuar a nossa caminhada?

1.1 O que so vetores?


Imaginem que um professor nos encomendou um programa, que
tenha que armazenar as mdias dos 50 alunos de uma turma. Como
faramos para armazenar essas mdias? At o ponto que estudamos
a linguagem C, teramos que declarar 50 variveis do tipo float, uma
por uma. Que trabalheira, no mesmo? E se o professor tivesse 300
alunos? Passaramos um tempo s declarando variveis e, alm
disso, teramos muito trabalho para fazer o controle das mesmas.
Mas no se preocupem, com os vetores, o professor pode ter mais de
1000 alunos, que a declarao e manuseio dos dados ser bem fcil.
Saiba Mais
Em ingls, um
vetor chamado
de array (que
significa cadeia).
Assim, quando
temos um array,
temos uma cadeia
de inteiros, reais
ou caracteres.
1

Os vetores so usados quando precisamos armazenar um conjunto


de dados do mesmo tipo. Por exemplo: armazenar as 50 mdias dos
alunos de uma turma (todas as mdias so do tipo float). Os vetores
so bem convenientes j que iremos colocar todas as informaes
dentro de um mesmo conjunto e faremos referncia de cada dado,
individualmente, atravs de um ndice1. De maneira mais formal, os
vetores so chamados de estruturas de dados homogneas (j
que armazenam dados do mesmo tipo). Os vetores so formados
por dados de mesmo tipo (homogneo) e possuem nmero fixo de
elementos (esttico).
Para entendermos melhor os vetores, vamos visualizar a sua
representao grfica, na figura 1.1.

Programao 2

media

3.0

7.5

5.8

9.5

8.2

Figura 1.1: Representao grfica de um vetor

Na figura 1.1 temos um vetor chamado media, formado por 5


elementos. Vocs lembram quando tnhamos uma varivel simples?
Representvamos com uma nica caixa. Agora, com os vetores,
teremos um conjunto de dados, por isso ele formado por vrias
caixas. Em cada uma delas poderemos armazenar um valor. Todas as
caixas tm um nico nome. Neste exemplo, o vetor se chama media.
Notem que, abaixo de cada caixa temos um nmero. Estes nmeros
so chamados de ndices. atravs do ndice, que iremos informar
qual das caixas do vetor que estamos querendo acessar. J que
todas as caixas tm um nico nome (media), a forma de diferenciar
uma da outra o ndice. Entenderam?
Na linguagem C, o ndice de um vetor, comea a partir de 0. Assim,
em um vetor com 5 elementos, os ndices variam de 0 a 4 (como no
exemplo da figura 1.1). Por isso, o primeiro elemento do vetor media
est na posio de ndice 0. Podemos dizer que a mdia do segundo
aluno est na posio de ndice 1 do vetor media, e igual a 7.5.
Esta no a nica maneira de estruturar um conjunto de dados.
Tambm podemos organizar dados sob forma de tabelas. Neste caso,
cada dado referenciado por dois ndices e dizemos que se trata de
um conjunto bidimensional (ou matriz).
Vamos aprender, nas prximas sees, como manusear os vetores
nos nossos programas.

1.2 Declarao de Vetores


Como j foi mencionado, um vetor um conjunto de variveis
do mesmo tipo, que possuem um nome identificador e um ndice de
referncia. A sintaxe para a declarao de um vetor a seguinte:
Sintaxe

tipo identificador[tamanho];

Programao 2

onde:
tipo: o tipo de dados que o vetor armazena: int, float, char,
etc.
identificador: o nome do vetor. As regras para nomear um
vetor so as mesmas usadas para nomear variveis, constantes
e funes.
tamanho: o tamanho do vetor. Isto , o nmero de elementos
que o vetor pode armazenar.
A seguir, so apresentados exemplos de declaraes de vetores.
Os vetores so declarados na seo de declarao de variveis do
programa. Se estivermos desenvolvendo um programa modularizado,
podemos declarar o vetor como uma varivel local de um mdulo.
Exemplo 1.1: declarao de vetores

Ateno
2
Ns j havamos
utilizado vetor
de caracteres, j
que trabalhamos
com variveis
que armazenam
uma cadeia de
caracteres. No
prximo volume,
teremos um
captulo dedicado
a este assunto.

int idade[100];

float nota[25];

char nome[80];

No primeiro exemplo, temos a declarao de um vetor chamado


idade, que pode armazenar at 100 nmeros inteiros. No segundo
exemplo, temos um vetor chamado nota, com capacidade para
armazenar at 25 nmeros reais. E, finalmente, no terceiro exemplo,
temos um vetor chamado nome, com capacidade de armazenar at
80 caracteres2.
Ao declararmos o vetor, j temos que ter uma previso de quantos
elementos sero armazenados no mesmo. Com isso, o processador
saber quanto de memria precisa ser reservada para armazenar os
dados do vetor, ao executar o programa. A quantidade de memria
(em bytes) usada para armazenar um vetor pode ser calculada como:
quantidade de memria = tamanho do tipo * tamanho do vetor

O tamanho do tipo indica quantos bytes um determinado tipo de


varivel utiliza para ser armazenado (vimos este assunto no Volume
1 Captulo 3). Ao compilar o programa, a quantidade de memria
necessria para armazenar o vetor alocada. Os vetores tm
tamanhos fixos e no podemos armazenar mais elementos do que a
quantidade que foi solicitada no momento da declarao do vetor. Por
10

Programao 2

isso, so chamados de estticos. A quantidade de elementos no


pode aumentar em tempo de execuo do programa.
Tambm possvel declarar um vetor com tamanho parametrizado:
usando uma constante. Declaramos uma constante com a diretiva
#define, no incio do programa, e depois declaramos o vetor com
esta constante como tamanho do vetor. Deste modo, podemos alterar
o nmero de elementos do vetor antes de qualquer compilao do
programa. Esta uma maneira simples de administrar o espao de
memria usado pelo programa, e tambm testar os limites de um
vetor.
Exemplo 1.2:
Declarao de vetor usando uma constante no local do tamanho do vetor.

#define TAMANHO 30

int valor[TAMANHO];

No exemplo 1.2, o vetor valor ter capacidade de armazenar 30


elementos (este o valor da constante TAMANHO).

1.3 Referncia a elementos de vetor


Agora que j sabemos como criar os vetores, a partir da sua
declarao, vamos aprender como acessar um elemento do vetor.
Segue abaixo a sintaxe.
Sintaxe

identificador[indice]

onde:
identificador: o nome do vetor que queremos acessar.
ndice: o ndice do elemento do vetor que queremos acessar.
Cada elemento do vetor referenciado pelo nome do vetor e,
entre colchetes, tem-se o ndice, que um nmero inteiro. O ndice
ir indicar qual elemento do vetor estamos querendo referenciar. A
seguir, so apresentadas algumas atribuies a elementos de um
vetor chamado valor, que composto por 10 elementos do tipo float.

11

Programao 2

Exemplo 1.3: Acessando os elementos de um vetor

float valor[10];

//declarao do vetor

int x;

x = 3;

valor[1] = 6.6;

valor[x] = 9.9

valor[x+2] = 10.0;

Entre os colchetes, que indicam o ndice do vetor que ser


acessado, podemos ter: um valor (exemplo da linha 4), uma varivel
(exemplo da linha 5) ou uma expresso (exemplo da linha 6).
Devemos ter cuidado quando usamos variveis e expresses, pois
estas devem ser inteiras e devem ter um valor dentro da capacidade
de armazenamento do vetor. Ou seja, se o vetor foi declarado com
tamanho 10, no podemos tentar acessar o ndice 18 do vetor.
Na linha 4, foi atribudo 6.6 ao elemento de ndice 1 do vetor valor.
Na linha 5, como a varivel x tem armazenado 3, ento o valor[3],
receber 9.9. Quando temos uma expresso, que o caso da linha
6, a expresso resolvida primeiro. Assim, como x = 3, e entre os
colchetes temos x+2, o resultado ser 5. Dessa forma, valor[5]
receber 10.0. A seguir, temos a situao final do vetor valor, aps as
atribuies dos valores do exemplo.
Valor

6.6
0

9.9
2

10.0
4

Figura 1.2: Situao do vetor valor aps atribuies

Viram como fcil trabalhar com vetor? Em uma nica linha, ns


criamos um conjunto de variveis, do tamanho da nossa necessidade.
Posteriormente, acessamos cada uma destas variveis utilizando o
nome do vetor e o ndice da varivel.
Na prxima seo, vamos ver como fazemos para inicializar os
elementos de um vetor, no momento da declarao.

12

Programao 2

1.4 Inicializao de vetores


No momento da declarao de um vetor, tambm podemos
inicializar os seus elementos, fazendo a atribuio de valores aos
mesmos. A sintaxe para a inicializao dos elementos de um vetor
a seguinte:
Sintaxe

tipo identificador[tamanho] = {lista de valores};

Onde:
tipo: o tipo dos elementos do vetor: int, float, char, etc.
identificador: o nome do vetor.
tamanho: o tamanho do vetor. Isto , o nmero de elementos
que o vetor pode armazenar.
lista de valores: uma lista, separada por vrgulas, dos valores
de cada elemento do vetor. A lista de valores colocada entre
chaves.
Vamos ver a seguir, exemplos de inicializao de vetores.
Exemplo 1.4: Inicializao de vetores

int idade[7] = {12, 30, 14, 7, 13, 15, 6};

char vogal[5] = {a, e, i, o, u};

float nota[5] = {8.4, 6.9, 4.5};

float media[5] = {0};

No exemplo da linha 1, temos o vetor chamado idade e para cada


posio do vetor, foi atribudo um valor. Aps esta atribuio, o vetor
idade ficar assim:
idade

12

30

57

25

18

15

13

Figura 1.3: Situao do vetor idade aps inicializao

No segundo exemplo, temos um vetor de caracteres, chamado


vogal. Quando inicializamos um vetor deste tipo de varivel, os valores
13

Programao 2

devem ser colocados entre apstrofo. Ao final desta atribuio, o vetor


vogal ficar como mostra a figura 1.4.
vogal

Figura 1.4: Situao do vetor idade aps inicializao

Na linha 3, temos a inicializao do vetor nota, que composto


por cinco elementos. Notem que, entre as chaves, no temos cinco
valores. Temos apenas trs. Quando no quisermos inicializar todo o
vetor, podemos colocar apenas os valores dos primeiros elementos, e
aos demais, ser atribudo zero (automaticamente). Vejam na figura
1.5 como ficar o vetor nota, aps a sua inicializao.
nota

8.4

6.9

4.5

0.0

0.0

Figura 1.5: Situao do vetor idade aps inicializao

Seguindo o raciocnio do exemplo anterior, quando precisarmos


inicializar todos os elementos do vetor com zero, fazemos como
mostra o exemplo da linha 4. Colocamos apenas um zero entre as
chaves, o primeiro elemento ser inicializado com zero, e os demais
tambm. Neste caso, o vetor media ficar como apresentado na figura
1.6.
media

0.0

0.0

0.0

0.0

0.0

Figura 1.6: Situao do vetor media aps inicializao

Opcionalmente, podemos inicializar os elementos do vetor


enumerando-os um a um. No exemplo 1.5, a seguir, observem que
estas duas inicializaes so possveis:

14

Programao 2

Exemplo 1.5: Inicializao de vetores

int valor[3] = {7,4,20};

ou

int valor[3];

valor[0] = 7;

valor[1] = 4;

valor[2] = 20;

Na prxima seo, vamos aprender a armazenar, em um vetor,


valores que so fornecidos via teclado.

1.5 Leitura de elementos para o vetor


Agora suponham que os valores que vo ser armazenados no
vetor sejam fornecidos pelo usurio, via teclado. O que devemos
fazer? Devemos utilizar uma estrutura de repetio, para controlar o
preenchimento dos dados no vetor, um por um. Assim, podem ocorrer
duas situaes:
Ns sabemos quantos elementos o usurio vai digitar;
Ns no sabemos a quantidade de elementos que o usurio
vai digitar.
Vamos ver como tratar cada uma das situaes? Quando ns
sabemos quantos elementos o usurio vai digitar, poderemos usar
uma estrutura de repetio como o for, que ir repetir a leitura dos
elementos, na quantidade definida. Vamos ver o Programa Completo
1.1 a seguir: o usurio precisa armazenar 5 elementos em um vetor
de inteiros, chamado valor.

15

Programao 2

Programa Completo 1.1:


Ler 5 nmeros inteiros, armazenando-os em um vetor

main()

int valor[5];

int i;
printf(Cadastro dos elementos do vetor Valor
\n\n);

5
6

for (i=0; i<5; i++)

printf(\n\nElemento %d: ,i+1);

scanf(%d,&valor[i]);

10

getche();

11

Comentrios sobre o Programa Completo 1.1:


Linha 3: declarao do vetor valor, que tem a capacidade de
armazenar 5 nmeros inteiros.
Linha 4: declarao da varivel i, que ir controlar o for.
Linha 5: printf para que o usurio saiba que ser feito o cadastro
dos elementos no vetor.
Linha 6: for que ser repetido 5 vezes, fazendo a leitura dos
elementos do vetor. Notem que a varivel de controle do for, o i,
inicializado com 0. Isso acontece porque o primeiro ndice do
vetor 0.
Linha 7: Abre chaves que inicia a sequncia de comandos
do for (j que teremos mais de um comando). Nesta linha,
tambm temos o printf para que o usurio saiba qual elemento
do vetor est sendo cadastrado no momento. Vejam que neste
printf temos a expresso: i+1. O motivo de colocarmos esta
expresso no printf que, como o i comea com zero e vai at
4, no ficaria muito interessante que sasse uma mensagem, na
tela, informando que o usurio estaria cadastrando o elemento
0. O correto dizer que ele est cadastrando o elemento 1. Por
16

Programao 2

isso, usamos a expresso i+1.


Linha 8: scanf que l o valor, armazenando no vetor. Notem
que estamos usando a varivel i, no ndice do vetor. Dessa
forma, o i vai variando a cada vez que o for repetido, e assim,
os elementos so armazenados em ndices diferentes do vetor.
Com isso, nenhum elemento ir sobrepor o outro.
Linha 9: fecha chaves que indica o final da sequncia de
comandos do for.
Linha 10: comando getche que faz com que a tela de execuo
do programa fique aberta, e assim podemos ver o resultado do
programa.
Linha 11: fecha chaves, indicando o final do programa
principal.
A figura 1.7, apresenta a tela de execuo do Programa Completo
1.1.

Figura 1.7: Tela de execuo do Programa Completo 1.1

Para facilitar o entendimento, vamos fazer um acompanhamento


dos valores das variveis do Programa Completo 1.1, ao longo da
sua execuo. Vamos considerar que o usurio est cadastrando os
valores apresentados na figura 1.7. A figura 1.8 mostra os valores das
variveis do programa, conforme o programa vai sendo executado.

17

Programao 2

i+1

valor
10

10

15

10

15

10

15

10

15

12

Figura 1.8: Acompanhamento das variveis do Programa Completo 1.1

O que fazemos quando no sabemos quantos elementos sero


armazenados no vetor? Neste caso, como no sabemos quantas
vezes o for deve ser executado, poderemos fazer a leitura dos dados
que sero colocados no vetor, usando um do/while, como mostra o
Programa Completo 1.2, a seguir. Neste programa, iremos fazer
a leitura de uma quantidade indeterminada de nmeros inteiros,
armazenando em um vetor.

18

Programao 2

Programa Completo 1.2:


Ler um conjunto de nmeros inteiros, armazenando-os em um vetor.

main()

{ int valor[5];

int q, continuar;

q=0;
printf(Cadastro dos elementos do vetor Valor
\n\n);

5
6

do

printf(\n\nElemento %d: ,q+1);

scanf(%d,&valor[q]);

q++;

10


printf(\n\nCadastrar
(1-sim/2-nao)? );

outro

11

12

} while ((continuar==1) && (q<5));

13

elemento

scanf(%d, &continuar);

Neste caso, a leitura ser finalizada quando o vetor ficar cheio,


com cinco elementos, ou quando o usurio decidir que no deseja
mais continuar a leitura. Neste ltimo caso, saberemos quantos
elementos foram armazenados no vetor atravs da varivel q. esta
varivel que indica, tambm, em qual ndice do vetor o elemento deve
ser armazenado3.
Comentrios sobre o Programa Completo 1.2:
Linhas 2: declarao do vetor valor, que tem a capacidade de
armazenar 5 nmeros inteiros.
Linha 3: declarao das variveis q (que controla a quantidade
de elementos que j foram cadastrados no vetor) e continuar
(que armazena a resposta do usurio informando se quer
cadastrar mais elementos ou no).
Linha 4: inicializao da varivel q com 0.
Linha 5: printf para que o usurio saiba que ser feito o cadastro
19

Ateno
3
Quando no
sabemos quantos
elementos sero
cadastrados,
temos que
estipular um valor
para a quantidade
de elementos
que sero
armazenados no
vetor. Isso se d
porque temos que
saber o tamanho
do vetor no
momento da sua
declarao.

Programao 2

dos elementos no vetor.


Linha 6: do indicando o incio da repetio.
Linha 7: Abre chaves que inicia a sequncia de comandos do
do/while (j que teremos mais de um comando). Nesta linha
tambm temos o printf para que o usurio saiba qual elemento
do vetor est sendo cadastrado no momento.
Linha 8: scanf que l o valor que ser armazenado no vetor.
Notem que estamos usando a varivel q, no ndice do vetor.
Linha 9: incremento da varivel q, indicando que mais um
elemento foi cadastrado no vetor. Atravs do valor de q,
saberemos se o vetor j est cheio ou no.
Linha 10: prinft que pergunta ao usurio se deseja cadastrar
outro elemento no vetor. O usurio pode parar o cadastro dos
elemento do vetor, no momento que ele desejar. Nesse caso, o
vetor pode ficar com posies sem valores armazenados.
Linha 11: scanf para ler a resposta do usurio.
Linha 12: fecha chaves do do/while e while com a condio
que faz com que a repetio fique sendo executada. Como
a condio formada por duas expresses relacionais, ns
colocamos cada expresso relacional entre parnteses e depois
colocamos toda a expresso entre parnteses. As expresses
esto conectadas pelo operador && (e). Com isso, quando uma
das expresses der falso, a repetio para. Vai parar porque
o vetor est cheio (q=5) ou porque o usurio desejou parar,
respondendo 2 a pergunta se deseja continuar.
Linha 13: fecha chaves, indicando o final do programa
principal.
A figura 1.9, apresenta a tela de execuo do Programa Completo
1.2.

20

Programao 2

Figura 1.9: Tela de execuo do Programa Completo 1.2

Vamos acompanhar o valor das variveis do Programa Completo


1.2? A Figura 1.9 mostra o cadastramento de 3 elementos no vetor. O
usurio respondeu que no queria mais cadastrar aps dar entrada
ao terceiro elemento. A figura 1.10 mostra os valores das variveis do
programa, conforme o programa vai sendo executado.
q

q+1

valor
12

12

15

12

15

18

Figura 1.10: Acompanhamento das variveis do Programa Completo 1.2

Agora que j sabemos colocar informaes em um vetor via


teclado, vamos ver como apresentar, na tela, os valores armazenados
em um vetor.

21

Programao 2

1.6 Impresso dos elementos de um vetor


Quando desejarmos apresentar os elementos que esto
armazenados no vetor, devemos utilizar uma estrutura de repetio,
que far com que cada uma das posies do vetor seja visitada e
seu contedo apresentado. Vale lembrar que, quando declaramos um
vetor, indicamos a sua capacidade de armazenamento. Mas durante a
execuo do programa, pode ser que o usurio no armazene dados
suficiente para preencher todas as posies do vetor. Assim, quando
formos imprimir os dados de um vetor, precisamos saber quantos
elementos tm armazenado no momento da impresso. O Programa
Completo 1.3, mostra a leitura e a impresso dos dados armazenados
em um vetor.
Programa Completo 1.3: Ler e imprimir um conjunto de nmeros inteiros,
armazenando-os em um vetor.

main()

{ int valor[5];

int q, continuar, i;

q=0;

printf(Cadastro dos elementos do vetor Valor


\n\n);

do

printf(\n\nElemento %d: ,q+1);

scanf(%d,&valor[q]);

q++;

10


printf(\n\nCadastrar
(1-sim/2-nao)? );

outro

11

scanf(%d, &continuar);

12

} while ((continuar==1) && (q<5));

13

printf(\n\nElementos do Vetor: );

14

for (i=0; i<q; i++)

15

16

getche();

17

printf( %d ,valor[i]);

22

elemento

Programao 2

At a linha 12, o Programa Completo 1.3 , praticamente, idntico


ao Programa Completo 1.2. A nica diferena que temos, na linha
3, a declarao da varivel i, que ser usada no for que imprimir os
elementos do vetor. Vamos ver o que est acontecendo nas demais
linhas?
Linha 13: printf para informar que sero apresentados os
elementos do vetor. Notem que o texto entre aspas no termina
com \n. Isso se d porque no queremos que o cursor v para
a linha seguinte.
Linha 14: for que ser utilizado para percorrer o vetor,
acessando cada uma das posies do vetor. A varivel que tem
a informao de quantos elementos foram armazenados no
vetor q. Dessa forma, o i do for vai variar de 0 at q-1. Uma
vez que se q for 3, a ltima posio ocupada no vetor 2.
Linha 15: printf que apresenta o elemento do vetor, na posio
de ndice i. Este printf tambm no tem o \n, porque queremos
que os elementos do vetor sejam impressos um ao lado do
outro. Este o nico comando do for, por isso no houve a
necessidade de delimitar com chaves.
Linha 16: getche que evita o fechamento da janela de execuo
do programa, e assim poderemos ver os elementos do vetor
impresso.
Linha 17: fecha chaves, indicando o final do programa
principal.
A figura 1.11 apresenta a tela de execuo do programa 1.3. Foram
cadastrados os mesmos valores do exemplo anterior.

23

Programao 2

Figura 1.11: Tela de execuo do Programa Completo 1.3

Neste caso, apesar do vetor ter sido declarado com 5 posies, s


foram preenchidas 3 posies. Vejam que, aps o usurio responder
que no quer mais cadastrar, os elementos do vetor so apresentados
um ao lado do outro.
Vamos ver outro Programa Completo? Neste programa iremos
ler as matrculas e notas dos alunos de uma turma e imprimir as
matrculas dos alunos de tiveram nota acima da mdia das notas da
turma.
Programa Completo 1.4

main()

{ int mat[10];

float nota[10];

int q, i, continuar;

float soma, media;

soma = 0;

q=0;

do

10

system(cls);


printf(Universidade Aberta do Brasil UFRPE\n\n);

24

Programao 2

11


q+1);

printf(\n\nDados

do

Alunos

12

printf(\nMatricula: );

13

scanf(%d,&mat[q]);

14

printf(\nNota: );

15

scanf(%f,&nota[q]);

16

soma = soma + nota[q];

17

q++;

18


);

19

20

} while ((continuar==1) && (q<10));

21

media = soma/q;

22

system(cls);

%d\n\n,

printf(\n\nCadastrar outro(1-sim/2-nao)?
scanf(%d, &continuar);

23

printf(Universidade Aberta do Brasil - UFRPE


\n\n);

24

printf(Media da turma: %.2f\n\n\n,media);

25

printf(Alunos
turma\n\n);

com

26

for (i=0; i<q; i++)

27

28

29

30

nota

acima

da

media

da

if (nota[i]>media)
printf(%d \n,mat[i]);

printf(\n\nDigite
);

31

getche();

32

qualquer

tecla

para

sair

Comentrios sobre o Programa Completo 1.4:


Linhas 2 a 5: declarao das variveis do programa. Vejam
que precisamos de um vetor para armazenar as matrculas e
um outro para armazenar as notas.
25

Programao 2

Linhas 6 e 7: inicializao das variveis soma (que acumula as


notas de todos os alunos) e q (que conta quantos elementos
foram cadastrados no vetor).
Linhas 8 a 20: do/while que faz a leitura das matrculas e das
notas de cada aluno, armazenando nos respectivos vetores.
Neste do/while, o usurio pode parar o cadastro no momento
que ele desejar. Para calcularmos a mdia da turma, temos que
somar as notas de todos os alunos e dividir pela quantidade
de alunos. Assim, enquanto estivermos no do/while, estamos
acumulando as notas de todos os alunos na varivel soma.
Linha 21: ao sair do do/while, a mdia da turma pode ser
calculada.
Linha 22: usa o system(cls) para limpar a tela e dar incio a
tela que ir apresentar os resultados.
Linha 24: printf para apresentar a mdia da turma.
Linhas 26 a 29: for para visitar cada posio do vetor que
armazena as notas dos alunos. Quando verifica que a nota do
aluno maior que a mdia da turma (armazenada na varivel
media), a matrcula do aluno apresentada.
A figura 1.12 apresenta a tela de execuo do programa 1.4, na
fase do cadastramento dos dados dos alunos (matrcula e nota).

Figura 1.12: Tela de Execuo do Programa Completo 1.4 Cadastro de Alunos

A figura 1.13 apresenta a tela de execuo do programa completo


1.4, na fase do apresentao dos resultados.

26

Programao 2

Figura 1.13: Tela de Execuo do Programa Completo 1.4 Apresentao dos Resultados

1.7 Tamanho de um vetor e segmentao de


memria
Na linguagem C, devemos ter cuidado com os limites de um vetor.
Embora na declarao tenhamos que definir o tamanho de um vetor,
o C no faz nenhum teste de verificao de acesso a um elemento
dentro do vetor ou no.
Por exemplo, se declaramos um vetor como int valor[5],
teoricamente, s tem sentido usarmos os elementos valor[0], valor[1],
valor[2] , valor[3] e valor[4]. Porm, o C no acusa erro se usarmos
valor[12] em algum lugar do programa. Estes testes de limite devem
ser feitos dentro do programa, pelo programador.
Este fato se deve maneira como o C trata os vetores. A memria
do computador um espao (fsico) particionado em pores de 1
byte. Se declararmos um vetor como int valor[3], estamos reservando
12 bytes (3 segmentos de 4 bytes lembrando que cada int ocupa
4 bytes) de memria para armazenar os seus elementos. O primeiro
segmento ser reservado para valor[0], o segundo segmento para
valor[1] e o terceiro segmento para valor[2]. O segmento inicial
chamado de segmento base, de modo que valor[0] ser localizado no
segmento base. Quando acessamos o elemento valor[i], o processador
acessa o segmento localizado em base+i. Se i for igual a 2, estamos
acessando o segmento base+2 ou valor[2] (o ltimo segmento
reservado para o vetor). Porm, se i for igual a 7, estamos acessando
o segmento base+7 que no foi reservado para os elementos do vetor
e que provavelmente est sendo usado por uma outra varivel ou
contm uma informao inesperada (lixo).
27

Programao 2

Observem que o acesso a um segmento fora do espao destinado


a um vetor pode destruir informaes reservadas de outras variveis.
Estes erros so difceis de detectar, pois o compilador no gera
nenhuma mensagem de erro. Por isso, a soluo mais adequada
sempre avaliar os limites de um vetor antes de manipul-lo. Como
feito no Programa Completo 1.2 que vai cadastrando os elementos no
vetor e para quando o vetor completa a sua capacidade.
A princpio, este fato poderia parecer um defeito da linguagem,
mas na verdade trata-se de um recurso muito poderoso do C. Poder
manipular sem restries todos os segmentos de memria uma
flexibilidade apreciada por programadores mais experientes.

1.8 Passando vetores como parmetros de


funes
Os vetores, assim como as variveis simples, podem ser usados
como argumentos de funes. Veremos como se declara uma funo
que recebe um vetor como parmetro e como se chama uma funo
passando um vetor como parmetro.
A sintaxe de uma funo que recebe um vetor como parmetro a
seguinte:
Sintaxe

tipo_retorno nome_funo(tipo_vetor nome_vetor[])


{
//corpo da funo
}

Onde:
tipo_retorno: o tipo de retorno da funo.
nome_funo: o nome da funo.
tipo_vetor: o tipo de dados dos elementos do vetor.
nome_vetor: o nome do vetor. Observe que depois do nome
do vetor temos o [ e o ], mas no colocamos nada entre eles.
Neste caso, no necessrio informar o tamanho do vetor.
Quando formos chamar uma funo que recebe um vetor como
28

Programao 2

parmetro, usamos a seguinte sintaxe:


Sintaxe

nome_da_funo(nome_do_vetor);

Onde:
nome_da_funo: o nome da funo que ser chamada.
nome_do_vetor: o nome do vetor que queremos passar
como parmetro. Neste caso, indicamos apenas o nome do
vetor, sem os colchetes.
O exemplo 1.6, a seguir, apresenta a declarao de uma funo
que tem um vetor como parmetro e a chamada da funo.
Exemplo 1.6:
declarao e chamada de uma funo que tem um vetor como parmetro

float media(float vetor[],float N)

//corpo da funo

5
6

main()

{ float valor[30]; // declarao do vetor

float n;

...

10

med = media(valor, n); // passagem do vetor


para a funo

11

...

12

Ateno: Ao contrrio das variveis comuns, o contedo de um


vetor pode ser modificado pela funo chamada. Isto significa que
podemos passar um vetor para uma funo e alterar os valores de
seus elementos. Isto ocorre porque a passagem de vetores para
funes feita de modo especial dito passagem por endereo.
Portanto, devemos ter cuidado ao manipular os elementos de um
29

Programao 2

vetor dentro de uma funo para no modific-los por descuido.

Atividades e Orientaes de Estudos


Vamos fazer um conjunto de exerccios, usando o assunto que
acabamos de aprender? Segue abaixo uma lista de exerccios em
que os dados sero armazenados em vetores. Vamos comear?
1. Ler um conjunto de nmeros e imprimi-los na ordem inversa da
leitura. A quantidade de nmeros tambm ser lida e ser no
mximo 10.
2. Ler o tamanho e os elementos de dois vetores e, em seguida,
caso os vetores tenham o mesmo tamanho, gere e imprima o
vetor SOMA, onde seus elementos sero formados pela soma
dos elementos de mesmos ndices dos dois vetores lidos.
Exemplo:
A

Soma

11

18

17

3. Ler um vetor de nmeros e imprimir os valores armazenados


nas posies PARES e, em seguida, os valores armazenados
nas posies MPARES. Exemplo:
V

Valores nas posies pares: 1 7 9


30

Programao 2

Valores nas posies impares: 4 2


4. Ler dois vetores e caso tenham tamanhos iguais, armazene seus
elementos alternadamente em um terceiro vetor. Exemplo:
A

Resultante

12

11

15

11

12

15

5. Ler um vetor de nmeros inteiros e imprimir as posies do


maior e do menor elemento do vetor. Assuma que no existem
elementos repetidos no vetor. Exemplo:
V

14

13

22

O menor elemento se encontra na posio 2


O maior elemento se encontra na posio 3
6. Ler um vetor de nmeros e inverter a ordem dos elementos
desse vetor no prprio vetor. Exemplo:

Vetor antes de ser invertido:


V

14

13

22

Vetor depois de ser invertido:

31

Programao 2

22

13

14

7. Ler dois vetores de nmeros e gerar um terceiro vetor formado


pela INTERSECO dos dois vetores lidos. O resultado da
interseo de dois conjuntos : os elementos que fazem parte
dos dois conjuntos. Exemplo:
A

12

14

25

interseccao

8. Ler dois vetores de nmeros e gerar um terceiro vetor formado


pela DIFERENA dos dois vetores lidos. O resultado da
diferena de dois conjuntos : os elementos do conjunto A que
no fazem parte do conjunto B. Exemplo:
A

12

14

25

Diferenca

32

12

Programao 2

9. Ler dois vetores de nmeros e gerar um terceiro vetor formado


pela UNIO dos dois vetores lidos. O resultado da unio de dois
conjuntos : todos os elementos que fazem parte dos conjuntos
A e B. Exemplo:
A

12

Unio

14

25

12

14

25

10. Ler um vetor de nmeros e imprimir os nmeros que se repetem


nesse vetor. Exemplo:
V

25

Os nmeros que se repetem no vetor so: 1 4 7

Conhea Mais
Para ampliar nossos conhecimentos sobre os assuntos tratados
neste captulo, leiam o captulo que aborda armazenamento em
vetores, do livro:
SCHILDT, Herbert. C Completo e Total. So Paulo: Makron,
1996.

33

Programao 2

Vamos Revisar?
Vamos lembrar rapidinho o que foi visto neste captulo?
Leia o resumo a seguir, composto com os principais conceitos
apresentados.
Vetores: conhecidos como estruturas de dados homogneas, os
vetores so um conjunto de variveis que armazenam elementos
do mesmo tipo.
ndices: para acessar um elemento do vetor, precisamos indicar em
que posio do vetor est o elemento.
No momento da declarao dos vetores, precisamos indicar quantos
elementos sero armazenados no mesmo.
de responsabilidade do programador o acesso aos elementos do
vetor. Se o programa tentar acessar uma posio que no existe no
vetor, o compilador no indicar o erro.
Quando passamos um vetor como parmetro de uma funo, seus
valores podem ser alterados

34

Programao 2

Captulo 2 Armazenamento de
Dados em Registros
Vamos conversar sobre o assunto?
Neste captulo, vamos aprender mais uma forma de armazenamento
de dados, que so os registros. Nos registros podemos agrupar dados
de tipos diferentes. Por conta disto, os registros so chamados de
estruturas de dados heterogneas. Assim como os vetores, os registros
vo facilitar o gerenciamento dos dados dos nossos programas, que
esto cada vez maiores. Veremos, tambm, como unir os conceitos
de vetores e registros, trabalhando com vetor de registro. Leiam este
captulo com calma e ateno, uma vez que iremos utilizar registros
em muitas situaes nos nossos programas, certo?

2.1 O que so registros?


Ns j sabemos que um conjunto homogneo de dados composto
por variveis do mesmo tipo (vetores). Mas, e se tivermos um conjunto
em que os elementos no so do mesmo tipo? Teremos, ento, um
conjunto heterogneo de dados, que so chamados de registros.
O registro uma das principais formas de estruturar os dados no
programa. O conceito de registro visa facilitar o agrupamento de
variveis de tipos diferentes, mas que possuem uma relao lgica.
Um registro um conjunto de uma ou mais variveis, que podem
ser de tipos diferentes, agrupadas sobre um nico nome. O fato de
variveis agrupadas em um registro poderem ser referenciadas por
um nico nome, facilita a manipulao dos dados armazenados nestas
estruturas. Como exemplo de um registro, imaginem uma estrutura que
armazene as diversas informaes do boletim de um aluno. O boletim
formado por um conjunto de informaes logicamente relacionadas,
porm de tipos diferentes, tais como: nmero de matrcula (inteiro),
nome do aluno (caractere), nome da disciplina (caractere), mdia (real)
e situao (caractere), que so subdivises do registro (elementos
de conjunto), tambm chamadas de campos. Logo, um registro
composto por campos que so partes que especificam cada uma das
informaes. A figura 2.1 apresenta o boletim de notas de um aluno.

35

Programao 2

Boletim de Notas
Matricula...: 12345
Nome........: Michel
Disciplina..: Matemtica
Mdia........: 10.0
Situao....: Aprovado

Figura 2.1 Boletim de Notas

Notem que, o boletim composto por informaes de diferentes


tipos. No entanto, todas as informaes do boletim esto relacionadas
ao mesmo aluno. O agrupamento de informaes de tipos diferentes,
que tem uma relao lgica, facilitar a manipulao de dados.
Nas prximas sees, vamos aprender a declarar e manipular
registros.

2.2 Declarao de um Registro


Para declarar uma varivel, precisamos informar o seu tipo e dar
um nome mesma. Mas, um registro formado por vrias variveis
de tipos diferentes. Como iremos declarar um registro? Para declarar
um registro, necessrio informar quais variveis, e seus respectivos
tipos, fazem parte do registro. Dessa forma, precisamos declarar
cada campo do registro, agrupando-os em um novo tipo de dado.
A declarao de um registro passa por duas fases: definio de um
novo tipo de dado e declarao do registro propriamente dito. Vamos
entender melhor isso tudo?
Primeiramente, precisamos definir quais campos fazem parte
do registro e criar um novo tipo de dado para o nosso programa.
Precisamos criar um novo tipo de dado porque no conseguiramos
representar o tipo de informao que o registro armazena, utilizando
os tipos primitivos disponveis na linguagem: int, float, char, etc. Uma
vez que o registro agrupa variveis de tipos de dados diferentes. Para
criar um novo tipo de dado, utilizamos a seguinte sintaxe:

36

Programao 2

Sintaxe

typedef struct { declarao das variveis;


} nome_do_tipo;

Onde:
typedef: indica que um novo tipo de dado ser definido.
struct: indica que o tipo de dado que ser definido um
registro, ou seja, um agrupamento de variveis de tipos de
dados diferentes.
declarao das variveis: so as variveis que fazem parte do
registro. Neste local, precisamos especificar quais as variveis
iro compor o registro, alm do tipo das mesmas. As variveis
so colocadas entre chaves.
nome_do_tipo: dado um nome ao novo tipo de dado que
est sendo criado. S depois que o novo tipo de dado criado,
que o registro poder ser declarado.
Na sequncia, vamos ver a declarao de um registro. Assim como
toda varivel, ao declarar uma varivel que um registro, precisamos
dizer que tipo de dado o registro armazena. Neste caso, iremos dizer
que o registro do tipo de dado que acabamos de definir no typedef.
A sintaxe a seguinte:
Sintaxe

nome_do_tipo

nome_do_registro;

Onde:
nome_do_tipo: o nome do tipo de dado que definimos
no nosso programa, formado pelo agrupamento de vrias
variveis.
nome_do_registro: o nome da varivel registro que est
sendo declarada. O nome de um registro segue as regras dos
identificadores.
O exemplo 2.1 apresenta a declarao do registro do boletim do
aluno:

37

Programao 2

Exemplo 2.1: Definio de tipo e declarao de registro

typedef struct { int matricula;


situao[10];

char nome[20], disciplina[20],

float media;

} Tipo_Aluno;

Tipo_Aluno aluno;

Primeiramente, entre as linhas 1 e 4, foi definido o conjunto de


variveis que fazem parte do registro. nesta parte que est sendo
definido um novo tipo de dado.
Linha 1: com o typedef estamos informando que ser definido
um novo tipo de dado. O struct indica que este tipo um
agrupamento de variveis de tipos diferentes, ou seja, um
registro. Colocamos o abre chaves e comeamos a declarar
as variveis que iro compor o registro. Comeamos com a
declarao da varivel inteira matricula. Se houvesse mais
variveis do tipo int, poderiam ser declaradas nesta mesma
linha.
Linha 2: declarao das variveis do tipo char: nome, disciplina
e situacao.
Linha 3: declarao da varivel media que do tipo float.
Linha 4: Aps a declarao de todas as variveis que compe
o registro, podemos fechar a chaves e, em seguida, dar um
nome a esse tipo de agrupamento, que acabamos de definir.
Neste caso, o tipo foi chamado de Tipo_Aluno. Ao definirmos
um tipo de dado no nosso programa, significa que: podemos
declarar variveis dos tipos de dados primitivos (int, float, char,
etc), alm de variveis do tipo de dado que ns definimos, neste
caso, Tipo_Aluno.
Linha 5: declarao de uma varivel chamada aluno, e o tipo
de dado que ela armazena Tipo_Aluno, ou seja, armazena:
matricula, nome, disciplina, situacao e media.
A figura 2.2 mostra a representao grfica da varivel aluno, que
do tipo Tipo_Aluno.

38

Programao 2

matricula
nome
disciplina
situacao
media

aluno
Figura 2.2: Representao grfica do registro aluno

Notem que, a varivel aluno (que um registro) formada pelos


campos definidos no Tipo_Aluno.
Como uma varivel registro formada por vrios campos,
precisamos utilizar uma forma diferenciada para informar qual campo
do registro ns estamos querendo acessar. Lembram dos vetores, que
precisvamos dizer qual elemento do vetor seria acessado? Com os
registros vai acontecer algo parecido. Mas isto, ns vamos aprender
na prxima seo.

2.3 Acessando os campos do registro


De acordo com a figura 2.2, a varivel aluno um registro formado
por vrios campos. Para acessar um campo de um registro, devemos
usar a seguinte sintaxe:
Sintaxe

nome_do_registro.campo

Onde:
nome_do_registro: o nome da varivel registro que queremos
acessar.
Aps o nome_do_registro devemos colocar um ponto, que
ir separar o nome do registro, do campo que vem logo em
seguida.
campo: o campo do registro que ser acessado.
39

Programao 2

Pensem da seguinte forma: suponham que queremos acessar


o registro aluno, do exemplo 2.1. Ao acessarmos esta varivel, ela
possui vrios campos. Precisamos dizer qual deles ser acessado
no momento. A seguir, so apresentados exemplos de acesso aos
campos do registro aluno. Ao acessar um campo do registro, podemos
atribuir valores, como mostra o exemplo 2.2.
Exemplo 2.2: Acesso aos campos de um registro

Saiba Mais
O ponto que
aparece neste
comando, deve
ser lido como
campo. Assim,
a leitura do
comando da linha
1 seria: aluno no
campo matricula
recebe 12345.
4

aluno.matricula = 12345;

scanf(%f, &aluno.media);

gets(aluno.nome);

printf(Situacao do aluno: %s, aluno.situacao);

Na linha 1, estamos acessando o campo matricula do registro


aluno. Assim, colocamos o nome do registro, o ponto e o campo que
queremos acessar. Com acesso ao campo, fizemos uma atribuio4.
Na linha 2, estamos acessando o campo media do registro aluno.
Neste caso, ao invs de atribuir um valor ao campo de registro, estamos
fazendo uma leitura via teclado e armazenando o valor digitado no
campo media. Como o campo media do tipo float, colocamos o %f
no scanf, indicando que ser lido um nmero real.
Na linha 3, temos o comando de leitura gets, responsvel por ler
variveis do tipo char. Neste gets, estamos fazendo uma leitura via
teclado e armazenando o valor digitado no campo nome do registro
aluno.
Na linha 4, temos um printf que apresenta a situao do aluno.
Para isso, acessamos o campo situacao do registro aluno.
Notem que, se tivermos vrios alunos em uma turma, precisaremos
de vrias variveis registro do tipo Tipo_Aluno, uma para cada
aluno. Para fazer isso de forma mais simplificada, devemos juntar os
conceitos de vetores e registros e criar um vetor de registro. Vamos
aprender como faz isto?

2.4 Vetor de registro


Os vetores so formados por um conjunto de dados do mesmo
tipo. No captulo anterior, utilizamos vetores que armazenavam dados
40

Programao 2

de tipos primitivos, ou seja, tipos disponveis na linguagem int,


float, char, etc. Veremos que podemos utilizar como elemento do vetor
no apenas um tipo primitivo, mas tambm os tipos construdos (tipos
definido pelo programador), neste caso, os registros. Imaginem que
queremos armazenar os boletins dos 50 alunos de uma turma. Para
isso, ser necessrio um registro diferente para cada aluno. Para
agrupar todos estes registros, iremos definir um vetor de registro.
Como possumos 50 alunos, podemos criar um vetor no qual cada
posio, armazena um Tipo_Aluno.
Para declarar um vetor de registro, precisamos antes definir os
elementos do registro, utilizando o typedef struct, e assim, definir um
novo tipo de dado que ser utilizado no programa. Aps definirmos o
novo tipo de dado, o vetor poder ser declarado. Para declararmos
um vetor, precisamos informar o tipo de dado que o vetor armazena,
damos um nome ao vetor e informamos, entre colchetes, o tamanho
do vetor. O exemplo 2.3 apresenta a declarao do vetor de registro
alunos:
Exemplo 2.3: definio do registro e declarao do vetor de registro

typedef struct { int matricula;


situao[10];

char nome[20], disciplina[20],

float media;

}Tipo_Aluno;

Tipo_Aluno alunos[50];

Neste exemplo, cada uma das 50 posies do vetor alunos ir


armazenar todos os dados que compe o Tipo_Aluno, ou seja:
matricula, nome, disciplina, situacao e media. A figura 2.3, a seguir,
representa o vetor de registro declarado no exemplo.

alunos

matricula
nome
disciplina
media
situacao
0

matricula
nome
disciplina
media
situacao
1

matricula
nome
disciplina
media
situacao
...

matricula
nome
disciplina
media
situacao

48

Figura 2.3: Representao grfica do vetor de registro aluno

41

49

Programao 2

Se apenas com os vetores, j havamos adquirido uma facilidade


na declarao e manipulao de um grande conjunto de variveis,
com os vetores de registros, esta facilidade ser aumentada.
Vamos aprender, na prxima seo, como acessamos um campo
de um vetor de registro.

2.5 Acessando os campos do vetor de


registro
Quando precisamos acessar um elemento do vetor, informamos,
entre colchetes, o ndice do elemento do vetor que ser acessado.
Quando queremos acessar um campo do registro, informamos o
nome da varivel registro, colocamos um ponto e o nome do campo
que queremos acessar. J no caso de um vetor de registro, temos
que usar a seguinte sintaxe:
Sintaxe

nome_do_vetor[indice].campo

Onde:
nome_do_vetor: nome do vetor que queremos acessar.
[ndice]: ndice do vetor que ser acessado.
.campo: campo do registro que ser acessado.
O exemplo 2.4 apresenta acessos a campos do vetor de registro
alunos.
Exemplo 2.4: Acesso aos elementos de um vetor de registro

alunos[2].media = 7.5;

alunos[3].matricula = 12345;

gets(alunos[0].nome);

scanf(%d,&alunos[2].matricula);

Na linha 1, acessamos o elemento de ndice 2 do vetor alunos e


atribumos 7.5 ao campo media. Na linha 2, acessamos o elemento
de ndice 3 do vetor alunos e atribumos 12345 ao campo matricula.
Nas linhas 3 e 4, temos acessos atravs de comandos de entrada
42

Programao 2

de dados. Na linha 3, temos um gets, que obtm o nome do aluno, via


teclado, e armazena no ndice 0 do vetor alunos, no campo nome. Na
linha 4, temos o scanf que l a matrcula do aluno, armazenando no
ndice 2 do vetor alunos, no campo matricula.

2.6 Usando vetor de registro


Vamos fazer um programa completo usando vetor de registro?
Este programa ser um pouco maior do que os outros programas que
j fizemos, e apresentar uma gama de coisas novas. Alm do uso
de vetor de registro, aprenderemos a mostrar os dados do vetor de
registro em forma de tabela. Vamos comear?
Primeiramente, vamos ler e entender o enunciado do Programa
Completo 2.1: Faa um programa que cadastre e apresente os
dados dos alunos de uma escola. Os dados dos alunos devem
ser armazenados em um vetor de registro, com a capacidade de
armazenar at 20 alunos. A quantidade de alunos que ser cadastrada
desconhecida. No momento do cadastro sero informados os
seguintes dados para cada aluno: matrcula, nome, srie(1-4) e se
tem irmo na escola (1-sim/0-nao). O programa ir calcular o valor
da mensalidade do aluno, que depende da srie do aluno e se o
mesmo tem irmo na escola. Valor da Mensalidade: 1 Serie: R$110,
2 Serie: R$130, 3 Serie: R$160, 4 Serie: R$170. O aluno que tiver
irmo na escola, receber 20% de desconto no valor da mensalidade.
Quando o usurio decidir que no deseja mais cadastrar, o programa
apresentar os dados de todos os alunos, em forma de tabela. Para
facilitar o entendimento deste enunciado, vejam os exemplos das telas
que so apresentadas durante a execuo do programa:
Colgio Legal
Cadastro de Aluno
Matricula..:
Nome.......:
Serie(1-4):
Irmao na escola (1-sim/0-nao):
Cadastrar outro aluno (1-sim/0-nao)?

43

Programao 2

Colgio Legal
Relatrio Geral
Matricula

Nome

Serie

Irmao

Mensalidade

xx

xxxxx

xx.xx

xx

xxxxx

xx.xx

xx

xxxxx

xx.xx

xx

xxxxx

xx.xx

xx

xxxxx

xx.xx

Tecle enter para sair...


Figura 2.4:Exemplos de telas do programa completo 2.1

A primeira tela representa a operao de cadastramento dos


dados dos alunos. Nesta tela, que sero fornecidos os dados para o
cadastramento dos alunos. Como a mensalidade um dado calculado
pelo programa, o usurio no fornecer este dado no momento do
cadastro.
A segunda tela representa a apresentao dos dados de todos
os alunos, em forma de tabela (listagem ou relatrio). Cada linha da
tabela apresentar os dados de um aluno.
Como precisamos armazenar os vrios dados de cada um dos
alunos da escola, se faz necessrio o uso de um vetor de registro.
Segue o cdigo do programa completo 2.1, que ser comentado
posteriormente.

44

Programao 2

Programa Completo 2.1

#include <stdio.h>

main()

{ typedef struct{ int mat, serie, irmao;

char nome[20];

float mens;

Tipo_Aluno;

Tipo_Aluno alunos[20];

int qa, i, resp;

qa =0;

10

do

11

system(cls);

12

printf(Colegio Legal\n);

13

printf(\n\nCadastro de Alunos\n\n);

14

printf(\nMatricula.: );

15

scanf(%d,&alunos[qa].mat);

16

printf(\nNome......: );

17

fflush(stdin);

18

gets(alunos[qa].nome);

19

printf(\nSerie(1-4): );

20

scanf(%d,&alunos[qa].serie);

21


);

22

scanf(%d,&alunos[qa].irmao);

23

switch(alunos[qa].serie)

24

{ case 1: alunos[qa].mens = 110; break;

25

case 2: alunos[qa].mens = 130; break;

26

case 3: alunos[qa].mens = 160; break;

27

case 4: alunos[qa].mens = 170; break;

28

printf(\nIrmao

na

escola(1-sim/0-nao):

45

Programao 2

29

if (alunos[qa].irmao == 1)

30

alunos[qa].mens = alunos[qa].mens*0.8;

31

qa++;

32

printf(\n\nDeseja
sim/0-nao)? );

cadastrar

outro

aluno(1-

33

34

}while ((resp == 1) && (qa <20));

35

system(cls);

36

printf(Colegio Legal\n);

37

printf(\n\nRelatorio Geral\n);

38

printf(\n________________________________);

39

scanf(%d,&resp);


printf(\nMatricula
Mensalidade);

Nome

Serie

Irmao

40

printf(\n________________________________);

41

for(i = 0; i < qa; i++)

42

printf(\n%9d

%-20s

%5d

%5d

%11.2f,

alunos[i].mat, alunos[i].nome, alunos[i].serie,


alunos[i].irmao, alunos[i].mens);

43

printf(\n_______________________________);

44

printf(\nTecle enter para sair...);

45

getche();

46

Comentrios sobre o Programa Completo 2.1


Linha 1: incluso da biblioteca stdio.h devido o uso do comando
fflush.
Linha 2: incio do programa principal.
Linhas 3 a 6: definio de um novo tipo de dado, que ser
chamado de Tipo_Aluno. O Tipo_Aluno formado pelos dados
dos alunos: mat (matrcula), nome, serie, irmao (indica se tem
irmo na escola) e mens (mensalidade).
Linha 7: declarao do vetor de registro alunos, com capacidade
de armazenar 20 elementos do Tipo_Aluno.
46

Programao 2

Linha 8: declarao das variveis qa (que ir controlar a


quantidade de alunos cadastrados no vetor), i (utilizada como
varivel de controle do for) e resp (utilizada para saber se o
usurio deseja continuar cadastrando novos alunos).
Linha 9: inicializao da varivel qa com 0;
Linhas 10 a 34: repetio do tipo do/while que ir controlar
o cadastro dos dados dos alunos no vetor de registro. Este
do/while ir parar a sua execuo se o vetor ficar cheio (20
elementos) ou se o usurio no quiser mais cadastrar.
Linha 11: Cada vez que o do/while executado, queremos que
a tela seja limpa. Para isso, usamos o system(cls). Esta linha
tem, tambm, o abre chaves que indica o incio da sequncia
de comandos do do/while.
Linhas 12 e 13: printf para indicar o nome do colgio (Colgio
Legal) e para indicar o que est sendo feito nesta tela (Cadastro
de Alunos).
Linhas 14 e 15: printf informando que o usurio deve digitar
a matrcula do aluno e scanf que obtm a matrcula do aluno,
armazenado-a no vetor de registro alunos, na posio qa e no
campo mat. Notem que a varivel qa iniciou com 0. Na primeira
vez que o do/while for executado, os dados dos alunos sero
armazenados na posio 0 do vetor. A cada vez que a repetio
executada, a varivel qa incrementada de uma unidade.
Assim, os dados de cada aluno sero armazenados em uma
posio, diferente, no vetor de registro.
Linhas 16 a 18: printf informando que o usurio deve digitar o
nome do aluno. fflush para limpar o buffer e, em seguida, o gets
responsvel por ler o nome do aluno, armazenando no vetor de
registro alunos, na posio qa e no campo nome.
Linhas 19 e 20: printf informando que o usurio deve digitar a
srie do aluno (que pode ser de 1 a 4). scanf responsvel por
ler a srie do aluno, armazenando no vetor de registro alunos,
na posio qa e no campo serie.
Linhas 21 e 22: printf informando que o usurio deve digitar se
o aluno tem irmo na escola (digitar 1 se tiver irmo e 0 se no
tiver irmo na escola). scanf responsvel por ler se o aluno tem
irmo na escola, armazenando no vetor de registro alunos, na
47

Programao 2

posio qa e no campo irmao.


Linhas 23 a 28: depois de obter todos os dados de um aluno,
o programa vai calcular o valor da mensalidade do aluno,
verificando a srie e se tem irmo na escola. Como cada uma
das sries da escola tem um valor diferente de mensalidade,
este switch serve para verificar em que srie o aluno est
matriculado, para atribuir ao campo mens do registro do aluno,
o valor da mensalidade correspondente a sua srie.
Linhas 29 e 30: if para verificar se o aluno tem irmo na escola.
De acordo com o enunciado, os alunos que tem irmo na escola,
recebem uma desconto de 20% na sua mensalidade. Como o if
s tem um comando, no foi necessrio o uso de chaves.
Linha 31: neste momento, todo o registro do aluno j foi
preenchido. Com isso, fazemos o incremento da varivel qa,
informando que mais um aluno acabou de ser cadastrado.
Linhas 32 e 33: printf que pergunta se o usurio deseja
continuar cadastrando novos alunos. scanf para ler a resposta
do usurio (1 se ele deseja continuar cadastrando e 0 se deseja
parar).
Linha 34: fechamento do do/while com a condio que faz a
repetio parar. Como mencionado anteriormente, este do/
while fica em execuo enquanto tem posies disponveis no
vetor ou enquanto o usurio desejar. Nesta linha, termina a fase
de cadastramento dos dados dos alunos no vetor de registro.
Linhas 35 a 47: Esta sequncia de comando serve para
apresentar os dados dos alunos que foram armazenados
no vetor de registro. Por uma questo de organizao, estes
dados sero apresentados na forma de tabela. Assim, cada
linha da tabela corresponder aos dados de um aluno, ou
seja, uma posio do vetor de registro. Para que a tabela fique
alinhada, precisamos saber que: a tela tem 80 colunas por 25
linhas. Dessa forma, temos que distribuir as informaes de um
jeito que no extrapole as 80 colunas da tela. Para entender
melhor esta parte do programa, acompanhem os comandos,
observando a figura 2.9 (tela de execuo do programa).
Linha 35: limpa a tela para darmos incio apresentao dos
dados de todos os alunos.
48

Programao 2

Linhas 36 e 37: printf para informar o nome do colgio e para


informar o que esta tela faz (Relatrio Geral).
Linha 38: printf para passar uma linha na tela. Esta linha vai
delimitar o cabealho da tabela.
Linha 39: printf que imprime os ttulos de cada coluna da tabela.
A tabela ser composta pelas seguintes colunas: Matricula,
Nome, Serie, Irmao e Mensalidade. Os ttulos que devemos
dar as colunas da tabela so sempre indicados nos enunciados
das questes, certo? Sigam esta dica, porque vocs esto
comeando a aprender a fazer tabelas agora. Este printf cheio
de detalhes, mas vamos ver isso agora, observando a figura
2.5. O resultado deste printf a linha que est indicada com a
seta.

Figura 2.5: Apresentao dos dados em forma de tabela

Vamos ver quais so os passos para montar o printf da linha 39


(cabealhos/ttulos das colunas da tabela).
Para cada coluna da tabela, verifiquem quantas letras tem
no seu cabealho. Por exemplo, a palavra matrcula, tem 9
letras. Vejam que, na figura 2.5, tem a indicao de quantas
letras tem em cada um dos cabealhos. A quantidade de
letras que tiver o cabealho, ser a largura da coluna.
Agora, precisamos verificar se os dados dos alunos vo
extrapolar a largura de cada uma das colunas da tabela.
Vamos ver uma por uma:
Matricula: a coluna que ser utilizada para apresentar
a matrcula, tem uma largura de 9 espaos (quantidade
de letras da palavra matrcula). Vamos considerar que
nossas matrculas tem sempre menos que 9 dgitos.
49

Programao 2

Assim, a largura de 9 espaos para esta coluna,


suficiente.
Nome: a palavra nome s tem 4 letras. Vejam que o
nome do aluno foi declarado com 20 letras. Assim, se
deixarmos a coluna Nome, com largura 4, no ser
suficiente para apresentar os nomes dos alunos.
Quando a quantidade de letras do cabealho menor
que o contedo que vem na coluna da tabela, devemos
completar a coluna com espaos em branco at fazer
com que a coluna tenha a largura que precisamos.
Srie: tem 5 letras. A srie do aluno varia entre 1 e 4,
dessa forma, a largura da coluna Serie (5 espaos),
ser suficiente para apresentar o dado.
Irmo: tambm tem 5 letras. A varivel que armazena
se o aluno tem ou no irmo na escola, varia entre 0 e
1, dessa forma, a largura da coluna Irmao (5 espaos),
ser suficiente para apresentar o dado.
Mensalidade: tem 11 letras. Esta largura suficiente
para apresentar o valor da mensalidade do aluno.
Agora que j sabemos que apenas a coluna Nome no tem
largura suficiente para apresentar os nomes dos alunos,
vamos ver quantos espaos em branco ns temos que
colocar depois da palavra Nome, para que esta coluna
tenha a largura que precisamos. Se o nome do aluno tem
at 20 letras e a palavra Nome tem apenas 4 letras, faremos
a seguinte conta: 20 4 = 16. Assim, depois da palavra
Nome, temos que colocar 16 espaos em branco, para que
a nossa coluna passe a ter a largura que precisamos (20).
Por fim, temos que definir um espaamento para separar
uma coluna da outra. Nos nossos exemplos, vamos usar
sempre trs espaos separando uma coluna da outra.
A padronizao do espaamento entre as colunas visa
facilitar a programao, j que estamos vendo este assunto
agora e o mesmo cheio de detalhes.
Agora vamos montar o printf, vejam a figura 2.6. Ns
vamos colocando os ttulos das colunas da tabela, e entre
cada palavra, vamos colocando trs espaos em branco,
50

Programao 2

que foi o espaamento definido para separar as colunas.


S no caso da coluna nome, que depois que colocamos
Nome, devemos dar os 16 espaos em branco para que ela
passe a ser uma coluna de largura 20. Mas ainda teramos
que dar mais 3 espaos em branco, que para separar a
coluna nome, da coluna serie.

Figura 2.6: Detalhamento do printf da linha 39

O printf est pronto! A primeira vista, parece complicado,


mas depois vocs estaro fazendo a tabela bem rpido.
Linha 40: printf para passar uma linha na tela. Esta linha vai
delimitar o cabealho da tabela.
Linha 41: for para visitar cada uma das posies do vetor e
apresentar os dados dos alunos. A varivel de controle do for,
o i, vai variar de 0 at a ultima posio ocupada do vetor. A
varivel que tem esta informao o qa.
Linha 42: este printf que vai fazer a montagem das linhas
da tabela, apresentado os dados dos alunos que esto
armazenados no vetor de registro. Este printf tambm tem
macetes, pois est relacionado com o printf da linha 39. Vamos
l! Lembram que fizemos a contagem para saber a largura
de cada coluna da tabela? Vamos precisar desta informao
agora.
Na primeira parte do printf, temos a string de controle
(a figura 2.7 faz o detalhamento dessa parte do printf).
Sabemos que as colunas da tabela so: matricula( nmero
inteiro e esta coluna deve ter largura 9), nome (vetor de
caracteres com at 20 letras), serie (nmero inteiro e esta
coluna tem largura 5), irmo (nmero inteiro e esta coluna
tem largura 5) e mensalidade (nmero real e esta coluna
tem largura 11). Alm disso, sabemos que entre cada
coluna, ns colocamos trs espaos em branco. Com estas
informaes, vamos montar a string de controle do printf da
51

Programao 2

linha 42.

Figura 2.7: Detalhamento do printf da linha 42

Entre o % e a letra que indica o que vai ser impresso (%d,


%s ou %f), devemos colocar a largura da coluna. A primeira
coluna da tabela a da matricula, que um nmero inteiro
e que tem largura 9. Por isso, temos o %9d. Aps cada
uma das formataes, colocamos trs espaos em branco,
j que foi o espaamento definido entre as colunas da
tabela. No caso da varivel caractere nome do aluno (que
a segunda coluna da tabela) colocamos %-20s (o
para que o nome do aluno seja alinhado pela esquerda).
Nas demais formataes no precisamos colocar o -, s
utilizamos em campos caractere.
Aps a string de controle, colocamos as variveis que sero
apresentadas na tela, na ordem em que as colunas foram
definidas.
Linha 43: printf para passar uma linha na tela. Esta linha vai
fechar a tabela.
Linha 44: printf que informa que o usurio deve teclar enter
para sair.
Linha 45: getche() que evita que a tela de execuo feche
antes de vermos os resultados.
Linha 46: fecha chaves do programa principal.
A figura 2.8 apresenta a tela de execuo do programa 2.1, na
fase do cadastramento dos alunos.

52

Programao 2

Figura 2.8: Tela de execuo do programa completo 2.1 - Cadastro

A figura 2.9 apresenta a tela de execuo do programa 2.1, na


fase do apresentao dos dados de todos os alunos cadastrados, em
forma de tabela.

Figura 2.9: Tela de execuo do programa completo 2.1 Relatrio Geral

Viram como esta questo cheia de detalhes? Mas no se


assustem, a explicao precisava ser minuciosa, para que cada linha
do programa fosse entendida. Agora precisamos treinar esse tipo de
questo. No percam tempo!

Atividades e Orientaes de Estudos


Vamos resolver mais uma lista de exerccios? Esta lista composta
por questes em que se faz necessrio o uso de vetor de registro.
DICA: sempre coloque as tabelas com os mesmos cabealhos
propostos nos enunciados (exemplos de telas). Mos a obra!
1. Uma empresa de turismo deseja um programa que calcule o
valor das viagens dos clientes. Sero informados os seguintes
53

Programao 2

dados: cdigo do cliente, nome, roteiro desejado(1-Brasil,


2-EUA, 3-frica), tipo de quarto (1-Standard, 2-Luxo), Se deseja
alugar carro(1-sim/0-nao) e a quantidade de dias. A quantidade
de clientes desconhecida. O programa ir calcular o total da
viagem usando os valores da tabela abaixo, que variam de
acordo com o roteiro escolhido. A diria do quarto de luxo
R$30 mais cara que o valor da diria em um quarto standard.
Exemplo: Se a pessoa escolher roteiro 2, em quarto de luxo, a
diria ir custar: 320 + 30 = R$ 350.
Roteiro

Diria Hotel
Quarto Standard

Diria - Aluguel
de carro

R$ 170

R$ 50

R$ 350

R$ 60

R$ 370

R$ 75

Total da Viagem:
dias*diriahotel + dias*diariacarro(se o cliente for alugar carro)

Armazenar os dados em um vetor de registro. Imprimir os dados


em forma de tabela. Exemplo das telas:
Viagem Legal Turismo

Cadastro de Cliente
Codigo:
Nome:
Roteiro (1-Brasil, 2-EUA, 3-frica):
Tipo de Quarto (1- Standard, 2-Luxo):
Alugar Carro (1-sim/0-nao)?
Quantidade de Dias:
Inserir outro (1-sim,0-nao)?
Viagem Legal Turismo
Relatrio Geral
Cdigo

Nome

Roteiro

Quarto

Carro

Dias

Total

xx

xxxxx

xx

xx.xx

xx

xxxxx

xx

xx.xx

xx

xxxxx

xx

xx.xx

Tecle enter para sair...

54

Programao 2

2. Faa um programa para montar a folha de pagamento dos


empregados de uma empresa. Para cada empregado sero
lidos os seguintes dados: matricula, nome, cargo(1-Analista
de Sistemas/2- programador), sexo(1-mas/2-fem), anos de
experincia e quantidade de filhos. O programa ir calcular
para cada empregado o seu salrio. Sabe-se que:
Cargo

Salrio Base

R$ 2500

R$ 1700

O salrio ser calculado da seguinte forma: Cada cargo tem


o salrio base. Alm do salrio base, o empregado recebe os
seguintes adicionais: R$ 50, para cada ano de experincia e R$
40 por cada filho. Portanto, um analista de sistemas com trs
anos de experincia e dois filhos ter o salrio = 2500 + 50*3 +
40*2 = R$ 2730.

Armazenar as informaes em um vetor de registros. Imprimir


o relatrio geral em forma de tabela contendo os dados de
cada empregado. A quantidade de empregados da empresa
desconhecida (declarar o vetor com capacidade de armazenar
20 funcionrios). Exemplos das telas:
Empresa Legal

Cadastro de Funcionario
Matricula:
Nome:
Cargo(1-Analista de Sistemas, 2- programador):
Sexo(1-mas/2-fem):
Anos de experincia:
Quantidade de filhos:
Cadastrar outro (1-sim/2-nao)?

55

Programao 2

Empresa Legal
Listagem Geral
Matricula

Nome

Cargo

Sexo

Anos

Q. Filho

Salrio

xx

xxxxx

xx

xxx.xx

xx

xxxxx

xx

xxx.xx

xx

xxxxx

xx

xxx.xx

xx

xxxxx

xx

xxx.xx

Tecle enter para sair...

3. Faa um programa para uma empresa de celular contendo as


seguintes operaes: cadastro de clientes e listagem geral.
Para cada cliente devemos armazenar: cdigo, nome, sexo
(1-feminimo/2-masculino), quantidade de ligaes, plano que
o cliente est associado (1-Dia/2-Noite/3-Fixo/4-Empresarial) e
Valor da conta. O programa ir calcular o valor da conta de cada
cliente. Sabe-se que, cada plano tem uma tarifa diferenciada,
segundo a tabela abaixo:
Plano

Valor de 1 ligao

Dia

1.30

Noite

1.60

Fixo

1.25

Empresarial

1.10

Armazenar os dados em um vetor de registro. Aps o cadastro dos


clientes, apresentar a listagem com os dados de todos os clientes, em
forma de tabela. A quantidade de clientes desconhecida. Declare o
vetor com capacidade de receber at 50 clientes.
Exemplos das telas:

56

Programao 2

Ligue Mais
Cadastro de Cliente
Cdigo:
Nome:
Sexo(1-fem/2-mas):
Quantidade de Ligaes:
Plano(1-Dia/2-Noite/3-Fixo/4-Empresarial):
Cadastrar outro (1-sim/0-nao)?
Ligue Mais
Listagem Geral
Codigo

Nome

Sexo

Quant. Lig.

Plano

Total

xx

xxxxx

xx

xxx.xx

xx

xxxxx

xx

xxx.xx

xx

xxxxx

xx

xxx.xx

xx

xxxxx

xx

xxx.xx

Tecle enter para sair...

4. Um professor quer um programa para o clculo da mdia dos


alunos de uma turma. Sero informadas a matrcula, nome (20
caracteres), e as trs notas dos alunos. O professor descarta
a menor nota do aluno e a media calculada com as duas
maiores notas. Calcular a mdia e apresentar os resultados em
forma de tabela, aps o cadastramento. Armazenar os dados em
um vetor de registro. A quantidade de alunos desconhecida,
declare o vetor com capacidade de receber at 20 alunos.
Exemplos das Telas:
Universidade Legal
Cadastro de aluno
Matricula:
Nome:
Nota 1:
Nota 2:
Nota 3:
Cadastraroutro (1-sim/0-nao)?

57

Programao 2

Universidade Legal
Relatrio Geral
Matricula

Nota1

Nota2

Nota3

Media

xxxxxxxxx

x.x

x.x

x.x

x.x

xxxxxxxxx

x.x

x.x

x.x

x.x

xxxxxxxxx

x.x

x.x

x.x

x.x

xxxxxxxxx

x.x

x.x

x.x

x.x

Tecle enter para sair...

5. O MEC quer um programa para fazer um relatrio sobre os


plos de educao a distncia da UFRPE. Para cada plo so
informados os seguintes dados: cdigo do plo, cidade, total
de alunos, total de tutores, se possui laboratrio de informtica
(1-sim/0-no) e se possui laboratrio de cincias (1-sim/0-no).
O MEC quer saber quanto deve ser liberado de verba para cada
plo. O calculo ser feito da seguinte forma:
Por cada aluno so liberados: R$ 100
Por cada tutor so liberados: R$ 500
Se o plo tem no tem laboratrio de informtica so liberados:
R$ 20.000
Se o plo no tem laboratrio de cincias so liberados: R$
17.000
Ex: um plo com 150 alunos, com 15 tutores, que tem laboratrio
de informtica, mas no tem laboratrio de cincias: Verba = 100 x
150 + 500 x 15 + 17000 = 15000 + 7500 + 17000 = 39500.
Armazenar os dados dos plos em um vetor de registro. A
quantidade de plos desconhecida. Declarar o vetor com a
capacidade de armazenar at 20 plos. Aps o cadastros dos plos,
apresentar todos os dados dos plos em forma de tabela.
Exemplos das telas:

58

Programao 2

Ministrio da Educao
Cadastro de Polo
Codigo:
Cidade:
Quantidade de alunos:
Quantidade de tutores:
Tem lab. de informatica (1-sim/0-nao)?
Tem lab. de ciencias (1-sim/0-nao)?
Cadastrar outro plo (1-sim,0-nao)?
Ministrio da Educao
Listagem Geral
Codigo

Cidade

Alunos

Tutores

LI

LC

Verba Liberada

xx

xxxxx

xxx

xxx

xxxxx.xx

xx

xxxxx

xxx

xxx

xxxxx.xx

xx

xxxxx

xxx

xxx

xxxxx.xx

xx

xxxxx

xxx

xxx

xxxxx.xx

Tecle enter para sair...

Conhea Mais
Vocs podero aprender mais sobre registros e vetores de registros
lendo os livros:

MONTGOMERY, Eduard. Programando em C: Simples e


Prtico. So Paulo: Alta Books, 2006.

SCHILDT, Herbert. C Completo e Total. So Paulo: Makron,


1996.

Vamos Revisar?
Nesta seo iremos revisar os principais tpicos vistos neste
59

Programao 2

captulo. Vale a pena dar uma lida para verificar como est o nosso
aprendizado. Observem o resumo a seguir:
Os registros so um agrupamento de variveis de tipos diferentes,
mas que tem uma relao lgica.
Por ser formado por elementos de diferentes tipos, os registros so
chamados de estruturas de dados heterogneas.
Para declarar uma varivel registro, precisamos definir um novo
tipo de dado para o programa, utilizando o typedef.
Cada elemento do registro chamado de campo.
Unindo os conceitos de vetores e de registros, temos os vetores
de registro que facilitam a declarao e o manuseio de grandes
volumes de dados.

60

Programao 2

Captulo 3 Armazenamento de
Dados em Arquivos
Vamos conversar sobre o assunto?
Neste captulo, vamos aprender a armazenar nossos dados de
forma definitiva. At ento, ao terminar a execuo de um programa,
todos os dados que foram armazenados nas variveis eram perdidos.
Em muitas aplicaes isto no pode acontecer. Por exemplo, um
professor precisa ter certeza de que todo o trabalho para digitar
as notas dos alunos da turma no ser perdido quando ele fechar
o programa. Com os arquivos, poderemos armazenar os dados e
recuper-los quando necessrio. Este captulo abordar os comandos
que nos possibilitaro manipular dados armazenados em um arquivo.
Vamos comear?

3.1 O que so arquivos?


Os arquivos so estruturas de dados manipuladas fora do ambiente
do programa. Considera-se como ambiente do programa a memria
principal, onde nem sempre conveniente manter certas estruturas
de dados. De modo geral, os arquivos so armazenados na memria
secundria, como, por exemplo: disco rgido (HD), CD e pendrive.
3.1.1. Como os arquivos so organizados?
A linguagem C utiliza o conceito de fluxo de dados (stream) para
manipular os vrios tipos de dispositivos de armazenamento e seus
diferentes formatos. Os dados podem ser manipulados em dois
diferentes tipos de fluxos: fluxos de texto e fluxos binrios.
Um fluxo de texto (text stream) composto por uma sequncia
de caracteres, que pode ou no ser dividida em linhas, terminadas
por um caractere de final de linha. Um fluxo binrio (binary stream)
composto por uma sequncia de bytes, que so lidos, sem traduo,
diretamente do dispositivo externo. A Figura 3.1 ilustra estes dois tipos
de fluxos.

61

Programao 2

Figura 3.1: Fluxo de dados

No fluxo de texto, os dados so armazenados como caracteres


sem converso para a representao binria. Cada um dos caracteres
ocupa um byte. O nmero 12 ocupa dois bytes e o nmero 113 ocupa
3 bytes. Um caractere em branco foi inserido entre cada um dos
nmeros para separ-los, de modo que a funo de entrada e sada
possa descobrir que so dois nmeros inteiros (12 e 113) e no o
nmero 12113. No fluxo binrio, cada nmero inteiro ocupa 32 bits (4
bytes) e armazenado na forma binria. Observem que, em arquivos
binrios, no h necessidade de separar os nmeros j que eles
sempre ocupam 32 bits.
Os arquivos binrios so utilizados quando queremos armazenar
registros completos. Com estes arquivos, poderemos acessar
qualquer registro de forma mais rpida. No caso dos arquivos texto,
quando queremos encontrar alguma informao, temos que fazer uma
varredura sequencial no arquivo, tornando a busca pouco eficiente.
Neste captulo, ser dada nfase ao armazenamento de dados
em arquivos binrios. Nas prximas sees, iremos conhecer os
comandos para manipular este tipo de arquivo.
3.1.2 Ponteiros
Antes de comearmos a conhecer os comandos de manipulao
de arquivos binrios, vamos ver um conceito que ser utilizado
neste captulo, que : ponteiro. Um ponteiro um tipo de varivel
que armazena um endereo de memria. Ns j vimos variveis que
armazenam nmeros inteiros, nmeros reais e caracteres. Ao trabalhar
com arquivos, precisamos saber em qual endereo de memria o
arquivo est armazenado. O endereo de memria onde o arquivo
62

Programao 2

est armazenado ser colocado em uma varivel que armazena


endereo de memria (ponteiro).
Para declarar uma varivel que capaz de armazenar um endereo
de memria, usamos a seguinte sintaxe:
Sintaxe

tipo

*nome_do_ponteiro;

Onde:
tipo: tipo de varivel que o ponteiro armazena endereo.
Podemos dizer que nosso ponteiro armazena o endereo de
uma varivel inteira, real, caractere, etc. Para este captulo,
estaremos utilizando um ponteiro que vai armazenar o endereo
de um arquivo.
*: o asterisco na frente do nome de uma varivel simboliza que
a varivel que est sendo declarada um ponteiro.
nome_do_ponteiro: daremos um nome nossa varivel que
armazena endereos.
O exemplo 3.1 apresenta exemplos de declaraes de ponteiros
que armazenam endereos de memria de arquivos.
Exemplo 3.1: Declarao de ponteiros para arquivos

FILE *p aluno;

FILE *p produto;

Na linha 1, temos a declarao do ponteiro paluno, que ir


armazenar o endereo de um arquivo (FILE). Devemos colocar o
FILE em maisculo. Na linha 2, temos a declarao de outro ponteiro,
pproduto, que armazena o endereo de um FILE.
Quando queremos inicializar uma varivel real ou inteira, atribumos
zero s mesmas. Quando precisarmos inicializar um ponteiro,
devemos atribuir: NULL. Quando um ponteiro armazena NULL, quer
dizer que ele no est armazenando um endereo no momento.
Tenham calma, daqui a pouco o conceito de ponteiros ficar mais
claro. Vamos comear a conhecer os comandos de manipulao de
arquivos binrios e entenderemos melhor onde o conceito de ponteiro
ser aplicado.
63

Programao 2

3.2 Comandos para manipular arquivos


binrios
Como j mencionado, os arquivos binrios so utilizados quando
queremos armazenar registros. como se tivssemos um vetor de
registro, s que os dados no so perdidos ao terminar a execuo do
programa. A figura 3.2 mostra a representao grfica de um arquivo
binrio.

Figura 3.2: Representao grfica de um arquivo binrio

O arquivo binrio formado por um conjunto de registros,


armazenados um aps o outro. As operaes realizadas em um
arquivo binrio dependero do local onde se encontrar o leitor. Pense
no leitor como se fosse a agulha de uma vitrola (Figura 3.3). Para
tocar uma msica, a agulha passa sobre o disco, fazendo a leitura da
msica. Dependendo de onde a agulha seja posicionada, tocada
uma msica do disco.

Figura:3.3: Vitrola com agulha tocando uma msica

O leitor do arquivo passar sobre os registros, fazendo a leitura


dos mesmos. Ns podemos colocar o leitor sobre qualquer registro
e executar uma operao sobre o mesmo (leitura e/ou gravao). O
arquivo tem uma marcao indicando onde ele termina (end of file).
Nas prximas sees, iremos detalhar os comandos para manipular
arquivos binrios. As operaes para a manipulao de arquivo esto
na biblioteca stdio.h. Com isso, ao trabalhar com arquivos, devemos
64

Programao 2

incluir esta biblioteca nos nossos programas.


3.2.1 Declarao de um ponteiro para arquivo
Na linguagem C, as funes que manipulam arquivos trabalham
com o conceito de ponteiros para arquivo. Com isso, teremos
uma varivel que armazenar o endereo de memria onde est
armazenado nosso arquivo. Ns vimos na seo 3.2.1 (exemplo 3.1),
como fazemos para declarar um ponteiro para um arquivo. Devemos
declarar um ponteiro para cada arquivo que formos manipular no
nosso programa.
3.2.2 Comando para abrir um arquivo
A maior parte das operaes sobre um arquivo (leitura, gravao,
etc) s pode ser executada com o arquivo aberto. O comando de
abertura do arquivo (fopen) apresenta a seguinte sintaxe:
Sintaxe

ponteiro_arquivo = fopen(nome_do_arquivo,

modo_de_abertura);

Onde:
ponteiro_arquivo: ao abrir um arquivo, a funo fopen retorna
o endereo de memria do arquivo. Por conta disso, devemos
atribuir o endereo de memria do arquivo, para um ponteiro.
Aps o arquivo ser aberto, usaremos este endereo de memria
para acess-lo.
nome_do_arquivo: determina qual arquivo dever ser aberto.
Neste espao colocado o nome do arquivo, da forma que
foi salvo no diretrio. O comando fopen procura o arquivo que
desejamos abrir, no mesmo diretrio onde est armazenado o
programa executvel.
modo_de_abertura: informa que tipo de uso voc vai fazer do
arquivo. O modo de abertura indica o que faremos no arquivo:
leitura, gravaes e alteraes. Alm disso, o modo de abertura
tambm vai indicar se queremos que um novo arquivo seja
criado. A tabela abaixo, apresenta os principais modos de
abertura.

65

Programao 2

Modo

Significado

r+b

Abre um arquivo binrio para leitura e escrita. O arquivo deve


existir antes de ser aberto.Dessa forma, este modo de abertura
s pode ser usado se o arquivo que estamos querendo abrir, j
existe no nosso computador.

w+b

Cria um arquivo binrio para leitura e escrita. Se o arquivo no


existir, ele ser criado. Se j existir, o contedo anterior ser
destrudo. Este modo de abertura tem a capacidade de criar novos
arquivos. Mas, se solicitarmos que seja aberto um arquivo que j
existe, o contedo do arquivo ser apagado.

a+b

Acrescenta dados ou cria um arquivo binrio para leitura e escrita.


Caso o arquivo j exista, novos dados podem ser adicionados,
apenas, no final do arquivo. Se o arquivo no existir, um novo
arquivo ser criado.

O exemplo 3.2, apresenta o uso do fopen.


Exemplo 3.2: Abertura de arquivo

FILE *paluno, *pprofessor;

paluno = fopen(alunos.bin, w+b);

pprofessor = fopen(professores.bin, r+b);

if (pprofessor == NULL)

printf(Arquivo de professores no existe);

Na linha 1, temos a declarao de dois ponteiros para armazenar


os endereos dos arquivos que iremos abrir logo em seguida.
Na linha 2, temos um fopen que ir abrir o arquivo alunos.bin,
utilizando o modo de abertura w+b. Caso o arquivo alunos.bin no
exista, ele ser criado (com o nome que passamos como parmetro).
Normalmente, usamos o modo de abertura w+b quando executamos
o nosso programa pela primeira vez. Neste momento, o arquivo ainda
no existe. Dessa forma, desejamos que o mesmo seja criado. Mas,
se o arquivo alunos.bin j existir, todo o seu contedo ser apagado.
E, como resultado, teremos o arquivo aberto, mas sem nenhum
registro armazenado. Ao abrir o arquivo, o endereo de memria do
arquivo ser armazenado no ponteiro paluno.
Na linha 3, temos um fopen que abrir o arquivo professores.
bin, utilizando o modo de abertura r+b. Este modo de abertura s
utilizado para arquivos que j existem, pois, diferente do modo de
abertura w+b, ele no tem a capacidade de criar um arquivo novo. Se
tentarmos abrir um arquivo que no existe, o fopen retornar NULL.
66

Programao 2

Para saber se um arquivo foi aberto corretamente, podemos fazer


um teste como mostra as linhas 4 e 5. Aps executar um fopen,
verificamos se o ponteiro est com NULL. Caso afirmativo, porque a
abertura no foi executada corretamente.
Uma vez aberto, o arquivo fica disponvel para leituras e gravaes
atravs da utilizao de funes adequadas.
3.2.3 Comando para fechar um arquivo
Aps terminar de usar um arquivo, devemos fech-lo. Para isso,
usamos a funo fclose, que tem a seguinte sintaxe.
Sintaxe

fclose(ponteiro_arquivo);

Onde:
ponteiro_arquivo: o ponteiro que tem armazenado o
endereo de memria do arquivo que queremos fechar.
S podemos fechar arquivos que esto abertos. O exemplo 3.3,
apresenta o uso do comando fclose. Vamos utilizar os ponteiros
declarados no exemplo anterior.
Exemplo 3.3: Fechamento de arquivo

fclose(palunos);

fclose(pprofessores);

Na linha 1, fechamos o arquivo que est armazenado no endereo


de memria palunos (que o ponteiro que armazena o endereo do
arquivo). Ns s utilizamos o nome do arquivo (o nome que est salvo
no diretrio), no momento da abertura. Depois de aberto, s utilizamos
seu endereo de memria, certo?
3.2.4 Comando para ler um registro armazenado no arquivo
Vamos aprender a ler os dados de um registro armazenado no
arquivo? Neste comando, teremos vrios detalhes e devemos ter em
mente o seguinte:
A leitura feita a partir do ponto onde o leitor se encontra. Ao
abrir o arquivo, o leitor posicionado no incio do primeiro
67

Programao 2

registro, como mostra a figura 3.2. medida que vamos


executando leituras, o leitor vai se deslocando. Dessa forma,
precisamos ter noo da posio onde o leitor se encontra.
Nos arquivos binrios, SEMPRE fazemos a leitura de um
registro completo, independente de quantos campos ele tenha.
Um arquivo deve armazenar registro do mesmo tipo. Se os
registros so do mesmo tipo, cada um deles ocupar o mesmo
espao de memria. Dessa forma, o leitor sempre se deslocar
em intervalos regulares. Vamos entender isto melhor, daqui a
pouco.
Vamos, primeiro, ver a sintaxe do comando de leitura:
Sintaxe

fread (&registro, numero_de_bytes, quantidade,


ponteiro_arquivo);

Onde:
&registro: o registro que armazenar os dados do registro
lido do arquivo. assim, ns pegamos um registro que est no
arquivo, e armazenamos no registro passado como parmetro.
numero_de_bytes: na verdade, o que o comando de leitura
faz informar que o leitor precisa se deslocar, fazendo a leitura
de uma certa quantidade de bytes. A quantidade de bytes que o
leitor deve se deslocar exatamente quantos bytes de memria
o registro ocupa. Por exemplo: se o nosso arquivo armazena
registros de alunos, composto pelos campos: matricula (int),
nota1 (float), nota2 (float) e media (float). Sabe-se que um int
ocupa 4 bytes e um float, tambm, ocupa 4 bytes. Dessa forma,
teremos: 4 bytes para a matricula + 4 bytes para a nota1 + 4
bytes para a nota2 + 4 bytes para a media = 16 bytes. Assim,
esse registro ocupa 16 bytes (Figura 3.4). esse o nmero de
bytes que o leitor dever ler, para recuperar o registro de um
aluno, armazenado no arquivo. Existe uma funo chamada
sizeof que informa quantos bytes ocupa um tipo de dado.
Assim, no precisamos estar lembrados de quantos bytes um
int ocupa. Alm disso, no precisamos fazer as contas para
saber quantos bytes o nosso registro ocupa. Para utilizar a
funo sizeof, precisamos apenas, passar como parmetro
68

Programao 2

para a funo, que tipo de dado queremos saber quantos bytes


ele ocupa. Por exemplo: sizeof(int) ou sizeof(TAluno). No caso
de um registro, a funo vai fazer as contas de quantos bytes
cada um dos campos do registro ocupa, e retorna a soma.
4 bytes

4 bytes

4 bytes

4 bytes

matricula

nota1

nota2

media

Figura 3.4: Campos do registro aluno

quantidade: neste terceiro parmetro, usaremos SEMPRE 1.


Este parmetro significa quantas vezes a leitura ser executada.
Ns sempre queremos que seja feita a leitura de um registro
por vez. Por isso, sempre utilizaremos 1.
ponteiro_arquivo: precisamos informar em qual arquivo a
leitura ser feita. Com isso, passamos o endereo de memria
onde o arquivo que ser lido est armazenado. Assim, utilizamos
o ponteiro que tem o endereo do arquivo.
Agora vamos ver o exemplo 3.4, que apresenta a leitura de um
registro do arquivo. Para um melhor entendimento, foram feitas as
declaraes das variveis que sero usadas no fread.
Exemplo 3.4: Leitura de um registro do arquivo

typedef { int matricula;

float nota1, nota2, media;


} TAluno

4
5

TAluno aluno;

FILE *paluno;

7
8

fread(&aluno, sizeof(TAluno), 1, paluno);

Nas linhas 1 a 3 temos a declarao de um novo tipo de dado,


que o agrupamento dos dados do aluno. Este tipo foi chamado de
TAluno. Na linha 5, temos a declarao da varivel aluno, que um
69

Programao 2

registro do tipo TAluno. Na linha 6 declaramos um ponteiro chamado


paluno, que armazena endereo de memria de arquivo.
Ateno
No esquecer
de colocar o & na
frente da varivel.
5

Na linha 8 que temos o comando de leitura. Vamos interpretar


cada parte do comando. No primeiro parmetro, temos a varivel
registro que vai armazenar as informaes lidas do arquivo5. Assim, o
registro que for lido do arquivo, ser armazenado no registro aluno. No
segundo parmetro, precisamos dizer quantos bytes sero lidos. Se
iremos ler os dados do registro do aluno, precisamos saber quantos
bytes ele ocupa. Para isso, foi usada a funo sizeof. Como parmetro
do sizeof foi colocado TAluno, que um tipo criado no programa e que
queremos saber quantos bytes esse tipo de dado ocupa. No terceiro
parmetro, ns sempre usaremos 1. Finalmente, no quarto parmetro
informamos o endereo do arquivo em que ser feita a leitura. Neste
caso, o endereo do arquivo est armazenado no ponteiro paluno.
Aps a leitura de um registro do arquivo, o leitor estar posicionado
no incio do prximo registro. A Figura 3.5 apresenta a posio do
leitor antes e depois da execuo do fread.

Figura 3.5: Posio do leitor antes e aps a execuo de um fread

Agora que j sabemos como fazer para ler um registro que est
armazenado no arquivo, vamos aprender a gravar um registro no
arquivo.

70

Programao 2

3.2.5 Comando para gravar um registro no arquivo


Para gravar um registro em um arquivo binrio, ns utilizamos
o comando fwrite. Este comando muito parecido com o fread.
A diferena que o fread l uma sequncia de bytes no arquivo, e
armazena em um registro (primeiro parmetro do fread). E o fwrite,
pega um registro, e armazena suas informaes no arquivo. Vamos
ver a sintaxe do fwrite:
Sintaxe

fwrite(&registro, numero_de_bytes, quantidade,


ponteiro_arquivo);

Onde:
&registro: o registro que ser armazenado no arquivo.
numero_de_bytes: a quantidade de bytes que sero
gravadas no arquivo. Neste parmetro, tambm usaremos o
sizeof.
quantidade: neste terceiro parmetro, tambm, usaremos
SEMPRE 1. Este parmetro significa quantas vezes a gravao
ser executada. Ns sempre queremos que seja feita a
gravao de um registro por vez. Por isso, sempre utilizaremos
1.
ponteiro_arquivo: precisamos informar em qual arquivo a
gravao ser feita. Assim, utilizamos o ponteiro que tem o
endereo do arquivo.
Agora vamos ver o exemplo 3.5, que apresenta a gravao de um
registro no arquivo. Para um melhor entendimento, foram feitas as
declaraes das variveis que sero usadas no fwrite.

71

Programao 2

Exemplo 3.5: Leitura de um registro do arquivo

typedef { int matricula;

float nota1, nota2, media;

} TAluno

4
5

TAluno aluno;

FILE *paluno;

7
8

fwrite(&aluno, sizeof(TAluno), 1, paluno);

Na linha 8 que temos o comando de gravao. Vamos interpretar


cada parte do comando. No primeiro parmetro, temos a varivel
registro que ser gravada no arquivo. No segundo parmetro,
precisamos dizer quantos bytes sero gravados. Para isso, foi usada
a funo sizeof. No terceiro parmetro, ns sempre usaremos 1.
Finalmente, no quarto parmetro informamos o endereo do arquivo
em que ser feita a gravao. Neste caso, o endereo do arquivo est
armazenado no ponteiro paluno.
Devemos lembrar que o comando de gravao no arquivo (fwrite)
executado na posio onde o leitor se encontra no momento. Se o
leitor estiver posicionado no incio de um registro e executarmos um
fwrite, o registro ser gravado sobre o outro. Dessa forma, quando
vamos inserir um novo registro no arquivo, devemos posicionar o leitor
num ponto do arquivo que no tenha nenhum registro armazenado,
ou seja, no final do arquivo. Vamos ver como faz isso?
3.2.6 Comando para posicionar o leitor em um ponto do
arquivo
As operaes de leitura e gravao so feitas na posio onde o
leitor se encontra no momento. Podemos mudar a posio do leitor,
colocando-o em um ponto especfico do arquivo. Este comando o
fseek. A sintaxe do fseek a seguinte:
Sintaxe

fseek(ponteiro_arquivo,numero_de_bytes, origem);

72

Programao 2

Onde:
ponteiro_arquivo: precisamos informar em qual arquivo o leitor
est sendo posicionado.
numero_de_bytes: a quantidade de bytes que o leitor ir se
deslocar pelo arquivo, at chegar no local desejado.
origem: determina a partir de onde os nmero_de_bytes de
deslocamento do leitor sero contados. Os possveis valores
so:
Origem

Significado

SEEK_SET

O deslocamento do leitor ser contado a partir do incio do


arquivo.

SEEK_CUR

O deslocamento do leitor ser contado a partir da sua posio


corrente.

SEEK_END

O deslocamento do leitor ser contado a partir do final do


arquivo.

O exemplo 3.6 apresenta o uso do comando fseek.


Exemplo 3.6: Comando fseek

fseek(paluno, 0,SEEK_END);

fseek(paluno, 2*sizeof(paluno), SEEK_SET);

No exemplo da linha 1, temos um fseek que ser muito utilizado


em nossos programas. Neste fseek solicitado que seja feito
o posicionamento do leitor do arquivo de endereo paluno. O
deslocamento do leitor ser feito iniciando a contagem a partir do
fim do arquivo (SEEK_END)6. O nmero de bytes que o leitor ir se
deslocar 0. Este tipo de fseek usado quando queremos gravar um
novo registro do nosso arquivo. Jogamos o leitor para o fim do arquivo
e no deslocamos nenhum byte. Com isso, temos a garantia que o
leitor no est sobre nenhum registro. Dessa forma, podemos gravar
um novo registro, sem perder registros que j haviam sido gravados
no nosso arquivo.
No fseek da linha 2, foi solicitado que o leitor seja posicionado no
incio do arquivo (SEEK_SET), antes do deslocamento ser efetivado.
Notem que, no segundo parmetro, foi passada uma expresso 2 * o
tamanho de um registro. Neste caso, significa que o leitor ir deslocar
a quantidade de bytes ocupadas por 2 registros, com isso, ir se
posicionar no incio do terceiro registro.
73

Ateno
6
O parmetro
origem, deve ser
colocado todo em
letra maiscula.

Programao 2

A figura 3.6 apresenta a posio do leitor aps a execuo dos


fseek do exemplo.

Figura 3.6: Posio do leitor aps a execuo dos fseek do exemplo 3.6

3.2.7 Comando para posicionar o leitor no incio do arquivo


Ns podemos posicionar o leitor no incio do arquivo, utilizando o
comando rewind. A sua sintaxe a seguinte:
Sintaxe

rewind(ponteiro_arquivo);

Onde:
ponteiro_arquivo: o ponteiro que tem o endereo do arquivo
que queremos posicionar o leitor.
O exemplo 3.7 apresenta o uso do comando rewind.
Exemplo 3.7: Uso do comando rewind

rewind(paluno);

O comando rewind utilizado quando precisamos fazer uma


varredura por todos os registros do arquivo. A varredura iniciada
colocando o leitor no incio do arquivo.
74

Programao 2

3.2.8 Comando para verificar se chegou ao final do arquivo


Quando fazemos uma varredura no arquivo, no sabemos quantos
registros tem armazenados no mesmo. No entanto, precisamos saber
o momento de parar de executar a leitura dos registros. O comando
feof (end of file) informa se o leitor chegou ao final do arquivo ou no.
A sintaxe do feof a seguinte:
Sintaxe

int feof(ponteiro_arquivo);

Onde:
int: o retorno da funo. A funo feof retorna um nmero
inteiro, que indica se o arquivo terminou ou no. Quando a
funo retorna zero, significa que ainda no chegou no final do
arquivo. Qualquer valor diferente de zero, indica que chegou ao
final do arquivo.
ponteiro_arquivo: o ponteiro que tem o endereo do arquivo
que queremos verificar se chegou ao fim.
O exemplo 3.8 apresenta o uso do comando feof.
Exemplo 3.8: uso do comando feof

while (feof(paluno)==0)

Normalmente, o feof usando como condio de um while, como


mostra o exemplo 3.8. Este while ser executado enquanto no
chegar no final do arquivo.
3.2.9 Comando para remover um arquivo
Quando desejamos apagar um arquivo do diretrio, podemos
utilizar o comando remove. Este comando s pode ser utilizado em
arquivos fechados. A sua sintaxe a seguinte:
Sintaxe

remove(nome_do_arquivo);

Onde:
nome_do_arquivo: o nome do arquivo que queremos apagar.
75

Programao 2

Neste caso, utilizado o nome do arquivo salvo no diretrio do


nosso computador.
O exemplo 3.9 apresenta o uso do comando remove.
Exemplo 3.9: uso do comando remove

remove(alunos.bin);

Neste exemplo,
computador.

arquivo

alunos.bin

ser

removido

do

3.2.10 Comando para renomear um arquivo


Ns podemos renomear um arquivo no diretrio do nosso
computador. Para isso, utilizamos o comando rename. Este comando,
tambm, s pode ser utilizado em arquivos fechados. A sua sintaxe
a seguinte:
Sintaxe

rename(nome_do_arquivo, novo_nome_do_arquivo);

Onde:
nome_do_arquivo: o nome do arquivo que queremos
renomear. Neste caso; utilizado o nome do arquivo salvo no
diretrio do nosso computador.
novo_nome_do_arquivo: o novo nome para o nosso
arquivo.
O exemplo 3.10 apresenta o uso do comando rename.
Exemplo 3.10: uso do comando rename

rename(alunos.bin, alunos_temp.bin);

Neste exemplo, o arquivo alunos.bin, ser renomeado para


alunos_temp.bin.

3.3 Implementao das operaes bsicas


em um arquivo
Agora a hora de fazermos o nosso programa completo, que
76

Programao 2

ir aplicar os comandos de manipulao de arquivo, descritos na


seo 3.2. Este programa ir gerenciar os dados dos alunos de uma
turma, que sero armazenados em um arquivo. O registro do aluno
composto pela matrcula, nome e mdia do aluno. O programa
implementar as seguintes operaes: cadastrar aluno, remover
aluno, consultar aluno por matrcula, alterar mdia do aluno e listagem
de todos os alunos.
Mais uma vez, teremos um programa cheio de detalhes, bem maior
do que os que fizemos at ento. Por isso, o programa completo 3.1
foi desenvolvido de forma modularizada. Para facilitar o entendimento
deste programa, que tem quase 200 linhas, o mesmo foi dividido em 8
partes. Vamos comear?
Na primeira parte do programa completo 3.1, teremos as
declaraes das variveis globais do programa. Alm, de mdulos
auxiliares, que sero utilizados ao longo do programa, por outros
mdulos.
Programa Completo 3.1- Parte 1
1

#include <stdio.h>

2
3

typedef struct{ int mat;

char nome[20];

float med;

} TAluno;

7
8

FILE *paluno;

TAluno aluno_aux, aluno_nulo;

10
11

void linha()

12

{ int i;

13

for (i=1; i<=80; i++)

14

15

printf(_);

16

77

Programao 2

17

void cabec()

18

{ system(cls);

19

printf(Universidade
Pernambuco\n);

20

linha();

21

Federal

Rural

de

22
23

void abre_arquivo()

24

{ paluno = fopen(aluno.dat, r+b);

25

if (paluno == NULL)

26

27

paluno = fopen(aluno.dat, w+b);

Comentrios sobre o Programa Completo 3.1, Parte 1:


Linha 1: incluso da biblioteca stdio.h devido o uso do comando
fflush e comandos de manipulao de arquivo.
Linhas 3 a 6: definio de um novo tipo de dados TAluno,
que agrupa os dados de um aluno. O tipo TAluno composto
pela matrcula, nome e mdia do aluno.
Linha 8: declarao do ponteiro paluno, que armazenar o
endereo do arquivo com os registros dos alunos.
Linha 9: declarao de dois registros: aluno_aux e aluno_nulo.
O registro aluno_aux, ser utilizado quando precisamos ler
ou gravar um registro no arquivo. O registro aluno_nulo ser
utilizado no momento da remoo de um aluno do arquivo.
As variveis declaradas nas linhas 8 e 9 so globais, por isso,
podem ser acessadas por todos os mdulos do programa.
Linhas 11 a 15: temos o primeiro mdulo do nosso programa. O
mdulo linha tem como objetivo, passar uma linha na tela. Este
mdulo ser chamado pelos demais mdulos do programa.
Linhas 17 a 21: temos a sequncia de comandos do mdulo
cabec. O mdulo cabec faz o cabealho das tela. Ao iniciar uma
operao do programa (cadastro, remoo, etc), a tela deve ser
limpa e precisamos colocar o nome da universidade no topo
78

Programao 2

da tela. O mdulo cabec vai: limpar a tela, colocar o nome da


instituio e passar uma linha (fazendo uso do mdulo linha).
Linhas 23 a 27: temos a sequncia de comandos do mdulo
que responsvel por abrir o arquivo dos alunos, e deix-lo
disponvel para uso. Vamos entender a lgica deste mdulo?
Primeiramente, feita uma tentativa de abrir o arquivo dos
alunos alunos.dat com o modo de abertura r+b, no comando
fopen. Lembrem que o modo de abertura r+b s pode ser
utilizado quando o arquivo j existe. O processador vai procurar o
arquivo alunos.dat no diretrio. Se o arquivo no for encontrado,
o ponteiro paluno, ficar com NULL. Mas, se for encontrado, o
endereo de memria do arquivo ser armazenado no ponteiro
paluno. Na sequncia (linha 25), temos um if que testa o valor
do ponteiro paluno. Se o ponteiro paluno estiver com NULL,
significa que o arquivo alunos.dat no existe ainda e precisa
ser criado. Se isso acontecer, o comando vinculado ao if
executado. Este comando um fopen, s que agora utiliza o
modo de abertura w+b, que deve ser utilizado para arquivos
que no existe. Mas, por que no abrimos o arquivo usando
logo o w+b? Vocs devem estar lembrados, que o modo de
abertura w+b apaga todos os registros de um arquivo quando
ele j existe. Assim, tentamos primeiro abrir o arquivo com r+b
(utilizado para arquivos que j existem e abre o arquivo sem
apagar os registros). Se der erro, porque o arquivo no existe.
Com isso, tentamos abrir com o modo de abertura w+b.
Vamos agora para a parte 2 do programa completo 3.1. Nesta
parte temos o mdulo inserir, que responsvel pelo cadastro dos
registros dos alunos no arquivo. Para fazer o cadastro de um registro
no arquivo binrio, devemos obter os dados do aluno, montando o
registro que iremos gravar no arquivo. Quando o registro estiver com
todas as informaes do aluno (mat, nome e media), o mesmo poder
ser gravado no final do arquivo.

79

Ateno
7
O nome do
arquivo que
ns passarmos
como parmetro
no fopen ser
utilizado para
salvar nosso
arquivo no
diretrio. Por
exemplo, aps
a execuo do
mdulo abre_
arquivo, teremos
um arquivo
chamado alunos.
dat no diretrio
onde est salvo
o programa
executvel. Por
conveno,
coloque os
arquivos de
dados sempre
com a extenso
dat ou bin.

Programao 2

Programa Completo 3.1- Parte 2


28

void inserir()

29

{ int resp;

30

do { cabec();

31

printf(\n\nCadastrar novo aluno\n\n);

32

printf(\nMatricula: );

33

scanf(%d, &aluno_aux.mat);

34

printf(\nNome.....: );

35

fflush(stdin);

36

gets(aluno_aux.nome);

37

printf(\nMedia....: );

38

scanf(%f, &aluno_aux.med);

39

fseek(paluno, 0, SEEK_END);

40


fwrite(&aluno_aux,
paluno);

41


printf(\n\nAluno cadastrado com sucesso!
\n\n);

42


printf(\nDeseja
(1-sim/0-nao)? );

43

44

} while (resp ==1);

45

sizeof(TAluno),

cadastrar

1,

outro

scanf(%d, &resp);

Comentrios sobre o Programa Completo 3.1, Parte 2


Linha 28: incio do mdulo inserir.
Linha 29: declarao da varivel resp. Esta varivel ir
armazenar a resposta do usurio, quando for perguntado se ele
deseja cadastrar mais alunos.
Linha 30: incio de um do/while. O mdulo inserir ficar
executando enquanto o usurio desejar cadastrar novos alunos.
Nesta linha, tambm temos a chamada do mdulo cabec. Cada
vez que um cadastro feito, a tela vai ser limpa, para iniciar um
80

Programao 2

novo cadastro.
Linha 31: printf que informa o que esta tela faz cadastro de
alunos.
Linhas 32 e 33: printf solicitando que seja digitada a matrcula
do aluno e scanf que l esta informao. Os dados do aluno
vo sendo colocados no registro aluno_aux.
Linhas 34 a 36: printf solicitando que seja digitado o nome do
aluno, fflush para limpar o buffer de entrada (j que teremos a
leitura de uma sequncia de caractere) e o gets que l o nome
do aluno e armazena no registro aluno_aux.
Linhas 37 e 38: printf solicitando que seja digitada a mdia do
aluno e scanf que l esta informao. Neste momento, o registro
aluno_aux acabou de ser todo preenchido com os dados do
aluno e j pode ser gravado no arquivo.
Linha 39: para gravar o registro no arquivo, devemos posicionar
o leitor no final do arquivo para no correr o risco de fazer a
gravao sobre algum outro registro. Para isso, executado o
fseek.
Linha 40: com o leitor posicionado no final do arquivo, podemos
executar o fwrite, que vai gravar o contedo do registro aluno_
aux, no nosso arquivo.
Linha 41: printf para informar que o aluno foi cadastrado com
sucesso.
Linhas 42 e 43: printf para pergunta se o usurio deseja
cadastrar outro aluno e scanf que l a resposta para esta
pergunta.
Linha 44: final do do/while, com a condio de parada. O do/
while executado enquanto o usurio estiver respondendo que
quer cadastrar mais alunos. Notem que, no precisamos nos
preocupar com a capacidade do arquivo. Vamos armazenando
quantos registros desejarmos.
Linha 45: fecha chaves que indica o final do mdulo inserir.
A figura 3.7 apresenta a tela de execuo do programa 3.1, na tela
de cadastro de novo aluno.

81

Programao 2

Figura 3.7: Tela de cadastro de aluno

Vamos ver agora o cdigo de dois mdulos que sero utilizados


pelos mdulos: consultar aluno por matrcula, remover aluno e alterar
mdia do aluno. Quando fazemos uma consulta, alterao ou remoo,
precisamos localizar o registro do aluno no arquivo e apresentar o
registro para o usurio. Por isso, foi criado um mdulo responsvel
para procurar um registro no arquivo e, outro mdulo, responsvel por
apresentar os dados do registro de um aluno. Vamos l, entender a
parte 3 do nosso programa completo 3.1!
Programa Completo 3.1- Parte 3
46

int procura(int matp)

47

{ int p;

48

p = 0;

49

rewind(paluno);

50

fread(&aluno_aux, sizeof(TAluno), 1, paluno);

51

while (feof(paluno)==0)

52

53

54

55
56

if (aluno_aux.mat == matp)

else


{
paluno);

return p;

fread(&aluno_aux,

p++;

82

sizeof(TAluno),

1,

Programao 2

57

58

59

return -1;

60

61
62

void mostre(int pos)

63

{ fseek(paluno, pos*sizeof(TAluno), SEEK_SET);

64

fread(&aluno_aux, sizeof(TAluno), 1, paluno);

65

printf(\n\n);

66

linha();

67

printf(Matricula

68

linha();

69

printf(%9d

70

71

linha();

72

%-20s

Nome

Media\n);

%5.1f\n, aluno_aux.mat,

aluno_aux.nome, aluno_aux.med);

Comentrios sobre o Programa Completo 3.1, Parte 3:


Linhas 46 a 60: temos a sequncia de comandos do mdulo
procura. O mdulo recebe um parmetro, que a matrcula do
aluno que est sendo procurado. Ao finalizar a sua execuo,
esse mdulo retorna um int que pode ser: -1 (significa que
procurou o registro do aluno no arquivo e no achou) ou um
nmero positivo (que significa em qual posio do arquivo
o registro foi encontrado). Este mdulo possui uma varivel
local p, que incrementada cada vez que feita a leitura de
um registro no arquivo. o valor desta varivel que indica em
que posio do arquivo o registro foi encontrado. Para localizar
o registro de um aluno, com uma dada matrcula, precisamos
percorrer todo o arquivo, at encontrar o registro ou at o
arquivo chegar ao fim. Para percorrer o arquivo, colocamos
o leitor no incio do mesmo (usando o rewind linha 49) e
efetuamos vrios fread, at que chegue no final do arquivo
(while da linha 51). Logo aps posicionar o leitor no incio do
83

Programao 2

arquivo, fazemos a leitura do primeiro registro do arquivo, para


verificar se no o final de arquivo (end of file). Lembrem que,
assim que um fread executado, o leitor j fica posicionado no
incio do prximo registro, pronto para um novo fread. Quando
um registro do arquivo tem a mesma matrcula que est sendo
procurada, significa que encontramos o aluno. Com isso, j
pode ser dado o retorno, indicando a posio onde o registro
foi encontrado (linha 52 e 53). Se fizermos a leitura de todos
os registros do arquivo e no encontrar nenhum aluno com a
matrcula procurada, o mdulo retornar -1 (linha 59).
Linhas 62 a 72: temos a sequncia de comandos do mdulo
mostre. Este mdulo recebe como parmetro a posio do
registro que deve ser apresentado, recupera o registro no
arquivo e apresenta os dados do registro em forma de tabela.
O mdulo comea com o posicionamento do leitor no incio do
registro que deve ser mostrado (linha 63). Notem que, no fseek,
no campo que indica o tamanho do deslocamento que o leitor
vai dar, feita a conta: pos*sizeof(TAluno). Vamos entender
o porqu desta conta. A varivel pos indica em que posio
o registro est armazenado no arquivo (se ele o primeiro,
segundo, etc.). Consequentemente, saberemos quantos
registros tem armazenados antes do registro que queremos
mostrar. E assim, saberemos sobre quantos registros o leitor
dever se deslocar, at ser posicionado no incio do registro
desejado. Com o leitor no ponto certo, podemos fazer a leitura
do registro do aluno, armazenando seus dados no registro
aluno_aux (linha 64). Aps isto, precisamos apenas apresentar
os dados do aluno (linhas 65 a 71).
Vamos agora entender o mdulo responsvel por consultar um
aluno atravs do seu nmero de matrcula. O mdulo consultar
vai solicitar que o usurio informe a matrcula do aluno que deseja
consultar. Atravs do uso do mdulo procura descoberta em que
posio o registro do aluno se encontra armazenado no arquivo. Se o
aluno estiver armazenado no arquivo, seus dados so apresentados,
atravs do uso do mdulo mostre. Se o aluno no for encontrado,
apresentada uma mensagem de erro.

84

Programao 2

Programa Completo 3.1- Parte 4


73

void consultar()

74

{ int resp, matcon, posicao;

75

do{ cabec();

76

printf(\n\nConsultar Aluno\n\n\n);

77

printf(Matricula do aluno: );

78

scanf(%d, &matcon);

79

posicao = procura(matcon);

80

if (posicao == -1)

81


\n\n);

82

83

84

printf(\n\nMatricula nao encontrada!

else
mostre(posicao);


printf(\n\nDeseja
(1-sim/0-nao)? );

85

86

} while (resp == 1);

87

consultar

outro

scanf(%d, &resp);

Comentrios sobre o Programa Completo 3.1, Parte 4


Linha 73: incio do mdulo consultar.
Linha 74: declarao das variveis locais: resp, matcon
(matricula que ser consultada) e posicao (armazena em que
posio o registro foi localizado).
Linha 75: incio de um do/while. O mdulo consultar ficar
executando enquanto o usurio desejar consultar alunos. Nesta
linha, tambm temos a chamada o mdulo cabec. Cada vez
que uma consulta feita, a tela vai ser limpa, para iniciar uma
nova consulta.
Linha 76: printf que informa o que esta tela faz consultar
aluno.
Linhas 77 e 78: printf solicitando que seja digitada a matrcula
85

Programao 2

do aluno que deseja consultar e scanf que l esta informao.


Linha 79: chamada do mdulo procura, passando a matrcula
que desejamos consultar como parmetro. O retorno do mdulo
procura armazenado na varivel posicao.
Linhas 80 a 83: if que verifica se a varivel posicao tem
armazenado -1. Se sim, porque o aluno no foi encontrado.
Com isso, escrita uma mensagem de erro. Caso posicao no
esteja com -1, porque o aluno foi encontrado e seus dados
devem ser apresentados. Para apresentar os dados do aluno,
fazemos uma chamada ao mdulo mostre, passando a posio
onde o aluno foi encontrado, como parmetro.
Linhas 84 e 85: printf para perguntar se o usurio deseja
consultar outro aluno e scanf que l a resposta para esta
pergunta.
Linha 86: final do do/while, com a condio de parada. O do/
while executado enquanto o usurio estiver respondendo que
quer consultar mais alunos.
Linha 87: fecha chaves que indica o final do mdulo consultar.
A figura 3.8 apresenta a tela de execuo do programa completo
3.1, na tela de consulta aluno por matrcula.

Figura 3.8: Tela de consulta aluno por matrcula

Vamos agora entender o mdulo responsvel por remover um


aluno do arquivo. O mdulo da remoo inicia de forma muito similar
ao da consulta. Primeiro, solicitado o nmero da matrcula do aluno
86

Programao 2

que ser removido, seu registro localizado e apresentado para que o


usurio possa ter certeza que vai remover o registro certo. Na verdade,
um registro no removido do arquivo, o que fazemos gravar sobre
o registro do aluno que queremos remover, um registro com os dados
zerados (aluno_nulo). Assim, toda vez que temos um registro com
a matrcula igual a zero no arquivo, significa que ele um registro
que foi removido. Se o aluno no for encontrado, apresentada uma
mensagem de erro.
Programa Completo 3.1- Parte 5
88

void remover()

89

{ int matrem, conf, resp, posicao;

90

aluno_nulo.mat = 0;

91

aluno_nulo.med = 0;

92

do{ cabec();

93

printf(\n\nRemover aluno\n\n\n);

94

printf(Matricula: );

95

scanf(%d, &matrem);

96

posicao = procura(matrem);

97

if (posicao == -1)

98

99

else

100

101

printf(\n\nDeseja

102

scanf(%d, &conf);

103

if (conf == 1)

printf(\nAluno nao encontrado!!\a);

mostre(posicao);

(1-sim/0-nao)? );

remover

aluno

104


{ f s e e k ( p a l u n o , p o s i c a o * s i z e o f
(TAluno),SEEK_SET);

105


f w r i t e ( & a l u n o _ n u l o ,
sizeof(TAluno), 1, paluno);

106


sucesso!);

107

printf(\n\nAluno

87

removido

com

Programao 2

108

109

110

111

else
printf(\nRemocao cancelada!);


printf(\n\n\nDeseja
(1-sim/0-nao)? );

112

113

} while (resp ==1);

114

remover

outro

scanf(%d, &resp);

Comentrios sobre o Programa Completo 3.1, Parte 5:


Linha 88: incio do mdulo remover.
Linha 89: declarao das variveis locais: resp, matrem
(matricula que ser removida), conf (confirmao se deseja
remover realmente) e posicao (armazena em que posio o
registro foi localizado).
Linhas 90 e 91: inicializao dos campos do registro aluno_
nulo.
Linha 92: incio de um do/while. O mdulo remover ficar
executando enquanto o usurio desejar remover alunos. Nesta
linha, tambm temos a chamada do mdulo cabec. Cada vez
que uma remoo feita, a tela vai ser limpa, para iniciar uma
nova remoo.
Linha 93: printf que informa o que esta tela faz remover
aluno.
Linhas 94 e 95: printf solicitando que seja digitada a matrcula
do aluno que deseja remover e scanf que l esta informao.
Linha 96: chamada do mdulo procura, passando a matrcula
que desejamos remover como parmetro. O retorno do mdulo
procura armazenado na varivel posicao.
Linhas 97 a 110: if que verifica se a varivel posicao tem
armazenado -1. Se sim, porque o aluno no foi encontrado.
Com isso, escrita uma mensagem de erro. Caso posicao no
esteja com -1, porque o aluno foi encontrado e seus dados
devem ser apresentados. Para apresentar os dados do aluno,
88

Programao 2

fazemos uma chamada ao mdulo mostre, passando a posio


onde o aluno foi encontrado como parmetro. Aps ver os dados
do aluno, o usurio pode desistir de remov-lo. Na linha 102,
temos o scanf que l se o usurio confirma ou no a remoo. A
remoo, propriamente dita, executada nas linhas 104 e 105.
Na linha 104 temos o posicionamento do leitor sobre o registro
que queremos remover. E, na linha 105, temos a gravao do
registro aluno_nulo sobre o registro antigo.
Linhas 111 e 112: printf para pergunta se o usurio deseja
remover outro aluno e scanf que l a resposta para esta
pergunta.
Linha 113: final do do/while, com a condio de parada. O do/
while executado enquanto o usurio estiver respondendo que
quer remover mais alunos.
Linha 114: fecha chaves que indica o final do mdulo remover.
A figura 3.9 apresenta a tela de execuo do programa 3.1, na tela
de remoo de aluno.

Figura 3.9: Tela de remoo do registro do aluno

Agora vamos entender o mdulo responsvel pela alterao da


mdia do aluno. Este mdulo parecido com a remoo. Primeiro,
solicitado o nmero da matrcula do aluno que ser alterado, seu
registro localizado e apresentado para que o usurio possa ter
certeza que vai alterar o registro certo. Na alterao, gravamos um
registro com a mdia alterada, sobre o antigo registro do aluno.
89

Programao 2

Programa Completo 3.1- Parte 6


115

void alterar()

116

{ int matalt, conf, resp, posicao;

117

do { cabec();

118


n\n);

printf(\n\nAlterar

media

119

printf(Matricula: );

120

scanf(%d, &matalt);

121

posicao = procura(matalt);

122

if (posicao == -1)

123

124

else

125

126

do

aluno\n\

printf(\nAluno,nao encontrado!!\a);

mostre(posicao);


printf(\n\nAlterar
aluno(1-sim/0-nao)? );

127

scanf(%d, &conf);

128

if (conf == 1)

129

130

media

do

printf(\nNova media: );
scanf(%f, &aluno_aux.med);

131


\n\n);

printf(\nMedia alterada com sucesso!

132


SEEK_SET);

fseek(paluno,posicao*sizeof(TAluno),

133


paluno);

fwrite(&aluno_aux,sizeof(TAluno),

134

135

1,

mostre(posicao);


printf(\nMedia do aluno alterada com
sucesso!\n);

136

137

else

90

Programao 2

138
139
140


\n\n);

printf(\n\nAlteracao

cancelada!


printf(\n\nDeseja
(1-sim/0-nao)? );

141

142

}while (resp ==1);

143

alterar

outro

scanf(%d, &resp);

Comentrios sobre o Programa Completo 3.1, Parte 6:


Linha 115: incio do mdulo alterar.
Linha 116: declarao das variveis locais: resp, matalt
(matricula que ser alterada), conf (confirmao se deseja
alterar a mdia do aluno) e posicao (armazena em que posio
o registro foi localizado).
Linha 117: incio de um do/while. O mdulo alterar ficar
executando enquanto o usurio desejar alterar alunos. Nesta
linha, tambm temos a chamada do mdulo cabec. Cada vez
que uma alterao feita, a tela vai ser limpa, para iniciar uma
nova alterao.
Linha 118: printf que informa o que esta tela faz alterar mdia
do aluno.
Linhas 119 e 120: printf solicitando que seja digitada a matrcula
do aluno que deseja alterar e scanf que l esta informao.
Linha 121: chamada do mdulo procura, passando a matrcula
que desejamos alterar como parmetro. O retorno do mdulo
procura armazenado na varivel posicao.
Linhas 122 a 139: if que verifica se a varivel posicao tem
armazenado -1. Se sim, porque o aluno no foi encontrado.
Com isso, escrita uma mensagem de erro. Caso posicao no
esteja com -1, porque o aluno foi encontrado e seus dados
devem ser apresentados. Para apresentar os dados do aluno,
fazemos uma chamada ao mdulo mostre, passando a posio
onde o aluno foi encontrado como parmetro. Aps ver os dados
do aluno, o usurio pode desistir de alterar a sua mdia. Na
91

Programao 2

linha 127, temos o scanf que l se o usurio confirma ou no a


alterao. Se o usurio confirma que quer alterar, solicitada
a nova mdia do aluno (linha 130). A alterao, propriamente
dita, executada nas linhas 132 e 133. Na linha 132, temos o
posicionamento do leitor sobre o registro que queremos alterar.
E, na linha 133, temos a gravao do registro alterado sobre o
registro antigo. Aps os dados serem alterados, o registro do
aluno reapresentado atravs de uma chamada ao mdulo
mostre (linha 134).
Linhas 140 e 141: printf para pergunta se o usurio deseja
alterar outro aluno e scanf que l a resposta para esta
pergunta.
Linha 142: final do do/while, com a condio de parada. O do/
while executado enquanto o usurio estiver respondendo que
quer alterar mais alunos.
Linha 143: fecha chaves que indica o final do mdulo alterar.
A figura 3.10 apresenta a tela de execuo do programa completo
3.1, na tela de alterao de mdia do aluno.

Figura 3.10: Tela de alterao de mdia do aluno

Veremos, agora, o ltimo mdulo do programa, que a listagem.


Este mdulo responsvel por apresentar todos dados dos alunos
que esto armazenados no arquivo. Os dados sero apresentados
em forma de tabela. Devemos lembrar que s iremos apresentar os
92

Programao 2

registros vlidos do arquivo, ou seja, registros com matrcula zerada


no devem ser apresentados.
Programa Completo 3.1- Parte 7
144

void listagem()

145

{ cabec();

146

printf(\n\nListagem Geral\n\n\n);

147

linha();

148

printf(Matricula

149

linha();

150

rewind(paluno);

151

fread(&aluno_aux, sizeof(TAluno), 1, paluno);

152

while (feof(paluno)==0)

153

154
155
156


mat,

Nome

Media\n);

if (aluno_aux.mat != 0)
printf(%9d

%-20s

%5.1f\n, aluno_aux.

aluno_aux.nome, aluno_aux.med);


fread(&aluno_aux,
paluno);

sizeof(TAluno),

1,

157

158

linha();

159

printf(tecle enter para voltar ao menu...);

160

getche();

161

Comentrios sobre o Programa Completo 3.1, Parte 7


Linha 144: incio do mdulo listagem.
Linha 145: chamada ao mdulo cabec, responsvel por limpar
a tela e escrever o nome da instituio.
Linha 146: printf que informa o que esta tela faz listagem
geral.
Linha 147: chamada do mdulo linha, para iniciar o desenho
da tabela.
93

Programao 2

Linha 148: printf que escreve os cabealhos das colunas da


tabela.
Linha 149: mais uma chamada ao mdulo linha.
Linha 150: posiciona o leitor no incio do arquivo, para que
possamos varrer o arquivo, visitando todos os registros do
arquivo.
Linha 151: Leitura do primeiro registro do arquivo, para verificar
se no o final do arquivo.
Linhas 152 a 157: while que executado enquanto no chegar
no final do arquivo. Para cada registro lido, verificado se o
mesmo tem a matrcula igual a zero. Se sim, o registro no
apresentado na listagem.
Linha 158: chamada do mdulo linha, para fechar a tabela.
Linha 159: printf informando que o usurio deve teclar enter
para sair da listagem.
Linha 160: getche para que possamos ver a listagem.
Linha 161: fecha chaves que indica o final do mdulo listagem.
A figura 3.11 apresenta a tela de execuo do programa completo
3.1, na tela de listagem dos dados de todos os alunos.

Figura 3.11: Tela de listagem de dados de todos os alunos

O programa principal do programa completo 3.1 apresentado a


seguir. no programa principal que sero feitas as chamadas aos
mdulos que o usurio deseja executar no momento.
94

Programao 2

Programa Completo 3.1- Parte 8


162

main()

163

{ int op;

164

abre_arquivo();

165

do{ cabec();

166

printf(\n\nOpcoes: \n\n\n);

167

printf(

1- Cadastrar novo aluno\n\n);

168

printf(

2- Remover aluno\n\n);

169
170


printf(
matricula\n\n);

\n\n);

3-

printf(

4-

Consultar

Alterar

aluno

media

do

por
aluno

171

printf(

5- Listagem geral\n\n);

172

printf(

0- Sair\n\n);

173

linha();

174

printf(Informe a opcao desejada: );

175

scanf(%d, &op);

176

switch(op)

177

{ case 1: inserir(); break;

178

case 2: remover(); break;

179

case 3: consultar(); break;

180

case 4: alterar(); break;

181

case 5: listagem(); break;

182

case 6: limpar(); break;

183

case 0: fclose(paluno); break;

184


invalida!);

185

default:

printf(\n\n\aOpcao

break;

95

Programao 2

186

187

} while (op != 0);

188

Comentrios sobre o Programa Completo 3.1, Parte 8:


Linha 162: incio do programa principal.
Linha 163: declarao da varivel local op, que vai armazenar
a operao que o usurio deseja executar.
Linha 164: chamada do mdulo abre_arquivo, disponibilizando
o mesmo para uso.
Linhas 165 a 187: do/while responsvel por ler a operao
que o usurio que executar e fazer a chamada do mdulo que
executar a implementa a operao.
Linha 188: fecha chaves do programa principal.
A figura 3.12 apresenta a tela de execuo do programa 3.1, na
tela do menu principal, onde informada a operao que desejamos
executar.

Figura 3.12: Tela do menu principal

E assim, terminamos mais um programa completo. Agora, colocar


a mo no teclado e comear a programar, armazenando dados em
arquivos.
96

Programao 2

Atividades e Orientaes de Estudos


Temos agora mais uma lista de exerccios para consolidar o nosso
entendimento do assunto visto neste captulo. Se preparem, pois as
questes esto maiores. Mas, isso bom porque vemos que estamos
fazendo programas interessantes, no mesmo?
1. Faa um programa para um shopping contendo as seguintes
telas:
Tela de Menu
Shopping Center
Opes:
1 .Cadastrar loja
2. Consultar loja
3. Listagem de todas as lojas
0. Sair
Entre com a opo:
Cadastro
Shopping Center
Cadastro de Loja
Cdigo:
Nome:
rea:
Tipo(1-Confeces, 2-Alimentao, 3-Livros, 4- Servios):
Cadastrar outra (1-Sim/0-Nao)?

Consulta
Shopping Center
Consultar Loja
Cdigo da loja que deseja consultar:
Cdigo

Nome

rea

Tipo

Condomnio

xxx

xxxxxxx

xx

xx

xxxx

Consultar outra (1-Sim/0-Nao)?

97

Programao 2

Relatrio Geral
Shopping Center
Listagem Geral
Codigo

Nome

rea

Tipo

Condomnio

xxx

xxxxxxx

xx

xx

xxxxx

xxx

xxxxxxx

xx

xx

xxxxx

xxx

xxxxxxx

xx

xx

xxxxx

Tecle enter para voltar ao menu...

O programa ir armazenar os dados das lojas em um arquivo.


O programa ir calcular o valor do condomnio de cada loja. O
valor do condomnio depende da rea e do tipo da loja. Veja
tabela abaixo:
Tipo da loja

Valor do m

R$ 50

R$ 65

R$ 80

R$ 95

2. Faa um programa para uma Agncia de Turismo armazenando


os dados em um arquivo. O programa dever ter as seguintes
funes: Cadastrar roteiro, Consultar roteiro, Listagem de todos
os roteiros e Simular valor de viagem. A seguir, sugestes de
telas.
Tela Principal
Vida Boa Turismo
Opes:
1- Cadastrar roteiro
2- Consultar roteiro
3- Listagem de todos os roteiros
4- Simular viagem
0- Sair
Entre com a opo:

98

Programao 2

Tela de Cadastro
Vida Boa Turismo
Cadastrar Roteiro
Cdigo:
Pas(1-Brasil, 2-Espanha, -3-Italia):
Cidade:
Diria de Hotel: R$
Diria Aluguel de Carro: R$
Inserir outro(1-sim,2-no)?

Tela de Remoo de Roteiro


Vida Boa Turismo
Consultar Roteiro
Cdigo do roteiro a ser consultado:
Cdigo

Pas

Cidade

xxx

xxxxxxxx

Diria

Hotel

Carro

xxx

xxxx

Consultar outro (1-Sim/0-Nao)?


Tela de Listagem de todos os roteiros
Vida Boa Turismo
Listagem de todos os roteiros
Cdigo

Pas

Cidade

xxx

xxx
xxx

Diria

Hotel

Carro

xxxxxxxx

xxx

xxxx

xxxxxxxx

xxx

xxxx

xxxxxxxx

xxx

xxxx

Pgina x de x... Tecle enter


Tecle enter para voltar ao menu...

99

Programao 2

Tela para simular valor de viagem


Vida Boa Turismo
Simular Viagem
Cdigo do roteiro:
Cdigo

Pas

Cidade

xxx

xxxxxxxx

Diria

Hotel

Carro

xxx

xxxx

Quantidade de dias:
Alugar carro(1-sim, 2-no)?
Valor total da viagem = R$ xxxxx
Simular outro roteiro(1-sim, 2-no)?

Observaes:
Os dados do roteiro devem ser armazenados em um arquivo.
No pode cadastrar roteiros com cdigos repetidos.
O valor da viagem deve ser calculado com base nos valores do
roteiro escolhido; viagem = quantos dias * valor diria hotel +
quantos dias * valor diria carro (caso alugue carro).
Na consulta deve passar o cdigo do roteiro e apresentar os
dados do roteiro.
Na listagem, apresentar os dados de todos os roteiros em forma
de tabela.

Conhea Mais
Para melhorar o nosso conhecimento sobre manipulao de
arquivos binrios, vejam este assunto nos livros:
LAUREANO, Marcos. Programando em C Para Linux, Unix e
Windows. Rio de Janeiro: Brasport, 2005.
MIZRAHI, Victorine Viviane. Treinamento em Linguagem C
Curso Completo. So Paulo: Makron, 1999.

100

Programao 2

Vamos revisar?
Vamos fazer uma reviso do assunto que foi visto neste captulo,
lendo o resumo a seguir:
Os arquivos servem para armazenar nossos dados de forma
definitiva.
Os arquivos binrios so adequados para o armazenamento de
registros.
Cada registro que armazenado no arquivo ocupa a mesma
quantidade de memria.
Toda operao sobre um arquivo ser executada no ponto onde
o leitor se encontra.
Com o comando fseek, podemos colocar o leitor sobre o registro
que desejamos ler ou gravar.
S podemos manipular um arquivo que esteja aberto. Aps o uso
do arquivo, devemos fech-lo.
O arquivo criado pelo programa salvo no mesmo diretrio em
que est armazenado o nosso programa executvel.

101

Programao 2

Consideraes Finais
Neste volume, tivemos a oportunidade de aprender como
armazenar dados em vetores, registros e arquivos. O armazenamento
adequado dos dados possibilitou o desenvolvimento de programas
com operaes mais elaboradas como: cadastro de elementos,
remoo, alterao, consultas e listagens. Perceberam o quanto
nossos programas evoluram desde o nosso primeiro programa
completo, at hoje? Vejam que todos os conceitos que aprendemos
esto sempre em uso nos nossos programas. Isto bom porque nos
acostumamos com a sintaxe dos comandos. Agora, temos apenas
mais um mdulo para finalizar a nossa caminhada, em busca do
aprendizado da linguagem de programao C. Continuem firmes nos
estudos! Estamos quase no final! At o prximo mdulo.

102

Programao 2

Referncias

ARAJO, Jairo. Dominando a Linguagem C. So Paulo:


Cincia Moderna, 2004.

ASCENIO, Ana Fernanda Gomes e CAMPOS, Edilene


Aparecida Veneruchi. Fundamentos de Programao de
Computadores. So Paulo: Prentice Hall, 2002.

DEITEL, H, M e DEITEL, P. J. Como Programar em C. Rio de


Janeiro: LTC, 1999.

LAUREANO, Marcos. Programando em C Para Linux, Unix e


Windows. Rio de Janeiro: Brasport, 2005.

MIZRAHI, Victorine Viviane. Treinamento em Linguagem C


Curso Completo. So Paulo: Makron, 1999.

MONTGOMERY, Eduard. Programando em C: Simples e


Prtico. So Paulo: Alta Books, 2006.

OLIVEIRA, Ulisses. Programando em C Volume I


Fundamentos. So Paulo: Cincia Moderna, 2004.

SCHILDT, Herbert. C Completo e Total. So Paulo: Makron,


1996.

103

Programao 2

Conhecendo a Autora
Sou graduada em Cincia da computao pela Universidade Federal
de Sergipe. Fiz mestrado e doutorado na Universidade Federal de
Pernambuco, desenvolvendo pesquisas nas reas de Sistemas Distribudos
e Geoprocessamento. Comeei a ensinar em 2000, nos cursos de Cincia
da Computao e Sistemas de Informao. Desde o incio da minha carreira
como professora, ministro disciplinas de Programao e tenho uma paixo
pela linguagem C. Atualmente, encontrei uma nova paixo: Educao a
Distncia.

104

You might also like