2013-10-25 4 views
0

Что (*PREDir->cfun) (d, &tf); ответственность за в ниже фрагмент кода:Понимание Указатели на функции в C

typedef struct { 
    FILE *fp; 
    char queue[ NAMELEN ]; 
    char fullpath[ NAMELEN ]; 
    char fname[ NAMELEN ]; 
} TRW; 

typedef struct { 
    char *dir_to_scan; 
    void (*cfun)(); 
} SCANNING; 

static TRW tf; 
static SCANNING *PREDir; 
char *d; 

(*PREDir->cfun) (d, &tf); 
+2

Кажется, что cfun никогда не устанавливается в какой-либо реальной функции ... у вас есть код, который устанавливает его где угодно? Предоставляет ли компилятор какие-либо предупреждения об этом коде? Или вы спрашиваете, что должно произойти под тем, что, вероятно, является неопределенным поведением? – atk

+0

Это просто вызов функции, которая зарегистрирована с помощью указателя функции 'cfun'. –

+1

Это не совсем дубликат (этот вопрос не спрашивает о 'typedef'), но есть некоторая полезная (и некоторая эзотерическая) информация в [How' typedef' работает для указателей на функции] (http: // stackoverflow. ком/вопросы/9357520/как-TYPEDEF-работа-для-функциональных указателей/9357637 # 9357637). –

ответ

2

PREDir является указателем на структуру. Структура содержит член, называемый cfun, который является указателем на функцию, которая принимает неопределенное количество аргументов и ничего не возвращает.

В

(*PREDir->cfun) (d, &tf); 

вызывает эту функцию с двумя аргументами, d и указатель на tf.

+0

Разве это не указатель на функцию без аргументов? Я так и думал, что ... Означает ли это, что можно указать на «void foo (int a)» или «void bar (char a, char b)», без каких-либо ошибок или предупреждений? – Eregrith

+2

@Eregrith: В C функция, не принимающая аргументов, будет 'void foo (void)'. OTOH, пустые круглые скобки означают «неопределенные аргументы». См. Также http://c-faq.com/decl/pfitypedef.html и ссылки в нем. – NPE

+0

Спасибо, я был обманут обычным предупреждением от '-Wstrict-prototypes', которое я всегда использую. Можно ли объявить 'void (* foo)();' без предупреждения при использовании этого флага? – Eregrith

0

cfun - это указатель на функцию, которая принимает любые аргументы и возвращает void.

Так (*PREDir->cfun) (d, &tf); будет вызывать функцию, назначенную PREDir->cfun с аргументами d и &tf (адрес ТФ).

Удостоверьтесь, что PREDir указывает на объект SCANNING, у которого есть назначенное поле cfun или вы получите неопределенное поведение.

+0

Как это нормально, поскольку cfun определяется как указатель на функцию, прототип которой должен быть 'void foo (void);'? – Eregrith

+1

@Eregrith: это C и 'void (* cfun)(); указатель' означает ', чтобы функция не возвращала значения и принимала неопределенные, но не переменные аргументы. В C++ это означает «указатель на функцию, возвращающую значение без аргументов». Это большая разница между C и C++. –

+0

@ JonathanLeffler Gee ... Спасибо! Я лгал всем своим первым годом в моей школе O_O hahaha ... – Eregrith

Смежные вопросы