Você está na página 1de 49

Introdução à

Programação
- Introdução à Linguagem C -

Prof. Dr. Adriano Caminha


adrianocaminha@id.uff.br
Profa. Dra. Vera Prudência Caminha
veraprudencia@id.uff.br

ICEx/UFF

Volta Redonda-RJ
© 1999-2020
Introdução à Programação – Introdução à Linguagem C –

Sumário

Funções ..................................................................................................... 03
Perguntas Básicas para Criação de Funções ......................................... 03
Variáveis Locais ....................................................................................... 04
Chamando uma Função ........................................................................... 04
Passagem de Parâmetros por Valor (Cópia) .......................................... 05
Exercícios .................................................................................................. 06
Ponteiros ................................................................................................... 07
Operadores de Ponteiros ......................................................................... 07
Aritmética de Ponteiros ........................................................................... 08
Comparações com Ponteiros .................................................................... 09
Indireção Simples .................................................................................... 09
Indireção Múltipla ................................................................................... 09
Inicialização de Ponteiros ........................................................................ 10
Passagem de Argumentos por Referência .............................................. 12
Ponteiros e Vetores .................................................................................. 15
Exercícios .................................................................................................. 17
Alocação Dinâmica ................................................................................... 18
Exercícios .................................................................................................. 21
Registros ................................................................................................... 22
Registros Dentro de Registros ................................................................. 23
Vetores e Registros .................................................................................. 25
Registros e Ponteiros ............................................................................... 26
Exercícios .................................................................................................. 28
Arquivos .................................................................................................... 28
Acessando Arquivos em C ....................................................................... 29
Abertura e Fechamento de Arquivos ...................................................... 29
Modos de Abertura de Arquivos ............................................................. 29
Funções para Acessar Dados de Arquivos ............................................. 30

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 2
Introdução à Programação – Introdução à Linguagem C –

Exercícios .................................................................................................. 34

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 3
Introdução à Programação – Introdução à Linguagem C –

Funções

→ Funções são utilizadas para dividir um programa grande em


diversas partes menores, cada parte executando uma pequena tarefa
especifica.
→ O uso de funções modulariza o código facilitando sua reutilização,
aprimoramentos e correções de erros.
→ A linguagem C é formada por funções pré-definidas (bibliotecas) e
instruções.
→ Os programas podem conter funções definidas pelo programador e
funções pré-definidas de C.

Perguntas Básicas para Criação de Funções

→ Importante: Antes de se criar uma função, é boa prática de


programação responder as seguintes perguntas básicas:
1. O que fará a função ? Cálculo? Impressão?
2. Que valores receberá para sua execução?
3. Que resultado deverá retornar? Haverá mesmo um valor de
retorno? Se ele existe, qual o tipo ?
→ Resumindo: Defina a tarefa, a entrada e o retorno.

Sintaxe:
<tipo de retorno> <nome>(<parâmetros>)
{
<declaração das variáveis locais>
<bloco de instrução>
<valor de retorno se existir>
}

Onde:
<tipo de retorno> = float, int, void (“vazio” ou “sem valor de
retorno”), etc.
<nome> = nome da função que será utilizado nas chamadas à função.
<parâmetros> = Lista de valores recebidos pela função para o
cálculo ou tarefa. A função pode não ter parâmetros, neste caso os
parênteses ficarão vazios.

Obs.: Assinatura = primeira linha da declaração da função.


© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 4
Introdução à Programação – Introdução à Linguagem C –

Exemplo: Função que imprime uma linha na tela.


• tarefa = imprimir linha,
• entrada = nenhum valor,
• retorno = nenhum valor.
#include <stdio.h>
//definição da função
void linha()
{
printf("\n--------------------------\n");
}
//função main com chamadas à função
int main()
{ linha(); //chamada à função
printf("Aprendendo funcoes...");
linha(); //quantas vezes for necessário
printf("Cada linha foi uma chamada");
linha(); //mais uma chamada
}

Variáveis Locais

→ Uma variável declarada dentro do corpo da função é chamada de


variável local (só existe dentro da função; naquele local; só existe entre
aquelas chaves).
→ Quando a função termina, a variável é liberada (apagada) da
memória, literalmente deixa de existir.

Chamando uma Função

→ Para executar uma função, deve-se chamá-la a partir de outra


função.
→ A função main() não pode ser chamada pelo programador (padrão
da linguagem para controle interno da execução), mas a partir dela é
possível chamar outras funções (mas não obrigatoriamente somente a partir
da main).

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 5
Introdução à Programação – Introdução à Linguagem C –

→ Por exemplo, uma função equação() pode chamar outra função


calculo_interno_1(), por exemplo.
→ As funções só podem ser chamadas depois de declaradas.

Exercício: Escreva um programa que possui uma função que lê


uma palavra e a imprime 10 vezes na tela. No início do programa,
imprimir a mensagem “Início”. Logo após, chamar a função para ler a
palavra e mostrar a palavra 10 vezes. No final do programa, imprimir a
mensagem “Fim”.

Passagem de Parâmetros por Valor (Cópia)

→ Em C, valores são passados para as funções através de


argumentos nas chamadas.
→ Os argumentos, quando recebidos nas funções, passam a ser
chamados de parâmetros e são usados nos blocos de código destas funções.
→ Na passagem por valor, os valores dos argumentos são
copiados para os parâmetros. Desta forma (por valor), os dados podem
ser alterados e manipulados na função chamada, mas não são alterados na
função origem.

Exemplo:
#include <stdio.h>
//função que imprime n vezes um caracter ch
void imprimeCaracter(char ch, int n)
{ int i; //variável local
for(i=0; i<n; i++)
printf("%c", ch);
}
int main()
{ //os parâmetros devem ser chamados na ordem
//argumentos '*' e 35 (valores para ch e n)
imprimeCaracter('*', 35);
printf("\nEstudando passagem de parâmetros.\n");

//chamada com '#' e 40


imprimeCaracter('#', 40);

printf("\n Teste finalizado.\n");

//outra chamada
imprimeCaracter('#', 40);

printf("\n\n");
}
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 6
Introdução à Programação – Introdução à Linguagem C –

Exercicio: Escreva um programa em C com uma função para


calcular o triplo de um número real. Leia o número na main, chame a
função passando o número lido dentro de um comando printf com a
mensagem “triplo de ... = ...”. A função deve então receber o número como
parâmetro e retornar o resultado do cálculo do triplo.

