Transcript
Page 1: Recursividade Na linguagem C, assim como em muitas outras

Na linguagem C, assim como em muitasoutras linguagens de programação, uma funçãopode chamar a si mesma. Uma função quechama a si mesma é chamada funçãorecursiva.

Recursividade

455

recursiva.

Muitos problemas são definidos com base nosmesmos, ou seja, podem ser descritos porinstâncias do próprio problema. Para estasclasses de problemas, o conceito derecursividade torna-se muito útil.

Page 2: Recursividade Na linguagem C, assim como em muitas outras

Todo cuidado é pouco ao se fazer funçõesrecursivas. A primeira coisa a se providenciar éum critério de parada, o qual vai determinarquando a função deverá parar de chamar a simesma. Este cuidado impede que a função sechame infinitas vezes.

Recursividade

456

chame infinitas vezes.

Um exemplo de um problema cuja definiçãopode ser recursiva é o cálculo do fatorial de umnúmero natural.

Page 3: Recursividade Na linguagem C, assim como em muitas outras

No caso

A!

pode ser definido como

Recursividade

457

A * (A - 1)!

no caso, é preciso especificar um critério deparada, qual seria?

0! = 1

Page 4: Recursividade Na linguagem C, assim como em muitas outras

Contudo, de acordo com o que vimos até omomento, podemos definir um laço de repetiçãoque implementaria o cálculo do fatorial de umnúmero natural. Definiremos agora este laço:

...

int i,num,fat;

Recursividade

458

int i,num,fat;

...

for (i=2,fat=1;i<=num;i++)fat*=i;

...

Page 5: Recursividade Na linguagem C, assim como em muitas outras

Ainda podemos definir uma função recursivaque implemente o computo do fatorial de umnúmero natural:

int fat(int n)

{

Recursividade

459

{

if (n)

return n*fat(n-1);

else

return 1;

}

Page 6: Recursividade Na linguagem C, assim como em muitas outras

/*Exemplo de um programa que se utiliza da função recursiva fat() */

#include <stdio.h>int fat(int n);int main(){

int n;printf("\nDigite o numero que voce deseja saber o fatorial: ");scanf("%d", &n);if (n>=0)

printf("\nO fatorial de %d e' %d", n, fat(n));

460

printf("\nO fatorial de %d e' %d", n, fat(n));else{

printf("\nNao existe fatorial de numeros negativos!");return 1;

}return 0;

} int fat(int n) {

/* ... */}

Page 7: Recursividade Na linguagem C, assim como em muitas outras

Para uma melhor compreensão dos problemasassociados à recursão, devemos nos recordar doconceito de “registro de ativação”, estudado nadisciplina Introdução a Algoritmos.

O registro de ativação é uma área de memóriaque guarda informações referentes ao estadoatual de uma função:

Recursividade

461

que guarda informações referentes ao estadoatual de uma função:

- valor dos parâmetros formais;- valor das variáveis locais;- valor do contador de programa (PC);- etc.

Page 8: Recursividade Na linguagem C, assim como em muitas outras

Sempre que uma função chama outra funçãoo registro de ativação da função invocadora ésalvo e um novo registro de ativação é criadopara a função invocada.

Este processo é conhecido como salvamento

Recursividade

462

Este processo é conhecido como salvamentoe troca de contexto e, dependendo da“profundidade” da recursão, consome memóriae um tempo de execução significativos.

Page 9: Recursividade Na linguagem C, assim como em muitas outras

Exercício:

Para uma melhor compreensão do conceito derecursividade construa, na linguagem deprogramação C, uma função recursiva que

Recursividade

463

programação C, uma função recursiva quereceba como parâmetro dados referentes a umvetor com elementos inteiros e inverta a ordem deseus elementos.

Page 10: Recursividade Na linguagem C, assim como em muitas outras

Um outro exemplo muito utilizado de problemaque possui uma definição recursiva é a geração dasérie de Fibonacci:

{0,1,1,2,3,5,8,13,21,34, …}

Uma função recursiva que recebe a posição doelemento na série e retorna seu valor é:

unsigned int fibonacci(unsigned int i)

Recursividade

465

unsigned int fibonacci(unsigned int i){

if (i==1)return 0;

if (i==2)return 1;

return (fibonacci(i-1) + fibonacci(i-2))}

Page 11: Recursividade Na linguagem C, assim como em muitas outras

Fora o problema do consumo de memória,gerado pela troca de contexto na recursão,mencionado anteriormente, qual seria outroproblema proveniente da recursão evidenciado nafunção recursiva apresentada para o cálculo dovalor de um elemento da série de Fibonacci combase na sua posição?

O cálculo do mesmo valor n vezes.

Recursividade

466

O cálculo do mesmo valor n vezes.

fibonacci(5)

fibonacci(4) + fibonacci(3)

fibonacci(3) + fibonacci(2) fibonacci(2) + fibonacci(1)

fibonacci(2) + fibonacci(1)

Page 12: Recursividade Na linguagem C, assim como em muitas outras

