2015-09-14 3 views
0

Я тестирую программу для понимания функций обратного вызова и указателей функций. Программа приведена ниже.Назначение функции указателям на функции

Мой вопрос при назначении

cb_display = (void*)display_struct; 

Я должен бросить функцию к void*. Почему это требуется, даже если возвращаемый тип функции недействителен?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct { 
    int a; 
    char b[16]; 
}myst_t; 

void (*cb_display)(void*); 

void display_struct(myst_t *st){ 
    fprintf(stdout, "a -> %d b -> %s \n",st->a,st->b);  
} 

int main() 
{ 
    myst_t myst; 
    myst.a = 789432; 
    strncpy(myst.b,"helloabcd",9); 

    cb_display = (void*)display_struct; 

    cb_display(&myst); 

    return 0; 
} 
+3

Листинг вызывает неопределенное поведение. 'void *' может быть преобразован только в/из указателя _object_, а не указателя функции. Если вы сделаете это правильно, вам также не нужно делать бросок. Получите ваши типы правильно! – Olaf

+3

Типы возвращаемого типа совпадают, однако типы аргументов различаются ('void *' vs. 'myst_t *'). – cremno

ответ

3
cb_display = (void*)display_struct; 

на самом деле также не действует на C. Не делайте этого. Вы не можете назначить void * указателю функции.

Чтобы устранить проблему объявить указатель на функцию, как:

void (*cb_display)(); 

Это означает, что он соответствует функции, которая не возвращать никакого значения и принимает неопределенное количество параметров. Вам тогда не нужно бросать. Также обратите внимание на то, что Олаф указал в комментариях, что декларатор функции с (), хотя и действителен, является устаревшей функцией C.

Конечно, если вы будете передавать только такие функции, как display_struct с параметром myst_t *, вы можете также объявить cb_display как: void (*cb_display)(myst_t *);

+0

Я собирался спросить wht о пустом списке параметров :) спасибо :) – liv2hak

+0

Я мог бы также указать 'void (* cb_display) (myst_t *)' как подпись указателя функции? – liv2hak

+1

@ liv2hak см. Редактирование, добавленное мной в то же время – ouah

0

Изменения пустоты (cb_display) (аннулируется); (cb_display) (void);

Может работать.

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