Buscar

CD Prog Estrut ll

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 108 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 108 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 108 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Programação Estruturada II
Autoria: Renato Cristiano Torres
Tema 01
Ponteiros
seç
ões
Tema 01
Ponteiros
Como citar esse documento:
TORRES, Renato Cristiano, Programação Es-
truturada II. Valinhos: Anhanguera Educacional, 
2014. p. 1-90. 
Disponível em: <http://www.anhanguera.com>. 
Acesso em: 03 fev. 2014.
SeçõesSeções
Tema 01
Ponteiros
5
Conteúdo
Nessa aula você estudará: 
•	 A utilização Ponteiros.
•	 Matrizes de Ponteiros.
•	 Ponteiros para Funções.
conteúdosEhabilidades
Introdução ao Estudo da Disciplina 
Caro(a) aluno(a).
Este Caderno de Atividades foi elaborado com base no livro C: Como Programar, dos 
autores Paul Deitel e Harvey Deitel, Editora Pearson, 2011.
Roteiro de Estudo:
Renato Cristiano TorresProgramação Estruturada II 
6
Habilidades 
Ao final, você deverá ser capaz de responder as seguintes questões:
•	 Como utilizar ponteiros em programação?
•	 Como utilizar matrizes de ponteiros?
•	 Como chamar funções utilizando ponteiros para funções?
conteúdosEhabilidades
Ponteiros
Segundo Mizrahi (2008), ponteiro é um endereço de memória e um mecanismo para 
acessar uma variável sem se referir a ela diretamente, ou seja, ela é acessada não pelo seu 
nome, mas pelo seu endereço (Figura 1.1). 
Algumas razões para o uso dos ponteiros (MIZRAHI, 2008; DEITEL; DEITEL, 2011):
•	 Manipular elementos de matrizes.
•	 Receber argumentos de funções que necessitem de modificação.
•	 Passar strings (cadeia de caracteres) de uma função para outras.
•	 Criar estruturas de dados complexas.
•	 Alocar e desalocar memória.
•	 Passar para uma função o endereço de outra.
A ideia do uso de ponteiros é que utilizemos posição de memória em vez de utilizarmos a 
passagem de estruturas em funções, visto que por ponteiros é bem mais eficiente (DEITEL; 
DEITEL, 2011).
leituraobRIgATóRIA
7
leituraobRIgATóRIA
Segundo Deitel e Deitel (2011), os ponteiros são variáveis que contêm valores que são 
endereços de memória. Ponteiros, assim como todas as variáveis, precisam ser definidos 
antes de serem utilizadas, exemplo:
int *iPtr; // ponteiro para inteiro
Isso quer dizer que a variável “iPtr” conterá o endereço de memória que apontará para uma 
variável do tipo int.
Figura 1.1 Representação de Ponteiro.
Erro Comum em Programação
A notação * (asterisco), usada para declarar variáveis de ponteiro, não distribui para todos 
os nomes de variáveis em uma declaração. Cada ponteiro precisa ser declarado com o * 
prefixado ao nome.
Exemplo:
int *iPtr,iPtr2; //ERRADO!
int *iPtr,*iPtr2; //CERTO!
8
Veja um exemplo:
Exemplo 1
1) #include <stdio.h>
2) int main()
3) {
4) int i,j,k;
5) printf(“Endereço de i = %d”, &i); 
6) // o símbolo & obtém o endereço onde está alocada a variável
7) printf(“Endereço de j = %d”,&j);
8) printf(“Endereço de k = %d”,&k); 
9) system(“PAUSE”);
10) return 0;
11) }
A saída da execução:
Endereço de i = 0012FED4 // o endereço pode variar de um computador para outro
Endereço de J = 0012FEC8
Endereço de K = 0012FEBC
Os ponteiros são utilizados para permitir alocação de memória em tempo de execução, 
aumentam a eficiência de acesso a matrizes e permitem que funções modifiquem seus 
argumentos de chamada.
leituraobRIgATóRIA
9
leituraobRIgATóRIA
Veja um exemplo de alocação dinâmica:
int *vetor;
vetor = (int *)malloc(linhas*sizeof(int));
Neste trecho de código, vemos a criação de um vetor com tamanho definido pela variável 
“linhas”. Como o tamanho de cada célula é de um inteiro, ou seja, 8 bytes, é preciso multiplicar 
linhas por 8 ou sizeof(int) que pega o tamanho do inteiro da máquina, pois, como o tamanho 
de um inteiro pode variar de uma máquina para outra, multiplicamos esse tamanho pelo 
número de linhas do vetor; logo, se linhas igual a 5, precisaremos de 40 bytes de memória 
para alocar o vetor.
Operadores de Ponteiros
O operador de endereço é um operador unário que retorna o endereço do operando e é 
simbolizado por “&”. 
Exemplo:
int y = 5;
int *yPtr; //declaração de ponteiro para inteiro
yPtr = &y; // atribuição ao ponteiro “yPtr” o endereço da variável “y”
Erro Comum em Programação
Um ponteiro não inicializado, ao ser acessado, gerará um erro e causará um erro fatal 
em tempo de execução. Garanta sempre que os ponteiros utilizados estejam inicializados 
corretamente para evitar efeitos colaterais indesejados.
Passando Argumentos para Funções por Referência
Segundo Deitel e Deitel (2011), existem duas maneiras de passar argumentos a uma função 
em C, chamada por valor ou por referência. A chamada por referência é utilizada quando há 
necessidade de alterar o valor do argumento passado, evitando overhead de passar o objeto 
por valor, pois isso leva à necessidade de a linguagem C fazer uma cópia do objeto todo.
10
Exemplo:
1) #include <stdio.h>
2) int cubo(int n);
3) int main()
4) {
5) int numero=5;
6) printf(“O valor original do número é %d”, numero);
7) numero = cubo(numero);
8) printf(“O novo valor do número é %d”, numero);
9) return 0;
10) }
11) int cubo(int n)
12) {
13) return n * n *n; // calcula o cubo da variável e retorna o resultado
14) }
Resultado da Execução:
O valor original da variável número é 5.
O novo valor do número é 125.
Aritmética de Ponteiros
Um conjunto limitado de operações aritméticas pode ser realizado com ponteiros. Um 
ponteiro pode ser incrementado (++), decrementado (--), somado ou subtraído. Suponha 
um vetor de inteiros com 5 posições v[5]. Seu primeiro elemento está no endereço 1000h, 
ou seja, o valor do ponteiro vPtr é 1000h (Figura 1.2).
int * vPtr
vPtr = v;
vPtr = &v[0];
Quando você incrementa um ponteiro de inteiro, por exemplo, 
vPtr += 2; // produzirá o valor 1008h.
leituraobRIgATóRIA
11
O valor de 1008h é gerado, pois o ponteiro não é simplesmente incrementado em 2 inteiros, 
mas pelo inteiro multiplicado pelo tamanho do objeto ao qual se refere. Logo, neste caso, 
considerando um inteiro com 4 bytes, temos (1000 + 2*4) = 1008.
Figura 1.2 Variável de ponteiro vPtr apontado para o primeiro endereço do vetor.
Relação entre Ponteiros e Matrizes
Deitel e Deitel (2011) afirmam que matrizes e ponteiros estão intimamente relacionados em 
C e normalmente são utilizados da mesma forma. Um nome de matriz pode ser considerado 
um ponteiro; desta forma, pode definir um ponteiro igual ao endereço do primeiro elemento 
na matriz mat. Por exemplo:
mPtr = mat; // essa instrução é equivalente a:
mPtr = &mat[0]
Em outra forma, o elemento 4 da matriz mat[3] pode ser referenciado pela seguinte 
expressão: *(mPtr + 3).
Matriz de Ponteiros
Uma matriz pode conter inúmeros ponteiros em suas células. Um exemplo comum são as 
matrizes de caracteres, normalmente conhecidas como matriz de strings. Cada entrada em 
uma matriz de string é um ponteiro para o primeiro caractere de uma string. Suponha uma 
matriz de strings baralho (Figura 1.3).
const char * baralho[4] = {“Copas”,”Ouros”,”Paus”,”Espadas”}
A definição baralho[4] indica uma matriz de 4 elementos, e “const char” indica que as strings 
apontadas não serão modificadas.
leituraobRIgATóRIA
12
Figura 1.3 Representação Gráfica da matriz ‘baralho’.
Ponteiros para Funções
Um ponteiro para uma função contém o endereço da função na memória. Você viu que um 
nome da matriz é na realidade um ponteiro para o primeiro elemento da matriz. De forma 
semelhante, um nome de função é o endereço inicial na memória do código que realiza a 
tarefa da função (DEITEL; DEITEL, 2011).
Veja o fragmento de um programa que utiliza a chamada de função por ponteiro.
1) #include <stdio.h>
2) #define SIZE 10
3) void bubble(int work[], const int size, int (*compare)(int a, int b));
4) int crescente(int a, int b);
5) int decrescente(inta, int b);
6) int main(void)
7) {
8) … // códigos iniciais
9) if ( order == 1){
10) bubble(a,SIZE,crescente)
11) else
leituraobRIgATóRIA
13
12) bubble(a,SIZE,decrescente)
13) }
14) int crescente(int a, int b)
15) {
i. return b < a;
16) }
17) int decrescente(int a, int b)
18) {
i. return b > a;
19) }
20) }
O trecho do código int(*compare)(int a, int b) na linha 3 diz à função bubble que espera 
por um parâmetro, que é um ponteiro, para a função que recebe dois parâmetros inteiros e 
retorna um resultado inteiro.
Podemos declarar um ponteiro para função da seguinte forma:
 void (*func)();
func é um ponteiro para uma função sem parâmetros e que retorna void. 
func = teste;
teste é uma função declarada da seguinte forma:
 void teste() {
 printf(“Olá ! teste”);
 }
Teste pode ser chamada por func da seguinte forma
 func(); // chama teste 
