You are on page 1of 24

Recursividade na

Linguagem C

Funo Recursiva


Funo recursiva aquela que chama a si


prpria. Uma funo poder tambm ser
considerada recursiva se chamar outras funes
que, em algum momento, chamem a primeira
funo, tornando esse conjunto de funes um
processo recursivo.

As funes recursivas so em sua maioria


solues mais elegantes e simples, se
comparadas a funes tradicionais ou iterativas,
j que executam tarefas repetitivas sem utilizar
nenhuma estrutura de repetio, como for ou
while. Porm essa elegncia e simplicidade
tm um preo que requer muita ateno em sua
implementao.

Trazendo a recursividade para o nosso cotidiano


um timo exemplo est na ao de contar um
saco de moedas, onde a cada ato de retirar uma
moeda do saco precisa-se contar dinheiro que
corresponde a identificar qual o valor da
moeda e som-la quantia que ainda est no
saco.

Para identificar a quantia que ainda est no


saco basta chamar a mesma funo contar
dinheiro novamente, porm dessa vez j
considerando que essa moeda no est mais l.
E este processo de retirar uma moeda,
identificar seu valor e somar com o restante do
saco se repete at que o saco esteja vazio,
quando atingiremos o ponto de parada e a
funo retornar o valor zero, indicando que
no h mais moedas no saco.

Nesse ponto a funo contar dinheiro foi


chamada um nmero de vezes igual a
quantidade de moedas no saco, e a ltima
chamada comea a devolver os valores de
retorno de cada instncia da funo, iniciando
por zero (saco vazio), somado ao valor da
ltima moeda, da penltima, etc, at retornar
primeira chamada referente a primeira moeda,
e nesse momento a funo inicial se encerra
trazendo como valor de retorno a soma dos
valores de todas as moedas que estavam no
saco.

Uma funo pode chamar a si prpria por um


nmero limitado de vezes. Esse limite dado
pelo tamanho da pilha (que poder ser melhor
compreendido aps a apresentao do trabalho
do grupo B). Se o valor correspondente ao
tamanho mximo da pilha for atingido, haver
um estouro da pilha ou Stack Overflow. No
conseguimos resultados muito conclusivos na
avaliao desse estouro de pilha nos testes
realizados, porm deu pra perceber num
programa para gerar uma seqncia de
Fibonacci com valores grandes, que o programa
estava usando acima de 90% dos recursos da
CPU, o que demonstra como pesado para o
computador realizar uma tarefa recursiva.

Cada vez que uma funo chamada de forma


recursiva, so alojados e armazenados uma
cpia dos seus parmetros, de modo a no
perder os valores dos parmetros das chamadas
anteriores. Em cada instncia da funo, s so
diretamente acessveis os parmetros criados
para esta instncia, no sendo possvel acessar
os parmetros das outras instncias.

A informao armazenada na chamada de uma


funo designada por estrutura de invocao
ou registro de ativao e consiste basicamente
na seguinte informao:

Endereo de retorno (quando a funo


terminar o programa deve continuar a sua
execuo na linha seguinte invocao da
funo)
Estado dos registros e flags da CPU
Variveis passadas como argumentos para a
funo (por valor, referncia, etc.)
Varivel de retorno (por valor, referncia,
etc.)

A chamada a uma funo recursiva igual


chamada de uma funo no recursiva, na qual
necessrio guardar uma estrutura de
invocao, sendo esta estrutura liberada depois
do fim da execuo da funo e atualizao do
valor de retorno.

Funes recursivas contem duas


partes fundamentais:


Ponto de Parada ou Condio de Parada:


que o ponto onde a funo ser encerrada,
e geralmente um limite superior ou inferior
da regra geral.
Regra Geral: o mtodo que reduz a
resoluo do problema atravs da invocao
recursiva de casos menores, que por sua vez
so resolvidos pela resoluo de casos ainda
menores pela prpria funo, assim
sucessivamente at atingir o ponto de
parada que finaliza o mtodo.

Para se criar um algoritmo recursivo, deve-se


