USF EAD U4 Ferramentas e Técnicas de Programação

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 22

FERRAMENTAS E TÉCNICAS

DE PROGRAMAÇÃO

FABIO ANDRIJAUSKAS
Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados UNIDADE 4

UTILIZAÇÃO DE ESTRUTURAS
HETEROGÊNEAS NA LEITURA E
4
ESCRITA DE ARQUIVOS DE DADOS

INTRODUÇÃO
Estamos na última etapa na produção de um software e, para finalizar, o ponto mais
importante não está nas “ferramentas” que são necessárias, mas sim como utilizar
e manter tudo de uma maneira organizada. Vamos listar o que é necessário para
construir um software:
a. Trabalhar os dados: variáveis, comandos de repetição e controle;

 int, if, else, for;

b. Organizar a memória: variáveis e vetores.

 int vet[ ]

c. Controlar o uso de maneira dinâmica: alocação dinâmica de memória;

 malloc e struct

d. Armazenar e recuperar os dados de um armazenamento não volátil (HD, SSD)

 fwrite e fread.

Já estudamos os itens a, b e c, porém a estrutura do software ainda pode ser mais


simples. Além da forma de organizar os softwares, é essencial que os dados utiliza-
dos estejam organizados da melhor maneira possível. Vamos analisar como podemos
manter os elementos mais organizados com formas diferentes de manter tudo mais
próximos das manutenções. O primeiro elemento, já explorado, apresenta o conceito de
funções e agora será formalizado.

1. FUNÇÕES
Diversos comandos (scanf(), printf(), strlen(), strcmp(), sin(), cos(), etc.) realizam tare-
fas bastante complexas sobre valores de entrada. Esses comandos são denominados
funções, pois consistem em agrupamentos de instruções assim como a função princi-
pal. Existem muitas funções em C que são de extrema importância e a documentação
desses dados é um pouco “solta”, mas o modelo apresentado na Figura 01 possui uma
grande gama de exemplos.

51
Figura 01. Exemplo de documentação de uma função.

Universidade São Francisco


Fonte: Elaborado pelo autor do site: https://cplusplus.com/reference/cstdio/fprintf/. Acesso em: 1 de setembro.

Uma função, portanto, é uma sequência de comandos que pode ser executada
a partir da função principal (ou de qualquer outra função). A função main(), por
exemplo, agrupa as instruções do programa e as funções simplificam a codifica-
ção, permitindo uma melhor estruturação do programa e evitando que uma mesma
sequência de comandos seja escrita diversas vezes no corpo (escopo) da função
principal. A Figura 02 apresenta uma função para calcular o fatorial de um número
(por exemplo, 5! = 5.4.3.2.1)

Ferramentas e Técnicas de Programação 52


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

Figura 02. Exemplo de função.

1. #include <stdio.h>
4 2. double fatorial(int x);
3.
4. double fatorial(int x)
5. {
6. double fat=1;
7. int i;
8. for (i=x; i > 1; i--)
9. {
10. fat = fat * i;
11. return(fat);
12. }
13. }
14. int main()
15. {
16. int c = fat(5);
17. printf(“%i\n”,);
18. }
Fonte: elaborado pelo autor.

Na realidade, todos os códigos em C, que possuem controles de decisão, são funções


(não considerando o struct e outras casos). A função fatorial recebe o valor de uma va-
riável na principal (linha 16), armazena uma variável no seu escopo e retorna o cálculo
do fatorial na variável c para o programa principal. Um programa pode ter variáveis e
funções em que uma função pode conter chamadas de outras funções do programa. A
Figura 03 apresenta como cada função deve ser declarada.
Figura 03. Como declarar a função.

1. tipo funcao(tipo var1, tipo var2, ... , tipo varn);


2. tipo funcao(tipo var1, tipo var2, ... , tipo varn)
3. {
4. return (valor_do_tipo);
5. }
Fonte: elaborado pelo autor.

53
O tipo do valor retornado pela função deve ser compatível com o tipo da função. Em
outras palavras, os valores de entrada e saída de uma função dos denominados parâ-
metros. Esses parâmetros podem ser de qualquer tipo:
4
` Registros

` Apontadores

