Buscar

Funcoes_e_Recursividade

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 12 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 12 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 12 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

funções, recursividade
Implementação de funções em C
Blocos de código que realizam ações discretas que o programa deve executar como parte de 
uma ação global para solução de um problema.
Três pontos importantes a respeito de funções em C:
 
Estrutura de um código fonte em C no que esse refere ao uso de funções (existe a 
alternativa clássica)
diretivas de pre-processamento: 
 includes, defines
definições globais: 
 estruturas, uniões, enumerações, campos de bits,... 
protótipos das funções.
declarações de variáveis globais (evite-as).
void main(int argc, char *argv[ ])
{ ............
chamadas a funções
.........
}
blocos de código das funções
1) Protótipo de uma função: 
Não é elemento do C original, tendo sido introduzido pelo padrão ANSI. Consiste em 
uma cópia (finalizada com ‘;’) do cabeçalho da função, sendo necessário em todos os 
arquivos onde houver chamada à respectiva. Serve para uma melhor verificação de 
tipos por parte do compilador. 
Formato geral: tipo_de_retorno nome_da_função (lista de parâmetros);
Onde lista de parâmetros corresponde a uma seqüência de declarações de variáveis: 
tipo var1, tipo var2,...., tipo var n
• O nome_da_função deve ser sugestivo;
• As variáveis declaradas na lista de parâmetros são locais ao corpo da função; 
• Uma função que não retorna nada explicitamente (return) deve ser do tipo void;
• O tipo_de_retorno default é tipo inteiro;
• Para especificar rigorosamente que uma função que não possui lista de parâmetros, 
escreva void no campo reservado a essa lista no protótipo;
• Apesar de pouco utilizado é possível declarar-se um protótipo com uma lista 
variável de parâmetros, como ocorre com o protótipo da função printf, onde as 
reticências significam uma lista variável de parâmetros:
 int printf(const char *format[, argument, ...]);
1
funções, recursividade
2) Definição de uma função
Divide-se em:
 cabeçalho: igual ao protótipo (sem o ponto e vírgula final);
 corpo ou bloco de código: efetivamente o que a função executa quando 
chamada, consiste seqüências de linhas de código não vista pelo resto do 
programa; 
Formato geral:
tipo_de_retorno nome_da_função (lista de parâmetros)
{ 
/* bloco de código */ 
}
ATENÇÃO
• Não é permitido em C, prototipar uma função dentro de outra;
• é possível (mas não recomendável !) utilizar no cabeçalho, declarações com
 identificadores diferentes dos exibidos no protótipo;
• O bloco de código de uma função deve ser o menor possível;
 Quando uma função é chamada, sua execução começa no início do seu corpo e 
termina no final deste ou quando for encontrada o comando return; . 
• O comando return pode também prover o retorno de valor (do mesmo tipo 
declarado para a função) para o ponto onde a função foi chamada, nesse caso sua 
sintaxe será: return (expressão); 
• O valor retornado por return será descartado se não for atribuído a nenhuma 
variável no ponto onde a função foi chamada.
• Uma função pode retornar um endereço de memória, para tanto basta ser declarada 
como um ponteiro para o tipo de retorno
int * func(.....);
.....
void main(void)
{ ........
}
int * func(.....)
{ int *p;
 .....
 return p;
}
3) Chamada a uma função
Consiste na invocação do nome da função com passagem dos parâmetros reais para os 
parâmetros formais declarados no protótipo da função. 
2
funções, recursividade
• Em geral os parâmetros reais, sua quantidade e tipo deve ser compatíveis com os 
parâmetros especificados no protótipo e cabeçalho da função. Além disso há uma 
correspondência entre a ordem dos parâmetros na chamada e a ordem em que foram 
formalmente declarados no protótipo da função.
Passagem de parâmetros reais para “dentro” da função:
Há duas modalidades de passagem de valores para funções (possíveis de serem 
combinadas):
Passagem por valor: nesse método há uma cópia do valor dos parâmetros reais nos 
parâmetros formais da função. Como conseqüência: Alterações feitas nos parâmetros 
formais da função não têm efeito sobre as variáveis utilizadas para chamar a função.
.......
main(void)
{ int x = 10;
 ......
 funcao(int x);
 printf(“x = %i”, x); /* exibe x = 10 */
}
...
void funcao(int x)
{ x= 202;
}
 A declaração de X dentro da função está no 
escopo local à função. 
Durante a chamada, o parâmetro X local à 
função recebe o valor de outra variável X 
externa ao escopo da função.
Alterações feitas na variável X do escopo 
interno à função não afetarão a variável X 
do escopo externo 
 Passagem por referência: há uma cópia do endereço de cada parâmetro real no 
