Você está na página 1de 59

Bibliotecas e arquivos

(RYSH) Linguagem C 1 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 2 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 3 / 47
Arquivos

Até agora, todos os programas feitos nesta disciplina lêem dados do teclado
(entrada padrão) e escrevem na tela do monitor (saı́da padrão);
As vezes não é suficiente para um programa usar somente a entrada e saı́da
padrão;
O armazenamento de dados em variáveis e arrays é temporário e de tamanho
limitado;
Arquivos são usados para armazenamento permanente de grandes
quantidades de dados (e programas) em dispositivos de armazenamento
secundário, como discos.

(RYSH) Linguagem C 4 / 47
Arquivos

Um arquivo (= file) é uma sequência de bytes que reside na memória


secundária (ex., HD);
Para que um programa possa manipular um arquivo, é preciso associá-lo a
uma variável do tipo FILE;
A variável do tipo FILE aponta para uma estrutura que contém informações
de sistema sobre o arquivo;
O tipo FILE é predefinido em stdio.h
1 FILE * fp ;
2

(RYSH) Linguagem C 5 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 6 / 47
Operações sobre arquivos

Uma variável FILE estará associada a um arquivo;


Associando/abrindo um arquivo:
▶ Função fopen
1 FILE * fp1 , * fp2 ;
2 fp1 = fopen ( " data . txt " , " r " ) ;
3 fp2 = fopen ( " imagem . pgm " , " w " ) ;
4

▶ O primeiro argumento da função é o nome do arquivo;


▶ O segundo argumento é modo que será aberto o arquivo:
⋆ “r”: somente leitura (do inı́cio do arquivo);
⋆ “r+”: leitura e escrita (do inı́cio do arquivo);
⋆ “w”: escrita, apagando o conteúdo do arquivo ou criando (do inı́cio do arquivo);
⋆ “w+”: leitura e escrita, apagando o conteúdo do arquivo ou criando (do inı́cio
do arquivo);
⋆ “a”: escrita, criando se não existir, posicionando no fim do arquivo;
⋆ “a+”: leitura e escrita, criando se não existir, posicionando no fim do arquivo;

(RYSH) Linguagem C 7 / 47
Operações sobre arquivos

A função fopen devolve o endereço de um FILE (ou NULL, se não encontrar


o arquivo especificado);
1 FILE * fp ;
2 fp = fopen ( " data . txt " , " r " ) ;
3 if ( fp == NULL )
4 printf ( " Erro ao abrir o arquivo \ n " ) ;
5

Observação:
▶ O teclado é o arquivo padrão de entrada (= standard input);
▶ Ele está permanente aberto e é representado pela constante stdin;
▶ A saı́da padrão também é um arquivo e está associado à constante stdout.

(RYSH) Linguagem C 8 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 9 / 47
Processando arquivo de texto (caracteres)

Depois que um arquivo de texto é aberto, existem 3 formas diferentes de ler


ou escrever sequencialmente os dados:
▶ um caracter por vez, usando as funções da biblioteca padrão fgetc() e fputc();
▶ uma linha por vez, usando fgets() e fputs();
▶ em um formato especı́fico, usando fscanf() e fprintf();
Vamos nos limitar ao uso do fscanf e fprintf;

(RYSH) Linguagem C 10 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 11 / 47
Processando arquivo de texto (caracteres)
A função fscanf() lê o conteúdo do arquivo representado por fp;
É preciso informar:
▶ Qual arquivo será lido;
▶ Quais tipos de dados serão lidos através dos especificadores de formato: %d,
%c, %f, %s;
▶ Em quais variáveis os dados lidos serão gravados.
1 FILE * fp ;
2 fp = fopen ( " data . txt " , " r " ) ;
3 int i , r ;
4 char s [11] , f [100];
5 if ( fp != NULL )
6 {
7 r = fscanf ( fp , " % d % s " , &i , s ) ;
8 r = fscanf ( fp , " %99[^\ n ] " , f ) ;
9 }
Valor retornado:
▶ EOF se o final do arquivo foi atingido ou em caso de erro;
▶ Em caso de sucesso: a quantidade de itens convertidos e atribuı́dos.
1 while ( fscanf ( fp , " % d % s " , &i , s ) != EOF )
2 printf ( " % d % s \ n " , i , s ) ;