Universidade São Francisco


` Cadeias de caracteres

` Vetores.

2. PARÂMETROS PASSADOS POR VALOR E POR REFERÊNCIA


No caso função fatorial, o valor de n na chamada fatorial(n) é passado para uma cópia x
da variável n. Dessa forma, qualquer alteração realizada em x não influencia o conteúdo
de n no escopo da função principal. Isso consiste em uma passagem por valor e permite
simplificar a função como mostra a Figura 04.
Figura 04. Passagem por referência.

1. double fatorial(int x)
2. {
3. double fat=1;
4. while (x > 1){
5. fat = fat * x;
6. x--;
7. }
8. return(fat);
9. }
Fonte: elaborado pelo autor.

Contudo, em certos momentos desejamos modificar o conteúdo de uma ou mais variá-


veis no escopo da função principal. Neste caso, os parâmetros devem ser passados por
referência, ou seja, ao invés da função criar uma cópia do seu conteúdo, cria um en-
dereço da variável correspondente na função principal. Dessa forma se torna possível
a alteração do conteúdo. Caso contrário, podemos trocar o conteúdo dessas variáveis,
como mostra a Figura 05.

Ferramentas e Técnicas de Programação 54


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

Figura 05. Exemplo de passagem por referência.

1. #include <stdio.h>
4 2. double fatorial(int x);
3. void troca(int *x, int *y);
4. double fatorial(int x)
5. {
6. double fat=1;
7. while (x > 1){
8. fat = fat * x;
9. x--;
10. }
11. return(fat);
12. }
13. void troca(int *x, int *y)
14. {
15. int aux;
16. aux = *x;
17. *x = *y;
18. *y = aux;
19. }
20. int main()
21. {
22. int n,p,c;
23. scanf(“%d %d” ,&n,&p);
24. if (p > n) troca(&p,&n);
25. if((p >= O)&&(n >= 0) ){
26. c = (int)(fatorial(n)/
(fatorial(p)*(fatorial(n-p))));
27. printf(“%d \n”,c);
28. }
29. return 0;
30. }
Fonte: elaborado pelo autor.

55
SAIBA MAIS
A linguagem C possui diversas funções que podem ser utilizadas, mais informações
4
Disponível em: https://cplusplus.com/reference/cmath/

Universidade São Francisco


cos: Calcular cosseno (função)

sin: Calcula seno (função)

tan: Calcular tangente (função)

acos: Calcular arco cosseno (função)

asin: Calcular arco seno (função)

atan: Calcular arco tangente (função)

atan2: Calcula a tangente do arco com dois parâmetros (função)

Funções exponenciais e logarítmicas

exp: Calcular função exponencial (função)

frexp: Obter significando e expoente (função)

ldexp: Gerar valor de significando e expoente (função)

log: Calcula o logaritmo natural (função)

log10: Calcula o logaritmo comum (função)

modf: Quebra em partes fracionárias e integrais (função)

exp2: Calcular função exponencial binária (função)

log1p: Calcula logaritmo mais um (função)

log2: Calcula o logaritmo binário (função)

logb: Calcula o logaritmo base de ponto flutuante (função)

scalbn: Escala significando usando expoente de base de ponto flutuante (função)

scalbln: Escala significando usando expoente de base de ponto flutuante (longo) (função)

pow: Elevar para potência (função)

sqrt: Calcular raiz quadrada (função)

cbrt: Calcular raiz cúbica (função)

hipot: Calcular hipotenusa (função)

Ferramentas e Técnicas de Programação 56


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

3. ARQUIVOS
Para utilizar arquivos, existe uma variável para isso: FILE *arquivo; Abertura (e fecha-
4 mento) de arquivos e para fechar o arquivo:

arquivo = fopen(“nome”, “modo”);


if(arquivo!=0) fclose(arquivo);
Onde nome = nome do arquivo e modo = tipo do arquivo (ASCII ou binário), e objetivo
de uso (leitura, escrita, anexação). A Tabela 01 apresenta os modos de abrir um arquivo.
Tabela 01. Modos de abrir os arquivos.

