2013-07-28 4 views
5

код я использую имеет это заявление:Является ли звездочка необязательной в указателе функции?

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

Это выглядит как объявление указателя функции для udp_data_notify, однако нет никакого *. Может ли он быть указателем на функцию без звездочки?

Вот заявление, которое использует udp_data_notify:

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

Любая помощь, как к тому, что происходит будут оценены!

+0

Разыменование указателя на функцию может технически произвести первые байты первой инструкции машинного кода функции. Большой вопрос - это то, что вы хотели бы сделать с этим переносным способом. –

+0

Возможный дубликат [Что такое typedef с круглыми скобками типа «typedef int (f) (void)» означает? Это прототип функции?] (http://stackoverflow.com/questions/3674200/what-does-a-typedef-with-parenthesis-like-typedef-int-fvoid-mean-is-it-a) –

ответ

0

typedef Вы показываете объявление udp_data_notify как псевдоним для типа функции. Затем объявление параметра udp_data_notify *nudp объявляет nudp указателем на функцию этого типа. Здесь нет вызова функции.

Относительно оператора функциональных вызовов (постфикс ()) выражение, обозначающее вызываемую функцию, должно быть указателем на функцию. Когда вы вызываете функцию нормально, без указателя, такого как sqrt(2), функция автоматически преобразуется в указатель для вас. Таким образом, sqrt(2) на самом деле (&sqrt)(2). Когда вы вызываете функцию с указателем, вызов уже находится в правильной форме.

+0

Функция, преобразованная в указатель Я считаю, что есть новое поведение C99. В C89 и K & R, с неявными функциями, формальная форма 'f()' для вызовов функций, по-видимому, действительно была частным случаем. Обратите внимание, что '(f)()' недействительно, если 'f' не объявляется, даже в C89. –

4

ЬурейиЕ, такие как:

typedef void name(int); 

(скобки вокруг name являются избыточными) определит name как тип функции, а не функция указателя. Это будет:

typedef void (*pname)(int); 

Возможно, вам интересно, для чего они хороши. Ну, типы функций не очень полезны, кроме как для объявляющих указателей:

name *pointer_to_function; 

И это может быть сделано, возможно, более удобным для чтения с другой ЬурейиМ:

pname pointer_to_function; 

Это потому, что вы не можете определить переменные типа. Если вы попробуете, вы просто написать прототип функции, но в довольно запутанном синтаксисе:

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

Но обратите внимание, что вы не можете использовать ЬурейиЙ для определения функции:

name foo {} //syntax error! 
+0

«Типы функций не очень полезны?» Есть ли случаи, в которых это полезно? – onmyway133

+1

@ onmyway133: Не знаю, о чем я знаю. Если вы не считаете, что запутывание полезно. – rodrigo

+0

Я слышал, что многие люди заявляют, что «объявление без звездочки» автоматически преобразуется в «объявление asterisk», – onmyway133

3

Как уже сказал, typedef объявляет псевдоним для типа функции. Когда вы хотите использовать его для объявления указателя функции, требуется звездочка (udp_data_notify* x). Объявление без звездочки (udp_data_notify x) будет объявлением функции, за исключением одного специального случая. При использовании в качестве параметра типа функции автоматически включается в соответствующий тип указателя функции:

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 
} 
Смежные вопросы