fscanf (stdin, ...) equivale a scanf(...)


(RYSH) Linguagem C 12 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 13 / 47
Processando arquivo de texto (caracteres)
A função fprintf() escreve no arquivo conectado ao fp;
É preciso informar:
▶ Em qual arquivo será gravado;
▶ O conteúdo que será gravado;
Ou é preciso informar:
▶ Em qual arquivo será gravado;
▶ Quais tipos de dados serão através dos especificadores de formato: %d, %c,
%f, %s;
▶ Em quais variáveis estão os dados que serão gravados.
1 FILE * t ;
2 t = fopen ( " teste " , " w " ) ;
3 fprintf (t , " Ola mundo \ n " ) ;
4
5 int a =10;
6 char b []= " lala " ;
7 fprintf (t , " % d % s \ n " , a , b ) ;

O valor de retorno é o número de caracteres escritos, ou negativo em caso de


ocorrência de erros.
fprintf(stdout, ...) equivale ao printf(...)
(RYSH) Linguagem C 14 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 15 / 47
Operações sobre arquivos

Fechando um arquivo:
▶ Função fclose
1 FILE * fp ;
2 fp = fopen ( " data . txt " , " r " ) ;
3 ...
4 fclose ( fp ) ;
▶ O protótipo da função fopen() é:
1 int fopen ( FILE *) ;
▶ Retorna 0 no sucesso e EOF no erro:
1 FILE * fp ;
2 fp = fopen ( " data . txt " , " r " ) ;
3 ...
4 if ( fclose ( fp ) == EOF )
5 printf ( " Erro ao fechar o arquivo \ n " ) ;

(RYSH) Linguagem C 16 / 47
Exemplo

Abrir um arquivo chamado “hino.txt”;


Criar um novo arquivo chamado hino copia.txt;
Copiar o conteúdo do arquivo hino.txt para o hino copia.txt;
Linha por linha;

(RYSH) Linguagem C 17 / 47
Exemplo

1 char linha [100];


2 FILE * origem , * destino ;
3
4 origem = fopen ( " hino . txt " , " r " ) ;
5 destino = fopen ( " hino_copia . txt " , " w " ) ;
6
7 if ( origem != NULL && destino != NULL )
8 {
9 while ( fscanf ( origem , " %[^\ n ] " , linha ) != EOF )
10 {
11 fprintf ( destino , " % s \ n " , linha ) ;
12 }
13 }
14 else
15 {
16 printf ( " Arquivo nao encontrado \ n " ) ;
17 }
18 fclose ( origem ) ;
19 fclose ( destino ) ;

(RYSH) Linguagem C 18 / 47
Exemplo

Abrir um arquivo chamado “hino.txt”;


Criar um novo arquivo chamado hino copia.txt;
Copiar o conteúdo do arquivo hino.txt para o hino copia.txt;
Caractere por caractere;

(RYSH) Linguagem C 19 / 47
Exemplo

1 char c ;
2 FILE * origem , * destino ;
3
4 origem = fopen ( " hino . txt " , " r " ) ;
5 destino = fopen ( " hino_copia . txt " , " w " ) ;
6
7 if ( origem != NULL && destino != NULL )
8 {
9 while ( fscanf ( origem , " % c " , & c ) != EOF )
10 {
11 fprintf ( destino , " % c " , c ) ;
12 }
13 }
14 else
15 {
16 printf ( " Arquivo nao encontrado \ n " ) ;
17 }
18 fclose ( origem ) ;
19 fclose ( destino ) ;

(RYSH) Linguagem C 20 / 47
Exemplo

Abrir uma imagem do tipo PGM;


