2012-02-04 18 views
6

Podczas odsłuchu kursu Stanforda Programming Abstractions, natrafiam na jakiś fragment kodu, który wygląda następująco.funkcja jako wskaźnik funkcji vs jako parametr

void plot(double start, double end, double (fn)(double)) { 
    double i; 
    for (i = start; i <= end; i += 1) 
     printf("fn(%f) = %f\n", i, fn(i)); 
} 

double plus1(double x) { 
    return x + 1; 
} 

int main(void) { 
    plot(1, 10, plus1); 
    return 0; 
} 

Skompilowałem kod w moim systemie przy użyciu GCC, a następnie G ++; obaj działają doskonale.

wiem, że przechodząc int i = 2 do funkcji takich jak void func1(int a) utworzy nową kopię tego i dla tej funkcji podczas przechodzenia &i do void func2(int *a) dadzą tylko funkcję func2 adres i.

Czy ktoś może mi wyjaśnić, jaki jest mechanizm przekazywania fn do plot i jak różni się od przekazywania wskaźnika funkcji jako parametru?

Odpowiedz

7

Nie ma absolutnie żadnej różnicy między void foo(double fn(double)) i void foo(double (*fn)(double)). Oba deklarują funkcje, które przyjmują wskaźnik do funkcji jako parametru.

Jest to podobne do tego, jak nie ma różnicy między void bar(double arr[10]) i void bar(double* arr).

+0

Czy masz odniesienie do drugiego zastrzeżenia dotyczącego tablic? Zwłaszcza gdy jest to C++? – krlmlr

+0

Istnieje pewna różnica, w pierwszym, 'fn' jest nieprzerwanie wskaźnikiem do funkcji, aw tym drugim' fn' jest jawnie deklarowanym wskaźnikiem do funkcji –

+3

@ user946850: '§8.3.5/5': ... Po określając typ każdego parametru, dowolny parametr typu "array of T" lub "function return T" jest odpowiednio dostosowywany do "wskaźnika do T" lub "wskaźnika do funkcji zwracającej T". ... – Mankarse

0

Przepraszam za mój błąd.

void foo(int (fn)(int)){} 
void bar(int (*fn)(int)){} 

skompilować powyższy kod tak:

gcc -S sample.c

okaże się, że nie ma żadnej różnicy. tylko inny styl kodowania.

można spróbować skompilować i uruchomić ten kod, a także:

#include <stdio.h> 
void foo(int (fn)(int)) 
{ 
    printf("foo: %x.\n",fn); 
} 
void bar(int (*fn)(int)) 
{ 
    printf("bar: %x.\n",fn); 
} 
int main(int argc) 
{ 
    foo(main); 
    bar(main); 
    return 0; 
} 
+0

Proszę ponownie przeczytać moje pytanie. Poprosiłem o różnicę między wskaźnikiem funkcji na liście parametrów a prototypem funkcji na liście parametrów. – MrOrdinaire

+0

moja wina. Napisałem nową odpowiedź. – for1096

Powiązane problemy