Clipper On Line • Ver Tópico - Exemplo confuso - Recursividade (linguagem C)
Mudar para estilo Clássico
Discussão sobre outras linguagens de programação.
Postar uma resposta

Exemplo confuso - Recursividade (linguagem C)

12 Ago 2008 21:09

Trago aqui a conhecimento um fato que ocorreu nas minhas primeiras empreitadas que tive na linguagem C e que irá soar um tanto estranho. Numa exemplificação de apostila dá o seguinte algoritmo (ou código fonte como queira dizer):

Código:
    int fatorial(int num){
        if(num == 0)                  // linha 1
        return 1;                     // linha 2
        return num*fatorial(num -1);  // linha 3
        }


A função fatorial mostra um exemplo de recursividade, para quem precise do conceito de recursividade:
A recursividade pode ser vista como funções que chamam a si mesmas. Assim um algoritmo é recursivo se a função que descreve o algoritmo chama a si própria, em algum local dessa função.


Na minha opinião, esse código estaria faltando-lhe um "else" entre as linhas 2 e 3, no entanto este procedimento (a não definição de intruções delimitativas para esta estrutura de decisão) é as vezes usual e é ainda válida, pois funciona. Essa função corresponderia na linguagem XBase:

Código:
? fatorial(0)
? fatorial(2)

function fatorial(num)
if (num == 0)
   return 1
endif
return num*fatorial2(num -1)


Eu questionei aos meus professores e ainda confesso que resta um pouco de dúvida. Não quanto a lógica do algoritmo sim da sintaxe utilizada. Pois acho que na maioria, por não dizer todos, que programam em Clipper não iriam deixar de mencionar o else ou até mesmo a inserção de delimitadores "{ }" para definir a estrutura. É dizer, muito de nós que programamos em Clipper preferimos a forma canônica na elaboração de algoritimo.

Eu cheguei a concluir mesmo que contrariando em tese o seguinte conceito:
3.2 Estrutura de decisão simples (if)

Na Seleção Simples, uma instrução ou um conjunto de instruções é executado somente se o teste condicional especificado retornar o valor verdadeiro. Caso o resultado do teste seja falso, nenhuma das instruções delimitadas pela estrutura de seleção será executada e a execução das instruções será desviada para a instrução imediatamente seguinte à estrutura de seleção.


Minha resolução: Pelo que eu comprovei é que após a formulação da condição simples, é executado as linhas logo após até o return 1; como parte do 1º bloco, logo o segundo bloco é considerado apartir da segunda linha após a definição da condição, de forma impreterível e continua a execução do resto até o próximo return.

Se alguém quiser comentar a respeito, por favor sinta-se a vontade eu ainda me sinto um tanto surpreso.

12 Ago 2008 23:17

Na minha opinião, esse código estaria faltando-lhe um "else" entre as linhas 2 e 3, no entanto este procedimento

Não está faltando. Por ser desnecessário, é opcional. Se a avaliação resultar falso, a estrutura de comando do if é ignorada e a linha 3 é executada.

Note que em C/C++ uma linha única de comando não necessita ser incluída entre chaves. O comando começa após o if() e termina com um ponto-e-vírgula. Se fossem necessárias duas ou mais linhas de comandos, aí sim, as chaves seriam obrigatórias.

Apesar de ser desnecessário delimitar a estrutura por chaves quando há apenas uma linha de comando, para efeito de legibilidade muitos programadores usam chave. As formas abaixo estão corretas e têm o mesmo efeito:

Código:
if (num == 0)
    return 1;

if (num == 0) return 1;

if (num == 0) {
    return 1;
}

if (!num) return 1;

if (0 == num) return 1;


As duas últimas formas, apesar de soarem estranho, são comuns. Particularmente a segunda, que testa uma constante contra uma variável. A fim de evitar distrações com os operadores de atribuição (=) e relacional (==), que são parecidos, muitos programadores só utilizam essa forma para que o compilador gere um erro se for utilizado o operador de atribuição ao invés do relacional. É um tipo de distração que acontece com freqüência. Se for utilizado if(num=0), tem-se um erro de lógica, mas não de sintaxe e o erro sutil só poderá ser percebido pela análise do comportamento do programa, que vai funcionar errado. Mas se for utilizado if(0=num), o compilador gerará uma mensagem de erro para essa linha e a distração será descoberta rapidamente.