Criar um novo arquivo;
Ler uma string e três inteiros (A, B, C) da imagem;
▶ Copiar a string de 2 caracteres em uma linha da imagem cópia;
▶ Copiar o primeiro e segundo números lidos em outra linha da imagem cópia;
▶ Copiar o terceiro número lido em outra linha da imagem cópia;
Ler AxB inteiros da imagem original e copiar para a imagem cópia;
A cada A números lidos da imagem original e copiar o \n para a imagem
cópia;

(RYSH) Linguagem C 21 / 47
Exemplo
1 FILE * origem , * destino ;
2 origem = fopen ( " brain . pgm " , " r " ) ;
3 destino = fopen ( " brain_copia . pgm " , " w " ) ;
4
5 char s [3];
6 int a , b , c , d ;
7 int i , j ;
8 if ( origem != NULL && destino != NULL ) {
9
10 fscanf ( origem , " % s % d % d % d " , s , &a , &b , & c ) ;
11 fprintf ( destino , " % s \ n " , s ) ;
12 fprintf ( destino , " % d % d \ n " , a , b ) ;
13 fprintf ( destino , " % d \ n " , c ) ;
14 i =0;
15 while (i < b ) {
16 j =0;
17 while (j < a ) {
18 fscanf ( origem , " % d " , & d ) ;
19 fprintf ( destino , " % d " , d ) ;
20 j ++;
21 }
22 fprintf ( destino , " \ n " ) ;
23 i ++;
24 }
25 }
(RYSH) Linguagem C 22 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 23 / 47
Escopo de variáveis - O que é?

Conjunto de regras que determinam a utilização de uma variável;


Alcance de uma variável;
Podemos dividir as variáveis quanto ao escopo em três tipos: variáveis
locais, parâmetros formais e variáveis globais.

(RYSH) Linguagem C 24 / 47
Escopo de variáveis
Variáveis locais
▶ Declaradas dentro de um bloco ({ }), só valem dentro deste bloco;
1 void funcao1 () {
2 int j =1;
3 printf ( " % d " , j ) ;
4 }
5
6 void main () {
7 int a =9 , b ; // pertencem ao bloco da main
8 if (a >9) {
9 int x ; // pertence ao bloco do if
10 x = a +1; // ok
11 }
12 printf ( " % d \ n " , x ) // erro : x eh local do if
13
14 funcao1 () ;
15 printf ( " % d \ n " , j ) // erro : j eh local da funcao1
16 }

Parâmetros formais
Variáveis globais e externas
Variáveis estáticas
(RYSH) Linguagem C 25 / 47
Escopo de variáveis
Variáveis locais
Parâmetros formais
▶ São os argumentos de uma função;
▶ Passagens por valor: escopo local;
▶ Passagens por referência: variável local porém pode acessar um escopo
externo;
1 // v por referencia e j por valor
2 void alo ( int v [] , int j )
3 {
4 j =1; // variavel local
5 v [0]= j ; // variavel local v , acessa vari á vel externa i
6 }
7
8 int main ()
9 {
10 int j =0 , i [2];
11
12 alo (i , j ) ;
13
14 printf ( " % d % d " , i [0] , j ) ; // 1 0
15 }
Variáveis globais e externas
Variáveis estáticas
(RYSH) Linguagem C 25 / 47
Escopo de variáveis
Variáveis locais
Parâmetros formais
Variáveis globais e externas
▶ Declaradas fora de todas as funções (válidas a partir do ponto de declaração);
▶ Compartilhada por todas as funções;
▶ Existem durante toda a execução do programa, ocupando memória;
▶ Devem ser manipuladas com atenção pois várias função podem utilizá-las;
▶ Externas: acessı́veis fora do arquivo
1 // teste . c teste . h
2 int j ; // variavel global
3
4 extern int i ; // acessivel para outros arquivos
5 // que inclu ı́ rem o teste . h
6
7 void alo () {
8 j =1;
9 printf ( " % d " , j ) ;
10 }
11
12 int main () {
13 j =3;
14 printf ( " % d " , j ) ;
15 }
(RYSH) Linguagem C 25 / 47
Escopo de variáveis
Variáveis locais
Parâmetros formais
Variáveis globais e externas
Variáveis estáticas
▶ Global: disponı́vel somente no arquivo onde foi declarada
▶ Local: disponı́vel por toda execução do programa
1 // teste . c teste . h
2
3 // para os arquivos que inclu ı́ rem o teste . h :
4 int i ; // acess ı́ vel com uso do extern
5 static int j ; // n a
~ o acessivel
6
7 void alo () {
8 j =1;
9 printf ( " % d " , j ) ;
10 st
11 }
12
13 int main () {
14 j =3;
15 printf ( " % d " , j ) ;
16 }