Fonte: Elaborda pelo autor.

Para abrir um arquivo o comando é o fread:

fread (&variavel, sizeof ( tipo_var), t, arquivo)

Onde:
` variavel: variável a ser lida do arquivo (tipos básicos ou compostos, porém ape-
nas variáveis, e não vetores);

` tipo_var: o tipo da variável a ser lida do arquivo;

` t é a quantidade de dados a ser lida (1 para uma só variável, mais para leitura
de vetores);

` arquivo: variável de arquivo

Para fechar o comando para escrita de dados em arquivos:

fwrite (&variavel, sizeof ( tipo_var), t, arquivo)

57
Onde:
` variavel: variável a ser escrita no arquivo (tipos básicos ou compostos, porém
apenas variáveis, e não vetores);
4
` tipo_var: o tipo da variável a ser escrita no arquivo;

` t é a quantidade de dados a ser escrita (1 para uma só variável, mais para leitura

Universidade São Francisco


de vetores);

` arquivo: variável de arquivo


Um exemplo do processo completo de um conjunto de registros é apresentado a seguir
na Figura 06. A parte inicial apresenta a declaração das variáveis, funções e bibliotecas.
Nas linhas de 1 a 4 são declaradas a bibliotecas que serão utilizadas de forma constan-
te. Nas linhas de 5 a 12 consiste em criar a estrutura, tendo como referência o tamanho
da lista na linha 4. Como já vimos, isso não é compatível com um sistema completo.
Figura 06. Primeira parte do exemplo completo do sistema.

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #define TAM 2
5. struct Elemento
6. {
7. char nome [100];
8. char rua [100];
9. char cidade [100];
10. char estado [2];
11. char cep [10];
12. } Lista [TAM];
13. char menu ();
14. void inicia_lista ();
15. void cadastra ();
16. void mostra ();
17. void salva ();
18. void carrega ();
Fonte: Elaborado pelo autor.

Ferramentas e Técnicas de Programação 58


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

A Figura 07 apresenta o menu da aplicação e também do início do sistema. Repare que


a função inicia_lista é chamada no começo do programada, a qual vamos ver mais à
frente. Entre as linhas de 6 a 15 são as opções de escolha do usuário. Esse sistema
4 apresenta algumas divisões entre cada ação do sistema e isso consiste em mais um
elemento para garantir a qualidade do sistema.
Figura 07. Primeira parte do exemplo completo do sistema.

1. int main()
2. {
3. char escolha;
4. inicia_lista();
5. for ( ;; )
6. {escolha = menu();
7. switch (escolha)
8. {case ‘c’:
9. case ‘C’: { cadastra(); } break;
10. case ‘m’:
11. case ‘M’: { mostra(); } break;
12. case ‘s’:
13. case ‘S’: { salva(); } break;
14. case ‘a’:
15. case ‘A’: { carrega(); } break;
16. case ‘t’:
17. case ‘T’: { exit (0 ); } break;
18. default : { printf ( “Opcao invalida. \n” ); }
19. }
20. printf ( “\n \n \n” );
21. }
22. system ( “Pause” );
23. return 0;
24. }
Fonte: Elaborado pelo autor.

59
A Figura 08 apresenta o menu que é chamado na função principal e essa parte consiste
na interface com o usuário. Dessa forma, caso seja necessário fazer alterações na área
que controla a interação com o usuário, é possível com menos interferências do que
quando as funções estão todas juntas. 4
Figura 08. Primeira parte do exemplo completo do sistema.

1. char menu()

Universidade São Francisco


2. {
3. char opcao;
4. printf (“\n \n \n”);
5. printf ( “ (C)adastrar. \n” );
6. printf ( “ (M)ostrar. \n” );
7. printf ( “ C(A)arregar. \n” );
8. printf ( “ (S)alvar. \n” );
9. printf ( “ (T)erminar. \n” );
10. fflush(stdin);
11. scanf ( “%c”, &opcao );
12. return opcao;
13. }
Fonte: Elaborado pelo autor.

Na Figura 09 a função exibe a lista inicializada. A questão é como o sistema sabe se o