Veja outro exemplo interessante:
1) include <stdio.h>
2) #include <stdlib.h>
3) int aplicar_funcao( int ( * fptr ) ( int arg1, int arg2 ),
4) int arg1, int arg2 ) 
leituraobRIgATóRIA
14
5) { 
6) int result = ( *fptr ) (arg1, arg2);
7) printf(“Resultado = %d\n”, result);
8) return result;
9) }
10) int adicionar( int arg1, int arg2 ) { return arg1 + arg2; }
11) int multiplicar( int arg1, int arg2 ) { return arg1 * arg2; 
12) }
13) int main() {
14) aplicar_funcao(adicionar, 2, 3);
15) aplicar_funcao(multiplicar, 3, 4);
16) system(“pause”);
17) return 0;
18) }
Note que a função aplicar_função na linha 3 recebe um ponteiro para a função que retorna um 
inteiro e recebe dois argumentos do tipo inteiro também. Nas linhas 10 e 11, são declaradas 
2 funções no formato descrito com retorno de inteiro e recebem dois argumentos. Na linha 
14, temos a primeira chamada da aplicar_função recebendo o nome da função desejada e 
valores como argumentos. Veja que, independentemente da função, como elas obedecem 
ao mesmo protótipo (formato), podemos chamar qualquer uma.
Os ponteiros para função são comumente utilizados em sistemas baseados em textos e 
controlados por menus, pois permitem associar chamadas de funções às opções dos menus. 
Suponha que tenhamos a matriz de funções ptrMenu (Figura 1.4). Cada posição da matriz 
aponta para o endereço de outra matriz que contém 16 funções diferentes.
Figura 1.4 Matriz de funções ptrMenu.
leituraobRIgATóRIA
15
linksImPoRTAnTEs
Quer saber mais sobre o assunto? 
Então:
Sites
Acesse o link: <http://linguagemc.com.br/matriz-em-c/>. Acesso em: 03/02/2014.
Você encontrará um site dedicado à linguagem C.
Acesse o link: <http://www.ime.usp.br/~pf/algoritmos/aulas/pont.html>. Acesso em: 
03/02/2014. 
Encontre informações sobre ponteiros, com exercícios e exemplos.
Acesse o link: <http://www.redes.unb.br/~udias/cpe/aulas18--.pdf>. Acesso em: 03/02/2014. 
Você encontrará um arquivo com exemplos e uma explicação detalhada sobre ponteiros.
Vídeos
Programar em C - Ponteiros / Vetores / Funções - Aula 73. Disponível em: <http://www.
youtube.com/watch?v=OMwWqONMIQ4>. Acesso em: 03/02/2014. 
Aula demonstrativa utilizando Dev C++ sobre ponteiros, vetores e funções.
UFRPE Linguagem C PONTEIRO aula 09 (chamando funções). Disponível em: <http://
www.youtube.com/watch?v=Fb46wYUvxSI>. Acesso em: 03/02/2014.
Aula de 8 minutos específica de chamada de funções utilizando ponteiros. Ela o ajudará na 
compreensão do uso de ponteiros em C. 
Isso quer dizer que, se você quiser alterar o menu para que a Opção C execute a Func12, 
apenas precisa alterar o ponteiro ptrMenu[2] e atribuir o endereço da Func12. Isso permite 
criar um menu personalizável.
leituraobRIgATóRIA
16
agoraéasuAvez
Instruções: 
Chegou a hora de você exercitar seu aprendizado por meio das resoluções 
das questões deste Caderno de Atividades. Essas atividades auxiliarão 
você no preparo para a avaliação desta disciplina. Leia cuidadosamente 
os enunciados e atente-se para o que está sendo pedido e para o modo de 
resolução de cada questão. Lembre-se: você pode consultar o Livro-Texto 
e fazer outras pesquisas relacionadas ao tema.
Questão 1:
O que é um ponteiro em linguagem C?
Questão 2:
Suponha que nPtr seja um ponteiro para 
uma matriz de inteiros. Qual endereço é 
referenciado por nPtr após a atribuição?
a) Endereço do primeiro elemento da 
matriz. 
b) Endereço do último elemento da matriz.
c) Nenhum, nPtr referencia a um endereço 
específico da matriz.
d) Endereço do segundo elemento da 
matriz.
e) Nulo.
Questão 3:
A seguir, temos atribuição de endereços 
a um Ponteiro de inteiros (int *iPtr). Qual 
atribuição está correta?
a) iPtr = 9; // 9 inteiro qualquer.
b) iPtr = a; // a variável inteira qualquer, 
inicializa com zero.
c) iPtr = &d; // d variável inteira qualquer, 
inicializa com zero.
17
d) iPtr = *m[5]; // m matriz de inteiros com 
5 elementos.
e) iPtr = 0.
Questão 4:
O que é do tipo int na instrução seguinte?
int *p
a) A variável p.
b) O endereço de p.
c) A variável apontada por p <-
d) endereço da variável apontada por p.
e) Obrigatoriamente, o conteúdo e 
endereço da variável p.
Questão 5:
Qual instrução a seguir declara um ponteiro 
para uma variável char?
a) char *p; <-
b) *char p;
c) string * p;
d) *p
e) string=*p;
Questão 6:
Uma string é uma coleção de caracteres. 
Por que podemos dizer que uma string é 
uma matriz de caracteres?
Questão 7:
O que há de errado com essa declaração 
a seguir?
const char * nomes[5] = {“Ana”,”Pedro”,”Ju
lia”,”Maria”};
Questão 8:
Um ponteiro para matriz sempre aponta 
para o primeiro elemento da matriz, então 
o trecho código a seguir está correto?
int mx[10];
int* vPtr;
vPtr = mx[3];
Questão 9:
Qual a diferença entre escrever mx[4] e 
*(mx+3)?
Questão 10:
Dado o programa:
void teste( )
 int (*func)( );
agoraéasuAvez
18
 int main(void)
{
 func = teste;
 func( );
}
void teste( ) {
 printf(“Olá ! teste”);
 }
Qual o erro do programa?
agoraéasuAvez
Um ponteiro inicializado sempre conterá o endereço de outra variável que conte 
um valor. Os ponteiros podem ser definidos para apontar para objetos de qualquer tipo. 
Um nome de matriz pode ser considerado um ponteiro constante, matrizes podem conter 
ponteiros, e ponteiros para uma função podem ser armazenados em matrizes e atribuídos 
a outros ponteiros de funções.
Neste tema, você aprendeu sobre o conceito de ponteiros, aprendeu a referenciar matrizes 
e seus elementos e a utilizar ponteiros e criar e chamar funções por meio de ponteiros.
Caro aluno, agora que o conteúdo dessa aula foi concluído, não se esqueça de acessar 
sua ATPS e verificar a etapa que deverá ser realizada. Bons estudos!
finalizando
19
MIZRAHI, Viviane V. Treinamento Linguagem C. São Paulo: Pearson, 2006.
SCHILDT, H. C. Completo e Total. 3. ed. São Paulo: Makron Books, 1996.
SEDGEWICK, R. Algorithms in C - Parts 1 – 4. Addison Wesley, 2003.
referências
glossário
Bubble: método de ordenação simples, baseado em percorrer um vetor alvo de ordenação 
n2 vezes.
Overhead: é considerado qualquer processamento ou armazenamento em excesso.
20
Questão 1
Resposta: Ponteiro é um tipo de variável que guarda o endereço de uma outra variável, 
matriz ou estrutura de dados.
Questão 2
Resposta: Alternativa A. 
Questão 3
Resposta: Alternativa C. 
Questão 4
Resposta: Alternativa C.
Questão 5
Resposta: Alternativa A. 
Questão 6
Resposta: Porque String é uma matriz unidimensional também chamada de vetor do tipo 
char, que armazena um texto formado de caracteres sempre terminado pelo caractere (‘0’).
Questão 7
Resposta: Declara um vetor com 5 elementos e está tentando inicializar o vetor, porémhá 
apenas 4 elementos para inicialização.
gabarito
21
gabarito
Questão 8
Resposta: Não!
vPtr = mx[3] não pode ser escrito dessa forma, pois vPtr é um ponteiro, e não uma variável 
inteira, e também não aponta para o primeiro elemento. 
O correto seria:
vPtr = mx ou vPtr = &mx[0];
Questão 9
Resposta: Não há diferença, pois são formas equivalentes de acessar o vetor; o primeiro 
acessa o quarto elemento e o segundo acessa o terceiro elemento. 
Questão 10
Resposta: Foi declarado um ponteiro de função que retorna um inteiro, porém a função do 
programa não retorna inteiro, e isso causará um erro.
Programação Estruturada II
Autoria: Renato Cristiano Torres
Tema 02
Recursividade
seç
ões
Tema 02
Recursividade
Como citar esse documento:
TORRES, Renato Cristiano, Programação Es-
truturada II. Valinhos: Anhanguera Educacional, 
2014. p. 1-90. 
Disponível em: <http://www.anhanguera.com>. 
Acesso em: 03 fev. 2014.
SeçõesSeções
Tema 02
Recursividade
5
Conteúdo
Nessa aula você estudará: 
•	 O que é Recursão.
•	 Funções Recursivas.
•	 Algoritmos Recursivos x Iterativos.
conteúdosEhabilidades
Introdução ao Estudo da Disciplina 
Caro(a) aluno(a).
Este Caderno de Atividades foi elaborado com base no livro C: Como Programar, dos 
autores Paul Deitel e Harvey Deitel, Editora Pearson, 2011.
Roteiro de Estudo:
Renato Cristiano TorresProgramação Estruturada II 
6
conteúdosEhabilidades
leituraobRIgATóRIA
Habilidades 
Ao final, você deverá ser capaz de responder as seguintes questões:
•	 Quando utilizar a recursão?
•	 Como escrever algoritmos ou funções recursivas?
•	 Quais as implicações de utilizar a recursão?
•	 Qual a diferença entre Recursão e Iteração?
Recursividade
Assim como em outras linguagens em C, uma função pode chamar a si própria quantas 
vezes for necessário. Uma função que chama a si própria é denominada função recursiva 
(DEITEL; DEITEL, 2011).
Porém, existem cuidados que devem ser tomados ao se escrever funções recursivas. Um 
deles é determinar um critério de parada, que determinará quando a função deve encerrar 
a chamada para si própria, impedindo uma chamada ininterrupta ou infinita.
Você verá um exemplo utilizando fatorial:
O Fatorial de n (n é um número natural) é sempre o produto de todos seus antecessores, 
incluindo o próprio n e excluindo o zero. A representação do fatorial é expressa pelo número 
seguido de um ponto de exclamação:
5! = 120 -> 5*4*3*2*1 = 120
Aqui, temos um exemplo do cálculo do fatorial de um número inteiro iterativo, ou seja, que 
utilizará um looping:
7
leituraobRIgATóRIA
1) #include <stdio.h>
2) int fat(int n)
3) {
4) int fat=1;
5) for(i=1;i <= n; i++)
a. fat = fat*i;
6) return fat;
7) }
8) int main(void)
9) {
10) int n,i;
11) scanf(“%d”,&n);
12) printf(“%\n”,fat(n);
13) }
Agora, veremos o cálculo do fatorial de um número inteiro utilizando uma função recursiva, 
ou seja, a função chamará ela própria n vezes.
1) #include <stdio.h>
2) int fatorial(int n)
3) {
4) if (n) // se for zero retorna 1, para qualquer outro número entra em recursão
return n*fat(n-1)
5) else 
6) return 1;
7) }
8) int main()
9) {
10) int n;
11) printf(“\n\n Digite um valor :”);
12) scanf(“%d”,&n);
13) printf(“\n O fatorial de %d”, n, fat(n));
14) return 0;
15) }
8
O critério de parada é quando n for menor ou igual a zero; enquanto n for maior que zero, 
a chamada continua.
Analise como o fatorial de 5 é calculado:
Para cada chamada, o programa coloca a chamada (expressão) em uma pilha até encontrar 
o critério de parada, depois desempilha resolvendo cada chamada.
EMPILHANDO DESEMPILHANDO
Passo 1 – 5! PASSO 6 = 1! = 1
Passo 2 – 5! = 5 * 4! PASSO 5 = 2! = 2*1! = 2
Passo 3 – 4! = 4 * 3! PASSO 4 = 3! = 3*2! = 6
Passo 4 – 3! = 3 * 2! PASSO 3 = 4! = 4*3! = 24
Passo 5 – 2! = 2 * 1! PASSO 2 = 5! = 5*4! = 120
Passo 6 – 1! = 1 PASSO 1 = 5! = 120
Apresentaremos outro exemplo utilizando a sequência de Fibonacci, que é uma sequência 
de números naturais, começando em 0 e 1, cuja propriedade estabelece que cada número 
de Fibonacci subsequente é a soma dos dois números de Fibonacci anteriores (DEITEL; 
DEITEL, 2011).
Exemplo:
a)
0 1º 2º
0 1 1
3º Número de Fibonacci somamos os 2 predecessores 0 e 1;
 = 0 +1 =1