Sintaxe para retorno de valor:


<tipo de retorno> <nome>(<parâmetros>)
{ <declaração das variáveis locais>
<bloco de instrução>
return <valor de retorno>;
}

#include <stdio.h>
//função que retorna o triplo de um real
float calcTriplo (float n) //n recebe valor de x
{ float triplo = 3 * n;
return triplo;
}

int main()
{ float x;
//leitura
printf("Digite um numero: ");
scanf("%f", &x);

//chamada com impressão do retorno


printf("\n\nTriplo de %f = %f \n\n”, x,
calcTriplo(x) );

Exercício: Escrever uma função para cada par de parênteses da


equação abaixo. Na main, ler dois números inteiros positivos x e y, chamar
cada função utilizando estes dois inteiros como argumentos de acordo com
cada assinatura de cada função (às vezes só será necessário passar um dos
valores) e depois mostrar o resultado.
Obs.: Neste exercício, o símbolo ^ será usado para representar “elevado a”.

E = (x*y) – (x - ( (x2) – (y^3) ) ^ (1/2) + ( (4*x) ^ (1/2) ) )

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 7
Introdução à Programação – Introdução à Linguagem C –

Exercícios

→ Faça os exercícios da Lista 4.

→ Comece escrevendo os programas no caderno, só depois


passe para o seu editor para então os compilar e executar,
anotando no caderno os possíveis erros e correções.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 8
Introdução à Programação – Introdução à Linguagem C –

Ponteiros

→ Um ponteiro é uma variável que contém o endereço de memória de


outra variável.
→ É possível ter um ponteiro para qualquer tipo de variável.
→ Quando um ponteiro não “aponta” para nada, ele possui valor nulo
(null).

Sintaxe: tipo *nome_da_variavel;

Exemplos: int *p, *t; //ponteiros p vars int


float *q; //ponteiro p var float

Operadores de Ponteiros

& → É um operador unário que retorna o endereço da memória do


seu operando.

Exemplo: a = &m; //a recebe o endereço de


//memória que contém m

*→ É um operador unário que retorna o valor (conteúdo) do seu


operando.

Exemplo 1:

#include <stdio.h>
int main()
{ int x=10, y = 20;
int *p; //declara apontador p

p=&x; //p recebe endereço de x (aponta p/ x)


y=*p; //y recebe o valor do “apontado” por p
*p=30; //”apontado” por p recebe 30
printf("\n\nx=%d, y=%d, p=%p\n\n", x, y, p);
}

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 9
Introdução à Programação – Introdução à Linguagem C –

→ No final, x=30, y=10 e p (o ponteiro p) contém o endereço de x (ou


seja, aponta para x).

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 10
Introdução à Programação – Introdução à Linguagem C –

Exemplo 2:

#include <stdio.h>
int main()
{ int y;
int *p, *q; //declara apontadores p e q

y = 10;
p = &y; //p "aponta" para y
q = p; //q "aponta" para p
*q = 40; //"apontado" por q recebe 40
printf("\ny=%d, *p=%d, *q=%d\n\n",y,*p,*q);
}
→ Ao final: y=40, *p=40, *q=40

Exemplo 3:

#include <stdio.h>
int main()
{ int *a; //a = apontador para vars int
int c, b=2;
a = &b; //a recebe o endereco de b
c = b;
//valor apontado por a, valor b, valor c
printf("\n\n*a=%d, b=%d, c=%d\n\n", *a, b, c);
b = 3;
//valor apontado por a, valor b, valor c
printf("\n\n*a=%d, b=%d, c=%d\n\n", *a, b, c);
}

Aritmética de Ponteiros

Existem duas operações aritméticas com ponteiros e o número de


bytes é a unidade considerada:

1) Incremento ou Adição → Incrementa ou adiciona de


acordo com a quantidade de bytes do tipo.

Ex: int *p; //p = 2000


p++; //p = 2004

2) Decremento ou Subtração → Decrementa ou subtrai


de acordo com a quantidade de bytes do tipo.
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 11
Introdução à Programação – Introdução à Linguagem C –

Ex: int *q; //q = 2000


q--; //q = 1996
Exemplo 4:

#include <stdio.h>
int main()
{ int *a; //a = apontador para vars int
int x = 10;

a = &x; //a aponta para x


printf("\n\na = %p", a); //endereço de a
a++; //incremento
printf("\na++ = %p", a); //endereço de a
a--; //decremento
printf("\na-- = %p\n", a); //endereço de a
}

Comparações com Ponteiros

Os operadores:

== != > >= < <=

→ São aceitos com ponteiros e comparam os endereços de memória.

Indireção Simples

Apontador → Endereço

Exemplo: int *p; //ponteiro para vars int


int x = 5;
p = &x; //indireção simples

Indireção Múltipla

→ Podemos ter um ponteiro apontando para outro ponteiro, que por


sua vez aponta para um valor final.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 12
Introdução à Programação – Introdução à Linguagem C –

Endereço → Endereço → Valor

Sintaxe: tipo **nome_da_variável;

Exemplo: int **q; //ponteiro de ponteiros

Exemplo 5:

#include <stdio.h>
int main()
{ int x, *p, **q; //q apontador para apontador
//de vars int
p = &x; //p aponta para x
q = &p; //q aponta para p
x = 100; //atribui valor a x

//valor do apontado por p


printf("\n**q=%d\n", **q); //q aponta p
//valor do apontado por p
printf("\n*p=%d\n", *p); //valor apontado p
printf("\n&x=%p\n", &x); //endereco de x
printf("\n&p=%p\n", &p); //endereco de p
printf("\n*q=%p\n", *q); //valor de q
}

Inicialização de Ponteiros

→ Quando se declara um ponteiro, ele não aponta para lugar


nenhum, ele não possui um valor.
→ Ao tentar imprimir um ponteiro não inicializado, é mostrado o
valor “nil” e comandos de atribuição ao apontado (que ainda não foi
definido) não são aceitos pelo compilador.

Exemplo:
Errado Certo
int *p; int *p, x;
*p=100; //apontado por p? p=&x; //ok!
*p=100;

→ Por convenção devemos atribuir o valor NULL (em maiúsculas) a


um ponteiro que não está apontando para nada.
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 13
Introdução à Programação – Introdução à Linguagem C –

→ Isso pode ser feito também para liberar um apontador, ou seja, um


apontador que aponta para um certo espaço na memória passará a não
apontar para nada.