elemento possui dados ou não? Para averiguar se existem dados, a linha 7 verifica se
o nome está em “branco”, caso contrário o sistema imprimi todos os elementos do vetor
(linha 9 a 13).

Ferramentas e Técnicas de Programação 60


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

Figura 09. Primeira parte do exemplo completo do sistema.

1. void mostra()
4 2. {
3. int t;
4. printf (“\n \n \n”);
5. for( t = 0; t < TAM; t++ )
6. {
7. if (!(strcmp(Lista[t].nome, “”)==0) )
8. {
9. printf ( “%s \n”, Lista[t].nome);
10. printf ( “%s \n”, Lista[t].rua);
11. printf ( “%s \n”, Lista[t].cidade);
12. printf ( “%s \n”, Lista[t].estado);
13. printf ( “%s \n”, Lista[t].cep);
14. }
15. printf (“\n”);
16. }
17. }
Fonte: Elaborado pelo autor.
A Figura 10 apresenta como o sistema define os registros inicializados. Dessa forma,
ao tratar dos dados, não existiram dados aleatórios nos vetores e ainda marcam os
registros como vazios.
Figura 10. Primeira parte do exemplo completo do sistema.

void inicia_lista()
{
int t;
for (t = 0; t < TAM; t++)
{
strcpy(Lista[t].nome , “”);
}
}
Fonte: Elaborado pelo autor.

61
A Figura 11 apresenta como é feito o cadastro, onde cada elemento é preenchido pelo
teclado.
Figura 11. Primeira parte do exemplo completo do sistema.
4
void cadastra ()
{

Universidade São Francisco


int i;
printf (“\n \n \n”);
for (i = 0; i < TAM; i++ )
{
printf ( “Nome: \n” );
fflush (stdin);
gets ( Lista[i].nome );
printf ( “ Rua: \n” );
fflush (stdin);
gets ( Lista[i].rua );
printf ( “Cidade: \n” );
fflush(stdin);
gets ( Lista[i].cidade );
printf ( “Estado: \n” );
fflush(stdin);
gets ( Lista[i].estado );
printf ( “CEP: \n” );
fflush (stdin);
gets ( Lista[i].cep );
}
}
Fonte: Elaborado pelo autor.

A Figura 12 apresenta como é feito a escrita dos arquivos. Na linha 6 o arquivo é aberto
para escrita e entre as linhas 12 a 19, os vetores de struct são gravados no arquivo.

Ferramentas e Técnicas de Programação 62


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

Figura 12. Gravar os dados em disco.

1. void salva ()
4 2. {
3. FILE *fp;
4. int i, result;
5. printf (“\n \n \n”);
6. fp = fopen (“cadastro”, “wb”);
7. if ( fp == NULL )
8. {
9. printf ( “O arquivo nao pode ser aberto. \n” );
10. return;
11. }
12. for (i = 0; i < TAM; i++ )
13. {
14. if ( !(strcmp(Lista[i].nome, “”)==0) )
15. {
16. result = fwrite ( &Lista[i], sizeof ( struct
Elemento ), 1, fp );
17. if ( result != 1 )
18. {
19. printf ( “Erro de escrita no arquivo. \n”
);
20. }
21. }
22. }
23. fclose (fp);
24. }
Fonte: Elaborado pelo autor.

A função carrega faz o mesmo processo da função salva, porém ele faz a leitura de
cada item.

63
Figura 13. Primeira parte do exemplo completo do sistema.

void carrega ()
{ 4
FILE *fp;

Universidade São Francisco


int i, resp;
printf (“\n \n \n”);
fp = fopen ( “cadastro”, “rb” );
if ( fp == NULL )
{
printf ( “O arquivo nao pode ser aberto. \n” );
return;
}
inicia_lista ();
for (i = 0; i < TAM; i++ )
{
resp = fread ( &Lista[i], sizeof (struct Elemen-
to), 1, fp );
if ( resp != 1 )
{
if ( feof (fp) )
{
break;
}
printf ( “ Erro de leitura no arquivo. \n” );
}
}
fclose ( fp );
}
Fonte: Elaborado pelo autor.