b)
0 1º 2º 3º
0 1 1 2
4º Número de Fibonacci somamos os 2 predecessores 1 e 1;
 = 1 + 1 = 2
leituraobRIgATóRIA
9
leituraobRIgATóRIA
c)
0 1º 2º 3º 4º
0 1 1 2 3
5º Número de Fibonacci somamos os 2 predecessores 1 e 2;
 = 1 + 2 = 2
Você verá como fica um programa iterativo para calcular a sequência no modo iterativo.
1) #include<stdio.h>
2) int main()
3) {
4) int n, primeiro = 0, segundo = 1, prox, c;
5) printf(“Entre com o número\n”);
6) scanf(“%d”,&n);
7) printf(“ A sequencia de Fibonacci para %d é :-\n”,n);
8) for ( c = 0 ; c < n ; c++ )
9) {
10) if ( c <= 1 )
11) prox = c;
12) else
13) {
14) prox = primeiro + segundo;
15) primeiro = segundo;
16) segundo = prox;
17) }
18) printf(“%d\n”,prox);
19) }
20) return 0;
21) }
O programa executa o que foi mostrado para calcular a sequência de Fibonacci, utilizando 
as variáveis “primeiro” e “segundo” para somar os antecessores e “prox” para acumular 
a soma sucessivamente nas posições até encontrar o número que informamos de forma 
iterativa, ou seja, utilizando uma estrutura de laço.
10
Veja agora um exemplo recursivo:
1) #include<stdio.h>
2) int Fibonacci(int);
3) main()
4) {
5) int n, result;
6) scanf(“Digite um número inteiro : %ld”,&n); // número fornecido pelo usuário
7) printf(“Série Fibonacci\n”);
8) result = Fibonacci(i); // calcula o valor de fibonacci para o número fornecido pelo 
usuário
9) printf(“Fibonacci (%ld) = (%ld)\n”, number, result);
10) return 0;
11) }
12) int Fibonacci(int n)
13) {
14) if ( n == 0 ) | ( n == 1 )
15) return n;
16) else
17) return ( Fibonacci(n-1) + Fibonacci(n-2) ); // Soma do antecessor do antecessor e o 
antecessor direto
18) }
Resultado do Programa em execução:
Digite um número inteiro: 4
Fibonacci(4) = 3
Digite um número inteiro: 6
Fibonacci(6) = 8
leituraobRIgATóRIA
11
Vamos testar:
0 1º 2º 3º 4º 5º 6º
0 1 1 2 3 5 8
= o quarto número da sequência é 3 – Certo!
0 1º 2º 3º 4º 5º 6º
0 1 1 2 3 5 8
= o sexto número da sequência é 8 – Certo!
linksImPoRTAnTEs
Quer saber mais sobre o assunto? 
Então:
Sites
Acesse o link: <http://www.matematicadidatica.com.br/Fatorial.aspx>. Acesso em: 
03/02/2014.
Você encontrará uma explicação detalhada sobre fatorial.
Para entender melhor as diferenças entre recursão e iteração, acesse: <http://programando-
ads.blogspot.com.br/2012/09/recursividade-entendendo-o-conceito.html>. Acesso em: 
03/02/2014.
Acesse o link: <http://www.ic.unicamp.br/~vanini/mc202/apresentacoes/aula3.pdf>. Acesso 
em: 03/02/2014.
Você encontrará exemplos de recursão.
leituraobRIgATóRIA
12
Instruções: 
Chegou a hora de você exercitar seu aprendizado por meio das resoluções 
das questões deste Caderno de Atividades. Essas atividades auxiliarão 
você no preparo para a avaliação desta disciplina. Leia cuidadosamente 
os enunciados e atente-se para o que está sendo pedido e para o modo de 
resolução de cada questão. Lembre-se: você pode consultar o Livro-Texto 
e fazer outras pesquisas relacionadas ao tema.
agoraéasuAvez
Vídeos
Para você que deseja conhecer um pouco mais sobre sequência de Fibonacci, veja a aula 
Sequência Fibonacci e Número de Ouro. Disponível em: <http://www.youtube.com/watch?v
=NIkJFjaWgi8&noredirect=1>. Acesso em: 03/02/2014.
Questão 1:
Qual a diferença entre recursão e iteração?
Questão 2:
As funções recursivas utilizam uma 
estrutura de dados interna do compiladordenominada:
a) Lista de Ponteiros.
b) pilha <-
c) Matriz.
d) Lista Encadeada.
e) Lista Ligada.
Questão 3:
Uma recursão é baseada em?
a) Laço de Controle.
13
b) Laço de Repetição.
c) Funções que chamam a si própria n 
vezes.
d) Chamada de funções externas.
e) Execução de comandos externos.
Questão 4:
Qual a desvantagem do uso da recursão?
a) Consome pouca memória.
b) Pode consumir muita memória.
c) Consome muito disco.
d) É eficiente.
e) Há limites para as funções chamarem 
a si próprias.
Questão 5:
Uma função interativa baseia-se em:
a) Uma estrutura de repetição <
b) Uma estrutura recursiva.
c) Funções que chamam a si próprias.
d) Bibliotecas.
e) Estruturas recursivas de repetição.
Questão 6:
Escreva o código de um programa que 
calcule a potência de um número inteiro de 
forma recursiva.
Questão 7:
Escreva o código de um programa que 
tenha duas funções para o cálculo da 
multiplicação de 2 números de forma 
recursiva e interativa.
Questão 8:
Há uma preocupação especial com o 
critério de parada em programas que 
utilizam funções recursivas. Qual o motivo 
dessa atenção?
Questão 9:
Demonstre como fica a tabela de 
empilhamento/desempilhamento do cálculo 
recursivo da multiplicação dos números 4 e 
5 utilizado na Questão 7. 
Questão 10:
Demonstre como fica a tabela de 
empilhamento/desempilhamento de uma 
função recursiva que calcula o fatorial do 
número 6.
agoraéasuAvez
14
Segundo Deitel e Deitel (2011), tanto a iteração quanto a recursão se fundamentam 
em uma estrutura de controle. A interação utiliza uma estrutura de repetição, enquanto a 
recursão utiliza uma estrutura de seleção. As duas envolvem critérios e testes para término. 
Porém, a recursão tem alguns pontos negativos que algumas vezes tornam um programa 
custoso computacionalmente, ou seja, consome muita memória por utilizar pilha e também 
por esse fato não é tão eficiente quanto o modelo iterativo. Logo, chegamos à conclusão de 
que a escolha de uma solução iterativa é utilizada quando uma recursiva não é tão clara.
Caro aluno, agora que o conteúdo dessa aula foi concluído, não se esqueça de acessar 
sua ATPS e verificar a etapa que deverá ser realizada. Bons estudos!
finalizando
referências
MIZRAHI, Viviane V. Treinamento Linguagem C. São Paulo: Pearson, 2008.
SEDGEWICK, R. Algorithms in C - Parts 1 – 4. Addison Wesley, 2003.
SCHILDT, H. C. Completo e Total. 3. ed. São Paulo: Makron Books, 1996.
15
glossário
Iterativa: processo que se repete várias vezes.
Fibonacci: Leonardo Fibonacci, matemático italiano criador da sequência de Fibonacci.
gabarito
Questão 1
Resposta: A interação utiliza uma estrutura de repetição. Logo, normalmente terá while/
for envolvido na solução, e a recursão utiliza uma estrutura de seleção. As duas envolvem 
critérios e testes para término, porém, a recursão utiliza-se do mecanismo de chamar a si 
própria várias vezes.
Questão 2
Resposta: Alternativa C. 
Questão 3
Resposta: Alternativa D. 
Questão 4
Resposta: Alternativa B. 
16
Questão 5
Resposta: Alternativa A. 
Questão 6
Resposta: 
1) #include <stdio.h>
2) int potencia(int base, int expoente){
3) if(expoente == 0)
4) return 1;
5) else
6) return (base * potencia(base, expoente-1));
7) }
8) int main(){
9) int base = 2, expoente = 8, resultado;
10) resultado = potencia(base,expoente);
11) printf(“%d elevado a %d = %d”, base, expoente,resultado);
12) return 0;
13) } 
Na linha 2, temos declarada a função recursiva potência que receberá a base e o expoente; 
ao chama-lá, ela fará sucessivas multiplicações.
EMPILHANDO DESEMPILHANDO
Passo 1 – 23 PASSO 6 = 21 = 2 * 20 = 2
Passo 2 – 23= 2 * 22 PASSO 5 = 22 = 2 * 21 = 4
Passo 3 – 22= 2 * 21 PASSO 4 = 23 = 2 * 22 = 8
 