Uma última forma, refatorada ao máximo com o par ternário ?: para o teste:

Código:
int Fatorial(int Num) return Num? Num*Fatorial(Num-1): 1;

Estrutura de decisão simples

12 Ago 2008 23:35

Grande Maligno !

O comando começa após o if() e termina com um ponto-e-vírgula.
Aqui falou tudo o que eu precisava saber. Pois este conceito é somente para estrutura de decisão simples. Agradeço o complemento dos seus comentários, com certeza me ajudaram a esclarecer melhor o tema. Pois eu estava ainda na dúvida, pois como toda linha tem que ser finalizada com ";" pensei que isso não fazia o fechamento do comando. Acostumado a ver o IF(<condição>,<faça tal>) o que não é igual ao do Clipper.

13 Ago 2008 12:33

Em C e C++ cada linha de comando sempre termina com um ponto-e-vírgula. Em qualquer situação pode-se ter um bloco de declarações, delimitado por chaves. Como acontece com if(), while(), etc. a linha de comando, sendo única, torna opcional o uso de chaves. Mas em alguns casos, como do e switch, por exemplo, as chaves são obrigatórias, mesmo que haja apenas uma simples declaração.

Re: Exemplo confuso - Recursividade (linguagem C)

27 Set 2008 15:06

Um erro. Na função Fatorial(), que citei acima, faltam as chaves; obrigatórias para a declaração de qualquer função. Do jeito que está é erro de compile-time. O correto:

Código:
int Fatorial(int Num) { return Num? Num*Fatorial(Num-1): 1; }

Exemplo confuso - Recursividade (linguagem C)

28 Set 2008 10:29

No início eu tinha olhado e achei estranho, mas achei que devesse ser caracteristica da linguagem. Pra mim mesmo achei que o ";" faria a diferença para que tudo pudesse estar na mesma linha. Pena que não compilei, senão eu podia ter comentado sobre o erro na compilação. Ainda bem, que você viu e corrigiu para que não ficasse sem os "{ }". Valeu mesmo seu esclarecimento.

Re: Exemplo confuso - Recursividade (linguagem C)

28 Set 2008 12:30

Também não compilei. Mas ontem estava caçando uma mensagem e me deparei com essa. Olhei e de cara percebi algo meio estranho. Logo vi o que era. Mas no momento em que postei a primeira vez nem me dei conta. Acho que ontem eu estava mais "cabeça-fria". :)

Exemplo confuso - Recursividade (linguagem C)

14 Jun 2013 11:52

Código:
function main()
? fatorial(5)
return nil

function fatorial(num)
if (num == 0)
   return 1
else
   return num*fatorial(num -1)
endif
return nil


Q tal isso ?

Exemplo confuso - Recursividade (linguagem C)

14 Jun 2013 19:04

Olá!

Outro exemplo, agora com algo mais corriqueiro do que calcular o fatorial de um número:
Código:
//------------------------------------------------------------------------------------------------------
/***
* PrintArray(aR, cTitle)
*
*  aR[]     - -Array to print
*  cTitle   - -The heading
*
*  Recursive routine to print an array
*/

FUNCTION PrintArray(aR, cTitle)

LOCAL i := 0, cHeading

  // Step through every array element. If the element is
  // itself an array, recurse to print the subarray,
  // just print the element name and subscript.

  AEval(aR, { |elem|  ;
        i++,  ;
        cHeading := cTitle + "[" + Ltrim(Str(i)) + "]", ;
                     Iif(ValType(elem) = "A", PrintArray(elem, cHeading), Qout(cHeading, elem)) } )

RETURN NIL
//------------------------------------------------------------------------------------------------------
Créditos: Rick Spence

Exemplo confuso - Recursividade (linguagem C)

14 Jun 2013 23:07

mas essa eh a forma hiper pró, vicio punk em xbase :X
Postar uma resposta