primeiro procurar encontrar uma soluo de
como o problema pode ser dividido em passos
menores. Depois definir um ponto de parada.
Em seguida, definir uma regra geral que seja
vlida para todos os demais casos. Deve-se
verificar se o algoritmo termina, ou seja, se o
ponto de parada atingido. Para auxiliar nessa
verificao, recomenda-se criar uma rvore de
execuo do programa, como um chins,
mostrando o desenvolvimento do processo.

Todo processo recursivo requer recursos da


mquina, tanto de tempo quando de espao de
memria. Uma medida no muito precisa
desses recursos, mas suficientemente til,
baseia-se na ordem de crescimento, ela nos
permite caracterizar, de forma aproximada, o
consumo de recursos em funo da dimenso
do problema.

Deve-se utilizar a recursividade quando esta


forma for a mais simples e intuitiva de
implementar uma soluo para a resoluo de
um determinado problema. Se no for (simples
e intuitiva), ser ento melhor empregar outros
mtodos no recursivos, tambm chamados de
mtodos iterativos.

Aplicaes prticas de funes


recursivas na linguagem C


Como primeiro exemplo de funo recursiva,


vamos ver o clculo de fatorial.

Fatorial
1 - //Recursividade na Linguagem C
2 - //PRC - Prof. Joo
3 - //FATORIAL
4 - #include stdio.h
5 - int fatorial(int x){
6 - if(( x == 0 ) || ( x ==1))
7return 1;
8 - else
9return(x * fatorial(x-1));
10 - }
11 - main(){
12 - int num;
13 - printf("Entre com um nmero: ");
14 - scanf("%d", &num);
15 - printf("O fatorial de %d %d.", num, fatorial(num));
16 - }

Chins Fatorial
5!

120

5*4!

5*(24)

4*3!

4*(6)

3*2!

3*(2)

2*1!

2*(1)

1*0!

1*(1)
1

Fibonacci
1 - //Recursividade na Linguagem C
2 - //PRC - Prof. Joo
3 - //FIBONACCI
4 - #include stdio.h
5 - int fibonacci(int N) {
6 - if( N == 1 )
7return 1;
8 - else
9if( N == 2)
10 return 1;
11 else
12 return(fibonacci(N-1) + fibonacci(N-2));
13 - }
14 - main() {
15 - int num, F;
16 - printf("Entre com um nmero: ");
17 - scanf("%d", &num);
18 - printf("A srie de Fibonacci para %d elementos :\n", num);
19 - for(F=1;F <= num;F++) {
20 printf("%d, ", fibonacci(F));}
21 printf("\nOk");
22 - }

Chins Fibonacci
5
5-1
4
4-1

4-2

5-2

3-1

3-2

3-1

3-2

Somatrio
1 - //Recursividade na Linguagem C
2 - //PRC - Prof. Joo
3 - //SOMATORIO
4 - #include stdio.h
5 - int somatorio(int x) {
6 - if( x == 1 )
7return 1;
8 - else
9return(x + somatorio(x -1));
10 - }
11 - main() {
12 - int num;
13 - printf("Entre com um nmero: ");
14 - scanf("%d", &num);
15 - printf("O somatrio de 0 at %d %d.", num, somatorio(num));
16 - }

Chins Somatrio
5

15

5+Somatorio(4-1)
5+10
5+4+Somatorio(3-1)
5+4+6
5+4+3+Somatorio(2-1)
5+4+3+3
5+4+3+2+Somatorio(1-1)
5+4+3+2+1
5+4+3+2+1+Somatorio(0)

Conta Dgitos
1 - //Recursividade na Linguagem C
2 - //PRC - Prof. Joo
3 - //CONTA DIGITOS
4 - #include stdio.h
5 - int digitos(int x) {
6 - if( abs(x) < 10 )
7return 1;
8 - else
9return(1 + digitos(x/10));
10 - }
11 - main() {
12 - int num;
13 - printf("Entre com um nmero: ");
14 - scanf("%d", &num);
15 - printf("O nmero de dgitos de %d %d.", num, digitos(num));
16 - }

Chins Conta Dgitos


123456

1+digito(12345/10)
1+5
1+1+digito(1234/10)
1+1+4
1+1+1+digito(123/10)
1+1+1+3
1+1+1+1+digito(12/10)
1+1+1+1+2
1+1+1+1+1+digito(1,2/10)
1+1+1+1+1+1
1+1+1+1+1+1+digito(0,12/10)

You might also like