(RYSH) Linguagem C 25 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 26 / 47
Bibliotecas - Visão geral

Definição:
▶ Conjunto de funções agrupadas;
▶ Compartilhamento de funcionalidades;

Utilização:
▶ Inclusão do arquivo cabeçalho (.h): contém os protótipos de cada função;
▶ Biblioteca padrão da linguagem C (também conhecida como libc): cada
compilador C possui sua implementação da biblioteca padrão C;
▶ Exemplos:
⋆ math.h Funções matemáticas comuns em computação. Ex.: sqrt, sin, cos, tan,
ceil
⋆ stdio.h Manipulação de entrada/saı́da. Ex.: printf, scanf
⋆ stdlib.h Diversas operações, incluindo conversão, geração de números
pseudo-aleatórios, alocação de memória. Ex.: abs, rand, malloc
⋆ string.h Tratamento de cadeia de caracteres.

(RYSH) Linguagem C 27 / 47
Biblioteca padrão - string.h
Há funções para manipulação de string já definidas na biblioteca padrão C:
strlen: tamanho de uma string;
strcmp: comparar duas strings;
strcpy: copiar uma string em outra;
man string: outras funções
1 # include < stdio .h >
2 # include < string .h >
3
4 int main () {
5 char s1 [11] = " alo " ;
6 int i = strlen ( s1 ) ; // 3 caracteres
7 char s2 [11] = " ala " ;
8 int i = strcmp ( s1 , s2 ) ; // 0 se iguais
9 // ou a subtracao da
10 // primeira diferenca
11 // ‘o ’- ‘a ’ = 111 - 97 = 14
12 // se s1 > s2 retorna positivo
13 // se s1 < s2 retorna negativo
14
15 char s3 [11];
16 strcpy ( s3 , s1 ) ; // copia s1 em s3
17 return 0;
18 }
(RYSH) Linguagem C 28 / 47
Bibliotecas - Funções de String
Possı́veis implementações das funções:
1 int strlen ( char str [] ) {
2 int comprimento = 0;
3 while ( str [ comprimento ] != ’ \0 ’ )
4 ++ comprimento ;
5
6 return comprimento ;
7 }
8
9 int strcmp ( char s1 [] , char s2 [] ) {
10 int i = 0;
11 for ( i = 0; x [ i ]!= ‘ \0 ’ && x [ i ] == y [ i ]; ++ i ) ;
12
13 return x [ i ] - y [ i ];
14 }
15
16 char * strcpy ( char dest [] , char src []) {
17 int i ;
18 // copia src [ i ] em dest [ i ] e se src [ i ] != 0 continua
19 for ( i = 0; ( dest [ i ] = src [ i ]) != 0; ++ i ) ;
20
21 return dest ;
22 }

(RYSH) Linguagem C 29 / 47
Biblioteca própria - Visão geral
1 Fazer o cabeçalho .h (arquivo com os protótipos das funções - ex. teste1.h);
1 // se prototipos ainda nao foram definidos
2 # ifndef _TESTE1_H
3 # define _TESTE1_H // definir
4
5 # include < stdio .h > // biblioteca padrao
6
7 int soma ( int , int ) ;
8 void soma_vetor ( float [] , float [] , int ) ;
9
10 # endif