respectivo parâmetro formal. Dessa forma o endereço pode ser usado para acesso 
indireto às variáveis utilizadas na chamada, permitindo alterações sobre estas.
3
funções, recursividade
Ponteiros para funções
Maneira mais flexível para chamar funções através do endereço de suas instruções 
na memória. Sintaxe: tipo_da_função (* nome_ponteiro_para_funcao) ( );
Exemplo: int (* ptr) ( );
não confunda a declaração acima com int *ptr (intx); que corresponde a uma 
declaração de função chamada ptr que devolve ponteiro para inteiro.
void check (char *a, char *b, int (* cmp)() );
int numcmp(char *a, char *b);
main(void)
{ int (* p )( ); /* ponteiro para uma função que retorna inteiro */
 char s1[M], s2[N];
 puts("entre com a primeira string");
 gets(s1);
 puts("entre com a segunda string");
 gets(s2);
 p = strcmp;
 check(s1,s2,p);
 getche();
 return 0;
}
void check (char *a, char *b, int (* cmp)( ) )
{ printf(" As cadeias sao: \n\n");
 if(! (*cmp)(a,b))
 puts("iguais");
 else
 puts("diferentes");
}
4
funções, recursividade
Recursividade ou “dividir para conquistar”
Diz-se que um problema é recursivo (recorrente) se ele pode ser definido em termos dele 
mesmo. 
Em termos de implementação computacional uma solução recursiva é aquela onde a função 
chama a si própria, de forma que a cada chamada a nova execução (da função) lida com 
casos cada vez mais simples do problema original. Portanto, para haver solução recursiva 
deve existir uma determinada instância do problema com solução imediata trivial que 
finalizará as chamadas recursivas à função. 
As definições recursivas são compostas de duas partes:
1. parada da recursividade, onde um ou mais casos simples possuem solução explícita
2. passo recursivo, onde outros casos são dados em termos dos casos anteriores.
Ex1: o produto de dois inteiros a e b positivos pode ser definido pela expressão recursiva
a * b = a se b = 1;
a * b = a* (b-1) + a se b >1.
Perceba que nessa expressão a operação produto é definida em termos dela mesma.
A função produto P(a,b) chama a si própria ciclicamente, e cada nova chamada trata uma 
instância mais simples do problema, até encontrar a solução do caso mais simples possível 
P(a,1) = 1. 
As chamadas recursivas são empilhadas, de forma que uma instância da função aguarda 
pelo retorno de valor que a próxima instância invocada (empilhada acima) deve devolver.
 
Vantagem da recursividade: propicia versões muito mais claras e simples, do que as 
soluções iterativas (com estruturas de repetição – for, while...). Apesar disso uma solução 
recursiva pode ser mais lenta que sua equivalente iterativa, devido à necessidade do uso da 
pilha de recursão para guardar o contexto de execução entre as chamadas recursivas.
5
funções, recursividade
Ex2: soma dos n naturais para n >= 1
Definição: soma(1) = 1
 soma(n) = soma(n-1) + n
int soma(int n)
{ if (n <= 1)
return(1);
 else
return(soma(n-1) + n);
}
Uma pilha de execução para a chamada soma(4):
6
funções, recursividade
Ex3: cálculo do mdc
Definição: 
mdc(x,y) = y; se x >= y e x mod y = 0 (resto da divisão de x por y) 
mdc(x,y) = mdc(y,x)
 mdc(x,y) = mdc(y,x mod y) 
mdc(int x,y)
{ if(x%y = = 0 && x >= y)return(y);
 else
if(x<y)
return(mdc(y,x));
else
return(mdc(y,(x%y)));
}
Ex4: Seqüência de Fibonacci. 
Seqüência de números f0, f1, f2, f3, f4, ..., fi, ..., fm
Onde: f0 = 0, f1 = 1 
 e fi = fi-1 + fi-2 , para i ≥ 2.