Ferramentas e Técnicas de Programação 64


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

4. RECURSÃO
Recursão é uma parte fundamental na programação, visto que um programa recursivo é
um programa que chama a si mesmo. Logo, uma função recursiva é definida em termos
4 dela mesma, ou seja, uma função que chama a si própria.
` Exemplos:
 Números naturais, Função fatorial, Árvore.
A recursividade é uma forma que pode ser utilizada quando o cálculo de uma função para o
valor n pode ser descrito a partir da operação desta mesma função para o termo anterior (n-1).
Figura 14. Exemplo – Função fatorial

1. n! = n * (n-1) * (n-2) * (n-3) *....* 1


2. (n-1)! = (n-1) * (n-2) * (n-3) *....* 1
logo:
3. n! = n * (n-1)!
Fonte: Elaborado pelo autor.

Quando dentro do corpo de uma função chama-se novamente a própria função, deno-
minamos definição. A recursão direta é quando a função A chama a própria função
A. Já a recursão indireta é quando a função A chama uma função B que chama A.
Nenhum programa e nenhuma função podem ser exclusivamente definidos por si. Além
disso, se torna necessário uma condição de parada.
Para cada chamada de uma função, recursiva ou não, os parâmetros e as variáveis
locais são empilhados na pilha de execução. Quando qualquer chamada de função é
feita dentro de um programa, é criado uma pilha de execução do programa.
Figura 15. Função fatorial recursiva

1. Fat (int n) {
2. if (n<=0)
3. return 1;
4. else
5. return n * Fat(n-1);
6. }
7. Main() {
8. int f;
9. f = fat(5);
10. printf(“%d”,f);
11. }
Fonte: Elaborado pelo autor.

65
Figura 16. Função fatorial iterativo

1. int fat (int n) {


2. int f; 4
3. f = 1;

Universidade São Francisco


4. while(n > 0){
5. f = f * n;
6. n = n – 1;
7. }
8. return f;
9. }

Fonte: Elaborado pelo autor.

Portanto, a recursividade nem sempre é a melhor solução, mesmo quando a definição


matemática do problema é feita em termos recursivos.

Outro exemplo: Série de Fibonacci:

` Fn = Fn-1 + Fn-2 n > 2,

` F0 = F1 = 1

` 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...


Figura 17. Função Fibonacci recursiva

1. int Fib(int n) {
2. if (n<2)
3. return 1;
4. else
5. return Fib(n-1) + Fib(n-2);
6. }
Fonte: Elaborado pelo autor.

Ferramentas e Técnicas de Programação 66


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

SAIBA MAIS
A recursividade consiste em uma forma de programação poderosa que pode criar diversas
formas de código, como o ilustrado na Figura 18.
4
Figura 18. Desenho das formas dos códigos na programação

Fonte: Elaborada pelo autor.

5. PROJETO DE SOFTWARE
O projeto de software é algo muito importante. Veja, a seguir, notícias de casos que
envolvem o seu uso.

ANAC CALCULA MULTAR GOL EM R$ 2 MILHÕES E PROÍBE NOVOS FRETAMENTOS

“A Anac acredita que o caos foi provocado por uma falha no software da Gol que calcula a
carga horária de trabalho dos funcionários, como disse a empresa.”

Disponível em: https://www.lipsum.com/feed/html

Acesso em: 4 set. 2022.

67
FALHA EM SOFTWARE DE DIFUSÃO DE DADOS CAUSOU PARADA DA BOVESPA HOJE

“De acordo com nota divulgada pela instituição, houve falha em software licenciado da NYSE 4
Euronext, utilizado para difusão de dados e envio de mensagens de confirmação de execu-
ção de ordens.”

Universidade São Francisco


Disponível em: http://oglobo.globo.com/economia/falha-em-software-de-difusao-de-da-
dos-causou-parada-da-bovespa-hoje-3048462

Acesso em: 4 set. 2022.

SOFTWARE BUG CONTRIBUTED TO BLACKOUT


“This fault was so deeply embedded, it took them weeks of poring through millions of lines of
code and data to find it.”