Exemplo: int *p = NULL;

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 14
Introdução à Programação – Introdução à Linguagem C –

Exemplo 6:

#include <stdio.h>
int main()
{ int *a, *b, x, y, aux;
x=10;
y=20;
a=&x; //ok, apontador inicializado
b=&y; //ok, apontador inicializado
//valor apontado a, valor apontado b
printf("\n*a=%d, *b=%d\n", *a, *b);
//troca
aux=*a;
*a=*b;
*b=aux;
//após a troca
printf("\nTroca: *a=%d, *b=%d\n", *a, *b);
}

Exercício 1: Tente escrever um programa que contém uma função


que troca os valores de duas variáveis inteiras. Na main, leia dois
inteiros, chame a função para trocar os valores das duas variáveis inteiras e
depois as imprima.

→ Não foi possível?

Explicação:
→ Na passagem de argumentos por valor, trocam-se os valores
dentro da função, mas não na função chamadora, ou seja, não funciona
com passagem por valor!

→ Teste o exemplo a seguir:

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 15
Introdução à Programação – Introdução à Linguagem C –

Exemplo 7:

#include <stdio.h>
void troca(int x, int y) //por valor
{ int aux;
aux = x;
x = y;
y = aux;
}
int main()
{ int x=10, y=20;
printf("\nx=%d, y=%d\n", x, y);
troca(x, y);
printf("\nTroca: x=%d, y=%d\n", x, y);
}
→ Na memória:
Endereço Comando
...
110 aux=a;
108 b=20; b=aux;
106 a=10; a=b;
104 y=20
102 x=10
...

Obs: Não funciona, pois quando a função termina as variáveis locais


deixam de existir, não são retornadas!

Solução:
→ Utilizar passagem de argumentos por referência!

Passagem de Argumentos por Referência

→ Na passagem por referência os endereços das variáveis são


passados, habilitando a função a manipular diretamente os valores das
variáveis da função chamadora.

Exemplo 8:

#include <stdio.h>
void troca(int *x, int *y) //por referência
{ int aux;
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 16
Introdução à Programação – Introdução à Linguagem C –

aux = *x; //apontado por x


*x = *y; //apontado por x e apontado por y
*y = aux; //apontado por y
}
int main()
{ int x=10, y=20;
printf("\nx=%d, y=%d\n", x, y);
troca(&x, &y); //por referência (endereços)
printf("\nTroca: x=%d, y=%d\n", x, y);
}

→ A função troca() tem o objetivo de receber duas variáveis inteiras


e trocar seu valor.
→ Na primeira resolução do exercício, são criadas cópias das
variáveis x e y dentro da função troca(). Estas cópias, que só existem
dentro da função, têm o seu valor trocado, mas isto não implica nenhuma
alteração nas variáveis x e y na função main().
→ Para que os valores dos argumentos possam ser alterados dentro
de uma função, é necessário que estes argumentos sejam passados por
referência (endereço).

Exercício 2: Acompanhe, anote e explique a saída do programa


abaixo:

#include <stdio.h>
int main()
{ int *p1, valor, idade, *p4, *p5, vetor[3];
float *p2, temp;
char aux, *nome="Algoritmos", *p3;

//a
valor = 10;
p1 = &valor;
*p1 = 20;
printf("%d\n", valor);
//b
temp = 27.59;
p2 = &temp;
*p2 = 29.35;
printf("%f\n", temp);

//c
p3 = &nome[0];
aux = *p3;
printf("%c\n", aux);

//d
p3 = &nome[4];
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 17
Introdução à Programação – Introdução à Linguagem C –

aux = *p3;
printf("%c\n", aux);

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 18
Introdução à Programação – Introdução à Linguagem C –

//e
p3 = nome;
printf("%c", *p3);

//f
p3 = p3 + 4;
printf("%c\n", *p3);
//g
p3--;
printf("%c\n", *p3);

//h
vetor[0] = 33;
vetor[1] = 55;
vetor[2] = 27;
p4 = vetor;
idade = *p4;
printf("%d\n", idade);

//i
p5 = p4+1;
idade = *p5;
printf("%d\n", idade);

//j
p4 = p5+1;
idade = *p4;
printf("%d\n", idade);

//k
p4 = p4-2;
idade = *p4;
printf("%d\n", idade);

//l
p5 = &vetor[2]-1;
printf("%d\n", *p5);

//m
p5++;
printf("%d\n", *p5);
}

Saída:
20
29.350000
A
r
A
r
o
33
55
27
33

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 19
Introdução à Programação – Introdução à Linguagem C –
55
27

Exercicio 3: Comente cada linha do código abaixo e desenhe o


esquema de funcionamento “na memória”:

#include <stdio.h>
int quadrado(int *a)
{ *a=(*a)*(*a);
return *a;
}
int main()
{ int x=10;
printf("\n\nQuadrado de %d=",x);
printf("%d\n\n", quadrado(&x));
}

Ponteiros e Vetores

→ Vetores em C são tratados pelo compilador como ponteiros.


→ Isso significa que o nome do vetor representa o endereço
ocupado pelo primeiro elemento.

Exemplo 9:

#include <stdio.h>
int main()
{ int i,*p, x[]={8,3,5,1,7};
p = x; //p aponta para o 1o elemento de x
for(i=0; i<5; i++)
{ printf("%d\t", *p);
p++;
}
printf("\n");
}

→ No exemplo 9, o operador & não é utilizado . Isto ocorre porque o


nome do vetor já é tratado pelo compilador como um endereço.
→ Se fosse usado p = &x[0];, no lugar de p = x;, também estaria
correto.

Exemplo 10:

#include <stdio.h>
int main()
{ int i, x[]={8,3,5,1,7};
for(i=0; i<5; i++)
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 20
Introdução à Programação – Introdução à Linguagem C –

//aritmética de ponteiros para navegar


printf("%d\t", *(x+i)); //no vetor
printf("\n");
}
Exemplo 11:

#include <stdio.h>
int main()
{ int v[]={10, 20, 30, 40, 50}, *p1, *p2, j, i=100;
for (j=0; j<5; j++)
printf("%d\t", v[j]); //elemento pelo índice
printf("\n");

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


printf("%d\t", *(v+j)); //aritmética
printf("\n");

p1=&v[2];
printf("%d\n", *p1);
p2=&i;
printf("%d\n", *p2);
p2=p1;
printf("%d\n", *p2);
p2++;
printf("%d\n", *p2);
p1=p1+2;
printf("%d\n", *p1);
}