2 Fazer o fonte .c (arquivo com a implementação das funções - ex. teste1.c);


3 Compilar o .c para a geração .o (código objeto):
gcc -c teste1.c -o libteste1.o
4 Agora podemos utilizá-la em outros programas (ex. meuprograma.c):
5 Compilar o programa ligando com o código objeto gerado:
gcc meuprograma.c -o meuprograma libteste1.o
6 Executar o programa:
./meuprograma
(RYSH) Linguagem C 30 / 47
Biblioteca própria - Visão geral
1 Fazer o cabeçalho .h (arquivo com os protótipos das funções - ex. teste1.h);
2 Fazer o fonte .c (arquivo com a implementação das funções - ex. teste1.c);
1 # include " teste1 . h " // biblioteca propria
2
3 int soma ( int a , int b ) {
4 return a + b ;
5 }
6
7 void soma_vetor ( float v1 [] , float v2 [] , int n ) {
8 int i ;
9 for ( i =0; i < n ; i ++)
10 v2 [ i ] = v1 [ i ]+ v2 [ i ];
11 }

3 Compilar o .c para a geração .o (código objeto):


gcc -c teste1.c -o libteste1.o
4 Agora podemos utilizá-la em outros programas (ex. meuprograma.c):
5 Compilar o programa ligando com o código objeto gerado:
gcc meuprograma.c -o meuprograma libteste1.o
6 Executar o programa:
./meuprograma
(RYSH) Linguagem C 30 / 47
Biblioteca própria - Visão geral

1 Fazer o cabeçalho .h (arquivo com os protótipos das funções - ex. teste1.h);


2 Fazer o fonte .c (arquivo com a implementação das funções - ex. teste1.c);
3 Compilar o .c para a geração .o (código objeto):
gcc -c teste1.c -o libteste1.o
4 Agora podemos utilizá-la em outros programas (ex. meuprograma.c):
5 Compilar o programa ligando com o código objeto gerado:
gcc meuprograma.c -o meuprograma libteste1.o
6 Executar o programa:
./meuprograma

(RYSH) Linguagem C 30 / 47
Biblioteca própria - Visão geral
1 Fazer o cabeçalho .h (arquivo com os protótipos das funções - ex. teste1.h);
2 Fazer o fonte .c (arquivo com a implementação das funções - ex. teste1.c);
3 Compilar o .c para a geração .o (código objeto):
gcc -c teste1.c -o libteste1.o
4 Agora podemos utilizá-la em outros programas (ex. meuprograma.c):
1 # include " teste1 . h "
2
3 int main () {
4 float a [2]={1 ,2} , b [2]={3 ,2};
5 int c ;
6
7 c = soma (1 , 2) ;
8 soma_vetor (a , b , 2) ;
9
10 printf ( " % d % f % f \ n " , c , b [0] , b [1]) ;
11
12 return 0;
13 }
14

5 Compilar o programa ligando com o código objeto gerado:


gcc meuprograma.c
(RYSH) -o meuprograma
Linguagem C libteste1.o 30 / 47
Biblioteca própria - Visão geral

1 Fazer o cabeçalho .h (arquivo com os protótipos das funções - ex. teste1.h);


2 Fazer o fonte .c (arquivo com a implementação das funções - ex. teste1.c);
3 Compilar o .c para a geração .o (código objeto):
gcc -c teste1.c -o libteste1.o
4 Agora podemos utilizá-la em outros programas (ex. meuprograma.c):
5 Compilar o programa ligando com o código objeto gerado:
gcc meuprograma.c -o meuprograma libteste1.o
6 Executar o programa:
./meuprograma

(RYSH) Linguagem C 30 / 47
Biblioteca própria - Visão geral

1 Fazer o cabeçalho .h (arquivo com os protótipos das funções - ex. teste1.h);


