2012-02-29 25 views
16

Duplicar posible:
what's the meaning of this piece of code? void (*signal(int sig, void (*func)(int)))(int);¿Cómo leo esta declaración compleja en C?

que tienen una declaración compleja que se han tomado del archivo de cabecera "signal.h", y a continuación es la declaración.

void (*signal(int sig, void (*func)(int)))(int); 

Ahora, ¿cómo lo analizo? Como

la señal es función tomando dos argumentos 'sig' de tipo int y 'func', que es un puntero a una función que toma int como argumento y devuelve tipo vacío; devuelve un puntero a la función tomando int como argumento y devolviendo el vacío.

¿Está OK o la señal es un puntero a la función?

+0

Pero aquí es donde me confundí de http://www.joyofprogramming.com/Docs_ColumnArticles/36-JoP-Dec-09.pdf –

+0

'typedef int foo (void)': foo es un puntero a funcionar , pero puede atajarlo y decir que es una función, porque puede hacer 'foo x; x(); ' – Benoit

+0

@Benoit puede agregarlo como respuesta? –

Respuesta

59

de inicio con el identificador de más a la izquierda y su forma de trabajo, recordando que [] y () se unen antes de *, por lo *a[] es una matriz de punteros, (*a)[] es un puntero a una matriz, *f() es una función que devuelve un puntero, y (*f)() es un puntero a una función:

 signal          -- signal 
     signal(      )   -- is a function 
     signal( sig,     )   -- with a parameter named sig 
     signal(int sig,     )   -- of type int 
     signal(int sig,  func  )   -- and a parameter named func 
     signal(int sig,  (*func) )   -- which is a pointer 
     signal(int sig,  (*func)( ))   -- to a function 
     signal(int sig,  (*func)(int))   --  taking an int parameter 
     signal(int sig, void (*func)(int))   --  and returning void 
     *signal(int sig, void (*func)(int))   -- returning a pointer 
    (*signal(int sig, void (*func)(int)))( ) -- to a function 
    (*signal(int sig, void (*func)(int)))(int) -- taking an int parameter 
void (*signal(int sig, void (*func)(int)))(int); -- and returning void 

signal asocia una función de controlador de señal func con una señal sig, y devuelve el puntero a la función de controlador de señal antigua:

void new_interrupt_handler(int sig) 
{ 
    ... // do something interesting with interrupt signal 
} 

int main(void) 
{ 
    void (*old_interrupt_handler)(int); 
    ... 
    /** 
    * Set up our new interrupt handler 
    */ 
    old_interrupt_handler = signal(SIGINT, new_interrupt_handler); 
    ... 
    /** 
    * Restore original interrupt handler 
    */ 
    signal(SIGINT, old_interrupt_handler); 
    ... 
} 
+4

+1 Muy agradable, explicación paso a paso. – watbywbarif

+0

Gracias a John por sus pensamientos, pero algunos usuarios que se oponen a esto y dicen que la señal es un indicador de la función. –

+0

@Amit - En el caso de Aaron, la cadena que alimentó a 'cdecl' no es lo que escribió en su pregunta. –

1

signal es una función que toma dos parámetros y devuelve un puntero a una función que toma un int como parámetro y devuelve void.

Los dos parámetros que signal toma son una int y un puntero a una función que toma int como un parámetro y devuelve void.

Y sí, tiene la descripción y la idea general correcta.

3

Usando cdecl.org, se obtiene

señal de declaración que la función (int, puntero a la función (int) devolver void) volviendo puntero a la función (int) el regreso de vacío

para la entrada

void (*signal(int, void(*)(int)))(int) 

Esto significa signal es una función. El resultado de llamar al signal es un puntero a una función void f(int).

Explicación: La llamada signal() instala un controlador de señal nueva y devuelve el manejador de la señal de edad (para que pueda restaurar más tarde si quieres).

+0

Pero en mi contexto es diferente, ¿no? –

+0

@ Aaron - no ingresó la misma declaración que el OP. –

+0

@JohnBode: tienes razón. Fijo. –

1

No, eso es correcto. la señal tarda 2 argumentos, un int y un puntero a una función y devuelve un puntero a una función

Es similar a la (OMI) más legible (con la misma firma que el argumento func.):

typedef void (*sig_func)(int); 
sig_func signal(int sig, sig_func func); 
+0

GNU lo llama 'sighandler_t', libc4 y libc5 lo llaman' SignalHandler' y glibc lo llama 'sig_t', BTW. ;) – Gandaro

+0

Así es como debe escribir el código. Si no está usando typedef cuando declara algo tan oscuro como "un puntero a una función que toma indicadores de función como parámetro", entonces es malo y posiblemente bastante tonto. – Lundin

0
void (*signal(int, void (*)(int)))(int); 

     signal(    )   // signal is a function 
       int, void (*)(int)   // the parameter types of the function: 
              // an int and a function pointer (take int, return void) 
void (*       )(int); // the return type of the function: 
              // a function pointer (take int, return void) 

// Editar haciendo referencia a la respuesta de John.

+0

Ahora, ¿cómo la señal es un puntero a la función? –

+0

indica que la señal es un puntero que devuelve la función. –

+0

Es realmente confuso ahora, la mayoría de la respuesta dice que su función devuelve el puntero y usted está diciendo diferente. –

Cuestiones relacionadas