Ex: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55.... 
f0 f1 f2 f3 f4 f5 f6 f7 ...
0 1 1 2 3 5 8 13 ...
Considerando o parâmetro n como o índice do número de fibonacci, dentro da 
seqüência. A seguinte função retorna o fn-ésimo número de Fibonacci:
unsigned long int fib(int n)
{ if (n ≤ 1)
 return n;
 else
 return (fib(n-1) + fib(n-2));
}
7
funções, recursividade
Árvore de execução para solução recursiva de fib(4):
Solução iterativa para o número de Fibonacci:
unsigned long int fib_i(int n)
{ unsigned long int a,b,x,i;
 if (n <= 1) return n;
 a = 0;
 b = 1;
 for( i = 2; i <= n; i ++)
 { x = a;
 a = b;
 b = x + a; 
 }
 return b;
} 
8
funções, recursividade
Para comparar os tempos de execução da solução recursiva em relação à iterativa. 
Execute o seguinte código:
#include “time.h”
........
main( )
{ int n;
 clock_t start, end;
 printf(“entre com n: “);
 scanf(“%i”, &n);
 start = clock( );
 printf(“Recursivo, f%i = = %li\n”, n,fib(n)); 
 end = clock( );
 printf(“tempo do calculo recursivo: %f\n\n”, (end-start)/CLK_TCK); 
 
 start = clock( );
 printf(“Iterativo, f%i = = %li\n”,n, fib_i(n)); 
 end = clock( );
 printf(“tempo do calculo iterativo: %f\n\n”, (end-start)/CLK_TCK);
 getche( );
}
9
funções, recursividade
Ex5: torres de Hanói
O problema das Torres de Hanói: dados três pinos (a, b, c) e cinco discos de diâmetros 
diferentes, conforme figura abaixo. O objetivo é mover os cinco discos para C 
utilizando B como auxiliar e garantindo que em C o maior disco ficará abaixo. 
Apenas o disco do topo poderá ser movido, além disso um disco maior nunca poderá ser 
colocado sobre um menor.
chamada :
hanoi(5, ‘A’, ‘B’,’C’);
hanoi(int n, char x, char y, char z)
{ if (n < 1)
 printf( “não há discos para remover ! \n”);
 else
 if(n = = 1)
 printf(“move disco da torre %c para a torre %c\n”, x,y);
 else
{ hanoi(n-1, x, z, y);
 printf(“move disco da torre %c para a torre %c\n”, x,y);
 hanoi(n-1, z, y, x);
 }
}
10
funções, recursividade
EX6 : Busca binária
Método de busca sobre uma coleção ordenada de dados. Simula a maneira como 
pesquisamos informações em um catálogo telefônico: abrimos em uma página 
intermediária e tentamos identificar ali o número procurado, caso ele não seja encontrado, 
procuramos em uma das outras metades do catalogo em função do número procurado e dos 
valores exibidos na posição atual do catalogo. Este procedimento se repete até 
localizarmos o número procurado ou deduzirmos que ele não se encontra catalogado.
BUSCA BINÁRIA RECURSIVA
/* Aqui, retorna a posição do registro procurado ou –1 (insucesso). O vetor A é a coleção 
ordenada de dados. Onde busca-se o elemento x (campo chave), low e high são os limites 
do intervalo de busca, que aqui funcionarão como índices do vetor */
int BuscaBin(int A[ ],int x,int low, int high) 
{
 int mid, ret; /*mid corresponderá sempre à posição de pesquisa entre low e high */
 
 if (low > high) /* se chegar nesse ponto, o item x não existe na coleção */
return(-1); 
 mid = (low+high)/2; /*cálculo de mid: aproximadamente metade da coleção considerada */
 if(x == A[mid]) /*sucesso na pesquisa item encontrado na posição mid. Fim da busca */
return(mid);
 else /* como a coleção é ordenada, o registro procurado deve encontrar-se na partição à 
esquerda ou naquela à direita de mid */
{ if(x < A[mid])
ret = BuscaBin(A, x,low,mid-1); /* continua busca na primeira partição, precisa 
ajustar high para mid-1 */
 else
 ret = BuscaBin(A,x,mid+1,high); /* continua busca na segunda partição, precisa 
ajustar low para mid+1 */
 return(ret);
}
}
11
funções, recursividade
Dado o vetor A ordenado conforme segue: [0,2,5,7,8]
 Simulação:
BuscaBin(A,8,0,4)
....
mid = 2;
if(8 < A[2])
..........
else
ret = BuscaBin(A,8,mid + 1,4)
Return (ret);
BUSCA BINÁRIA ITERATIVA (sem recursão)
int BuscaBin(int A[ ],int x,int low, int high) 
{ int mid;
 while(low <= high)
{ mid = (low+high)/2; 
 if(x<A[mid])
high = mid-1;
 else 
if(x>A[mid])
low = mid+1;
 else
return(mid);
}
 return(-1);
}
12
ret = BuscaBin(A,8,3,4)
mid = 3;
if(8<A[3])
...
else
ret = BuscaBin(A,8,3+1,4)
 
 Return(ret);
BuscaBin(A,8,4,4)
mid = 4;
...
if(8==A[4])
return(mid);
	Implementação de funções em C
	2) Definição de uma função
	ATENÇÃO
	Recursividade ou “dividir para conquistar”
	Ex3: cálculo do mdc
	EX6 : Busca binária

Outros materiais