2012-11-20 17 views
7

Próbowałem zarówno - C i C++ i oba działają dobrze.Wywołanie funkcji za pomocą wskaźnika funkcji - usunięcie wskaźnika, czy nie? Co za różnica?

Jestem trochę nowych do wskaźników funkcji i oto prosty kod, który mnie zaskoczył:

#include <assert.h> 
void sort(int* arr, const int N); 

int main() 
{ 
    int arr1[] = { 1, 5, 2, 6, 2 }; 
    int arr2[] = { 1, 5, 2, 6, 2 }; 

    void (*sort_ptr)(int*, const int) = sort; 

    sort_ptr(arr1, 5); 
    (*sort_ptr)(arr2, 5); 

    assert(arr1[0] == 1 && arr1[1] == 2 && arr1[2] == 2 && 
      arr1[3] == 5 && arr1[4] == 6); 
    assert(arr2[0] == 1 && arr2[1] == 2 && arr2[2] == 2 && 
      arr2[3] == 5 && arr2[4] == 6); 

    return 0; 
} 

void sort(int* arr, const int N) 
{ 
    // sorting the array, it's not relevant to the question 
} 

Więc jaka jest różnica między

sort_ptr(arr1, 5); 

i

(*sort_ptr)(arr2, 5); 

Oba wydają się działać (brak błędów, brak ostrzeżeń, posortowane tablice) i jestem trochę zdezorientowany. Który z nich jest prawidłowy lub oba są poprawne?

Odpowiedz

15
sort_ptr(arr1, 5); 

i

(*sort_ptr)(arr2, 5); 

Obie są poprawne. W rzeczywistości, można umieścić jak najwięcej gwiazdki chcesz i wszystkie są prawidłowe:

(*****sort_ptr)(arr2, 5); 

Nazwa funkcji rozpada się wskaźnik do funkcji. W związku z tym wielokrotne odwoływanie się do niego będzie miało taki sam wskaźnik.

+0

dlaczego ***** tak wielu, jak chcesz, możesz wyjaśnić? – Omkant

+0

Wow, to naprawdę dziwne dla mnie. Dlaczego język na to pozwala? OK, nic mi nie jest z użyciem jednego '* - może to być jakieś jawne/ukryte dereferencje (jak powiedział w jego odpowiedzi @Als), ale dlaczego pozwalam na tak wiele' * '? –

+5

Ponieważ formalnie, aby wywołać funkcję, potrzebny jest wskaźnik do funkcji, a funkcja niejawnie konwertuje wskaźnik na funkcję. Za każdym razem, gdy dodajesz '*', wynikiem jest funkcja, która konwertuje wskaźnik na funkcję, co pozwala na dalsze '*'. –

2

Jeśli chodzi o kompilator, sort_ptr i (*sort_ptr) są identyczne. Jeśli rzeczywiście jest wskaźnikiem sort_ptr, jawne wyłuskiwanie go sprawia, że ​​czytelnik jest bardziej zrozumiały. Ogólnie; istnieje jeden przypadek, w którym fakt, że można wywołać funkcję bezpośrednio na wskaźniku do funkcji, jest przydatny: w szablonach, gdzie tworzy wskaźnik do działania obiektu funkcjonalnego, który zachowuje się dokładnie jak klasa z operator()().

Powiązane problemy