Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: geeke en 4 Febrero 2015, 00:04 am



Título: Peculiar función recursiva
Publicado por: geeke en 4 Febrero 2015, 00:04 am
Navegando por internet me encontré un programa el cual no entiendo porque compila en mi caso en CodeBlock, como verán se define una función dentro de otra según tenia entendido esto es ilegal en C por lo cual esto me extraña mucho:

Código
  1. #include <stdio.h>
  2.  
  3. long fib(long x)
  4. {
  5.    long fib_i(long n)
  6.    {
  7.        return n < 2 ? n : fib_i(n - 2) + fib_i(n - 1);
  8.    };
  9.    if (x < 0)
  10.    {
  11.        printf("Bad argument: fib(%ld)\n", x);
  12.        return -1;
  13.    }
  14.    return fib_i(x);
  15. }
  16.  
  17. long fib_i(long n)
  18. {
  19.    printf("This is not the fib you are looking for\n");
  20.    return -1;
  21. }
  22.  
  23. int main()
  24. {
  25.    long x;
  26.    for (x = -1; x < 4; x ++)
  27.        printf("fib %ld = %ld\n", x, fib(x));
  28.  
  29.    printf("calling fib_i from outside fib:\n");
  30.    fib_i(3);
  31.  
  32.    return 0;
  33. }
  34.  

Alguien puede explicar porque funciona esto y como funciona  :huh:


Título: Re: Peculiar función recursiva
Publicado por: avesudra en 4 Febrero 2015, 01:28 am
Muy curioso, gracias por compartirlo, buscando veo que las funciones anidadas no son parte del estándar de C, sin embargo se implementan como una extensión del compilador GNU C.

Aquí tienes más información https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

En la función fib , la declaración de una función con el mismo nombre se carga la visibilidad de la función externa, podrías entenderlo como que dentro de fib se llama a la función fib_i más cercana a su ámbito, es decir el local. Entonces si llamas a fib_i dentro de fib va a entrar a fib_i, pero a la que está dentro de la función fib

Si llamas a fib_i desde el main te llamará a la externa.

Funciona tal y como las variables globales y locales con el mismo identificador.

¡Y Codeblocks no es un compilador, es un entorno de desarrollo!

Saludos.