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?
Są używane w językach takich jak Pascal z (co najmniej) dwóch powodów:
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.
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.
@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
voidf(void){
// Declare a function called gvoidg(void);
// Call g
g();
}
// Definition of gvoidg(void){
}
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:
voidf(){
auto g = [] () { /* Some functionality */ }
g();
}
@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).
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.intmain(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.voiddisplayAccounts(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)? ");
//...return0;
}
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ź :)
Odpowiedzi:
Nie można zdefiniować funkcji w ramach innej funkcji w standardzie C.
Możesz zadeklarować funkcję wewnątrz funkcji, ale nie jest to funkcja zagnieżdżona.
gcc ma rozszerzenie języka, które pozwala na zagnieżdżone funkcje . Są niestandardowe i jako takie są całkowicie zależne od kompilatora.
źródło
Nie, nie istnieją w C.
Są używane w językach takich jak Pascal z (co najmniej) dwóch powodów:
źródło
Funkcje zagnieżdżone nie są częścią ANSI C , jednak są one częścią GNU C .
źródło
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) { }
źródło
g
jest 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.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(); }
źródło
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.
źródło
outer
->nested
->outer
->nested
, to będą dwie różne ramkiint declared_in_outer
, więc nie możesz po prostu ustawićdeclared_in_outer
jako statycznej globalnej.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ą:
by wymienić tylko kilka...
źródło
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
źródło
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; }
źródło