Fonction imbriquée en C


93

Pouvons-nous avoir une fonction imbriquée dans C? À quoi servent les fonctions imbriquées? S'ils existent en C, leur implémentation diffère-t-elle d'un compilateur à l'autre?


1
Semble être un double de: stackoverflow.com/questions/1348095/…
zoli2k

Réponses:



36

Non, ils n'existent pas dans C.

Ils sont utilisés dans des langages comme Pascal pour (au moins) deux raisons:

  1. Ils permettent une décomposition fonctionnelle sans polluer les espaces de noms. Vous pouvez définir une seule fonction visible publiquement qui implémente une logique complexe en comptant sur une ou plusieurs fonctions imbriquées pour diviser le problème en plus petits morceaux logiques.
  2. Ils simplifient le passage des paramètres dans certains cas. Une fonction imbriquée a accès à tous les paramètres et à tout ou partie des variables dans la portée de la fonction externe, de sorte que la fonction externe n'a pas à passer explicitement une pile d'états locaux dans la fonction imbriquée.

21

Fonctions emboîtées ne font pas partie de la norme ANSI C , cependant, ils font partie de Gnu C .


Quelle est leur signification s'ils font partie de Gnu C
Sachin Chourasiya

4
@Sachin Aide à comprendre pourquoi le code C avec des fonctions imbriquées peut être compilé avec gcc. L'information a une valeur éducative. De plus, la question ne précise pas si elle est limitée uniquement à C89, C99 ou GNU C
zoli2k

4
D'autres langages pris en charge par GCC en ont (ADA et Pascal que je connais), il est donc probable que soit il était facile à ajouter à l'implémentation C, soit qu'il ait été ajouté à C afin de préparer les langages de support qui les exiger.
nategoose

MATLAB a également des fonctions imbriquées.
mikeTronix

17

Non, vous ne pouvez pas avoir de fonction imbriquée C. Le plus proche que vous puissiez approcher est de déclarer une fonction dans la définition d'une autre fonction. La définition de cette fonction doit cependant apparaître en dehors de tout autre corps de fonction.

Par exemple

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

    // Call g
    g();
}

// Definition of g
void g(void)
{
}

6
Si la fonction g est déclarée de cette manière, quelle sera sa portée?
Sachin Chourasiya le

6
La déclaration a une portée comme toute autre déclaration, donc dans ce cas jusqu'à la fin de la fonction. Bien sûr, une fois que la définition de gest visible plus tard dans le fichier, cette déclaration est dans la portée du reste de l'unité de traduction. De plus, vous pouvez appeler des fonctions en C sans déclaration visible dans la portée même si cela n'est pas conseillé.
CB Bailey

5

Je mentionne cela car de nombreuses personnes codant en C utilisent maintenant des compilateurs C ++ (tels que Visual C ++ et Keil uVision) pour le faire, vous pourrez donc peut-être utiliser cela ...

Bien que cela ne soit pas encore autorisé en C, si vous utilisez C ++, vous pouvez obtenir le même effet avec les fonctions lambda introduites dans C ++ 11:

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

    g();
}

4
La question portait spécifiquement sur C, pas C ++
Virgile

11
@Virgile - Et la question énonçait également spécifiquement "Les fonctions imbriquées sont-elles autorisées dans une autre langue?". La réponse de Jon m'a aidé.
www-0av-Com

3

Comme d'autres l'ont répondu, la norme C ne prend pas en charge les fonctions imbriquées.

Les fonctions imbriquées sont utilisées dans certains langages pour enfermer plusieurs fonctions et variables dans un conteneur (la fonction externe) de sorte que les fonctions individuelles (à l'exclusion de la fonction externe) et les variables ne soient pas vues de l'extérieur.

En C , cela peut être fait en plaçant ces fonctions dans un fichier source distinct. Définissez la fonction principale comme globale et toutes les autres fonctions et variables comme statiques . Désormais, seule la fonction principale est visible en dehors de ce module.


S'il y a récursivité outer-> nested-> outer-> nested, alors il y aurait deux cadres différents int declared_in_outer, donc vous ne pouvez pas simplement les mettre declared_in_outercomme un global statique.
Adrian Panasiuk

1

Pour répondre à votre deuxième question, il existe des langages qui permettent de définir des fonctions imbriquées (une liste peut être trouvée ici: nested-functions-language-list-wikipedia ).

En JavaScript, qui est l'un des plus célèbres de ces langages, l'une des fonctions imbriquées (appelées fermetures) peut être:

  • Pour créer des méthodes de classe dans les constructeurs d'objets.
  • Pour atteindre la fonctionnalité des membres de la classe privée avec les setters et les getters.
  • Ne pas polluer l'espace de noms global (cela vaut pour toutes les langues, bien sûr).

pour n'en nommer que quelques-uns ...


0

Ou vous pouvez être intelligent à ce sujet et utiliser le préprocesseur à votre avantage ( 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

-1

n'est-ce pas une fonction imbriquée dans C? (la fonction displayAccounts ())

Je sais que j'aurais pu définir la fonction différemment et passer des variables et ce qui ne fonctionne pas mais de toute façon fonctionne bien car j'avais besoin d'imprimer les comptes plusieurs fois.

(extrait tiré d'un devoir scolaire) ...

//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;
}

4
Ce n'est pas la norme légale C. Si cela fonctionne avec votre compilateur, c'est parce que votre compilateur a fourni une extension au langage C standard; dans un certain sens, votre compilateur compile un langage différent, qui est, à proprement parler, pas C.
Nate Eldredge

Merci pour votre participation. Depuis, j'ai appris la bonne façon de déclarer, définir et utiliser des fonctions. c'est un peu embarrassant de regarder en arrière>. <
midnightCoder

1
@midnightCoder: Vous pouvez toujours supprimer votre réponse :)
chqrlie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.