2 Fazer o fonte .c (arquivo com a implementação das funções - ex. teste1.c);
3 Compilar o .c para a geração .o (código objeto):
gcc -c teste1.c -o libteste1.o
4 Agora podemos utilizá-la em outros programas (ex. meuprograma.c):
5 Compilar o programa ligando com o código objeto gerado:
gcc meuprograma.c -o meuprograma libteste1.o
6 Executar o programa:
./meuprograma

(RYSH) Linguagem C 30 / 47
Automatizar comandos: Make
O utilitário para automatização de execuções (compilações, comandos)
Pode-se usar make com qualquer linguagem de programação cujo compilador
possa ser executado com um comando shell
Os comandos ficam em um arquivo chamado Makefile
▶ Insira todas as relações dos arquivos que compõe o seu programa (geração dos
códigos objetos das suas bibliotecas, complicação dos seu programas, remoção
de arquivos etc.)
▶ Os comandos devem estar indentados por TABs
Depois basta rodar, no terminal, o comando: make
A ferramenta make irá executar os comandos contidos no Makefile
1 all : meuprograma
2
3 meuprograma : libteste1 . o
4 gcc meuprograma . c - o meuprograma libteste1 . o
5
6 libteste1 . o :
7 gcc - c teste1 . c - o libteste1 . o
8
9 clean :
10 rm - rf *. o

(RYSH) Linguagem C 31 / 47
Automatizar comandos: Make
Exemplo com passagem de valores:
1 all : makedouble clean rename
2
3 test : makepdf clean rename
4
5 makepdf :
6 pdflatex $ ( tex ) . tex
7 mv $ ( tex ) . pdf $ ( pdf ) . pdf
8
9 makedouble :
10 pdflatex $ ( tex ) . tex
11 pdflatex $ ( tex ) . tex
12
13 rename :
14 ifdef $ ( pdf )
15 mv $ ( tex ) . pdf $ ( pdf ) . pdf
16 endif
17
18 clean :
19 rm - f *. aux *. log *. nav *. out *. snm *. toc *. vrb

(RYSH) Linguagem C 32 / 47
Roteiro

1 Manipulação de Arquivos
Arquivos
Abrindo arquivos
Processando arquivo de texto (caracteres)
Leitura
Escrita
Fechando arquivos

2 Escopo de variáveis

3 Bibliotecas

4 Análise de algoritmos

(RYSH) Linguagem C 33 / 47
Eficácia x Eficiência
1 int p1 ( int n )
2 {
3 if ( n == 1 || n == 2)
4 return 1;
5 else
6 return p1 ( n - 1) + p1 ( n - 2) ;
7 }
8

1 int p2 ( int n )
2 {
3 int i , f_ant = 1 , f_ant_ant = 1 , f_atual = 1;
4 for ( i =3; i <= n ; i = i +1)
5 {
6 f_atual = f_ant + f_ant_ant ;
7 f_ant_ant = f_ant ;
8 f_ant = f_atual ;
9 }
10 return f_atual ;
11 }
12

(RYSH) Linguagem C 34 / 47
Eficácia x Eficiência
1 int p2 ( int n )
2 {
3 int i , f_ant = 1 , f_ant_ant = 1 , f_atual = 1;
4 for ( i =3; i <= n ; i = i +1)
5 {
6 f_atual = f_ant + f_ant_ant ;
7 f_ant_ant = f_ant ;
8 f_ant = f_atual ;
9 }
10 return f_atual ;
11 }
12
13 p2 (5)
14 | __ f_atual =? , f1 =1 , f2 =1
15 | __ for
16 | | __ i =3 - > f_atual = 1+1 = 2 , f_ant_ant = 1 , f_ant = 2
17 | | __ i =4 - > f_atual = 1+2 = 3 , f_ant_ant = 2 , f_ant = 3
18 | | __ i =5 - > f_atual = 2+3 = 5 , f_ant_ant = 3 , f_ant = 5
19 | __ return 5
20
21

(RYSH) Linguagem C 35 / 47
Eficácia x Eficiência

1 int p1 ( int n )
2 {
3 if ( n == 1 || n == 2)
4 return 1;
5 else
6 return p1 ( n - 1) + p1 ( n - 2) ;
7 }
8