Exemplo 12: Programa que lê uma string origem e chama uma


função que recebe duas strings (destino e origem) e copia a string origem
para a string destino. No final imprime as duas strings. Obs.: não usar a
função strcpy(...).

#include <stdio.h>
//declaração permite implementação após a main
void strcop(char *d, char *o); //protótipo

int main()
{ char destino[30];
char *origem = "Cadeia de caracteres de origem.";
strcop(destino, origem);
printf("%s\n%s\n\n", origem, destino);
}
//implementação da função declarada
void strcop(char *d, char *o)
{ while( *o != '\0')
{ *d = *o;
o++;

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 21
Introdução à Programação – Introdução à Linguagem C –

d++;
}
}

Exercício 4 (resolvido): Reescrever a função strcop em apenas


uma linha.

Solução:
#include <stdio.h>
void strcop(char *d, char *o); //protótipo
int main()
{ char destino[30];
char *origem="Cadeia de caracteres de origem.";
strcop(destino, origem);
printf("%s\n%s\n\n", origem, destino);
}
void strcop(char *d, char *o) //implementação
{ while( ( *d++ = *o++) != '\0' );
}

Exercício 5: Escrever um programa onde é definida uma string


qualquer. Logo após, mostrar a string e o tamanho da string, sem usar a
função strlen().

Exercícios

→ Faça os exercícios da Lista 4.

→ Procure revisar os seus algoritmos em Portugol correspondentes a


estes exercícios e tente reescrevê-los em linguagem C, este é o
processo normal de escrita de um bom programa.
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 22
Introdução à Programação – Introdução à Linguagem C –

→ Comece escrevendo os programas no caderno, só depois


passe para o seu editor para então os compilar e executar,
anotando no caderno os possíveis erros e correções.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 23
Introdução à Programação – Introdução à Linguagem C –

Alocação Dinâmica

→ É possível obter memória durante a execução do programa, para


permitir a solução de problemas nos quais ainda não se sabe o tamanho ou a
quantidade de espaço necessário para as variáveis ou estruturas declaradas
dentro dele.

Funções (biblioteca stdlib.h):

• malloc → memory allocation (alocação de memória) –


reserva sequencialmente um certo número de blocos de
memória e retorna, para um ponteiro, o endereço do primeiro
bloco reservado (primeiro byte livre encontrado);

• free → liberação de memória – libera memória alocada


através de um ponteiro.

Sintaxe:
ponteiro = (tipo*)malloc(tam*sizeof(tipo));

Onde:

ponteiro → nome do ponteiro que receberá o endereço do primeiro


espaço de memória alocado;

(tipo*) → cast para garantir que o retorno terá o mesmo tipo do


ponteiro;

tam → quantidade de elementos a alocar;

sizeof(tipo) → tamanho do tipo ;

Obs.: Se não for possível alocar memória suficiente, retorna NULL.

Exemplo 1:

#include <stdio.h>
#include <stdlib.h>
int main()
{ int *p; //declara apontador

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 24
Introdução à Programação – Introdução à Linguagem C –

//alocar 50 inteiros:
p = (int*)malloc(50 * sizeof(int));

*p=20; //valor do primeiro


*(p+1)=30; //valor do segundo...
*(p+2)=40;

printf("\n\n*p = %d, *(p+1) = %d, *(p+2) = %d\n\n",


*p, *(p+1), *(p+2));

free(p); //após utilização, liberar


}

Exemplo 2: Programa que lê o tamanho de um vetor de reais, aloca


memória para os elementos do vetor, lê valores para preencher o vetor e
imprime os valores lidos.

#include <stdio.h>
#include <stdlib.h>
int main()
{ float *v;
int i, tam;

printf("Qual o tamanho do vetor? ");


scanf("%d", &tam);

//alocação:
v = (float*)malloc(tam * sizeof(float));

if( v == NULL )
{ printf("\nImpossivel alocar memória.\n");
return; //interrompe a execução
}

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


{ printf("\n\nv[%d]: ", i);
scanf("%f", v+i); //leitura
}

printf("\n\nVetor alocado e lido:\n");


for (i=0; i<tam; i++)
printf("%.2f\t", *(v+i)); //impressão

printf("\n\n");
free(v); //liberação
}

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 25
Introdução à Programação – Introdução à Linguagem C –

Exemplo 3: Programa que lê o tamanho de um vetor de reais e aloca


memória para o vetor. Logo após, chama uma função que faz a leitura e
impressão do vetor, recebendo o vetor e seu tamanho. Outra função procura
o maior elemento no vetor lido e mostra quantas vezes o elemento maior
aparece no vetor. Esta função retorna o valor do maior. No final, imprime o
valor do maior e a quantidade de vezes que ele aparece no vetor.

#include <stdio.h>
#include <stdlib.h>

void leImprime (float *v, int tam)


{ int i;

for (i=0;i<tam;i++)
{ printf("\n\nv[%d]: ", i);
scanf("%f", v+i); //leitura
}

printf("\n\nVetor: ");
for (i=0;i<tam;i++)
printf("%.2f\t", *(v+i));
}

float buscaMaior(float *v, int tam, int *vz)


{ int i, maior;
maior = *v; //primeiro elemento

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


if( *(v+i) > maior)
maior = *(v+i);
else if( *(v+i) == maior)
(*vz)++; //incrementa apontado
//CUIDADO: parenteses!

return maior;
}