gabarito
17
gabarito
Questão 7
Resposta: 
Forma Iterativa
1) #include <stdio.h>
2) long int multiplicação(int a, int b){ 
3) long int res=0;
4) while( b != 0){ 
5) r += a;
6) b--;
7) }
8) return(r);
9) }
Note que a base da função é um laço While. A cada iteração, faz uma soma baseada nos 
argumentos recebidos. Um exemplo de execução seria:
4 * 5 = 4 + 4 + 4+ 4+ 4 cinco vezes a soma do número quatro
Forma Recursiva
1) long int mult(int a, int b) 
2) { 
3) if (b == 1) // qualquer número multiplicador por 1 o resultado é ele mesmo
4) return(a); 
5) else 
6) if (b == 0)
7) return 0;
8) else
9) return(a + mult(a, b-1)); // sucessivas somas até b == 0
10) }
18
Questão 8
Resposta: As funções recursivas exigem memória para executar, e, em um programa 
defeituoso que fique infinitamente em looping, haverá o travamento da Sistema Operacional; 
por isso, o critério de parada é importante.
Questão 9
Resposta: 
EMPILHANDO DESEMPILHANDO
4 + mult(4 4) 4 + (4 + (4+(4+(4+(0))))
4 + (4 + mult(4 3)) 4 + (4 + (4+(4+(4)))
4 + (4 + 4+(mult(4 2)) 4 + (4 + (4+(8))
4 + (4 + (4+(4+(mult(4 1)))) 4 + (4 + (12))
4 + (4 + (4+(4+(4+(mult(4 0))))) 4 + (16) = 20
Questão 10
Resposta: 
EMPILHANDO DESEMPILHANDO
Passo 1 – 6! PASSO 7 = 1! = 1
Passo 2 – 6! = 6 * 5! PASSO 6 = 2! = 2*1! = 2
Passo 3 – 5! = 5 * 4! PASSO 5 = 3! = 3*2! = 6
Passo 4 – 4! = 4 * 3! PASSO 4 = 4! = 4*3! = 24
Passo 5 – 3! = 3 * 2! PASSO 3 = 5! = 5*4! = 120
Passo 6 – 2! = 2 * 1! PASSO 2 = 6! = 6*5! = 720
Passo 7 – 1! = 1 PASSO 1 = 6! = 720 
gabarito
Programação Estruturada II
Autoria: Renato Cristiano Torres
Tema 03
Arquivos
seç
ões
Tema 03
Arquivos
Como citar esse documento:
TORRES, Renato Cristiano, Programação Es-
truturada II. Valinhos: Anhanguera Educacional, 
2014. p. 1-90. 
Disponível em: <http://www.anhanguera.com>. 
Acesso em: 03 fev. 2014.
SeçõesSeções
Tema 03
Arquivos
5
Conteúdo
Nessa aula você estudará: 
•	 Manipulação de Arquivos em C.
•	 Acesso a arquivos de Forma Aleatória e Sequencial.
•	 Modos de Abertura de Arquivos.
conteúdosEhabilidades
Introdução ao Estudo da Disciplina 
Caro(a) aluno(a).
Este Caderno de Atividades foi elaborado com base no livro C: Como Programar, dos 
autores Paul Deitel e Harvey Deitel, Editora Pearson, 2011.
Roteiro de Estudo:
Renato Cristiano TorresProgramação Estruturada II 
6
conteúdosEhabilidades
Habilidades 
Ao final, você deverá ser capaz de responder as seguintes questões:
•	 Como ler e escrever em arquivos?
•	 Qual a diferença entre acesso aleatório e sequencial?
•	 Quais são os tipos de streams?
conteúdosEhabilidades
Arquivos
O armazenamento de dados em variáveis, estruturas e matrizes é temporário. Esses 
dados são perdidos quando um programa é encerrado, e os arquivos são utilizados na 
conservação permanente de dados (DEITEL; DEITEL, 2011).
Cada arquivo é uma sequência de bytes, em que cada linha termina com um marcador de 
fim de linha, e o arquivo contém outro marcador de fim de arquivo.
Quando um arquivo é aberto, um objeto é criado e um stream é associado ao objeto. Os 
streams fornecem canais de comunicação entre arquivos e programas.
Segundo Schildt (1996), existem dois tipos de streams:
Stream de Texto – formado por sequência de caracteres; o padrão C ANSI permite que 
um stream de texto seja organizado em linhas terminadas por um caractere de nova linha.
Stream Binário – formado por sequência de bytes, a quantidade de byte é a mesma do 
dispositivo, ou seja, não há tradução.
leituraobRIgATóRIA
7
leituraobRIgATóRIAleituraobRIgATóRIA
Criação de um Arquivo de Acesso Sequencial
A linguagem C não impõe uma estrutura definida a um arquivo. Os conceitos de registro não 
fazem parte da linguagem. Isso quer dizer que você deve estruturar os dados da forma que 
satisfaçama necessidade da aplicação. Ao manipular um arquivo de forma sequencial, após 
a abertura do arquivo a posição corrente é o início do arquivo. Esse indicador é atualizado 
a todo momento enquanto se move pelo arquivo (Figura 3.1).
Figura 3.1 Arquivo de acesso sequencial.
8
No modo sequencial, o indicador é posicionado no início do arquivo e faz uma varredura 
até o final de arquivo ser encontrado para realizar uma leitura total do arquivo. Caso haja a 
necessidade de ler parte do arquivo, você tem de avançar a partir do início do arquivo até o 
ponto desejado, sequencialmente.
Veja no exemplo, a seguir, uma maneira simples de manipular registros em um arquivo:
1) #include <stdio.h>
2) int main(void)
3) {
4) int account;
5) char name[30];
6) double balance
7) FILE *fptr;
8) if ((fptr = fopen(“clientes.dat”,”w”)) == NULL){
9) printf(“O arquivo não pode ser aberto\n”);
10) }
11) else
12) {
13) printf(“Digite o número de conta, nome e saldo.\n”);
14) printf(“Digite fim de arquivo para terminar a entrada.\n”)
15) printf(“?”);
16) scanf(“%d%s%lf”,&account,name, balance);
17) while (!eof(stdin)){
i. fprintf(fptr,%d,%s,%2.f\n”,account,name,balance);
ii. printf(“? ”)
iii. scanf(“%d%s%lf”,&account,name, balance);
18) }
19) fclose(fptr);
20) return 0;
21) }
leituraobRIgATóRIA
9
O comando fprintf funciona de forma similar ao printf. A diferença é que o fprint exige como 
parâmetro o ponteiro para arquivo, onde será escrito o dado no formato especificado no 
segundo argumento. Para ler dados do arquivo, podemos utilizar o comando fscanf, que 
também é similar ao scanf, da seguinte forma:
fscanf(fptr,”%d”,&numero);
 
O primeiro argumento da função é o ponteiro do arquivo, de onde será lido o dado; o segundo 
é a máscara de formato; e o terceiro é a referência da variável que receberá o dado lido.
A combinação de teclas para informar fim de arquivo para Linux/Mac OS e Unix é <Ctrl>d, 
no Windows é <Ctrl>Z.
Examinando o código na linha 7, você notará que o fptr é um ponteiro para uma estrutura 
FILE. Neste momento, você não precisa conhecer os detalhes para utilizar arquivos, porém, 
caso seja necessário, basta procurar o arquivo stdio.h na pasta padrão include do seu 
compilador. O ponteiro fptr será utilizado para referenciar o arquivo. Todo arquivo precisa 
de um ponteiro do tipo FILE associado. A função fopen na linha 8 retorna um ponteiro do 
tipo FILE e recebe como argumentos o nome do arquivo e o modo de abertura, “w” significa 
que o arquivo pode ser alterado, “r” será apenas leitura (Figura 3.2). Se fopen retornar 
NULL, logo o fptr será nulo. Desta forma, o arquivo não foi aberto, e um erro será retornado. 
Todo arquivo aberto deve ser fechado! Veja no nosso código a função fclose(fptr). Com 
isso, libera o arquivo para ser alterado por outro usuário.
MODO DESCRIÇÃO
r Abre um arquivo existente para leitura.
w Criar um arquivo para gravação. Se o arquivo já existe, sobrescreve.
a Abre ou Cria um arquivo para adicionar dados ao seu final.
r+ Abre um arquivo para leitura e escrita; caso não exista, será criado.
w+ Abre um arquivo para escrita; caso não exista, será criado.
a+ Abre ou cria um arquivo para atualização; dados serão gravados no final do arquivo.
leituraobRIgATóRIA
10
rb Abre um arquivo existente para leitura no mode binário.
wb Abre um arquivo existente para escrita no mode binário.
ab Abre ou cria um arquivo binário para adicionar dados ao seu final.
rb+ Abre um arquivo binário para leitura e escrita; caso não exista, será criado.
wb+ Abre um arquivo binário para escrita; caso não exista, será criado.
ab+ Abre ou cria um arquivo binário para atualização; dados serão gravados no final do arquivo.
Figura 3.2 Modos de abertura de arquivo.
Arquivos de Acesso Aleatório
O acesso a arquivos de forma aleatória possibilita fazer o acesso diretamente a registros, 
sem a necessidade de passar pelos registros anteriores. Logo, para acessar qualquer parte 
do arquivo, basta utilizar uma função de busca, por exemplo:
fseek(fPtr,OffSet, SEEK_SET)
A função fseek possui 3 argumentos. O primeiro é o ponteiro para arquivo; o segundo é a 
quantidade de bytes que o indicador precisará caminhar para chegar até o dado desejado a 
partir da origem especificada no terceiro argumento, que pode assumir 3 valores:
ORIGEM VALOR
Início do Arquivo SEEK_SET
Posição Corrente SEEK_CUR
Fim do Arquivo SEEK_END
FILE *fp;
char ch;
if ((fp = fopen(“cliente.dat”, “rb”)) == NULL)
{
leituraobRIgATóRIA
11
leituraobRIgATóRIA
puts(“Não posso abrir arquivo!”);
exit(1);
}
fseek(fp, 44, SEEK_SET);
ch = getc(fp); //lê um caractere na posição 45o
A função fseek( ) retorna zero se houve sucesso ou um valor diferente de zero, se houve 
falha no posicionamento do indicador do arquivo. Normalmente, o arquivo terá comprimento 
de registro fixo, ou seja, as linhas do arquivo terão o mesmo número de bytes.
Os registros criados com a função fprintf não têm necessariamente o mesmo tamanho. 
Registros individuais de um arquivo de acesso aleatório normalmente têm tamanhos fixos 
e podem ser acessados diretamente, rapidamente, sem pesquisa por outros registros. 
Isso torna os arquivos de acesso aleatório ideais para arquivos que precisam de acesso 
rápido a dados específicos, como arquivos de configuração, tabelas de dados em sistemas 
corporativos e outros.
A função fwrite transfere para um arquivo um número especificado de bytes de um local da 
memória. A função fread transfere um número de bytes do arquivo para memória.
Exemplo:
fwrite(&numero, sizeof(int),1,fptr);
Para ler e escrever tipos de dados maiores que um byte, C fornece duas funções fwrite e 
fread, que são capazes de ler e gravar qualquer tipo de informação.
Exemplo:
#include <stdio.h>
#include <stdio.h>
void main(void)
{
 FILE *fp;
double d=12.23;
int i = 101;
long l = 123023L;
12
if ((fp=fopen(“teste”,”wb+”)) == NUL{
printf(“O arquivo não pode ser aberto\n”);
exit(1)
}
//Escrita de dados binário de vários tipos
fwrite(&d,sizeof(double),1,fp); 
fwrite(&i,sizeof(int),1,fp); 
fwrite(&l,sizeof(long),1,fp); 
rewind(fp); // move o indicador para o inicio do arquivo
//Leitura de dados binário de vários tipos
fread(&d,sizeof(double),1,fp); 
fread (&i,sizeof(int),1,fp); 
fread (&l,sizeof(long),1,fp); 
prinff(“%f %d %ld, d ,i ,l);
flclose(fp);
}
Nesse exemplo o programa escreve dados não caracteres em um arquivo e depois lê de 
volta. Esses dados não são visíveis em um editor de texto, caso você abra o arquivo.
Uma das aplicações de fread() e fwrite() envolve ler e escrever estrutura de dados. Veja o 
exemplo:
struct scruct_type{
float balanco;
char nome[80];
}custo;
leituraobRIgATóRIA
13
linksImPoRTAnTEs
Quer saber mais sobre o assunto? 
Então:
Sites
Acesse o link: <http://linguagemc.com.br/matriz-em-c/>. Acesso em: 03/02/2014. 
Você encontrará um site dedicado à linguagem C.
Vídeos
Assista aos vídeos:
Acesse o vídeo: Linguagem C Aula 12 Arquivos Escrever. Disponível em: <http://www.
youtube.com/watch?v=gLAxAbv0KuY>. Acesso em: 03/02/2014.
O vídeo apresenta uma aula sobre manipulação de arquivo, com a possibilidade de obter os 
arquivos fontes da aula no link informado pelo autor. 
Acesso o vídeo: Programar em C - Manipulação de Arquivos txt em C /Ler Dados. Disponível 
em: <http://www.youtube.com/watch?v=y_euDUgoND8>. Acesso em: 03/02/2014.
Você encontrará um vídeo sobre manipulação de arquivos texto. 
Essa sentença escreve o conteúdo de custo no arquivo apontado por fp.
fwrite(&custo, sizeof(struct struct_type),1,fp); 
Suponha que você precise guardar parâmetros da inicialização de um sistema. Você pode 
utilizar o fwrite para gravar a estrutura de dados e fread para ler as configurações.
14
Instruções: 
Chegou ahora de você exercitar seu aprendizado por meio das resoluções 
das questões deste Caderno de Atividades. Essas atividades auxiliarão 
você no preparo para a avaliação desta disciplina. Leia cuidadosamente 
os enunciados e atente-se para o que está sendo pedido e para o modo de 
resolução de cada questão. Lembre-se: você pode consultar o Livro-Texto 
e fazer outras pesquisas relacionadas ao tema.
agoraéasuAvez
Questão 1:
Uma porta de comunicação do computador 
pode ser manipulada como arquivo?
Questão 2:
As funções fopen e fclose servem 
respectivamente para:
a) Ler e escrever um arquivo.
b) Abrir e fechar um arquivo.
c) Fechar e abrir um arquivo.
d) Escrever e ler um arquivo binário.
e) Ler e escrever um arquivo texto.
Questão 3:
Quais dos seguintes parâmetros podem ser 
especificados pela função fopen( )?
Acesso o vídeo: Manipulação de Arquivos em C. Disponível em: <http://www.youtube.com/
watch?v=Za93F-lhbRs>. Acesso em: 03/02/2014. 
Esse é outro vídeo que ensina como fazer manipulação de arquivos em C.
linksImPoRTAnTEs
15
a) Que o arquivo será aberto para 
acrescentar dados ao seu final.
b) Que o arquivo será aberto em modo 
hexadecimal.
c) Que todos os números serão gravados 
em formato binário.
d) Que todo o arquivo será lido caractere 
a caractere.
e) Que o arquivo será lido linha a linha.
Questão 4:
Se um programador descuidado abrir um 
arquivo para inserir dados e não fechar 
esse arquivo, o que pode acontecer?
a) Nada, o sistema operacional fecha 
o arquivo automaticamente durante a 
execução do programa.
b) Enquanto o programa estiver sendo 
executado, nenhum usuário consegue 
escrever no arquivo.
c) Enquanto o programa estiver sendo 
executado, nenhum usuário consegue ler 
o arquivo.
d) Após encerrar o programa, o sistema 
operacional mantém o arquivo como 
somente leitura.
e) Após encerrar o programa, o sistema 
operacional mantém o arquivo aberto.
Questão 5:
Para ler e escrever tipos de dados maiores 
que um byte, C fornece duas funções:
a) read e write.
b) fopen e fclose.
c) fputs e fgets.
d) fread e frwrite.
e) fread e fget.
Questão 6:
O que há de errado com o programa a 
seguir?
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
 FILE *fptr;
 fptr = fopen(“Testestr.txt”,”w”);
 fptr = NULL;
 fputs(“Um grande antidote contra o 
egoísmo\n”,fptr); 
 fputs(“é a generosidade.... Dê, mesmo 
que\n”,fptr);
 fputs(“isso requeira de você um 
esforço\n”,fptr);
 fputs(“consciente. Pelo fato de 
partilhar\n”,fptr);
agoraéasuAvez
16
 fputs(“tudo o que possui. Seu egosimo 
se\n”,fptr);
 fputs(“abrandará.\n”,fptr); 