1
2 _____ p1 (5) _____
3 / \
4 p1 (4) p1 (3)
5 / \ / \
6 p1 (3) p1 (2) p1 (2) p1 (1)
7 / \ | | |
8 p1 (2) p1 (1) 1 1 1
9 | |
10 1 1
11

(RYSH) Linguagem C 36 / 47
Eficácia x Eficiência

Eficácia

Faz o que deveria fazer

Eficiência

Faz bem o que deveria fazer

(RYSH) Linguagem C 37 / 47
Como calcular a eficiência do algoritmo?

Eficiência temporal:
▶ Analisar somente as operações relevantes
▶ Observando a tendência do comportamento a medida que a entrada cresce
▶ Fazendo o cálculo aproximado dos custos das operações
Eficiência espacial:
▶ Quantidade de memória extra ocupada

(RYSH) Linguagem C 38 / 47
Valores comuns da função de custo f (n) = n

Complexidade linear
Realiza-se um pequeno trabalho sobre cada elemento da entrada
n entradas, n saı́das
Anel ou laço
▶ (Tempos comandos internos + avaliação da condição) x número de iterações
1 int pesquisa ( int x , int n , int v [])
2 {
3 for ( int i =0; i < n && v [ i ]!= x ; i = i +1) ;
4 return i ;
5 }

(RYSH) Linguagem C 39 / 47
Valores comuns da função de custo f (n) = n

Complexidade linear
Realiza-se um pequeno trabalho sobre cada elemento da entrada
n entradas, n saı́das
Anel ou laço
▶ (Tempos comandos internos + avaliação da condição) x número de iterações
1 int pesquisa ( int x , int n , int v [])
2 {
3 for ( int i =0; i < n && v [ i ]!= x ; i = i +1) ;
4 return i ;
5 }

(RYSH) Linguagem C 39 / 47
Valores comuns da função de custo f (n) = n

Complexidade linear
Realiza-se um pequeno trabalho sobre cada elemento da entrada
n entradas, n saı́das
Anel ou laço
▶ (Tempos comandos internos + avaliação da condição) x número de iterações
1 int pesquisa ( int x , int n , int v [])
2 {
3 for ( int i =0; i < n && v [ i ]!= x ; i = i +1) ;
4 return i ;
5 }

(RYSH) Linguagem C 39 / 47
Valores comuns da função de custo f (n) = n

Complexidade linear
Realiza-se um pequeno trabalho sobre cada elemento da entrada
n entradas, n saı́das
Anel ou laço
▶ (Tempos comandos internos + avaliação da condição) x número de iterações
1 int pesquisa ( int x , int n , int v [])
2 {
3 for ( int i =0; i < n && v [ i ]!= x ; i = i +1) ;
4 return i ;
5 }

(RYSH) Linguagem C 39 / 47
Valores comuns da função de custo f (n) = n

Complexidade linear
1 // fatorial iterativo
2 // f ( n ) = 3* n + 1
3 int fat ( int n ) {
4 int f = 1;
5 while ( n > 0)
6 f *= n - - ;
7 return f ;
8 }

1 // fatorial recursivo
2 int fat ( int n ) {
3 if ( n ==0) return 1;
4 return n * fat ( n - 1) ;
5 }

(RYSH) Linguagem C 40 / 47
Valores comuns da função de custo f (n) = n2
Complexidade quadrática
Caracterizam-se pelo processamento dos dados em pares, muitas vezes com
vários aninhamentos
Se n dobra, o tempo quadruplica
Úteis para problemas pequenos
1 // versao quadradica != ordenacao seja quadratica
2 void selectio n_sort ( int v [] , int n ) {
3 int menor ;
4 for ( int i =0; i < n ; i ++) { // n
5 menor = i ;
6 for ( int j = i +1; j <= r ; j ++) { // ~ n
7 if ( v [ j ] < v [ menor ]) {
8 menor = j ;
9 }
10 }
11 if ( i != menor ) troca ( v [ i ] , v [ menor ]) ;
12 }
13 }

