Top Banner
Recursividade Aula 9
97

Recursividadedois espelhos planos paralelos e frente a frente surge uma imagem recursiva, porque a imagem do objeto refletida num espelho passa a ser o objeto a ser refletido no outro

Jan 29, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • Recursividade

    Aula 9

  • � Em matemática vários objetos são definidos

    apresentando-se um processo que os

    produz.

    � Ex PI (circunferência/diâmetro)

    � Outra definição de um objeto por um

    processo é o fatorial de um número

  • � Fatorial(n) ou n! � = n*(n-1)*(n-2)...(2)*1 se n >0

    � =1 se n==0� Se formulamos:� 0! = 0

    � 1! = 1� 2! = 2 * 1

    � 3! = 3 * 2 * 1� 4! = 4 * 3 * 2 * 1� Não é possível listar a fórmula para fatorial de cada

    inteiro

  • � Para evitar qualquer abreviatura e um cjto infinito de definições poderemos apresentar um algoritmo que

    aceite um número inteiro n e retorne n!

    prod = 1;

    for (x = n; x > 0; x--)

    prod *= x;

    return prod;

    ALGORITMO ITERATIVO: Requer de repetição

    explícita até uma condição ser satisfeita.

  • � Um algoritmo pode ser considerado “Um programa ideal” sem quaisquer limitações práticas de um computador real e portanto

    pode ser usado para definir uma função

    matemática, entretanto uma função de C não

    serve como definição matemática da função

    fatorial por causa de limitações como

    precisão e tamanho finito de uma máquina

    real.

  • � Examinemos detalhadamente a definição de n! que lista uma fórmula separada para cada valor de n

    � Ex 4! = 4 * 3 * 2 * 1 isso é igual a 4 * 3!

    � Para todo n>0 verificamos que

    n! = n* (n-1)!

    � Podemos definir:

    0! = 1

    1! = 1 * 0!

    2! = 2 * 1!

    3! = 3 * 2!

    4! = 4 * 3!

    5! = 5 * 4!

  • � Se empregamos uma notação matemática temos que

    � n! = 1 se n == 0

    � n! = n * (n - 1)! se n >0

    � Definição de uma função em termos de se mesma, aparentemente circular.

    � Método conciso de escrever um número infinito de equações necessárias para definir n!

    � Definição RECURSIVA

  • � A recursividade pode ser utilizada quando um problema puder ser definido em termos de si próprio.

    � Por exemplo, quando um objeto é colocado entre dois espelhos planos paralelos e frente a frente surge uma imagem recursiva, porque a imagem do objeto refletida num espelho passa a ser o objeto a ser refletido no outro espelho e, assim, sucessivamente.

    � Uma função recursiva chama ela mesma, mas com outros parâmetros.

  • Algoritmos Recursivos� A idéia básica de um algoritmo recursivo consiste em

    diminuir sucessivamente o problema em um problema menor ou mais simples, até que o tamanho ou a simplicidade do problema reduzido permita resolvê-lo de forma direta, sem recorrer a si mesmo.

    � Quando isso ocorre, diz que o algoritmo atingiu uma condição de parada, a qual deve estar presente em pelo menos um local dentro algoritmo.

    � Sem esta condição o algoritmo não pára de chamar a si mesmo, até estourar a capacidade da pilha de execução, o que geralmente causa efeitos colaterais e até mesmo o término indesejável do programa.

  • Componentes de um algoritmorecursivo

    � Condição de parada, quando a parte do problema pode ser resolvida diretamente,

    sem chamar de novo a função recursiva.

    � Outros comandos que resolvem uma parte do problema (chamando novamente a função

    recursiva);

  • Algoritmos Recursivos

    f1(..)

    ...

    ...

    ...

    chama f1(..)

    ...

    ...

    fim

    f1(..)

    ...

    ...

    ...

    condição de

    parada!

    f1(..)

    ...

    ...

    chama f1(..)

    ...

    ...

  • 1. 5! = 5 * 4!

    2. 4! = 4 * 3!

    3. 3! = 3 * 2!

    4. 2! = 2 * 1!

    5. 1! = 1 * 0!

    6. 0! = 1

    Cada caso é reduzido a um caso mais simples até

    chegarmos ao caso 0! Que é definido

    imediatamente como 1

  • Se voltarmos

    6’ 0! = 1

    5’ 1! = 1 * 0! = 1 * 1 = 1

    4’ 2! = 2 * 1! = 2 * 1 = 2

    3’ 3! = 3 * 2! = 3 * 2 = 6

    2’ 4! = 4 * 3! = 4 * 6 = 24

    1’ 5! = 5 * 4! = 5 * 24 = 120

  • � Se levamos esse processo a um algoritmos

    teremos

    if (n == 0) fact = 1;else {

    x = n -1;ache o valor de x!. Chame-o de y;fact = n * y;}

    Definição recursiva do processo do cálculo do

    fatorial

  • int main(void){ int NUMERO, RESULTADO;

    scanf("%d", &NUMERO);RESULTADO = FAT(NUMERO);printf("%d\n", RESULTADO); }

    int FAT(int N){ int AUX;

    if(N == 0) // condição de paradareturn 1;

    AUX = N * FAT(N - 1);return AUX; }

    � LEMBRE-SE!! N é variável local da função FAT. � É melhor a definição recursiva de fatorial?

  • � Programa principal:main

    � NUMERO = 2

    RESULTADO = FAT(2)

    � Função FAT:PRIMEIRA CHAMADA

    � N = 2

    AUX = 2 * FAT(1)

    1

  • � Função FAT:

    PRIMEIRA CHAMADA

    � N = 2

    AUX = 2 * FAT(1)

    � Função FAT:

    SEGUNDA CHAMADA

    � N = 1

    AUX = 1 * FAT(0)

    1 2

  • � Função FAT:

    SEGUNDA CHAMADA

    � N = 1

    AUX = 1 * FAT(0)

    � Função FAT:

    TERCEIRA CHAMADA

    � N = 0

    condição de parada

    atingida!!!

    if (N = = 0)

    return 1;

    2 3

  • � Função FAT:

    SEGUNDA CHAMADA

    � N = 1

    AUX = 1 * FAT(0)

    AUX = 1

    � Função FAT:

    TERCEIRA CHAMADA

    � N = 0

    condição de parada

    atingida!!!

    if (N = = 0)

    return 1;

    1

    2 3

  • � Função FAT:

    PRIMEIRA CHAMADA

    � N = 2

    AUX = 2 * FAT(1)

    AUX = 2

    � Função FAT:

    SEGUNDA CHAMADA

    � N = 1

    AUX = 1 * FAT(0)

    AUX = 1

    11

    21

  • � Programa principal:

    main

    � NUMERO = 2

    RESULTADO = FAT(2)

    RESULTADO = 2

    � Função FAT:

    PRIMEIRA CHAMADA

    � N = 2

    AUX = 2 * FAT(1)

    AUX = 2

    22

    1

  • Problemas associados a recursividade

    � Recursões que não terminam!!!

    � Um requisito fundamental é que a chamadarecursiva esteja sujeita à uma condição booleana que em um determinado momento irá se tornar falsa e não mais ativará a recursão (condição de parada!).

    � Um subprograma recursivo deve terobrigatoriamente uma condição que controla sua execução ou término, sob pena de produzir uma computação interminável.

  • Multiplicação de números naturais

    � Outro exemplo de definição recursiva

    � O produto A*B em que a e b são inteiros

    positivos pode ser definido como A somado a

    se mesmo b vezes. Essa definição é

    ITERATIVA

    � Definição recursiva

    a * b = a se b == 1

    a * b = a * (b - 1) + a se b > 1

  • � Exemplo:

    6 * 3 = 6 * 2 + 6 = 6 * 1 + 6 + 6 = 6 + 6 + 6 = 18

    Exercício: Converter num algoritmo recursivo.

    Observe padrão de definições recursivas (caso

    simples e avaliação de casos mais simples)

    Por que não podemos usar definições como ??

    n! = (n + 1)! / (n + 1)

    a * b = a * (b + 1) - a

  • A seqüência de Fibonacci

    � Seqüência de inteiros do tipo

    � 0, 1, 2, 2, 3, 5, 8, 13, 21, 34

    � Cada elemento da seqüência é a soma dos dois elementos anteriores. Se permitimos que fib(0) = 0 e fib(1) = 1

    � fib(n) = n se n == 0 ou n == 1

    � fib(n) = fib(n-2) + fib(n-1) se n >= 2

    � Que diferencia a definição da seqüência de Fibonacci da do fatorial e da multiplicação dos números naturais??

  • A seqüência de Fibonacci

    � Note que:

    � fib(6) = fib(5) + fib(4)

    � = fib(4) + fib(3) + fib(3) + fib(2)

    � = fib(3) + fib(2) + fib(3) + fib(3) + fib(2)

    E assim por diante. Que tem de errado??????

    Seria mais eficiente lembrar quanto é fib(3) na primeira

    vez que ele for chamado

  • Solução iterativa:if (n

  • Solução recursiva

  • FIB(5)

  • FIB(5)

    FIB(3)FIB(4)

  • FIB(5)

    FIB(3)FIB(4)

    FIB(3) FIB(2)

  • FIB(5)

    FIB(3)FIB(4)

    FIB(3) FIB(2) FIB(2) FIB(1)

  • FIB(5)

    FIB(3)FIB(4)

    FIB(3) FIB(2) FIB(2) FIB(1)

    FIB(1)FIB(2)

  • FIB(5)

    FIB(3)FIB(4)

    FIB(3) FIB(2) FIB(2) FIB(1)

    FIB(1)1

  • FIB(5)

    FIB(3)FIB(4)

    FIB(3) FIB(2) FIB(2) FIB(1)

    11

  • FIB(5)

    FIB(3)FIB(4)

    2 FIB(2) FIB(2) FIB(1)

    11

  • FIB(5)

    FIB(3)FIB(4)

    2 FIB(2) FIB(1)

    11

    1

  • FIB(5)

    FIB(3)FIB(4)

    2 FIB(1)

    11

    1 1

  • FIB(5)

    FIB(3)FIB(4)

    2

    11

    1 1 1

  • FIB(5)

    FIB(3)3

    2

    11

    1 1 1

  • 23

    2

    11

    1 1 1

    FIB(5)

  • 5

    23

    2

    11

    1 1 1

    Resposta: O 5º termo da série é 5.

  • Torres de Hanoi

    � Problema criado pelo matemático francês EdouardLucas, em 1883;

    � 3 torres;

    � x discos de vários tamanhos na primeira torre;

    � Objetivo: transportar os discos, 1 a 1, para a terceiratorre;

    � Regras:� nunca colocar um disco maior sobre um disco menor;

    � pode-se mover um único disco por vez;

    � nunca colocar um disco noutro lugar que não numa das três hastes.

  • Torres de Hanoi

  • Torres de Hanoi� Lucas também criou uma “lenda” que dizia que em

    Benares, durante o reinado do imperador Fo Hi, existia um templo que marcaria o centro do universo. Dentro deste templo, alguns monges moviam discos de ouro entre 3 torres de diamante. Deus colocou 64 discos de ouro em uma das torres na hora da criação do universo. Diz-se que, quando os monges completarem a tarefa de transportar todos os discos para a terceira torre, o universo terminará.

    � (como vai levar pelo menos 264 - 1 movimentos para completar a tarefa, estamos a salvo por enquanto. Assumindo que os monges realizem 1 movimento por segundo, e não cometam erros, eles irão levar um total de 585,000,000,000 anos.)

  • Como resolver?

    � Sejam 4 discos na torre 1.

    � Problema principal: Mover 4 discos da torre 1

    para a torre 3.

  • Recursão!

    � Mover 4 discos da torre 1 para a torre 3:

    � mover 3 discos da torre 1 para a torre 2;

    � mover 1 disco da torre 1 para a torre 3;

    � mover 3 discos da torre 2 para a torre 3.

  • Recursão!

    � Mover 4 discos da torre 1 para a torre 3:

    • mover 3 discos da torre 1 para a torre 2;

    • mover 1 disco da torre 1 para a torre 3;

    • mover 3 discos da torre 2 para a torre 3.

  • Recursão!

    � Mover 4 discos da torre 1 para a torre 3:

    • mover 3 discos da torre 1 para a torre 2;

    • mover 1 disco da torre 1 para a torre 3;

    • mover 3 discos da torre 2 para a torre 3.

  • Recursão!

    � Mover 4 discos da torre 1 para a torre 3:

    • mover 3 discos da torre 1 para a torre 2;

    • mover 1 disco da torre 1 para a torre 3;

    • mover 3 discos da torre 2 para a torre 3.

  • Divisão do problema

    � Logo o problema principal:

    � Mover 4 discos da torre 1 para a torre 3

    � Se transforma em um problema menor:

    � mover 3 discos da torre 1 para a torre 2;

    � mover 1 disco da torre 1 para a torre 3;

    � mover 3 discos da torre 2 para a torre 3.

    � Mas, como mover 3 discos?

  • Divisão do problema

    � Mover 3 discos da torre 1 para a torre 2:

    � mover 2 discos da torre 1 para a torre 3;

    � mover 1 disco da torre 1 para a torre 2;

    � mover 2 discos da torre 3 para a torre 2.

  • Divisão do problema

    � Mover 3 discos da torre 1 para a torre 2:

    • mover 2 discos da torre 1 para a torre 3;

    • mover 1 disco da torre 1 para a torre 2;

    • mover 2 discos da torre 3 para a torre 2.

  • Divisão do problema

    � Mover 3 discos da torre 1 para a torre 2:

    • mover 2 discos da torre 1 para a torre 3;

    • mover 1 disco da torre 1 para a torre 2;

    • mover 2 discos da torre 3 para a torre 2.

  • Divisão do problema

    � Mover 3 discos da torre 1 para a torre 2:

    • mover 2 discos da torre 1 para a torre 3;

    • mover 1 disco da torre 1 para a torre 2;

    • mover 2 discos da torre 3 para a torre 2.

  • Algoritmo

    � Mover x discos, da torre a para a torre b:

    � mover (x-1) discos, da torre a para a torre c

    � mover 1 disco da torre a para a torre b

    � mover (x-1) discos, da torre c para a torre b

    � Função de parada:

    � Se o número de discos = 1, move direto.

  • Observações

    � Sejam 3 torres, com os números 1, 2 e 3.

    � Dadas 2 torres, como descobrir qual a

    terceira?

    � Isto é, dadas as torres 1 e 3, como descobrir

    que a outra torre é a 2?

    � Dadas as torres 2 e 3, como descobrir que a

    outra torre é a 1?

  • Observação

    � Note: 1 + 2 + 3 = 6

    � Logo: A outra torre é

    6 - (soma das torres indicadas)

    � Exemplos:

    � torres 1 e 2

    � Outra torre: 6 - (1 + 2) = 6 - 3 = 3

    � torres 2 e 3

    � Outra torre: 6 - (2 + 3) = 6 - 5 = 1

  • Soluçãovoid HANOI(int ND, int DE, int PARA)

    {int OUTRA_TORRE = 6 - (DE + PARA);

    if(ND == 1){printf("Mover disco da torre %d para a

    torre %d.\n", DE, PARA);return;

    }

    HANOI(ND-1, DE, OUTRA_TORRE);HANOI(1, DE, PARA);HANOI(ND-1, OUTRA_TORRE, PARA);return;

    }

  • SoluçãoDigite o numero de discos: 4

    Mover disco da torre 1 para a torre 2.Mover disco da torre 1 para a torre 3.Mover disco da torre 2 para a torre 3.Mover disco da torre 1 para a torre 2.Mover disco da torre 3 para a torre 1.Mover disco da torre 3 para a torre 2.Mover disco da torre 1 para a torre 2.Mover disco da torre 1 para a torre 3.Mover disco da torre 2 para a torre 3.Mover disco da torre 2 para a torre 1.Mover disco da torre 3 para a torre 1.Mover disco da torre 2 para a torre 3.Mover disco da torre 1 para a torre 2.Mover disco da torre 1 para a torre 3.Mover disco da torre 2 para a torre 3.Pressione qualquer tecla para continuar . . .

  • � Mover disco da torre 1 para a torre 2.

  • � Mover disco da torre 1 para a torre 3.

  • � Mover disco da torre 2 para a torre 3.

  • � Mover disco da torre 1 para a torre 2.

  • � Mover disco da torre 3 para a torre 1.

  • � Mover disco da torre 3 para a torre 2.

  • � Mover disco da torre 1 para a torre 2.

  • � Mover disco da torre 1 para a torre 3.

  • � Mover disco da torre 2 para a torre 3.

  • � Mover disco da torre 2 para a torre 1.

  • � Mover disco da torre 3 para a torre 1.

  • � Mover disco da torre 2 para a torre 3.

  • � Mover disco da torre 1 para a torre 2.

  • � Mover disco da torre 1 para a torre 3.

  • � Existem linguagens de programação que não suportam recursividade como FORTAM, COBOL e muitos linguagens de máquina

    � Porem soluções recursivas podem ser simuladas se entendermos o conceito e funcionamento da recursividade

    � Não é raro que um programador consiga enunciar uma solução recursiva para um problema, as vezes a solução recursiva é a mais natural e simples porem as soluções recursivas são com freqüência mais dispendiosas que a solução não recursiva.

  • � Em geral uma solução não recursiva de um programa executarácom mais eficiência em termos de espaço e tempo, isso acontece porque a solução não recursiva evita o trabalho extra de entrar e sair de um bloco e o empilhamento de desnecessário de variáveis

    � Contudo verificaremos que a solução recursiva é as vezes o método mais natural e lógico de desenvolver como é o caso das torres de Hanoi e menos propenso a erros

    � Conflito EFICIENCIA DA MAQUINA X EFICIENCIA DO PROGRAMADOR

    � Nestes casos versões simuladas dos casos recursivos é uma excelente solução

  • � Que acontece quando uma função é chamada??

    1. Passar argumentos: Para um parâmetro em C uma copia é criada localmente dentro da função e quaisquer mudança e feita nessa copia local. O original não é alterado

    2. Alocar e inicializar variáveis locais: Depois que os argumentos forem passados as variáveis locais da função serão alocadas. As diretamente declaradas na função e as temporais

    3. Transferir o controle para a função: Deve ser passado o endereço de retorno como parâmetro

  • � Quando retorna que acontece?

    1. O endereço de retorno é recuperado e

    armazenado num logar seguro

    2. A área de dados da função é liberada

    3. Usa-se um desvio para o endereço de

    retorno salvo anteriormente, deve também

    salvar se os valores de retorno para que o

    chamador possa recuperar esse valor.

  • Chamada de b Chamada de c

    Endereço de

    retorno

    Chamada de d

    Endereço de

    retorno

    Endereço de

    retorno

    controle

    Programa principal Procedimento bProcedimento c Procedimento d

    Chamada de b Chamada de c

    Endereço de

    retorno

    Chamada de d

    Endereço de

    retorno

    controle

    Programa principal Procedimento bProcedimento c

  • � Observe que a seqüência de endereços de retorno forma uma pilha isto é o mais recente endereço de retorno a ser incluído na cadeia é o primeiro a ser removido. Em qualquer ponto só poderemos acessar o endereço de retorno a partir da função

    atualmente em execução que representa o topo da pilha. Quando uma pilha é esvaziada (isto é quando

    a função retornar) será revelado um novo topo dentro da rotina de chamadas.

    � Chamar uma função tem o efeito de incluir um

    elemento numa pilha e retornar da função de eliminá-lo

  • � Cada vez que uma função recursiva chama a

    si mesma uma área de dados totalmente

    nova para essa chamada precisa ser

    alocada. Essa área contem todos os

    parâmetros variáveis locais temporárias e

    endereços de retorno. Todo retorno acareia a

    liberação da atual área de dados. Sugere-se

    o uso de uma pilha

  • � Poderemos usar uma estrutura do tipo

    #define MAXSTACK 50;

    struct stack{

    int top;

    struct dataarea item[MAXSTACK]

    }

  • � Passos da conversão

    � Desenvolver caso recursivo

    � Desenvolver simulação com todas as pilhas e temporários

    � Eliminar todas as pilhas e variáveis supérfluas

    � Quando uma pilha não pode ser eliminada da versão não recursiva e quando a versão recursiva não contem nenhum dos parâmetros adicionais o variáveis locais, a versão recursiva pode ser tão o mais veloz que a não recursiva sob um compilador eficiente. Exemplo Torres de Hanoi

  • � O fatorial que não precisa pilha na implementação não recursiva e a geração de números de fibonacci onde temos uma chamada desnecessária e também não precisa de pilha a solução recursiva deve ser evitada na pratica

    � Até onde uma solução recursiva pode ser transformada em direta dependerá do problema e a engenhosidade do programador

  • Simulação de Recursividadestruct stack {

    int top;

    struct dataarea item[MAXSTACK];

    };

    void popsub(struct stack *s, struct dataarea *a){

    *a = s->item[s->top];

    s->top--;

    }

    void push(struct stack *s, struct dataarea *a){

    s->top++;

    s->item[s->top] = *a;

    }

  • Simulação de Recursividade

    int fact(int n){

    int x, y;

    if (n==0)

    return(1);

    x = n-1;

    y = fact(x);

    return (n * y);

    }

    Ponto 2 para retornar (label1: return(result);)

    Ponto 1 para retornar (labe2 y = result;)

  • Simulação de Recursividade

    struct dataarea{

    int param; //parametro simulado (n)

    int x; //variaveis atuais da chamada

    long int y;

    short int retaddr; //endereço de retorno (1 ou 2)

    };

    switch(i){

    case 1: goto label1; //retorno ao prg principal

    case 2: goto label2; //simulando à atribuição do valor //retornado à variavel y na execução//anterior de fact

    }

  • Simulação de Recursividade

    //retorno a partir de fact

    result = valor a ser retornado;

    i = currarea.retaddr;

    popsub(&s, &currarea);

    switch(i){

    case 1: goto label1;

    case 2: goto label2;

    }

  • Simulação de Recursividade

    //chamada introduz a atual área na pilha

    //atualiza os valores dos parâmetros e

    //transfere o controle para o inicio da rotina

    push(&s, &currarea);

    currarea.param = currarea.x;

    currarea.retaddr = 2;

    goto start;

  • long int simfact(int n){

    struct dataarea currarea;

    struct stack s;

    short i;

    long int result;

    s.top = -1;

    currarea.param = 0;

    currarea.x = 0;

    currarea.y = 0;

    currarea.retaddr = 0;

    push (&s, &currarea);

    currarea.param = n;

    currarea.retaddr = 1;

    start:

    if (currarea.param ==0){

    result = 1;

    i = currarea.retaddr;

    popsub(&s, &currarea);

    switch(i){

    case 1: goto label1;

    case 2: goto label2;

    }

    }

    currarea.x = currarea.param -1;

    push(&s, &currarea);

    currarea.param = currarea.x;

    currarea.retaddr = 2;

    goto start;

    label2:

    currarea.y = result;

    result = currarea.param*currarea.y;

    i = currarea.retaddr;

    popsub(&s, &currarea);

    switch(i){

    case 1: goto label1;

    case 2: goto label2;

    }

    label1:

    return result;

    }

  • Simulação de Recursividade

    � São necessárias todas as variáveis temporais? (n, x, y)

    � n necessita ser empilhada (y=n*fact(x);)

    � Embora x seja definida na chamada nunca seráusada depois de retornar (se x e y não fossem declaradas na função e sim globais, a rotina funcionaria igualmente bem.

    � x e y não precisam ser empilhadas

    � E o endereço de retorno?? Só existe um endereço de retorno importante (fact), mas se não empilhamos a area de dados artificial UNDERFLOW

    � Podemos fazer popandtest...

  • #include

    #include

    #define MAXSTACK 50

    struct stack {

    int top;

    int param[MAXSTACK];

    };

    int empty(struct stack *s){

    return (s->top == -1);

    }

    void popandtest(struct stack *s, int *a,

    short int *und){

    if (!empty(s)){

    und = 0;

    *a = s->param[s->top];

    s->top--;

    return;

    }

    *und = 1;

    }

    void push(struct stack *s, int *a){

    s->top++;

    s->param[s->top] = *a;

    }

  • label2:

    y = result;

    result = currparam*y;

    popandtest(&s, &currparam, &und);

    switch(und){

    case 1: goto label1;

    case 0: goto label2;

    }

    label1:

    return(result);

    }

    int simfact1(int n){

    struct stack s;

    short int und;

    long int result, y;

    int currparam, x;

    s.top = -1;

    currparam = n;

    start:

    if (currparam == 0){

    result = 1;

    popandtest(&s, &currparam, &und);

    switch(und){

    case 0: goto label2;

    case 1: goto label1;

    }

    }

    x = currparam -1;

    push(&s, &currparam);

    currparam = x;

    goto start;

  • Simulação de Recursividade

    � As instruções goto start e goto label2;

    ?????? Repetições de código

    � Para currparam == 0 e currparam != 0

    popandtest(&s, &currparam, &und);

    switch(und){

    case 0: goto label2;

    case 1: goto label1;

    }

  • int simfact2(int n){

    struct stack s;

    short int und;

    long int y;

    int x;

    s.top = -1;

    x = n;

    start:

    if (x == 0) y = 1;

    else{

    push(&s, x--);

    goto start;

    }

    label1:

    popandtest(&s, &x, &und);

    if(und == 1) return(y);

    label2:

    y*=x;

    goto label1;

    }

    Repetição normal

    Repetição normal

  • int simfact3(int n){

    struct stack s;

    short int und;

    long int y;

    int x;

    s.top = -1;

    x = n;

    start:

    while (x!=0) push(&s, x--);

    y = 1;

    popandtest(&s, &x, &und);

    label1:

    while (und == 0){

    y*=x;

    popandtest(&s, &x, &und);

    }

    return (y);

    }

  • int simfact4(int n){

    long int y;

    int x;for(y=x=1; x