Función anidada en C

93

¿Podemos tener una función anidada en C? ¿Cuál es el uso de funciones anidadas? Si existen en C, ¿su implementación difiere de un compilador a otro?

Sachin Chourasiya
fuente

Respuestas:

108

No puede definir una función dentro de otra función en el estándar C.

Puede declarar una función dentro de una función, pero no es una función anidada.

gcc tiene una extensión de idioma que permite funciones anidadas . No son estándar y, como tales, dependen completamente del compilador.

James McNellis
fuente
36

No, no existen en C.

Se utilizan en lenguajes como Pascal por (al menos) dos razones:

  1. Permiten la descomposición funcional sin contaminar los espacios de nombres. Puede definir una única función visible públicamente que implemente cierta lógica compleja confiando en una o más funciones anidadas para dividir el problema en piezas lógicas más pequeñas.
  2. Simplifican el paso de parámetros en algunos casos. Una función anidada tiene acceso a todos los parámetros y algunas o todas las variables en el alcance de la función externa, por lo que la función externa no tiene que pasar explícitamente una pila de estado local a la función anidada.
Marcelo Cantos
fuente
21

Funciones anidadas no son una parte de ANSI C , sin embargo, que son parte de C de GNU .

zoli2k
fuente
¿Qué significado tiene si son parte de Gnu C
Sachin Chourasiya
4
@Sachin Ayuda a darse cuenta de por qué el código C con funciones anidadas se puede compilar con gcc. La información tiene valor educativo. Además, la pregunta no especifica si está limitada solo a C89, C99 o GNU C
zoli2k
4
Otros lenguajes admitidos por GCC los tienen (ADA y Pascal que yo sepa), por lo que es probable que sea fácil de agregar a la implementación de C o que se haya agregado a C para prepararlos para los lenguajes de soporte que requerirlos.
nategoose
MATLAB también tiene funciones anidadas.
mikeTronix
17

No, no puede tener una función anidada en C. Lo más cerca que puede llegar es declarar una función dentro de la definición de otra función. Sin embargo, la definición de esa función tiene que aparecer fuera de cualquier otro cuerpo de función.

P.ej

void f(void)
{
    // Declare a function called g
    void g(void);

    // Call g
    g();
}

// Definition of g
void g(void)
{
}
CB Bailey
fuente
6
Si la función g se declara de esta manera, ¿cuál será su alcance?
Sachin Chourasiya
6
La declaración tiene un alcance como cualquier otra declaración, por lo que en este caso hasta el final de la función. Por supuesto, una vez que la definición de ges visible más adelante en el archivo, esa declaración está dentro del alcance del resto de la unidad de traducción. Además, puede llamar a funciones en C sin una declaración visible en el alcance, incluso si no es recomendable.
CB Bailey
5

Menciono esto ya que muchas personas que codifican en C ahora usan compiladores de C ++ (como Visual C ++ y Keil uVision) para hacerlo, por lo que es posible que pueda hacer uso de esto ...

Aunque aún no está permitido en C, si está utilizando C ++, puede lograr el mismo efecto con las funciones lambda introducidas en C ++ 11:

void f()
{
    auto g = [] () { /* Some functionality */ }

    g();
}
Jon Green
fuente
4
La pregunta era específicamente sobre C, no C ++
Virgile
11
@Virgile - Y la pregunta también expresó específicamente "¿Se permiten funciones anidadas en cualquier otro idioma?". La respuesta de Jon me ayudó.
www-0av-Com
3

Como han respondido otros, el estándar C no admite funciones anidadas.

Las funciones anidadas se usan en algunos lenguajes para encerrar múltiples funciones y variables en un contenedor (la función externa) para que las funciones individuales (excluyendo la función externa) y las variables no se vean desde afuera.

En C , esto se puede hacer poniendo tales funciones en un archivo fuente separado. Defina la función principal como global y todas las demás funciones y variables como estáticas . Ahora solo la función principal está visible fuera de este módulo.

PauliL
fuente
Si hay recursividad outer-> nested-> outer-> nested, entonces habrá dos marcos diferentes que se mantendrán int declared_in_outer, por lo que no puede simplemente ponerlo declared_in_outercomo un global estático.
Adrian Panasiuk
1

Para responder a su segunda pregunta, existen lenguajes que permiten definir funciones anidadas (se puede encontrar una lista aquí: nested-functions-language-list-wikipedia ).

En JavaScript, que es uno de los lenguajes más famosos, una de las funciones anidadas (que se llaman cierres) son:

  • Crear métodos de clase en constructores de objetos.
  • Para lograr la funcionalidad de los miembros de la clase privada junto con los setters y getters.
  • No contaminar el espacio de nombres global (que se aplica a todos los idiomas, por supuesto).

para nombrar unos pocos...

kyriakosSt
fuente
0

O puede ser inteligente al respecto y usar el preprocesador a su favor ( source.c):

#ifndef FIRSTPASS
#include <stdio.h>

//here comes your "nested" definitions
#define FIRSTPASS
#include "source.c"
#undef FIRSTPASS

main(){
#else
    int global = 2;
    int func() {printf("%d\n", global);}
#endif
#ifndef FIRSTPASS
    func();}
#endif
AnArrayOfFunctions
fuente
-1

¿No es esta una función anidada en C? (la función displayAccounts ())

Sé que podría haber definido la función de manera diferente y pasar variables y lo que no, pero de todos modos funciona bien ya que necesitaba imprimir las cuentas varias veces.

(snipet tomado de una tarea escolar) ...

//function 'main' that executes the program.
int main(void)
{
    int customerArray[3][3] = {{1, 1000, 600}, {2, 5000, 2500}, {3, 10000, 2000}};  //multidimensional customer data array.
    int x, y;      //counters for the multidimensional customer array.
    char inquiry;  //variable used to store input from user ('y' or 'n' response on whether or not a recession is present).

    //function 'displayAccounts' displays the current status of accounts when called.
    void displayAccounts(void)
    {
        puts("\t\tBank Of Despair\n\nCustomer List:\n--------------");
        puts("Account #    Credit Limit\t  Balance\n---------    ------------\t  -------");
        for(x = 0; x <= 2; x++)
        {
            for(y = 0; y <= 2; y++)
                printf("%9d\t", customerArray[x][y]);
            puts("\n");
        }
    }

    displayAccounts();  //prints accounts to console.
    printf("Is there currently a recession (y or n)? ");


//...

    return 0;
}
midnightCoder
fuente
4
No es el estándar C legal. Si funciona con su compilador, es porque su compilador ha proporcionado una extensión al lenguaje C estándar; en cierto sentido, su compilador está compilando un lenguaje diferente, que es, estrictamente hablando, no C.
Nate Eldredge
Gracias por su aporte. Desde entonces he aprendido la forma correcta de declarar, definir y usar funciones. es un poco vergonzoso mirar hacia atrás>. <
midnightCoder
1
@midnightCoder: Siempre puedes borrar tu respuesta :)
chqrlie