int main()
{ float *v, maior;
int tam, vezes;
printf("Digite o tamanho do vetor: ");
scanf("%d", &tam);

v=(float*)malloc(tam*sizeof(float));
if( v != NULL )
{ leImprime(v, tam);
maior = buscaMaior(v, tam, &vezes);
printf("\nMaior: %.2f e aparece %d vezes no
vetor.\n", maior, vezes);
free(v);
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 26
Introdução à Programação – Introdução à Linguagem C –

}
else
printf("\nImpossivel alocar memória.\n");
}

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 27
Introdução à Programação – Introdução à Linguagem C –

Exercício 1: Escreva um programa sem alocação de memória que


leia uma frase de 30 caracteres e chame uma função que recebe um ponteiro
para a frase e imprime a frase 10 vezes na tela. Imprima a mensagem “FIM”
no final do programa.

Exercício 2: Reescreva o programa anterior usando alocação


dinâmica de memória na definição do vetor.

Exercício 3: Escrever um programa que contém uma função que lê


uma frase e retorna um ponteiro para o início da frase. Na main(), declarar
um ponteiro de caracteres, chamar a função e imprimir 10 vezes a frase lida.
Imprimir a mensagem “FIM” no final do programa.

Exercício 4: Escreva um programa que leia o seu nome completo,


conte e mostre quantas vezes 'a' ou 'A' aparecem no seu nome (ou mostre
uma mensagem “não aparece”).

Exercício 5: Escreva um programa que leia uma frase e copie a frase


em outro vetor de forma inversa a que foi lida. Imprima a frase lida, o
tamanho da frase e a frase inversa.

Exercício 6: Escreva um programa que leia uma frase, verifique o


seu tamanho e chame uma função que recebe a frase, o seu tamanho e um
caractere lido. A função deve contar e retornar o valor da quantidade de
ocorrências do caractere da frase. Imprima o valor retornado.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 28
Introdução à Programação – Introdução à Linguagem C –

Exercícios
→ Faça os exercícios da Lista 4.

→ Comece escrevendo os programas no caderno, só depois


passe para o seu editor para então os compilar e executar,
anotando no caderno os possíveis erros e correções.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 29
Introdução à Programação – Introdução à Linguagem C –

Registros

→ Um registro é um conjunto de variáveis, provavelmente de tipos


diferentes, referenciados por um nome.
→ As variáveis que formam o registro são chamados de elementos do
registro.

Forma Geral:

struct nomedoregistro {
elementos (variáveis separadas por “;”)
};

Exemplo: struct data {


int dia;
char mes[10];
int ano;
};

→ Este código cria o tipo registro chamado data que contém três
elementos: dia, mês e ano.

→ Para declarar variáveis do tipo data, utilizamos a sintaxe:

struct data hoje;

→ Este código declara uma variável chamada hoje do tipo struct


data.

→ Para acessar elementos do registro separadamente, utiliza-se o


operador “.” (ponto).

Exemplo:
hoje.dia = 10;
hoje.mes = “junho”;
hoje.ano = 2015;
printf(“%d de %s de %d\n”, hoje.dia, hoje.mes,
hoje.ano);

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 30
Introdução à Programação – Introdução à Linguagem C –

Exemplo 1:

#include <stdio.h>
struct pessoa //cria tipo registro pessoa
{
char *nome;
int idade;
float altura;
};
int main()
{ struct pessoa p1; //declara variável
p1.nome="Maria de Souza";
p1.idade=32;
p1.altura=1.69;
printf("\nNome: %s\nIdade: %d\nAltura: %f\n\n",
p1.nome, p1.idade, p1.altura);
}

Exercício 1: Reescrever o programa fazendo a leitura dos dados da


pessoa via telado. Acrescentar o elemento peso no registro pessoa, para no
final calcular e imprimir o IMC da pessoa.

Registros Dentro de Registros

→ Registros podem conter outros registros como elementos.

Exemplo:

struct data {
int dia;
char mes[10];
int ano;
};

struct pessoa {
char nome[60];
char end[80];
char fone[20];
struct data nascimento;
};

struct pessoa p;
p.nome = “José da Silva”;
p.end = “Rua A, 300”;
p.fone = “3333-2222”;
p.nascimento.dia = 20;
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 31
Introdução à Programação – Introdução à Linguagem C –

p.nascimento.mes = “maio”;
p.nascimento.ano = 1985;
Exercício 2: Escrever um programa utilizando um registro dentro de
um registro. Dada a tabela abaixo, ler os dados do registro para uma pessoa
(nome, endereço, fone, altura, peso e nascimento) e calcular seu IMC.
Imprimir os dados lidos, o IMC e uma das mensagens de acordo com a
tabela.

Abaixo de 18.4 “Abaixo do peso ideal”


Entre 18.5 e 24.9 “Parabéns, peso normal”
Entre 25,0 e 29.9 “Acima do peso (sobrepeso)”
Entre 30.0 e 34.9 “Obesidade de grau I”
Entre 35.0 e 39.9 “Obesidade de grau II”
Acima de 40.0 “Obesidade de grau III”

Exemplo 2: (com protótipo da função que exibe os dados do registro)

#include <stdio.h>
//cria tipo registro
struct livro {
char *titulo;
int codigo;
float preco;
};

//prototipo da funcao
void imprime(struct livro b);

main()
{ //declara variável registro
struct livro book;
//define valores dos campos
book.titulo="Programando em C";
book.codigo=1452;
book.preco=99.99;
//chamada da funcao
imprime(book);
}
//funcao que recebe registro por valor/copia
void imprime(struct livro b)
{

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 32
Introdução à Programação – Introdução à Linguagem C –

printf("\n\nTitulo: %s\nCodigo: %d\nPreco: %.2f\n\n",


b.titulo, b.codigo, b.preco);

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 33
Introdução à Programação – Introdução à Linguagem C –

Vetores e Registros

→ É a forma mais comum de uso de registros, pois é similar a uma


coleção ou a um banco de dados.
→ Simplifica a passagem de parâmetros por referência.

Exemplo 3:
-Programa que lê os dados de 3 livros.
-Considere a estrutura do exemplo anterior modificando o campo título para
vetor de char.

#include <stdio.h>
#define MAX 3
//cria tipo registro
struct livro {
char titulo[30]; //ja aloca espaço na memoria
int codigo;
float preco;
};

//prototipo da funcao
void imprime(struct livro v[]);

int main()
{ //declara vetor de registros
struct livro vb[MAX];
//leitura dos valores dos campos
int i;
printf("\n\nCadastro de livros\n\n");
for(i=0; i<MAX; i++)
{ printf("Titulo %d: ", i);
gets( vb[i].titulo);
printf("Codigo %d: ", i);
scanf("%d", &vb[i].codigo);
printf("Preco %d: ", i);
scanf("%f", &vb[i].preco);
fgetc(stdin); //limpa buffer
printf("\n");
}
printf("\n");
//chamada da funcao
imprime(vb);
}
//funcao que recebe vetor (por referencia)
void imprime(struct livro v[])
{ int i;

printf("Livros Cadastrados:\n");
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 34
Introdução à Programação – Introdução à Linguagem C –

printf("--------------------------\n");

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


{
printf("Livro %d:\n", i+1);
printf("Título: %s\n", v[i].titulo);
printf("Codigo: %d\n", v[i].codigo);
printf("Preco: %.2f\n", v[i].preco);
}
printf("--------------------------\n\n");

Exercício 3: Escrever um programa utilizando um registro chamado


aluno e duas funções (leitura e impressao) que recebem um vetor do
tipo struct aluno. Na main(), chamar a função leitura para ler os dados
de 3 alunos e calcular a média de cada um. Logo após, chamar a função
impressão para mostrar os dados de cada aluno e uma das seguintes
mensagens:

• “Aprovado”, se a média for maior ou igual a 6.0;


• “Reprovado”, se a média for menor que 4.0;
• “Fazer VS”, caso contrário.

Exercício 4: Criar um programa para descrever carros de uma


determinada revendedora, que contém uma estrutura com os seguintes
campos: marca (string 15), cor (string 10), ano (inteiro) e preco (real).
1. Escreva a definição para a estrutura 'Carro';
2. Declare um vetor tipo struct Carro com tamanho 5;
3. Crie um menu com as seguintes opções (utilize uma função para executar
cada tarefa):
1) Leitura de dados;
2) Impressão (todos os dados lidos);
3) Busca por marca (cor, ano e preço) ;
4) Sair