(RYSH) Linguagem C 41 / 47
Valores comuns da função de custo f (n) = n3

Complexidade cúbica
Eficientes apenas para pequenos problemas.
1 // versao cubica != multiplicacao seja cubica ( algoritmo de
Strassen )
2 void m u l t i p l i c a _ m a t r i z e s ( int A [3][2] , int B [2][3] , int C
[3][3])
3 {
4 for ( int l = 0; l < 3; l ++) {
5 for ( int c = 0; c < 3; c ++) {
6 C [ l ][ c ] = 0;
7 for ( int i = 0; i < 2; i ++) {
8 C [ l ][ c ] += A [ l ][ i ] * B [ i ][ c ];
9 }
10 }
11 }
12 }
13

(RYSH) Linguagem C 42 / 47
Valores comuns da função de custo f (n) = 2n

Complexidade exponencial
Resultantes de problemas resolvidos por força bruta (verificar todas as
possibilidades)
Quando n é 20, o tempo é cerca de 1 milhão
Exemplo: enumerar as linhas de uma tabela verdade
Complexidade fatorial - f (n) = n!: pior que a exponencial
Exemplo: ???

(RYSH) Linguagem C 43 / 47
Valores comuns da função de custo f (n) = 2n
Complexidade exponencial
1 int p1 ( int n ) {
2 if ( n == 0) return 0;
3 else if ( n == 1) return 1;
4 else return p1 ( n - 1) + p1 ( n - 2) ;
5 }

1
2 2^0 _____ p1 (5) _____
3 / \
4 2^1 p1 (4) p1 (3)
5 / \ / \
6 2^2 p1 (3) p1 (2) p1 (2) p1 (1)
7 / \ / \ / \ |
8 2^3 p1 (2) p1 (1) p1 (1) p1 (0) p1 (1) p1 (0) 1
9 / \ | | | | |
10 2^4 p1 (1) p1 (0) 1 1 1 1 1
11 | |
12 1 1
13

(RYSH) Linguagem C 44 / 47
Valores comuns da função de custo: f (n) = log n

Complexidade logarı́tmica
Função logarı́tmica é a inversa da função exponencial

Um pouco mais lento a medida que n cresce


Tempo tı́pico de algoritmos que divide o problema em problemas menores

(RYSH) Linguagem C 45 / 47
Valores comuns da função de custo: f (n) = log n

Complexidade logarı́tmica
Função logarı́tmica é a inversa da função exponencial
Um pouco mais lento a medida que n cresce
Tempo tı́pico de algoritmos que divide o problema em problemas menores
1 // vetor ordenado
2 int pesquisa ( int x , int v [] , int esq , int dir ) {
3 int meio = ( esq + dir ) /2;
4
5 if ( v [ meio ] == x ) return meio ;
6 if ( esq >= dir ) return - 1;
7 else if ( v [ meio ] < x )
8 return pesquisa (x , v , meio +1 , dir ) ;
9 else
10 return pesquisa (x , v , esq , meio - 1) ;
11 }

(RYSH) Linguagem C 45 / 47
Valores comuns da função de custo f (n) = n log n

Complexidade “linearı́tmica(?)”
Caracterizam-se por resolver um problema quebrando em problemas
menores, resolvendo cada um deles independentemente e depois juntando
as soluções, localmente resolvidos, gerando um nova solução.
Divisão e conquista
1 void intercala ( int p , int q , int r , int v []) {...}
2 void mergesort ( int p , int r , int v []) {
3 if ( p < r - 1) {
4 int q = ( p + r ) /2;
5 mergesort (p , q , v ) ;
6 mergesort (q , r , v ) ;
7 intercala (p , q , r , v ) ;
8 }
9 }

Quadrática x Linearı́tmica

(RYSH) Linguagem C 46 / 47
Operações x Entradas

(RYSH) Linguagem C 47 / 47

Você também pode gostar