Como vimos, mesmo problemas que possuemuma definição recursiva sempre podem sersolucionados de forma imperativa. Um exemplodisso é o cálculo imperativo do valor de umelemento da série de Fibonacci com base na suaposição, apresentado abaixo:unsigned int fibonacci(unsigned int i){

Recursividade

467

{if (i==1)

return 0;if (i==2)

return 1;else{

unsigned int a, b;for(a=0, b=1; i-2; b+=a,a=b-a,i--);return b;

}}

Page 13: Recursividade Na linguagem C, assim como em muitas outras

Assim como a série de Fibonacci existem outrassequências definidas por recorrência, ou seja,onde um valor da sequência é definido em termosde um ou mais valores anteriores, o que édenominado de relação de recorrência.

Exercício:Estabeleça a relação de recorrência presente na

Recursividade

468

Estabeleça a relação de recorrência presente nasequência abaixo.

S = { 1, 2, 6, 24, ... }

Page 14: Recursividade Na linguagem C, assim como em muitas outras

Exercício:Com base na relação de recorrência

estabelecida no exercício anterior, considerando oprincípio da modularização, construa um programaque receba uma lista de inteiros positivos,representando posições de elementos nasequência e retorne na saída padrão os

Recursividade

470

sequência e retorne na saída padrão osrespectivos valores da sequência. A lista deposições será finalizada pelo valor zero. Não énecessário validar as entradas.Exemplo de entrada: Exemplo de saída:4 242 20

Page 15: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

1. Agregados Heterogêneos (Estruturas)

Um agregado heterogêneo agrupa váriasvariáveis numa só. Sendo utilizados para agruparum conjunto de dados não similares formandoum novo tipo de dado.

472

um novo tipo de dado.

Page 16: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

1. Agregados Heterogêneos (continuação)

Para se criar um agregado heterogêneo usa-seo comando struct. Sua forma geral é:

struct nome_do_tipo_da_estrutura {

473

{tipo_1 nome_campo1;tipo_2 nome_campo2;...tipo_n nome_campon;

} variáveis_do_tipo_da_estrutura;

Page 17: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

struct nome_do_tipo_da_estrutura {

tipo_1 nome_campo1;tipo_2 nome_campo2;... tipo_n nome_campon;

};

474

};struct{

tipo_1 nome_campo1;tipo_2 nome_campo2;... tipo_n nome_campon;

} variáveis_estrutura;

Page 18: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

1. Agregados Heterogêneos (continuação)

Vamos criar um agregado heterogêneo paraarmazenar um endereço:

struct tipo_endereco

{

475

{

char rua [50];

int numero;

char bairro [20];

char cidade [30];

char sigla_estado [3];

long int CEP;

};

Page 19: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

1. Agregados Heterogêneos (continuação)

Vamos agora criar uma estrutura chamadaficha_pessoal capaz de armazenar os dadospessoais de uma pessoa:

476

struct ficha_pessoal

{

char nome [50];

long int telefone;

struct tipo_endereco endereco;

};

Page 20: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

1. Agregados Heterogêneos (continuação)

Assim como ocorria nos agregadoshomogêneos (vetores) , nos agregadosheterogêneo também se faz necessário acessarindividualmente seus elementos.

477

Para isso será utilizado o operador “.”.

Veremos sua utilização no exemplo a seguir.

Page 21: Recursividade Na linguagem C, assim como em muitas outras

#include <stdio.h>#include <string.h>/*aqui entrariam as declarações das struct’s vistasanteriormente na sequência correta*/int main (){

struct ficha_pessoal ficha;strcpy (ficha.nome, "Fulano de Tal");

478

ficha.telefone=4921234;strcpy (ficha.endereco.rua,"Rua das Flores");ficha.endereco.numero=10;strcpy (ficha.endereco.bairro,"Cidade Velha");strcpy (ficha.endereco.cidade,"Belo Horizonte");strcpy (ficha.endereco.sigla_estado,"MG");ficha.endereco.CEP=31340230;

}

Page 22: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

2. Definição de tipo

O comando typedef é utilizado para definir umnovo tipo de dado. Ele é utilizado da seguinteforma:

479

typedef tipo nome_do_tipo;

Page 23: Recursividade Na linguagem C, assim como em muitas outras

Exemplo:

typedef struct

{

int dia;

int hora;

Tipos de Dados Definidos pelo Usuário

480

int hora;

int minuto;

} data;

Page 24: Recursividade Na linguagem C, assim como em muitas outras

Tipos de Dados Definidos pelo Usuário

Exercício:

Construa um programa que manipule um vetorcom 5 registros de alunos, onde cada registropossui informações referentes ao nome, data denascimento, número de matricula, CPF ecoeficiente de rendimento do aluno. Amanipulação do vetor deve ser feita através das

481

coeficiente de rendimento do aluno. Amanipulação do vetor deve ser feita através dasseguintes funções: inicializar vetor, imprimir umdeterminado registro com base no valor do campoCPF e imprimir um determinado registro combase em sua posição no vetor. O programa nãopode possuir variáveis globais, deve se utilizar deforma satisfatória das funções mencionadas edeve definir um novo tipo de dado.


Recommended