Qualquer outra opção, imprima “Inválido”.

Registros e Ponteiros
© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 35
Introdução à Programação – Introdução à Linguagem C –

→ Ponteiros podem apontar para registros do mesmo modo que


apontam para qualquer variável.
→ Podemos acessar os dados através do operador “->” (seta). A
vantagem é o aumento da velocidade de processamento, já que é necessário
copiar apenas o endereço, ao invés de todo conteúdo da variável.
→ É recomendável que estruturas muito grandes sejam sempre
passadas por endereço.

→ No exemplo abaixo, struct livro ocupa 40 bytes. Se


passássemos o argumento por valor, o programa seria obrigado a copiar 40
bytes, porém, passando o argumento por referência, apenas 4 bytes
(endereço) são copiados.

Exemplo 4:

#include <stdio.h>
#define MAX 5
struct livro {
char titulo[30];
int codigo; //4 bytes
float preco; //4 bytes
};

//funcao recebe registro por referencia


void leitura(struct livro *b)
{ int i;
for(i=0;i<MAX;i++)
{ printf("Titulo %d: ", i);
gets(b->titulo); //operador seta
printf("Codigo %d: ", i);
scanf("%d", &b->codigo);
printf("Preco %d: ", i);
scanf("%f", &b->preco);
printf("\n");
fgetc(stdin);
b++; //proximo registro
}
}

//funcao recebe registro por referencia


void impressao(struct livro *b)
{
int i;
for(i=0;i<MAX;i++)
{ //uso do operador seta para acessar cada
//campo do apontado

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 36
Introdução à Programação – Introdução à Linguagem C –

printf("%d\nTit: %s\nCod: %d\nPreco: %.2f\n\n",


i, b->titulo, b->codigo, b->preco);
b++; //proximo registro
}
}

int main()
{ struct livro vb[MAX];
//leitura
printf("\nCadastre os %d livros:\n\n", MAX);
leitura(vb);
//impressao
printf("Livros Cadastrados:\n");
printf("----------------------\n\n");
impressao(vb);
printf("----------------------\n\n");
}

Exercício 5: Escrever um programa que cria um registro chamado


ponto contendo as posições de x e y de um ponto, do tipo real. Declarar dois
pontos na main(), ler a posição (coordenadas x e y) de cada um e calcular a
distância entre eles. Dividir o programa em funções (leitura e calculo de
distancia). Imprimir o valor da distância entre os dois pontos.

Exercícios
→ Faça os exercícios da Lista 4.

→ Comece escrevendo os programas no caderno, só depois


passe para o seu editor para então os compilar e executar,
anotando no caderno os possíveis erros e correções.

Arquivos

→ Os arquivos são usados para conservação permanente de grandes


quantidades de dados.
→ Os computadores armazenam arquivos em dispositivos secundários
de armazenamento (discos rígidos, etc).
→ Um arquivo é uma sequência ordenada de bytes, em geral
representando dados utilizados por aplicativos.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 37
Introdução à Programação – Introdução à Linguagem C –

→ Um registro é um grupo de campos relacionados entre si.


→ Um arquivo é um grupo de registros relacionados entre si.

Exemplo: Um sistema de folha de pagamento


→ Cada registro de um empregado possui os seguintes campos:
• nome,
• endereço,
• PIS,
• CPF,
• RG,
• imposto retido na fonte, etc.
→ Logo, um arquivo de folha de pagamento de uma empresa contém
registros, um registro para cada empregado.

Acessando Arquivos em C

→ Antes de acessar os dados dentro de um arquivo é necessário abri-


lo e ao terminar de realizar as operações no arquivo, devemos fechá-lo.
→ As operações de abertura e fechamento garantem a integridade
dos dados.
→ As funções referentes a arquivos estão na biblioteca stdio.h

Abertura e Fechamento de Arquivos

→ Todo arquivo aberto é referenciado por um ponteiro do tipo FILE


(estrutura que contém informações usadas para processar arquivos).

Sintaxe: FILE *fopen (char *nome, char *modo)

*fopen – função que abre o arquivo nome com o modo de abertura e


retorna um ponteiro para a estrutura FILE.
*nome – nome do arquivo deve ser uma string, que pode incluir o
caminho completo.

→ A função fclose() é usada para fechar o arquivo.

Modos de Abertura de Arquivos


© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 38
Introdução à Programação – Introdução à Linguagem C –

r – abrir arquivo para leitura


w – abrir arquivo para gravação
a – abrir arquivo para gravação em anexo
+ – a adição do símbolo + permite leitura e escrita
b – abrir arquivo em modo binário
t – abrir arquivo em modo texto

Exemplos:
r+ → leitura e escrita
rb → leitura modo binário
wb → escrita modo binário
rt → leitura modo texto
wt → escrita modo texto

→ No modo w, se o arquivo estiver presente, ele será destruído e


reinicializado. Se não existir será criado.
→ Para abrir para escrita e acrescentar dados ao final do arquivo,
sem destruir os dados inseridos anteriormente, deve-se usar o modo ª

Funções para Acessar Dados de Arquivos

→ getc() e putc() – ler e gravar, caracter a caracter.


→ fgets() e fputs() – ler e gravar, linha a linha.
→ fread() e fwrite() – ler e gravar sequências de caracteres,
números, etc.
→ fprintf() – grava dados em um arquivo.
→ fscanf() – lê dados de um arquivo.
→ feof() – verifica se é o fim de um arquivo.
→ EOF – significa fim de arquivo e, assim como a feof() é usado
para testes enquanto se percorre o arquivo.