fclose(fptr);
return 0;
}
Questão 7:
Qual a diferença entre acessar um arquivo 
de forma aleatória e sequencial?
Questão 8:
Qual o objetivo das funções fprintf e fscanf? 
Questão 9:
Crie um programa que escreva 10 números 
inteiros em um arquivo e depois leia do ar-
quivo e imprima os dados em tela.
Questão 10:
Explique o que faz a declaração a seguir:
tfPtr = fopen(“dados.dat”,”r”);
agoraéasuAvez
17
finalizando
A linguagem C trata cada arquivo como uma sequência de bytes. Quando um arquivo 
é aberto, um stream é associado ao arquivo, indicado por ponteiro do tipo FILE.
Esse ponteiro será o elo para a manipulação do arquivo. Os arquivos sequência devem 
obedecer à regra da estrutura para percorrerem seus registros, já, no modo aleatório, o 
percurso dentro do arquivo é realizado pelo reposicionamento do indicador de endereço 
dentro do arquivo.
Caro aluno, agora que o conteúdo dessa aula foi concluído, não se esqueça de acessar 
sua ATPS e verificar a etapa que deverá ser realizada. Bons estudos!
referências
MIZRAHI, Viviane V. Treinamento Linguagem C. São Paulo: Pearson, 2008.
SCHILDT, H. C. Completo e Total. 3. ed. São Paulo: Makron Books, 1996.
SEDGEWICK, R. Algorithms in C - Parts 1 – 4. Addison Wesley, 2003.
18
glossário
Bubble: método de ordenação simples, baseado em percorrer um vetor alvo de ordenação 
n2 vezes.
Overhead: é considerado qualquer processamento ou armazenamento em excesso.
gabarito
Questão 1
Resposta: Sim, todo local que tem capacidade para receber bytes da memória do computador 
ou transferi-los pode ser manipulado como arquivo, por exemplo: teclado, vídeo, impressora, 
portas de comunicação etc. Desta forma, o conceito de arquivo é ampliado.
Questão 2
Resposta: Alternativa B. 
Questão 3
Resposta: Alternativa A. 
Questão 4
Resposta: Alternativa B. 
19
gabarito
Questão 5
Resposta: Alternativa D. 
Questão 6
Resposta: Foi atribuído nulo ao ponteiro de arquivo. Com isso, ele não tem conexão com o 
arquivo aberto por fopen.
Questão 7
Resposta: Na forma sequencial, quando abrimos o arquivo, o indicador do arquivo 
é posicionado no início do arquivo, e para ler os dados do arquivo temos de percorrer 
sequencialmente todos os bytes; no acesso aleatório, podemos utilizar a função seek para 
posicionar o indicador no registro ou posição desejada, iniciando a busca a partir do início 
do arquivo, posição corrente ou fim do arquivo.
Questão 8
Resposta: Os comandos fprintf e scanf servem respectivamente para escrever e ler dados 
formatados. O fprintf funciona de forma similar ao printf, a diferença é que o fprint exige 
como parâmetro o ponteiro para arquivo, onde será escrito o dado no formato especificado 
no segundo argumento. O scanf, também de forma similar ao scanf, lê um dado formatado, 
porém do arquivo informado no primeiro argumento e com o formato informado no segundo 
argumento, e coloca o dado lido na variável informada no terceiro argumento.
Questão 9
Resposta: 
1) #include <stdio.h> 
2) #include <stdlib.h> 
3) main() 
4) { 
5) FILE *fp; 
6) char nomeArquivo[25] = “DezNumeros.txt”; 
7) int I,valor;
 // bloco de escrita do arquivo
20
8) 
9) fp = fopen(nomeArquivo, “w”); 
10) if (fp != NULL) 
11) { 
12) printf(“\n\n Arquivo Criado com Sucesso\n\n”); 
13) for (i = 1; i <=10; i++) 
14) fprintf(fp,”%d\n”,i); 
15) } 
16) else{ 
17) printf(“Falha ao criar o Arquivo”); 
18) exit(1); 
19) } 
20) fclose(fp); 
 // bloco de leitura do arquivo
