2012-12-10 15 views
6

mam ten kod C, które mam problemy zrozumienie.jakiś „dziwny” C kod

int foo(int f(int,int), int g(int,int), int x) { 

    int y = g(x,x); 
    return f(y,y); 
} 

int sq(int x, int y) { 
    if (x == 1) { return y; } 
    return pl(y, sq(x-1, y)); 
} 

int pl(int x, int y) { 
    if (x == 0) { return y; } 
    return pl(x-1, y+1); 
} 

int main (int argc, const char * argv[]) 
{ 
    printf("sq = %d\n", sq); 
    printf("output=%d\n", foo(sq, pl, 1)); 
    return 0; 
} 

Zrozumiałem, że f jest pomnożenie dwóch zmiennych i g jest pomnożenie, oni najwyraźniej zbudowany w funkcja foo ma dwa parametry zadeklarowane jako deklaracja funkcji -> f (int, int) i g (int, int). Ale wtedy foo jest przekazywany z dwoma argumentami - sq i pl. Te dwa argumenty mają również bardzo dziwne wartości - 3392 i 3488, są to logiczne adresy funkcji sq i pl? Jeśli są i są przekazywane jako liczby całkowite, to w jaki sposób foo je akceptuje? Od foo, ma deklarację funkcji w miejsce parametrów, do których te argumenty powinny się kierować.

Dziękuję, EDYCJA: fajnie, dziękuję wam wszystkim, to wyjaśniło sprawę!

+0

Czy to kompilacja? Nie sądziłem, że łatwo jest stworzyć funktora bez wskaźników. Głupek, to musi być albo jak widziałbyś "bardzo dziwne wartości" –

+0

wydrukuj adres z '% p': printf (" sq =% p \ n ", sq); – perreal

+0

foo przyjmuje 3 argumenty - dwie funkcje (int, int) identyfikatory/wskaźniki i jedną liczbę całkowitą. Wywołanie foo przekazuje dwie funkcje i jedną liczbę całkowitą. Jest to nieco dziwaczne, ale nic szczególnie egzotycznego. –

Odpowiedz

4

f i g. Są to tylko parametry funkcji foo(), jak już widać.

Poza tym printf("sq = %d\n", sq); jest niezdefiniowanym zachowaniem, ponieważ sq nie jest liczbą całkowitą, ale funkcją wzgl. jego adres w tym kontekście. Powinieneś więc napisać printf("sq = %p\n", sq);, aby wyczyścić adres funkcji.

Co naprawdę się dzieje, że dasz foo() funkcja sq jako parametr f i funkcji pl jako parametr g. foo wywołuje te funkcje za pomocą parametru x w formie pisemnej.

Zasadniczo foo dzwoni pl(1,1) i przechowuje wynik w y, który jest następnie używany do sq(y,y). W ten sposób deleguje pracę na te funkcje. Te funkcje mogą być postrzegane jako funkcje zwrotne, ponieważ foo() wywołuje funkcje podane przez wywołującego.

To, co teraz zrobiłem, jest poza moim zrozumieniem.

2

Zakładając, że rozumiem twoje pytanie i pamiętam C, to foo jest funkcją, która pobiera wskaźników na 2 funkcje f i g plus int, zwraca int.

Zarówno f ​​jak i g są funkcjami, które pobierają 2 wartości int i zwracają wartość int.

Liczba widać to adres funkcji PL i sq, więc wygląda dobrze

Musisz iść i czytać o przekazywanie wskaźników funkcji jako parametry, aby uzyskać pełniejsze wyjaśnienie, co się dzieje w tej sprawie, może pomóc (nawet jeśli to C++) http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/FPT/em_fpt.html.

2
int foo(int f(int,int), int g(int,int), int x) 

deklaruje foo jako funkcja biorąc trzy argumenty, dwie pierwsze są (wskaźniki do) Funkcje, które mają dwa int s jako argumenty i zwraca int, trzeci argument jest int.

sq i pl są funkcjami odpowiedniego typu, więc wywołanie

foo(sq, pl, 1) 

jest poprawna. Nie są wbudowane

4

Nie ma absolutnie nic szczególnego w tym kodzie. Nie ma tu nic "wbudowanego".

Są to zwykłe wskaźniki funkcji. W deklaracji C

int foo(int f(int,int), int g(int,int), int x) 

jest automatycznie interpretowane jako

int foo(int (*f)(int,int), int (*g)(int,int), int x) 

Funkcje sq i pl są przekazywane jako argumenty do foo

foo(sq, pl, 1); // same as foo(&sq, &pl, 1) 

(operator & jest opcjonalne) i nazywane przez tych wskaźników wewnątrz foo

int y = g(x,x); // same as (*g)(x,x) 
return f(y,y); // same as (*f)(y,y) 

(Operator * w rozmowie jest opcjonalny).

Nie wiem, skąd pochodzą te wartości: 3392 i 3488. Wskaźniki funkcji nie są "przekazywane jako liczby całkowite". Jeśli twój debugger zdecydował się wyświetlić wartości wskaźnika jako 3392 i 3488, musi to być problem z twoim debuggerem.