Arquivo Texto

Quando escrevemos informações em um arquivo texto, tudo é


armazenado na forma de caracteres. Mesmo os números (int, float) são
convertidos automaticamente para caracteres, da mesma forma como é feito
na impressão de valores numéricos na tela do computador. Na leitura ocorre
um processamento semelhante, sendo os valores armazenados no arquivo

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 39
Introdução à Programação – Introdução à Linguagem C –

convertidos para valores numéricos quando necessário. Nos arquivos texto


utilizamos o caracter ‘ ‘ (espaço em branco) e o caracter ‘\n’ como
separadores das informações armazenadas.

As seguintes funções manipulam arquivos texto: putc(), getc(), fputs(),


fgets(), fprintf() e fscanf().

1. putc() (ou fputc( )) - escreve caracteres no arquivo.

Sintaxe:
int putc (int ch, FILE *fp);

Onde:
fp é um ponteiro de arquivo retornado por fopen.
ch é definido como int (2 bytes) mas apenas o byte menos significativo é
levado em conta.

Se putc() falha ela devolve o carácter de fim de arquivo EOF.

2. getc() (ou fgetc()) - Lê caracteres do arquivo.

Sintaxe:
int getc (FILE *fp);

Lê um carácter de um arquivo previamente aberto por fopen() usando o


ponteiro fp. Da mesma forma que putc(), getc() devolve um inteiro, mas
apenas o byte menos significativo é usado.
Quando chega ao final do arquivo getc( ) devolve o carácter EOF.

3. fgets() - Lê uma string de um arquivo.

Sintaxe:
char * fgets (char *s, int n, FILE *arq);

onde:
s é uma string a ser preenchida com os caracteres lidos, n é o número
máximo de caracteres (contando o ‘\0’) que podem ser lidos e arq é um
ponteiro para um arquivo já aberto (aberto para leitura).

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 40
Introdução à Programação – Introdução à Linguagem C –

A função fgets() lê os caracteres do arquivo, armazenando-os na string s. A


função interrompe a leitura quando ela lê n - 1 caracteres ou quando chega
um caracter ‘\n’, o que vier primeiro. O último carácter lido é seguido por
um carácter ‘\0’, de modo a finalizar corretamente a string.

A função fgets() retorna um ponteiro para a string s, em caso de sucesso; em


caso de erro ou fim de arquivo, retorna NULL.

4. fputs() - Escreve uma string em um arquivo.


Sintaxe:
int fputs (char *s, FILE *arq);

onde:
s é a string a ser escrita no arquivo e arq é um ponteiro para um arquivo já
aberto (aberto para escrita ou para append).

A função fputs() retorna o último caracter escrito, em caso de sucesso; em


caso de erro, retorna EOF.

A função fputs() não acrescenta o caracter ‘\n’ após a string. Caso seja
necessário o uso do ‘\n’ como separador, ele deve ser estar presente na
string a ser escrita.

5. fprintf() - Escrita formatada em um arquivo.


Sintaxe:
int fprintf (FILE *arq, char *formato, <lista de
variáveis>);

onde:
arq é um ponteiro para um arquivo já aberto,
formato é uma string representando o tipo das variáveis a serem escritas
(como no printf) e
<lista de variáveis> representa a lista de variáveis a serem escritas no
arquivo.

Esta função é análoga a função printf com a diferença que as informações


são escritas no arquivo, ao invés de na tela.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 41
Introdução à Programação – Introdução à Linguagem C –

A função fprintf() retorna o número de bytes escritos, em caso de sucesso;


em caso de erro, retorna EOF.

6. fscanf() - Leitura formatada de um arquivo.


Sintaxe:
int fscanf (FILE *arq, char *formato, <lista de
variáveis>);

onde:
arq é um ponteiro para um arquivo já aberto,
formato é uma string representando o tipo das variáveis a serem lidas
(como no scanf) e
<lista de variáveis> representa o nome das variáveis que receberão os
valores a serem lidos (como no scanf).

A função fscanf() retorna EOF em caso de erro ou fim de arquivo.

Exemplo 1: Programa que lê caracteres do arquivo entrada.txt


para o arquivo saida.txt. É necessário criar estes dois arquivos na mesma
pasta e entrada.txt deve conter um texto qualquer.

#include <stdio.h>
int main()
{
char ch;
FILE *in, *out; //ponteiros para arquivos

//abertura para leitura, com teste


if ((in = fopen("entrada.txt", "rt")) == NULL)
{ printf("Impossivel abrir arquivo");
return;
}

//abertura para gravação, com teste


if ((out = fopen("saida.txt", "wt")) == NULL)
{ printf("Impossivel abrir arquivo");
return;
}

//copia, enquanto não chegar ao fim do arquivo


while( (ch = getc(in)) != EOF)
putc(ch, out); //grava caracter no arquivo

//fecha os arquivos
fclose(in);

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 42
Introdução à Programação – Introdução à Linguagem C –

fclose(out);
}

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 43
Introdução à Programação – Introdução à Linguagem C –

Exemplo 2: Programa que abre um arquivo e grava uma mensagem


que inclui o nome do próprio arquivo.