21) fp = fopen(nomeArquivo, “r”); 
22) if (fp = fopen(nomeArquivo, “r”) != NULL) 
23) { 
24) printf(“\n\n Arquivo Criado com Sucesso\n\n”); 
25) for (i = 1; i <=10; i++) 
26) fscanf(fp,”%d\n”,&valor); 
27) printf(“Dado Lido :%d”,valor);
28) } 
29) else{ 
30) printf(“Falha ao criar o Arquivo”); 
31) exit(1); 
32) } 
gabarito
21
33) fclose(fp); 
34) system(“pause”); 
35) } 
Questão 10
Resposta: Abre um arquivo chamado dados.dat como leitura e associa o ponteiro do 
arquivo à variável tfPtr.
gabarito
Programação Estruturada II
Autoria: Renato Cristiano Torres
Tema 04
Aprendendo a Depurar e Documentar 
o Código
seç
ões
Tema 04
Aprendendo a Depurar e Documentar o Código
Como citar esse documento:
TORRES, Renato Cristiano, Programação Es-
truturada II. Valinhos: Anhanguera Educacional, 
2014. p. 1-90. 
Disponível em: <http://www.anhanguera.com>. 
Acesso em: 03 fev. 2014.
SeçõesSeções
Tema 04
Aprendendo a Depurar e Documentar o Código
5
Conteúdo
Nessa aula você estudará: 
•	 Uso da Depuração.
•	 Boas Práticas de Manutenção de Sistemas.
•	 Documentação de Código-Fonte.
•	 Versionamento.
conteúdosEhabilidades
Introdução ao Estudo da Disciplina 
Caro(a) aluno(a).
Este Caderno de Atividades foi elaborado com base no livro C: Como Programar, dos 
autores Paul Deitel e Harvey Deitel, Editora Pearson, 2011.
Roteiro de Estudo:Renato Cristiano TorresProgramação Estruturada II 
6
Habilidades 
Ao final, você deverá ser capaz de responder as seguintes questões:
•	 Como configurar a depuração no Dev C++?
•	 Quando utilizar a depuração?
•	 Por que documentar o código-fonte?
•	 Para que serve a versão dos sistemas e programas?
conteúdosEhabilidades
Aprendendo a Depurar
Depurar um programa é acompanhar sua execução linha a linha ou por meio de um ponto de 
interrupção, conhecido como breakpoint. O ponto de interrupção pausará a execução; será 
possível, utilizando uma ferramenta de depuração, avaliar conteúdo de variáveis, retorno 
de funções e outros. 
O objetivo é analisar o comportamento do programa durante sua execução. Normalmente, 
utilizamos o artifício de depuração quando buscamos entender algum erro que não esteja 
evidente e que se manifeste apenas durante a execução do programa. O exemplo utilizado 
será baseado no uso da IDE Dev C++.
Configurando o Dev C++
O primeiro passo para utilizar o depurador do Dev C++ é configurar o compilador para incluir 
informações de depuração no código objeto gerado (Figura 4.1).
leituraobRIgATóRIA
7
leituraobRIgATóRIA
Vá em Ferramentas->Opções do Compilador
Figura 4.1 Configuração do compilador.
Na aba Compilador, marque a caixa de seleção “Adicionar os seguintes comandos quando 
chamar o compilador” e adicione o comando –O0. Esse comando instruirá o compilador 
para o modo de depuração (Figura 4.2).
8
Figura 4.2 Configuração do compilador – Opções.
Depois, vá à aba Linker e modifique o parâmetro da opção “Gerar informação de depuração 
(–g3)”, coloque em YES (Figura 4.3). Isso fará com que o linkeditor se prepare para o modo 
de depuração.
leituraobRIgATóRIA
9
leituraobRIgATóRIA
Figura 4.3 Configuração do Linkeditor.
Pronto! Agora o ambiente está pronto para depurar um programa!
Depurando um Programa
Click com o botão direito do mouse em cima dos números à esquerda do código, uma barra 
vermelha destacará a linha informando que é um ponto de interrupção, ou seja, o programa 
executará até esse momento e aguardará o comando de continuação (Figura 4.4).
10
Figura 4.4 Depurando um programa.
Para executar o programa em modo de depuração, vá em Executar->Depurar ou utilize a 
tecla F5 (Figura 4.5).
Figura 4.5 Executando um programa em modo de depuração.
leituraobRIgATóRIA
11
Após a execução em modo de depuração, o ambiente irá executar e pausará a execução 
na linha marcada. Neste momento, a linha em destaque se torna azul e informa que a 
execução atingiu o ponto de interrupção (Figura 4.6).
Figura 4.6 Depuração em tempo de execução.
Neste momento, você tem disponível na parte inferior do ambiente diversas opções para 
continuar a execução linha a linha, continuar a execução ou parar (Figura 4.7).
Figura 4.7 Opções de depuração.
Com esses recursos, é possível observar o comportamento do programa em tempo de 
execução para detectar e corrigir erros.
leituraobRIgATóRIA
12
Documentando o Código-Fonte do Programa
Nas empresas que desenvolvem softwares profissionais, é comum que cada programador 
seja responsável por uma parte do código de um grande sistema, que pode ser um ERP, 
um sistema de BI ou e-commerce etc. Para que a leitura do código seja inteligível a todos, 
é fundamental utilizar algumas práticas e padrões, uma delas é a documentação do código.
A documentação do código serve para explicar em forma de comentário o objetivo das 
funções, variáveis e até mesmo do programa ou da unidade do código, que pode ser um 
arquivo do tipo header (.h), biblioteca ou outros.
Porém, para a documentação ser eficiente, o primeiro passo é pensar em quem vai ler 
aquele código, ou seja, quem for realizar uma manutenção ou precisar entender o código 
precisará saber facilmente o que ele faz, pois isso torna a manutenção e a compreensão 
eficiente e previne erros de interpretação.
Veja o exemplo de documentação:
Como deve ser feito:
1) #include <stdio.h> // dependente da biblioteca stdio
2) int fatorial(int n) // função que calcula fatorial de maneira recursiva
3) {
4) if (n)
return n*fat(n-1) // recebe o número e chama a própria função novamente 
decrementando o número recebido.
5) else return 1;
6) }
7) int main()
8) {
9) int n;
10) printf(“\n\n Digite um valor :”);
11) scanf(“%d”,&n); // recebe o número para calcular o fatorial
12) printf(“\n O fatorial de %d”, n, fat(n)); // imprime o valor do fatorial do número digitado
13) return 0;
14) }
leituraobRIgATóRIA
13
Como não deve ser feito:
1) #include <stdio.h> // adiciona o arquivo stdio.h
2) int fatorial(int n) // declara função fatorial
3) {
4) if (n)
return n*fat(n-1) // calcula fatorial
else return 1; // retorna 1
5) }
6) int main()
7) {
8) int n;
9) printf(“\n\n Digite um valor :”); // imprime a requisição de um valor
10) scanf(“%d”,&n); 
11) printf(“\n O fatorial de %d”, n, fat(n)); // imprime o valor do fatorial do número 
digitado
12) return 0;
13) }
Veja que no primeiro exemplo os comentários são dirigidos para a compreensão do 
código, já o segundo tenta explicar o que faz a linha de comando, o que é um erro, pois um 
programador sabe tecnicamente o que a linha de comando está fazendo, o que ele precisa 
entender é como aquela linha de comando contribui para o código todo.
A documentação exige disciplina e também adota uma metodologia ou padrão. Vamos 
adotar, aqui, de forma didática, um padrão que terá as seguintes premissas:
1) O que precisa ser documentado
Uma boa documentação começa com padrões de declaração de variável e funções, sempre 
utilizando por padrão letras minúsculas. Todas as funções devem possuir um cabeçalho 
detalhando sua finalidade e seus parâmetros. Variáveis importantes, ou seja, que não são 
somente auxiliares, devem ser comentadas. Laços devem ter seu escopo comentado e 
principalmente as condições de contorno. Se o programa recebe algum parâmetro para 
executar, devemos colocar esse comentário no cabeçalho da função main(). 
leituraobRIgATóRIA
14
2) Como documentar
A documentação do nosso código terá o seguinte padrão: todo arquivo conterá uma 
marcação superior e um cabeçalho que conterá os seguintes dados:
Objetivo: <Descrever aqui um resumo do “que” faz o código>
Autor: <Nome de quem escreveu a primeira versão>
Data da Ultima Alteração: <Data da última alteração realizada>
Responsável Pela Última Alteração: <Nome de quem fez a última alteração>
3) Versionamento
Quando temos várias pessoas alterando um sistema, ou seja, adicionando ou removendo 
funcionalidades, precisamos criar um mecanismo que controle tais alterações, informando 
quais alterações ou funcionalidades estão presentes nessa VERSÃO.
Esse controle de mudanças é denominado versionamento e baseia-se no registro das 
mudanças, acompanhado de um código de versão. 
Exemplo de versionamento em um sistema de gestão de projetos:
Versão Registro
1.0 Versão Inicial
2.0 Incluso a remoção de Atividades
2.1 Corrigido um erro ao alterar a data de conclusão de atividade
Note que o código de versão apresentado segue o padrão:
2 Dígitos => O primeiro dígito informa que houve uma mudança significativa, inclusão ou 
remoção de funcionalidade. O segundo dígito informa pequenas mudanças ou correção de 
erros.
As empresas podem empregar diferentes metodologias para versionamento. É comum ver 
a utilização de até 4 dígitos no código de versionamento. Porém, uma característica comum 
é o uso da data de liberação da versão. Veja como fica a tabela completa de versionamento:
leituraobRIgATóRIA
15
Versão Registro Data de Liberação
1.0 Versão Inicial 01/10/2013
2.0 Incluso a remoção de Atividades 20/11/2013
2.1
Corrigido um erro ao alterar a 
data de conclusão deatividade
10/12/2013
Quando um sistema sofre alteração, é necessário realizar testes intensos para evitar erros 
pós-alteração; com isso, a data de liberação indica quando foi disponibilizada para o usuário 
aquela versão do sistema.
Em sistemas comerciais, normalmente a liberação de versões segue uma política de períodos 
de distribuição que pode ser mensal, bimestral ou até semestral, exceto as liberações para 
correção de erros críticos.
Durante muito tempo, o método comum de controle de versão era copiar os arquivos de 
um diretório para outro e renomeá-los com o código de versão manualmente. Essa técnica 
estava susceptível a erros, era fácil sobrescrever arquivos equivocadamente.
Para apoiar esse controle, há sistemas específicos para o controle de versão. Os mais 
conhecidos e open source são: CVS e Subversion.
Vamos conhecer o funcionamento básico de um sistema de controle de versão centralizado! 
(Figura 4.8)
leituraobRIgATóRIA
16
Figura 4.8 Diagrama Padrão de um Sistema de Versionamento.
Quando um programador quer obter a última versão do código-fonte, ele utiliza um comando 
chamado checkin; após esse comando, todos os arquivos selecionados são enviados para a 
máquina local. Após realizar as alterações, o programador utiliza o comando checkout para 
postar no servidor a nova versão alterada e, com isso, disponibilizar para todos os demais 
programadores. Quando o servidor de controle de versão recebe os arquivos, ele registra 
automaticamente o código de versão e grava também as modificações, sendo possível 
revertê-las ou, até mesmo, mesclá-las com outras versões.
leituraobRIgATóRIA
17
linksImPoRTAnTEs
Quer saber mais sobre o assunto? 
Então:
Sites: 
Veja uma apresentação que demonstra a depuração passo a passo de um programa no 
DEV C++. Disponível em: <http://wiki.icmc.usp.br/images/1/18/Aula12-Arquivos-Parte1.
pdf>. Acesso em: 03/02/2014.
Vídeos:
Assista aos vídeos:
Para aprender como instalar subversion (software para controle de versão), acesse: <http://
www.youtube.com/watch?v=R59PzH79IN4>. Acesso em: 03/02/2014.
Para aprender como instalar e utilizar o ambiente Dev C++, visite o endereço: <https://www.
youtube.com/watch?v=SJqt7c6JuYs>. Acesso em: 03/02/2014.
Você vai encontrar um tutorial bem prático que orientará a instalação e o uso do ambiente.
Se você pretende iniciar o uso Dev C++, visite o endereço: <http://www.youtube.com/
watch?v=qHMXPIaHJrI>. Acesso em: 03/02/2014. 
Você encontrará uma videoaula que o auxiliará nos primeiros passos.
Versionamento no desenvolvimento de aplicações: <http://www.youtube.com/
watch?v=Wb6RPV9peJ8>. Acesso em: 03/02/2014.
Uma apresentação interessante sobre versionamento, explicando a motivação, as 
dificuldades e ferramentas para versionamento.
18
agoraéasuAvez
Instruções: 
Chegou a hora de você exercitar seu aprendizado por meio das resoluções 
das questões deste Caderno de Atividades. Essas atividades auxiliarão 
você no preparo para a avaliação desta disciplina. Leia cuidadosamente 
os enunciados e atente-se para o que está sendo pedido e para o modo de 
resolução de cada questão. Lembre-se: você pode consultar o Livro-Texto 
e fazer outras pesquisas relacionadas ao tema.
Questão 1:
O que é Depuração ou Debug?
Questão 2:
A depuração serve para:
a) Observar o comportamento do 
programa em tempo de execução.
b) Encontrar erros de compilação.
c) Encontrar erros de linkedição.
d) Observar o comportamento do 
programa em tempo de compilação.
e) Observar o comportamento do 
programa em tempo de linkedição.
Questão 3:
Qual a função do breakpoint ou ponto de 
interrupção?
a) Informar o compilador onde deve parar 
a compilação.
b) Informar o ponto de execução.
c) Informar o depurador onde deve pausar 
a execução.
d) Destacar a linha de execução.
e) Destacar a linha de depuração.
Questão 4:
Para que serve a documentação do código-
fonte?
19
agoraéasuAvez
a) Serve para detalhar em forma de 
comentário o uso de argumentos de 
compilação e linkedição.
b) Tem por objetivo declarar o tipo, a data 
e o autor do código.
c) Tem por objetivo declarar o autor do 
código para rastrear o responsável pelos 
erros.
d) Serve para explicar em forma de 
comentário o objetivo das funções, 
variáveis e até mesmo do programa ou da 
unidade do código.
e) Serve para documentar o uso de 
bibliotecas e arquivos adicionar (.h).
Questão 5:
O versionamento de programa é baseado 
em:
a) Parametrização do compilador para 
registrar alterações no programa.
b) Registro das funções do programa, 
identificado por um código. Ex: f2.0, f2.1 e 
informações adicionais referentes a cada 
função.
c) Registro de versões do programa, 
identificado por um código. Ex: 2.0, 2.1 e 
informações adicionais referentes a cada 
versão.
d) Parametrização do linkeditor para 
registrar alterações nas bibliotecas.
e) Registro do uso de arquivos do tipo 
header (.h).
Questão 6:
Utilizando o que você aprendeu sobre 
documentação de código, comente o 
código a seguir:
1) #include<stdio.h>
2) int main()
3) {
4) int n, primeiro = 0, segundo = 1, prox, c;
5) printf(“Entre com o número\n”);
6) scanf(“%d”,&n);
7) printf(“ A sequencia de Fibonacci para 
%d é :-\n”,n);
8) for ( c = 0 ; c < n ; c++ )
9) {
10) if ( c <= 1 )
11) prox = c;
12) else
13) {
14) prox = primeiro + segundo;
15) primeiro = segundo;
16) segundo = prox;
17) }
18) printf(“%d\n”,prox);
19) }
20) return 0;
21) }
20
agoraéasuAvez
Questão 7:
Qual o problema com os comentários do 
código a seguir?
1) #include <stdio.h> // adiciona o arquivo 
stdio.h
2) int fatorial(int n) // declara função fatorial
3) {
4) if (n)
 return n*fat(n-1) // calcula fatorial
 else return 1; // retorna 1
