2013-06-10 21 views
7
int (*ptr)(char (*ch)[]); 

Co oznacza powyższa deklaracja? Czy to oznaczaArgument przyjęcia wskaźnika funkcji

ptr jest wskaźnikiem do funkcji, która akceptuje argument będący tablicą wskaźników do znaków zwracających liczbę całkowitą?

Jak oceniać?

+5

Był to jeden obszar C że projektanci dostał strasznie źle źle! –

+0

To prawda! Trudno jest ocenić takie wyrażenia .. – RDX

+2

To jest błąd składniowy. –

Odpowiedz

3

Jest zasada: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

skrócie, należy zacząć od identyfikatora, a następnie analizować wszystko z identyfikatorem w prawo (może to być () - funkcja lub []tablica), a następnie przeanalizować wszystko od identyfikatora lewo. Nawiasy zmienia ten porządek - należy przeanalizować wszystko w najbardziej wewnętrznych nawiasach pierwszy i tak dalej, to działa jak z obliczeń arytmetycznych.

Innymi słowy, nie jest kolejność pierwszeństwa (która może być zmieniana w nawiasach) z wyższego do niższego:

1) () - funkcja i [] - tablicy od lewej w prawo;

2) * - wskaźnik, typ, rodzaj modyfikatora, od prawej do lewej.


Twój przykład

int (*ptr)(char (*ch)[]) 

Zaczynamy od identyfikatora

int (*ptr)(char (*ch)[]); // (1)ptr 
     |_|      
     1 

Identifier ptr jest w nawiasie, więc analizować wszystko parenteses pierwszych

(*ptr) // (1)ptr 
    |_|  
    1 

Nic w prawo, więc analizować w lewo

(*ptr) // (1)ptr is (2)a pointer 
||_|  
2 1 

Skończyliśmy w nawiasach, teraz analizować po prawej nawiasach

int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function 
    ||_| |____________| 
    2 1  3 

Dotychczas ignorowanie argumentów funkcji i analizowania z lewej nawiasach

int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function which returns (4)int 
|_| ||_| |____________| 
4 2 1  3 

w ten sam sposób analizowania argument funkcji (mam wstawione jakieś przestrzenie dla lepszego dopasowania)

char (* ch)[ ] // (1)ch is (2)a pointer to (3)array of (4)chars 
|___| | |_| |_| 
    4 2 1 3 

Wreszcie mamy:

ptr jest wskaźnik do funkcji, która zwraca int i przyjmuje wskaźnik do tablicy znaków jako argument

1

Współpracuje w GCC.

Tak ptr jest wskaźnik funkcji. Jest to wskaźnik do funkcji powrocie liczbę całkowitą i przyjmując wskaźnik do tablicy znaków jako argument.

Rozważmy funkcję zabawy z następującym prototypie,

int fun(char (*ptr)[]); 

fun() jest funkcją przyjmując wskaźnik do tablicy znaków jako argument.

i następującej części kompilacji kodu bez błędu lub ostrzeżenia

int (*ptr)(char (*ch)[]); 
ptr=fun; 
+0

Pytanie jest oznaczone jako C++. G ++ nie potrafi skompilować tego kodu. Zobacz: http://ideone.com/G7kJpr – jxh

4

PTR jest wskaźnik do funkcji, które akceptuje argumentu jest wskaźnikiem do tablicy znaków, powracającej całkowitą.

+1

jak oceniasz to samo? – RDX

+0

Nie jesteś pewien, o co pytasz. Czy możesz to inaczej sformułować? – Ziffusion

+0

Mam na myśli, jak doszło do tego wniosku? – RDX

2

Jak już napisano ptr jest wskaźnikiem do funkcji, która zwraca int i przyjmuje jako argument wskaźnik do tablicy char.

Jednak nie wolno mieć wskaźnika do tablicy bez ograniczenia tablicy. Twoja zmienna jest niepoprawnie określona i nie będzie się kompilować. Wygląda na to, że chcesz, aby ptr miał typ, który może przyjąć wskaźnik do funkcji, która może przyjmować dowolną tablicę rozmiarów. Wymaga to konstrukcji szablonu. Na argument funkcji, byłoby mieć postać:

template <unsigned N> 
int foo (int (*ptr)(char (*)[N])) { 
    //... 
} 

Normalnie, sposób na uproszczenie tych rodzajów jest użycie typedef do reprezentowania skomplikowanych części, tak że sama zmienna staje się prosty wskaźnik do pewnego typu. Jest to szczególnie przydatne przy próbie napisania funkcji, która zwraca wskaźnik funkcji.

void x (char *s) {} 
typedef void xtype (char *); 

void (* y_hard())(char *) { return x; } 
xtype * y_easy() { return x; } 

Jednak sparametryzowana natura argumentu funkcji czyni to trudniejszym do osiągnięcia. Zakładając C++ 11, można stosować następujące konstrukt (thanks to this answer):

template <unsigned N> 
using ArrayArg = const char [N]; 

template <unsigned N> 
using Function = int (ArrayArg<N> *); 

template <unsigned N> 
int foo (Function<N> *ptr) { 
    //... 
} 
Powiązane problemy