#include <stdio.h>
#include <stdlib.h>
int main()
{ FILE *fp;
char nome[50], c;

printf("Digite o caminho do arquivo:");


gets(nome);

//abre o arquivo para gravação


if( !(fp = fopen(nome, "w")) )
{ printf("Impossivel abrir o arquivo.\n");
return;
}

printf("\n\nMensagem gravada no arquivo:\n\");


//imprime a mensagem do arquivo
fprintf(fp, "Nome deste arquivo: %s\n", nome);
fclose(fp); //fecha o arquivo

//abre novamente o arquivo, agora para leitura


fp = fopen(nome, "r");

//função para verificar o final do arquivo


while( !feof(fp) )
{ //lê um caractere do arquivo
fscanf(fp, "%c", &c);

printf("%c", c); //mostra caractere lido


}

fclose(fp); //fecha arquivo


}

Arquivo binário

Além do arquivo na forma de caracteres (texto) podemos armazenar


informações no computador na forma binária, isto é, byte a byte. A grande
vantagem está no armazenamento de
valores numéricos, pois armazenar um número inteiro na forma de
caracteres, significa guardar um carácter para cada dígito do número.
Por exemplo, o número 10346 precisaria de 5 caracteres para
armazená-lo em um arquivo texto. Para armazená-lo na forma binária

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 44
Introdução à Programação – Introdução à Linguagem C –

precisaríamos apenas de 2 bytes, que é o espaço necessário para armazenar


qualquer número inteiro.

Existem duas funções usadas para armazenar dados no formato


binário em arquivos:

1. fwrite() - Escreve um conjunto de bytes em um arquivo.

Sintaxe:
int fwrite (<tipo> *item, int tam_item, int num_itens,
FILE *arq);

Onde:
<tipo> - qualquer um dos tipos conhecidos: int, char, float.
item - elemento a ser armazenado. Pode ser tanto um único valor passado
por referência quanto um vetor.
tam_item - número de bytes do item a ser armazenado.
num_itens - número de elementos de item. Se item for um ponteiro para
um único valor, este parâmetro será 1, em caso contrário, será o número de
elementos do vetor.
arq - Ponteiro para a estrutura FILE. Este valor é retornado pela chamada
fopen.

A função fwrite() retorna o número de itens (não é o número de bytes) que


efetivamente foram escritos.

2. fread() - Lê um conjunto de bytes de um arquivo.

Sintaxe:
int fread (<tipo> *item, int tam_item, int num_itens,
FILE *arq);

Onde:
<tipo> - qualquer um dos tipos conhecidos: int, char, float.
item - elemento a ser lido. Ponteiro para a área de memória onde os
elementos serão armazenados. Pode ser um tanto um endereço de uma
variável quanto o nome de um vetor.
tam_item - número de bytes do item a ser lido.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 45
Introdução à Programação – Introdução à Linguagem C –

num_itens - número de elementos de item. Se item for um ponteiro para


um único valor, este parâmetro será 1, em caso contrário, será o número de
elementos do vetor a ser lido.
arq - ponteiro para a estrutura FILE. Este valor é retornado pela chamada
fopen.

A função fread() retorna o número de itens (não é o número de bytes) que


foram lidos (possivelmente 0 caso tenha chegado ao fim do arquivo).

Exemplo 3: Programa que abre um arquivo no modo binário e grava uma


mensagem e um vetor de números.

#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
char ch[20] = "Arquivo Binário";
int valor[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20};
FILE *in;

in = fopen("binario.bin", "wb");
if( in == NULL )
{ printf("Impossivel abrir o arquivo");
return;
}
fwrite(ch, sizeof(char), 20, in);
fwrite(valor, sizeof(int), 20, in);
}

Exemplo 4: Programa que abre um arquivo no modo binário, lê seu


conteúdo e mostra na tela.
#include <stdio.h>
#include <stdlib.h>
int main()
{ int i;
char ch[20];
int valor[20];
FILE *in;

in = fopen("binario.bin", "rb");
if(in == NULL)
{ printf("Impossivel abrir O arquivo");
return;
}

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 46
Introdução à Programação – Introdução à Linguagem C –

fread(ch, sizeof(char), 20, in);


fread(valor, sizeof(int), 20, in);
for(i=0; i<20; i++)
printf("%c", ch[i]);

printf("\n");

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


printf("%d \n", valor[i]);

printf("\n");

fclose(in);
}

Exemplo 5: Programa que cria um tipo registro, lê dados para um


vetor de registros, copia o vetor para um arquivo binário, lê os dados do
arquivo binário para um segundo vetor de registros e imprime este segundo
vetor.

#include <stdio.h>
#include <stdlib.h>
#define MAX 2

struct pessoa{
char nome[40];
int dia;
char mes[20];
int ano;
};

int main()
{ int i;
FILE *pa;
char arquivo[40];
struct pessoa dados[MAX], dadosarq[MAX];

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


{ puts("Nome: ");
gets(dados[i].nome);
puts("Dia: ");
scanf("%d", &dados[i].dia);
fgetc(stdin);
puts("Mes: ");
gets(dados[i].mes);
puts("Ano: ");
scanf("%d", &dados[i].ano);
fgetc(stdin);

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 47
Introdução à Programação – Introdução à Linguagem C –

puts("Imprimindo\n");
for(i=0; i<MAX; i++)
{
printf("Dia = %d \n", dados[i].dia);
printf("Mes = %s \n", dados[i].mes);
printf("Ano = %d \n\n", dados[i].ano);
}

puts("Qual o nome do arquivo? ");


gets(arquivo);

puts("Gravando \n\n");
if((pa = fopen(arquivo, "w+b")) == NULL)
{
puts("Arquivo nao pode ser aberto");
exit(1); //saida com codigo 1 (erro)
}

//gravacao
for(i=0; i<MAX; i++)
if(fwrite(&dados[i], sizeof(struct pessoa), 1, pa)!= 1)
{
puts("Erro na escrita");
}

//leitura
rewind(pa); //aponta para o inicio do arquivo
for(i=0; i<MAX; i++) {
if(fread(&dadosarq[i], sizeof(struct pessoa), 1, pa)!=1)
{
puts("Erro na leitura");
}
if( feof(pa) ) //se fim, erro
{
puts("Erro na leitura");
break;
}
}

puts("Imprimindo vetor lido do arquivo\n");


for(i=0; i<MAX; i++)
{
printf("Nome = %s \n", dadosarq[i].nome);
printf("Dia= %d \n", dadosarq[i].dia);
printf("Mes = %s \n", dadosarq[i].mes);
printf("Ano = %d \n\n", dadosarq[i].ano);
}

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 48
Introdução à Programação – Introdução à Linguagem C –

Exercício 1: Escrever um programa para ler números reais e os


gravar em um arquivo cujo nome deve ser dados.txt. Em seguida mostra o
conteúdo do arquivo na tela.

Exercício 2: Escrever um programa para ler 3 registros de alunos


(nome, v1, v2 e media) – a média deve ser calculada, não lida – e os gravar
em um arquivo cujo nome deve ser turma.bin. Em seguida mostra o
conteúdo do arquivo na tela. Mostre também a média da turma.

Exercícios

→ Faça os exercícios da Lista 4.

→ Comece escrevendo os programas no caderno, só depois


passe para o seu editor para então os compilar e executar,
anotando no caderno os possíveis erros e correções.

© 1999 – 2020 Prof. Dr. Adriano Caminha e Prof. Dra. Vera Lúcia Prudência dos Santos Caminha – ICEx/UFF – Volta Redonda-RJ 49

Você também pode gostar