5) }
6) int main()
7) {
8) int n;
9) printf(“\n\n Digite um valor :”); // imprime 
a requisição de um valor
10) scanf(“%d”,&n); 
11) printf(“\n O fatorial de %d”, n, fat(n)); 
// imprime o valor do fatorial do número 
digitado
12) return 0;
13) }
Questão 8:
Por que em sistemas profissionais há 
uma preocupação com documentação e 
versionamento?
Questão 9:
Imagine que você fará a manutenção de 
um programa que faz a gestão de proje-
tos de uma empresa e que está na versão 
3.6.1. Você fará alterações em duas fases. 
A primeira será uma grande alteração de 
inclusão da gestão de projetos por portfó-
lio; a segunda será apenas um ajuste para 
corrigir um erro ao alterar a data de encer-
ramento das tarefas. Apresente como fica-
ria a tabela de versionamento.
Questão 10:
Como é o padrão de aquisição e postagem 
(checkin e checkout) de arquivos em um 
sistema de versionamento?
21
A evolução de uma área denominada engenharia de software trouxe inúmeras atividades 
e processos bem-estabelecidos como “boas práticas” para tornar eficiente a programação 
e o desenvolvimento de sistemas (SOMMERVILLE, 2003). A documentação do código e o 
versionamento são o resultado intenso da revisão dessas práticas, pois o grande objetivo é 
tornar um programa de fácil de leitura e compreensão por parte dos programadores e, por 
outro lado, garantir que a distribuição do programa esteja livre de erros e de acordo com a 
expectativa do usuário cliente, por meio de uma política de distribuição de versões.
Caro aluno, agora que o conteúdo dessa aula foi concluído, não se esqueça de acessar 
sua ATPS e verificar a etapa que deverá ser realizada. Bons estudos!
finalizando
referências
MIZRAHI, Viviane V. Treinamento Linguagem C. São Paulo: Pearson, 2008.
SCHILDT, H. C. Completo e Total. 3. ed. São Paulo: Makron Books, 1996.
SOMMERVILLE, IAN. Engenharia de Software. 6. ed. São Paulo: Pearson, 2003.
22glossário
Código-fonte: código do programa em linguagem natural que será compilado e interpretado 
pelo computador.
ERP: sistema integrado de gestão corporativa, normalmente possui módulos financeiro, 
vendas, faturamento, entre outros.
e-Commerce: sistema de compras pela internet, cujo objetivo é possibilitar compras 
eletrônicas, sendo normalmente integrado ao ERP.
BI (Business Intelligence): sistema que tem por objetivo construir análises de diversas 
bases de dados para apoiar a tomada de decisão; as análises podem ser baseadas em 
relatórios, gráficos ou indicadores.
gabarito
Questão 1
Resposta: Depurar e acompanhar a execução do programa linha a linha ou por meio de um 
ponto de interrupção, conhecido como breakpoint. O objetivo é analisar o comportamento do 
programa durante sua execução. Normalmente, utilizamos o artifício de depuração quando 
buscamos entender algum erro que não esteja evidente e que se manifeste apenas durante 
a execução do programa.
23
gabarito
Questão 2
Resposta: Alternativa A. 
Questão 3
Resposta: Alternativa C. 
Questão 4
Resposta: Alternativa D. 
Questão 5
Resposta: Alternativa C. 
Questão 6
Resposta: 
// Autor: Estudante
// Data Criação: 12/12/2013
//Objetivo: Cálculo do Número de Fibonacci
1) #include<stdio.h>
2) int main()
3) {
4) int n, primeiro = 0, segundo = 1, prox, c;
5) printf(“Entre com o número\n”);
6) scanf(“%d”,&n); // Obtém o número para calcular a sequencia de fibonacci
7) printf(“ A sequencia de Fibonacci para %d é :-\n”,n); // Apresenta sequencia de fibonacci 
até o número informado.
24
8) for ( c = 0 ; c < n ; c++ ) // Looping responsável pela interação de 0 até o número fornecido 
pelo usuário
9) {
10) if ( c <= 1 )
11) prox = c;
12) else
13) {
14) //nesse ponto a variável prox armazena os 2 últimos antecessores do número atual 
apontado pela iteração
15) prox = primeiro + segundo;
16) primeiro = segundo;
17) segundo = prox;
18) }
19) printf(“%d\n”,prox);
20) }
21) return 0;
22) }
Questão 7
Resposta: 
O problema do código é que os comentários dizem sobre os comandos de cada linha e não 
explicam como essas linhas cumprem sua função perante o objetivo do código.
1) #include <stdio.h> // adiciona o arquivo stdio.h
2) int fatorial(int n) // declara função fatorial
3) {
4) if (n)
 return n*fat(n-1) // calcula fatorial
 else return 1; // retorna 1
