Verschachtelte Funktion in C.

92

Können wir eine verschachtelte Funktion in C haben? Was ist die Verwendung von verschachtelten Funktionen? Wenn sie in C existieren, unterscheidet sich ihre Implementierung von Compiler zu Compiler?

Sachin Chourasiya
quelle

Antworten:

107

Sie können in Standard C keine Funktion innerhalb einer anderen Funktion definieren.

Sie können eine Funktion innerhalb einer Funktion deklarieren , diese ist jedoch keine verschachtelte Funktion.

gcc hat eine Spracherweiterung, die verschachtelte Funktionen erlaubt . Sie sind nicht standardisiert und daher vollständig vom Compiler abhängig.

James McNellis
quelle
36

Nein, sie existieren nicht in C.

Sie werden in Sprachen wie Pascal aus (mindestens) zwei Gründen verwendet:

  1. Sie ermöglichen eine funktionale Zerlegung, ohne die Namespaces zu verschmutzen. Sie können eine einzelne öffentlich sichtbare Funktion definieren, die eine komplexe Logik implementiert, indem Sie eine oder mehrere verschachtelte Funktionen verwenden, um das Problem in kleinere logische Teile aufzuteilen.
  2. Sie vereinfachen in einigen Fällen die Parameterübergabe. Eine verschachtelte Funktion hat Zugriff auf alle Parameter und einige oder alle Variablen im Bereich der äußeren Funktion, sodass die äußere Funktion keinen Stapel lokaler Zustände explizit an die verschachtelte Funktion übergeben muss.
Marcelo Cantos
quelle
21

Verschachtelte Funktionen sind nicht Bestandteil von ANSI C , aber sie Teil sind Gnu C .

zoli2k
quelle
Welche Bedeutung hat es, wenn sie Teil von Gnu C
Sachin Chourasiya sind?
4
@Sachin Hilft zu erkennen, warum der C-Code mit verschachtelten Funktionen mit gcc kompiliert werden kann. Die Informationen haben pädagogischen Wert. Darüber hinaus wird die Frage nicht angegeben, ob sie nur auf C89, C99 oder GNU C
zoli2k
4
Andere von GCC unterstützte Sprachen haben sie (ADA und Pascal, die ich kenne), daher ist es wahrscheinlich, dass es entweder einfach war, die C-Implementierung hinzuzufügen, oder dass es zu C hinzugefügt wurde, um sich auf die Unterstützung von Sprachen vorzubereiten, die benötigen sie.
Strategie
MATLAB hat auch verschachtelte Funktionen.
MikeTronix
16

Nein, Sie können keine verschachtelte Funktion in haben C. Am nächsten können Sie eine Funktion innerhalb der Definition einer anderen Funktion deklarieren. Die Definition dieser Funktion muss jedoch außerhalb eines anderen Funktionskörpers erscheinen.

Z.B

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

    // Call g
    g();
}

// Definition of g
void g(void)
{
}
CB Bailey
quelle
6
Wenn die Funktion g auf diese Weise deklariert wird, welchen Umfang hat sie dann?
Sachin Chourasiya
6
Die Deklaration hat wie jede andere Deklaration einen Gültigkeitsbereich, also in diesem Fall bis zum Ende der Funktion. Sobald die Definition von gspäter in der Datei sichtbar ist, gilt diese Deklaration natürlich für den Rest der Übersetzungseinheit. Zusätzlich Sie können Funktionen in C aufrufen , ohne eine sichtbare Erklärung in ihrem Umfang auch wenn es nicht ratsam ist.
CB Bailey
5

Ich erwähne dies, da viele Leute, die in C codieren, jetzt C ++ - Compiler (wie Visual C ++ und Keil uVision) verwenden, damit Sie dies möglicherweise nutzen können ...

Obwohl in C noch nicht zulässig, können Sie mit C ++ den gleichen Effekt mit den in C ++ 11 eingeführten Lambda-Funktionen erzielen:

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

    g();
}
Jon Green
quelle
4
Die Frage betraf speziell C, nicht C ++
Virgile
11
@Virgile - Und die Frage lautete auch ausdrücklich "Sind verschachtelte Funktionen in einer anderen Sprache zulässig?". Jons Antwort hat mir geholfen.
www-0av-Com
3

Wie andere geantwortet haben, unterstützt Standard C keine verschachtelten Funktionen.

Verschachtelte Funktionen werden in einigen Sprachen verwendet, um mehrere Funktionen und Variablen in einen Container (die äußere Funktion) einzuschließen, sodass die einzelnen Funktionen (mit Ausnahme der äußeren Funktion) und Variablen nicht von außen gesehen werden.

In C kann dies durch Einfügen solcher Funktionen in eine separate Quelldatei erfolgen. Definieren Sie die Hauptfunktion als global und alle anderen Funktionen und Variablen als statisch . Jetzt ist nur noch die Hauptfunktion außerhalb dieses Moduls sichtbar.

PauliL
quelle
Wenn es eine Rekursion gibt outer-> nested-> outer-> nested, werden zwei verschiedene Frames gespeichert int declared_in_outer, sodass Sie nicht einfach declared_in_outerals statisches Global setzen können.
Adrian Panasiuk
1

Um Ihre zweite Frage zu beantworten, gibt es Sprachen, mit denen verschachtelte Funktionen definiert werden können (eine Liste finden Sie hier: verschachtelte Funktionen-Sprachliste-Wikipedia ).

In JavaScript, einer der bekanntesten dieser Sprachen, können verschachtelte Funktionen (sogenannte Closures):

  • So erstellen Sie Klassenmethoden in Konstruktoren von Objekten.
  • Um die Funktionalität von privaten Klassenmitgliedern zusammen mit Setzern und Gettern zu erreichen.
  • Den globalen Namespace nicht verschmutzen (das gilt natürlich für jede Sprache).

um ein paar zu nennen...

kyriakosSt
quelle
0

Oder Sie können klug sein und den Präprozessor zu Ihrem Vorteil verwenden ( 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
quelle
-1

Ist dies nicht eine verschachtelte Funktion in C? (die Funktion displayAccounts ())

Ich weiß, ich hätte die Funktion anders definieren und Variablen übergeben können und was nicht, funktioniert aber trotzdem gut, da ich die Konten mehrmals drucken musste.

(Ausschnitt aus einer Schulaufgabe) ...

//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;
}
MitternachtsCoder
quelle
4
Es ist kein gesetzlicher Standard C. Wenn es mit Ihrem Compiler funktioniert, liegt es daran, dass Ihr Compiler eine Erweiterung der Standard-C-Sprache bereitgestellt hat. In gewisser Weise kompiliert Ihr Compiler eine andere Sprache, die streng genommen nicht C ist.
Nate Eldredge
Danke für deinen Beitrag. Seitdem habe ich gelernt, wie man Funktionen richtig deklariert, definiert und verwendet. Es ist ein bisschen peinlich, auf>. <
MitternachtsCoder
1
@midnightCoder: Sie können Ihre Antwort jederzeit löschen :)
chqrlie