Disponível em: http://www.securityfocus.com/news/8016/

Acesso em: 4 set. 2022.

Nesse caso, temos algumas perguntas:

` Como produzir um software que deve ficar em funcionamento durante 30 anos?

` De que forma devo produzir um software que depois de 30 anos de sua criação
seja passível de manutenção?

` Como entender o que cliente quer?

` Como fazer testes para garantir que tudo irá funcionar?

` Como gerar documentação para que o software seja produzido de forma correta?

` Como economizar tempo e produzir mais?

Os modelos de criação de software têm por função diminuir os problemas encontrados


no processo de desenvolvimento do software. Um paradigma reúne metodologias, mé-
todos e técnicas, com o propósito de promover uma abordagem para a resolução de
problemas através da Engenharia de Software.

` conjunto de métodos, técnicas e ferramentas que possibilitam:

` ao gerente controlar o processo de desenvolvimento

` ao desenvolvedor ter uma base para produzir software de alta qualidade de ma-
neira produtiva

Ferramentas e Técnicas de Programação 68


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

` Rigor e Formalidade

` Busca da confiabilidade e controle


4 ` Separação de Preocupações

` Decisões focadas

A Figura 19 apresenta uma comparação entre o software e hardware, dessa forma se


torna necessário tratar esses elementos de maneira diferente.
Figura 19. Comparação entre software e hardware no seu tempo.

hw sw

Alteração
Mortalidade
Taxa de falhas

Taxa de falhas
infantil Desgaste

Real
0
0
0

Ideal

Tempo

Fonte: Adaptado de PRESSMAN, 2016, pag. 40.

CONCLUSÃO
Para que seja possível construir um sistema completo são necessários vários elementos:

1. Trabalhar os dados: variáveis, comandos de repetição e controle;

2. Organizar na memória: variáveis e vetores.

3. Controlar o uso de maneira dinâmica: alocação dinâmica de memória;

4. Armazenar e recuperar os dados de um armazenamento não volátil (HD, SSD)

Nesse momento podemos construir um software completo e organizado, e não neces-


sariamente fazer na linguagem C. Agora é o momento de buscar outras formas de im-
plementação e comparar os comandos que você já aprendeu.

69
REFERÊNCIAS BIBLIOGRÁFICAS.
Andrijauskas, Fabio, Programação orientada a objetos II Londrina: Editora e Distribuidora Educacional
S.A.,2018. 240
4
DEITEL, Paul; DEITEL, Harvey. C Como Programar. 6. ed. São Paulo: Prentice Hall, 2011.

Universidade São Francisco


Forbellone, André L.V; Eberspache, Henri F. Lógica de programação: a construção de algoritmos e estruturas
de dados. 3.ed. São Paulo: Pearson, 2005. 218 p. ISBN 978-85- 7605-024-7.

Feofiloff, Paulo. Algoritmos em linguagem C. Rio de Janeiro: Elsevier, 2009. 208 p. ISBN 978-85-352-3249-3.
Mokarzel, Fábio; Soma, Nei. Introdução à ciência da computação. Rio de Janeiro: Elsevier, 2008. 429 p. ISBN
978-85-352-1879-4.

MANZANO, José Augusto N G. Programação de Computadores com C/C++.Editora Saraiva, 2014.


9788536519487. E-book. Disponível em: https://integrada.minhabiblioteca.com.br/#/books/9788536519487/.
Acesso em: 15 ago. 2022.

MANZANO, José Augusto Navarro G. Estudo Dirigido de Linguagem C. [Digite o Local da Editora]: Edi-
tora Saraiva, 2002. 9788536519128. E-book. Disponível em: https://integrada.minhabiblioteca.com.br/#/
books/9788536519128/. Acesso em: 15 ago. 2022.

PRESSMAN, Roger S.; MAXIM, Bruce R.. Engenharia de software: uma abordagem profissional. 8 ed. Porto
Alegre: AMGH, 2016. 940 p.

Ferramentas e Técnicas de Programação 70


Utilização de Estruturas Heterogêneas na Leitura e Escrita de Arquivos de Dados

71

Você também pode gostar