5) }
gabarito
25
6) int main()
7) {
8) int n;
9) printf(“\n\n Digite um valor :”); // imprime a requisição de um valor
10) scanf(“%d”,&n); 
11) printf(“\n O fatorial de %d”, n, fat(n)); // imprime o valor do fatorial do número digitado
12) return 0;
13) }
Questão 8
Resposta: Como em sistemas grandes e profissionais vários programadores realizam 
alterações nos códigos, é importante registrar as alterações e as versões que consolidam 
essas alterações para que se controle quem, o que, quando foram feitas as alterações e 
quais funcionalidades contêm cada versão.
Questão 9
Resposta: 
Versão Registro Data de Liberação
3.6.1 Versão Inicial 03/01/2014
4.0.0 Incluso Gestão de Projetos por Portfólio 10/01/2013
4.0.1
Corrigido um erro da data de 
encerramento das tarefas.
10/12/2013
Foi colocada a versão 3.6.1 como versão inicial para fins didáticos, a fim de notar como se 
altera a versão 3.6.1 para versão 4.0.0, visto que a mudança é grande; já a transição da 
versão 4.0.1 é uma mudança pequena, por isso alterou apenas o último dígito do código de 
versão.
gabarito
26
Questão 10
Resposta: Quando um programador deseja obter a última versão do código–fonte, ele 
utiliza um comando chamado checkin. Após esse comando, todos os arquivos selecionados 
são enviados para a máquina local. Após realizar as alterações, o programador utiliza o 
comando checkout para postar no servidor a nova versão alterada e, com isso, disponibilizá-
la para todos os demais programadores. Quando o servidor de controle de versão recebe os 
arquivos, ele registra automaticamente o código de versão e grava também as modificações, 
sendo possível revertê-las ou, até mesmo, mesclá-las com outras versões.
gabarito
24/03/2014
1
Programação Estruturada II
Tema: Revisão de Conteúdo
Profª MSc. Edilene A. V. de Campos
Objetivos desse encontro
• Revisar conteúdo ponteiro;
• Revisar conteúdo recursividade;
• Revisar conteúdo arquivo;
• Revisar conteúdo depuração e 
documentação 
O que é um Ponteiro?
Indica um espaço de memória em particular.
Referencia indiretamente um conteúdo.
Resumindo, um ponteiro é uma variável que
armazena um endereço de memória.
24/03/2014
2
Criação de ponteiro
char a, *b;
int *c;
...
a M 000123A1
000123A2b 000423E1
000423E1
c 000223FB
000223FB
...
Operadores de ponteiros
Existem 2 operadores necessários relacionados
com ponteiros:
& → obtém o endereço de memória 
ocupado por qualquer variável
* → possui duas funções: 1) criar um 
ponteiro e 2) fazer uma indireção
Exemplo do uso dos operadores * e &
#include <stdio.h>
int main(void) {
int *pt, n;
pt = &n;
*pt = 10;
println(“valor de n = %d“, n);
println(“o endereço de n = %p “, pt);
return 0; }
24/03/2014
3
Passagem de parâmetros (ou
argumentos)
Existem 2 maneiras para realizar a passagem
de parâmetros para uma função: por valor e
por referência.
A linguagem C permite apenas passagem por
valor. Entretanto, pode-se usar ponteiro para
simular uma passagem por referência.
Passagem de parâmetros (ou
argumentos) por valor
A passagem de parâmetros por valor cria cópia
de conteúdos para serem utilizados pela
função.
Quando a execução da função termina, tais
cópias são destruídas e todas as mudanças que
as cópias sofreram são perdidas.
Passagem de parâmetros (ou
argumentos) por referência
A passagem de parâmetros por referência
trabalha com o conteúdo original, sem criar
cópias. Quando a execução da função termina,
nada é destruído.
C simula a passagem por referência usando
ponteiros. Assim, são criadas cópias apenas
dos endereços de memória.
24/03/2014
4
Usando qualificador const com
ponteiros
O qualificador const também pode ser utilizado
com ponteiros, das seguintes maneiras:
- ponteiro não constante referenciando dados
constantes;
- ponteiro constante referenciando dados não
constantes;
- ponteiro constante referenciando dados
constantes.
Operador sizeof
O operador sizeof permite descobrir o tamanho
em bytes de um tipo de dado.
size_t y = sizeof(float);
OU
float a;
double b[12];
size_t x = sizeof(a);
size_t y = sizeof(b);
Aritmética de ponteiros
Exemplo:
int *ptr, vet[5];
ptr = &vet[0];
*ptr = 6;
ptr=ptr+2;
*ptr = 8;
...
0 1 2 3 4 
6 8
24/03/2014
5
Ponteiros e arrays
Arrays são diretamente ligados a ponteiros na
linguagem C.
Utilizar o nome de um array sem um subscrito
informa o endereço da primeira posição do
array.
Exemplo:
int a[5], *pt1, *pt2;
pt1 = a; //equivale a pt1 = &a[0];
O que é Recursividade?
•Alguma coisa que é definida em termos
dela própria.
•É a possibilidade de representar um
problema em função dele próprio, contudo,
numa instância menor.
•Diminuir o problema até chegar em uma
solução trivial (óbvia ou de fácil cálculo).
24/03/2014
6
Exemplo de Recursividade
1) Cálculo da potência de um número:
24 é bem mais fácil de calcular que 2876.
Entretanto, o problema é o mesmo, o que
muda é a instância do problema (ou o
tamanho do problema).
Exemplo de Recursividade
24 = 2 * 23
23 = 2 * 22
22 = 2 * 21
21 = 2
Exemplo de Recursividade
2) Cálculo do fatorial de um número:
4! é bem mais fácil de calcular que 345!
Entretanto, o problema é o mesmo,o que
muda é a instância do problema (ou o
tamanho do problema).
24/03/2014
7
Exemplo de Recursividade
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1
Características importantes para
funções recursivas
•Possuem uma função de recorrência;
•Possuem uma condição que identifica o
momento de interromper a recorrência;
•Possuem sempre instância do problema para
a qual a solução é facilmente obtida.
Função recursiva para calcular uma
potência
24 = 2 * 23
23 = 2 * 22
22 = 2 * 21
21 = 2
Suponto uma potência genericamente representada 
por be:
- Função de recorrência: be = b * be-1
- Instância com solução conhecida: b1 = b
- Condição de parada: se e=1 
24/03/2014
8
Função recursiva da potência em C
#include<stdio.h>
int potencia(int b, int e);
int main() {
int base, exp, result;
printf(“\nDigite valor da base: “);
scanf(“%d”, &base);
printf(“\nDigite valor do expoente: “);
scanf(“%d”, &exp);
result = potencia(base, exp);
printf(“\nPotencia = %d“, result);
getchar();
}
Função recursiva da potência em C
(continuação)
int potencia(int b, int e) {
int pot = 0;
if (e == 1) {
pot = b;
}
else {
pot = b * potencia(b, -1);
}
return pot;
}
23
2 * 22
2 * 21
2
E 1
E 2
E 3
2
4
8
pot(base=2, expoente=3) = 8
Analisando a execução ...
24/03/2014
9
O que é um Arquivo?
É um recurso utilizado para armazenamento
permanente de informações.
Um arquivo é uma sequência de valores
binários (0s ou 1s), agrupados em bytes.
Manipulação de arquivo - abertura
fopen → abre um arquivo (ou seja, cria uma
stream para o arquivo).
ptr = fopen(“arquivo”, “modo abertura”)
Obs: Se não for possível abrir o arquivo, o
ponteiro ptr assumirá o valor null e nenhuma
operação de leitura ou escrita poderá ser
realizada.
24/03/2014
10
Modos de abertura
r→ Abre um arquivo existente para leitura.
w→ Cria um arquivo para gravação. Se o arquivo
já existe, sobrescreve.
a→ Abre ou cria um arquivo para adicionar dados
ao seu final.
r+ → Abre um arquivo para leitura e escrita; caso
não exista, arquivo será criado.
w+ → Abre um arquivo para escrita; caso não
exista, será criado.
a+ → Abre ou cria um arquivo para atualização;
dados serão gravados no final do arquivo.
Modos de abertura
rb→ Abre um arquivo para leitura no modo binário.
wb → Cria um arquivo para gravação no modo
binário; se o arquivo já existir, sobrescreve.
ab→ Abre ou cria um arquivo para adicionar dados
ao seu final, no modo binário .
rb+ → Abre um arquivo para leitura e escrita no
modo binário.
wb+ → Cria um arquivo para escrita no modo
binário; se o arquivo já existir, sobrescreve.
ab+ → Abre ou cria um arquivo para atualização no
modo binário; a gravação é feita no final do arquivo.
Arquivo binário X Arquivo texto
• Em algum arquivo texto todos os dados
gravados são obrigatoriamente convertidos
para caracteres.
Assim, arquivos textos podem ser visualizados
através de qualquer editor de texto. Com isso,
cada caractere consome 8 bits.
• Arquivos binários gravam os dados no formato
original, sem conversões. A quantidade de
memória depende do tipo de dado gravado.
24/03/2014
11
Manipulação de arquivo - fechamento
fclose→ todo arquivo precisa ser fechado.
Para tal, utiliza-se o ponteiro obtido no momento
da abertura.
fclose(ptr)
Manipulação de arquivo – detectando
fim do arquivo
feof → a função feof retorna verdadeiro toda
vez que o programa tenta acessar dados de um
arquivo cujo ponteiro já chegou ao final (e,
portanto, não tem mais dados para retornar).
Normalmente feof é usada em uma condição.
feof(ptr)
Ler e Escrever em arquivo de acesso
sequencial
fprintf → escreve um conteúdo em um arquivo.
fprintf(ptr, “%d”, idade);
fscanf → lê um conteúdo de um arquivo.
fscanf(ptr, “%d%s”, &idade, nome);
24/03/2014
12
Arquivo de acesso aleatório
• Acessar aleatoriamente um arquivo significa
que não é necessário percorrer todas as
posições desde o início.
• O acesso aleatório permite realizar a operação
de leitura ou de gravação na posição exata,
usando deslocamentos.
Leitura e Gravação em arquivo de
acesso aleatório
- gravação
int ret= fwrite(&variável, sizeof(algum tipo), 
qtd_gravacoes, ponteiro_arquivo);
- leitura
int ret= fread(&variável, sizeof(algum tipo), 
qtd_leituras, ponteiro_arquivo);
Reposicionando ponteiro de um
arquivo de acesso aleatório
fseek(ponteiro_arquivo, tamanho do 
deslocamento, posicao_origem);
O valor de posicao_origem pode ser um valor
definido dentre 3 possibilidades:
SEEK_SET → a partir do início do arquivo
SEEK_CUR → a partir da posição atual 
SEEK_END → a partir do fim do arquivo
24/03/2014
13
Depuração de programas
Depurar programas é:
Acompanhar a execução de um programa,
tentando encontrar falhas ou tentando
melhorar o seu desempenho.
Teste de mesa
• Estratégia utilizada pelo programador para,
manualmente, acompanhar a as linhas
escritas em um programa, simulando a sua
execução.
• Além de acompanhar as linhas, também
ocorre o monitoramento do conteúdo das
variáveis de memória.
24/03/2014
14
Depuração automática de programas
•Quando o programa (ou trecho de código) a ser
analisado é muito extenso ou muito complexo,
pode-se fazer uso da depuração automática.
•Grande parte das IDEs (como o DEV C++) traz
este recurso através do Debug.
Objetivos da depuração automática
•Verificar a execução de todas as linhas do
programa;
•Acompanhar a utilização das variáveis de
memória e seus respectivos valores ao longo da
execução.
•Todo programa de computador passa por
manutenção durante sua vida útil.
•Essa evolução requer manutenção pode ser
corretiva ou evolutiva.
•A documentação do código-fonte tem como
objetivo facilitar as manutenções futuras.
Documentação de código
24/03/2014
15
•Documentação começa pela escolha de
nomes de variáveis, constantes e funções.
•Os nomes escolhidos devem refletir o
conteúdo de uma variável ou constante ou a
ação realizada por uma função.
Boas práticas na documentação de
código
• Existem 2 tipos de comentários usados em C:
� Comentário de uma linha, iniciando com os
símbolos // terminado ao final da linha;
� Comentário de múltiplas linhas, iniciando
com os símbolos /* e terminando com os
símbolos */.
Comentar o código
• Comentários de uma linha são indicados para
apresentar uma explicação rápida sobre o
significado de um comando, feito na respectiva
linha.
• Comentários de múltiplas linhas são indicados
para explicar o que é feito em um bloco de
comandos, como uma função ou um laço, por
exemplo.
Comentar o código
24/03/2014
16
•É importante adotar controle de versões dos
programas para que seja possível registrar a sua
evolução e, também, permitir o trabalho de várias
pessoas em um mesmo código.
•Existe um padrão para determinar o número de
uma versão.
Controlando versionamento
Padrão de versionamento
Nº versão Registro Data liberação
1.0 Versão inicial 10/02/2013
2.0 Acrescimo função XXX 20/08/2013
2.1 Correção cálculo valor a 
pagar
15/12/2013
Fonte: Adaptado de TORRES, Renato Cristiano, Programação Estruturada II. Valinhos: Anhanguera 
Educacional, 2014. p. 1-90. Disponível em: <http://www.anhanguera.com>. Acesso em: 03 fev. 2014.
Fonte: TORRES, Renato Cristiano, Programação Estruturada II. Valinhos: Anhanguera Educacional,
2014. p. 1-90. Disponível em: <http://www.anhanguera.com>. Acesso em: 03 fev. 2014.
Como versionar?

Continue navegando