Zagnieżdżona funkcja w C


97

Czy możemy mieć funkcję zagnieżdżoną w C? Jaki jest pożytek z funkcji zagnieżdżonych? Jeśli istnieją w C, czy ich implementacja różni się od kompilatora do kompilatora?


1
Wygląda na to, że jest duplikatem: stackoverflow.com/questions/1348095/ ...
zoli2k

Odpowiedzi:



36

Nie, nie istnieją w C.

Są używane w językach takich jak Pascal z (co najmniej) dwóch powodów:

  1. Pozwalają na funkcjonalną dekompozycję bez zanieczyszczania przestrzeni nazw. Można zdefiniować pojedynczą publicznie widoczną funkcję, która implementuje złożoną logikę, polegając na jednej lub większej liczbie funkcji zagnieżdżonych w celu rozbicia problemu na mniejsze, logiczne części.
  2. W niektórych przypadkach upraszczają przekazywanie parametrów. Funkcja zagnieżdżona ma dostęp do wszystkich parametrów i niektórych lub wszystkich zmiennych w zakresie funkcji zewnętrznej, więc funkcja zewnętrzna nie musi jawnie przekazywać stosu stanu lokalnego do funkcji zagnieżdżonej.

21

Funkcje zagnieżdżone nie są częścią ANSI C , jednak są one częścią GNU C .


Jakie ma znaczenie, jeśli są częścią Gnu C
Sachin Chourasiya

4
@Sachin Pomaga zrozumieć, dlaczego kod C z zagnieżdżonymi funkcjami można skompilować za pomocą gcc. Informacje mają wartość edukacyjną. Co więcej, pytanie nie precyzuje, czy jest ograniczone tylko do C89, C99 lub GNU C
zoli2k

4
Inne języki obsługiwane przez GCC mają je (o których wiem, ADA i Pascal), więc jest prawdopodobne, że albo było to łatwe do dodania do implementacji C, albo że zostało dodane do C w celu przygotowania do obsługi języków, które wymagają ich.
nategoose

MATLAB ma również funkcje zagnieżdżone.
mikeTronix,

17

Nie, nie możesz mieć funkcji zagnieżdżonej w C. Najbliższe możliwe jest zadeklarowanie funkcji wewnątrz definicji innej funkcji. Definicja tej funkcji musi jednak pojawić się poza jakimkolwiek innym ciałem funkcji.

Na przykład

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

    // Call g
    g();
}

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

6
Jeśli funkcja g zostanie zadeklarowana w ten sposób, to jaki będzie jej zakres?
Sachin Chourasiya

6
Deklaracja jest objęta zakresem jak każda inna deklaracja, a więc w tym przypadku do końca funkcji. Oczywiście, gdy definicja gjest widoczna później w pliku, deklaracja ta jest objęta zakresem pozostałej części jednostki tłumaczeniowej. Poza ty może wywoływać funkcje w C bez widocznego deklaracji w zakresie, nawet jeśli nie jest to wskazane.
CB Bailey,

5

Wspominam o tym, ponieważ wiele osób kodujących w C korzysta teraz z kompilatorów C ++ (takich jak Visual C ++ i Keil uVision), aby to zrobić, więc możesz być w stanie wykorzystać to ...

Chociaż nie jest to jeszcze dozwolone w C, jeśli używasz C ++, możesz osiągnąć ten sam efekt za pomocą funkcji lambda wprowadzonych w C ++ 11:

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

    g();
}

4
Pytanie dotyczyło języka C, a nie C ++
Virgile

11
@Virgile - I pytanie również wyraźnie brzmi: „Czy funkcje zagnieżdżone są dozwolone w jakimkolwiek innym języku?”. Odpowiedź Jona pomogła mi.
www-0av-Com

3

Jak odpowiedzieli inni, standardowa C nie obsługuje funkcji zagnieżdżonych.

Funkcje zagnieżdżone są używane w niektórych językach do umieszczania wielu funkcji i zmiennych w kontenerze (funkcja zewnętrzna), dzięki czemu poszczególne funkcje (z wyjątkiem funkcji zewnętrznej) i zmienne nie są widoczne z zewnątrz.

W C można to zrobić, umieszczając takie funkcje w oddzielnym pliku źródłowym. Zdefiniuj główną funkcję jako globalną, a wszystkie inne funkcje i zmienne jako statyczne . Teraz tylko główna funkcja jest widoczna poza tym modułem.


Jeśli istnieje rekurencja outer-> nested-> outer-> nested, to będą dwie różne ramki int declared_in_outer, więc nie możesz po prostu ustawić declared_in_outerjako statycznej globalnej.
Adrian Panasiuk

1

Odpowiadając na drugie pytanie, istnieją języki, które pozwalają na definiowanie funkcji zagnieżdżonych (lista znajduje się tutaj: nested-functions-language-list-wikipedia ).

W JavaScript, który jest jednym z najbardziej znanych języków, jedną z funkcji zagnieżdżonych (nazywanych domknięciami) są:

  • Tworzenie metod klasowych w konstruktorach obiektów.
  • Aby osiągnąć funkcjonalność członków klasy prywatnej wraz z ustawiającymi i pobierającymi.
  • Nie zanieczyszczać globalnej przestrzeni nazw (dotyczy to oczywiście każdego języka).

by wymienić tylko kilka...


0

Lub możesz być sprytny i wykorzystać preprocesor na swoją korzyść ( 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

czy to nie jest funkcja zagnieżdżona w C? (funkcja displayAccounts ())

Wiem, że mogłem zdefiniować funkcję inaczej i przekazywać zmienne, a co nie, ale i tak działa dobrze, ponieważ musiałem wielokrotnie drukować konta.

(wycinek pobrany z zadania szkolnego) ...

//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
Nie jest to norma prawna C. Jeśli to działa z twoim kompilatorem, to dlatego, że twój kompilator dostarczył rozszerzenie standardowego języka C; w pewnym sensie twój kompilator kompiluje inny język, który, ściśle rzecz biorąc, nie jest językiem C.
Nate Eldredge Kwietnia

dziękuję za wkład. Od tego czasu nauczyłem się prawidłowego sposobu deklarowania, definiowania i używania funkcji. to trochę zawstydzające patrzeć wstecz>. <
midnightCoder

1
@midnightCoder: Zawsze możesz usunąć swoją odpowiedź :)
chqrlie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.