2013-07-28 11 views
5

Il codice che sto usando ha questa dichiarazione:Un asterisco è facoltativo in un puntatore funzione?

typedef void (udp_data_notify)(OS_FIFO * pfifo, WORD port); 

Questo appare come una dichiarazione di un puntatore a funzione per udp_data_notify, tuttavia non v'è alcuna *. Può ancora essere un puntatore a funzione senza asterisco?

Ecco una dichiarazione che utilizza udp_data_notify:

void RegisterUDPFifoWithNotify(WORD dp, OS_FIFO *pnewfifo , udp_data_notify * nudp) 

Qualsiasi aiuto per ciò che sta accadendo sarebbe apprezzato!

+0

Il dereferenziamento di un puntatore di funzione potrebbe tecnicamente produrre il primo byte della prima istruzione di codice macchina della funzione. La grande domanda è cosa vorresti fare con quello in modo portatile. –

+0

possibile duplicato di [Che cosa significa un typedef con parentesi come "typedef int (f) (void)" significa? È un prototipo di funzione?] (http://stackoverflow.com/questions/3674200/what-does-a-typedef-with-parenthes-like-typedef-int-fvoid-mean-is-it-a) –

risposta

0

Lo typedef che viene dichiarato dichiara udp_data_notify come un alias per un tipo di funzione. Quindi la dichiarazione dei parametri udp_data_notify *nudp dichiara che nudp è un puntatore a una funzione di quel tipo. Non c'è chiamata di funzione qui.

Per quanto riguarda l'operatore di chiamata di funzione (postfix ()), l'espressione che designa la funzione chiamata deve essere un puntatore a una funzione. Quando si chiama normalmente una funzione, senza un puntatore, ad esempio sqrt(2), la funzione viene automaticamente convertita in un puntatore. Quindi sqrt(2) è in realtà (&sqrt)(2). Quando si chiama una funzione con un puntatore, la chiamata è già nella forma corretta.

+0

La funzione da convertire in un puntatore c'è un nuovo comportamento C99 che credo. In C89 e K & R, con funzioni implicite, la forma non parentesi 'f()' per le chiamate di funzioni sembra essere stata effettivamente un caso speciale. Si noti che '(f)()' non è valido se 'f' non è dichiarato, anche in C89. –

4

Un typedef quali:

typedef void name(int); 

(la parentesi intorno name sono ridondanti) definirà name come tipo di una funzione, non un puntatore a funzione. Quello sarebbe:

typedef void (*pname)(int); 

Probabilmente ti starai chiedendo per cosa sono adatti. Beh, tipi di funzione non sono molto utili, diversi da quelli per i puntatori dichiarano:

name *pointer_to_function; 

E questo può essere fatto senza dubbio più leggibili con l'altra typedef:

pname pointer_to_function; 

Questo perché non è possibile definire una variabile di tipo di funzione. Se si tenta, sarà sufficiente scrivere il prototipo di una funzione, ma in una sintassi del tutto offuscato:

name foo; //declaration (prototype), not variable 
void foo(int x) //definition 
{ 
} 

Ma nota che non è possibile utilizzare il typedef per definire la funzione:

name foo {} //syntax error! 
+0

"I tipi di funzione non sono molto utili? Ci sono dei casi in cui è utile? – onmyway133

+1

@ onmyway133: Non che io sappia. A meno che tu non consideri utile l'offuscamento. – rodrigo

+0

Ho sentito dire da molte persone che la" dichiarazione di asterisco "è convertito automaticamente in "asterisco", – onmyway133

3

Come già detto, il typedef dichiara un alias per il tipo di funzione. Quando si desidera utilizzarlo per dichiarare un puntatore a funzione, è richiesto un asterisco (udp_data_notify* x). Una dichiarazione senza l'asterisco (udp_data_notify x) sarebbe una dichiarazione di funzione, tranne in un caso speciale. Se utilizzato in un parametro, un tipo di funzione viene automaticamente convertito nel tipo di puntatore della funzione corrispondente:

typedef void F(void); 
void foo(F a, F* b) // special case; a and b are both function pointers 
{ 
    F c; // function declaration 
    F* d; // function pointer 
} 
Problemi correlati