2009-11-06 20 views
10
void (*func)(int(*[ ])()); 
+0

Ver http: // stackoverflow.com/questions/1448849/how-to-understand-complicated-function-declarations – pmg

Respuesta

5

Sí:

 
$ cdecl 
explain void (* x)(int (*[])()); 
declare x as pointer to function 
    (array of pointer to function returning int) returning void 
+0

¡Hah! ¡Increíble! .. –

+0

No creo que lo sea, a cdecl simplemente no le gusta el nombre 'func'. – caf

+0

Nahhhh ... es un error en cdecl :) – pmg

20

No es una declaración, es una declaración.

Declara func como un puntero a una función que devuelve nulo y teniendo un solo argumento de tipo int (*[])(), que en sí es un puntero a un puntero a una función que devuelve un entero y teniendo un número fijo, pero indeterminado de argumentos.


salida cdecl para hombres de poca fe:

cdecl> explain void (*f)(int(*[ ])()); 
declare f as pointer to function (array of pointer to function returning int) returning void 
+0

"número de argumentos fijo pero no especificado" - la pregunta también está etiquetada C++, en cuyo caso ese segundo tipo de función toma precisamente cero argumentos. –

+3

La etiqueta C++ fue agregada por alguien que no sea el cartel original, después de haber respondido. Un movimiento demasiado inteligente a la mitad, según mi libro. – caf

+0

Gosh, eso es astuto. Nunca está claro cuando alguien dice "C/C++" si lo han dicho porque piensan que la respuesta es la misma para ambos idiomas, porque piensan que las respuestas son diferentes entre los dos ... –

2

void (*func)(blah); es un puntero a una función de tomar blah como argumento, donde blah sí se int(*[ ])() es una matriz de punteros de función.

31

El procedimiento general para la lectura declaradores peludas es encontrar el identificador de más a la izquierda y su forma de trabajo, recordando que [] y () se unen antes de * (es decir, , *a[] es una matriz de puntero, no un puntero a una matriz). Este caso se hace un poco más difícil por la falta de un identificador en la lista de parámetros, pero de nuevo, [] se une antes de *, por lo que sabemos que *[] indica una matriz de poitners.

Por lo tanto, dado

void (*func)(int(*[ ])()); 

lo rompemos la siguiente manera:

 func     -- func 
     *func     -- is a pointer 
    (*func)(   )  -- to a function taking 
    (*func)( [ ] )  -- an array 
    (*func)( *[ ] )  -- of pointers 
    (*func)( (*[ ])())  -- to functions taking 
           --  an unspecified number of parameters 
    (*func)(int(*[ ])())  -- returning int 
void (*func)(int(*[ ])()); -- and returning void 

Lo que esto podría ser en la práctica sería algo así como lo siguiente:

/** 
* Define the functions that will be part of the function array 
*/ 
int foo() { int i; ...; return i; } 
int bar() { int j; ...; return j; } 
int baz() { int k; ...; return k; } 
/** 
* Define a function that takes the array of pointers to functions 
*/ 
void blurga(int (*fa[])()) 
{ 
    int i; 
    int x; 
    for (i = 0; fa[i] != NULL; i++) 
    { 
    x = fa[i](); /* or x = (*fa[i])(); */ 
    ... 
    } 
}  
... 
/** 
* Declare and initialize an array of pointers to functions returning int 
*/ 
int (*funcArray[])() = {foo, bar, baz, NULL}; 
/** 
* Declare our function pointer 
*/ 
void (*func)(int(*[ ])()); 
/** 
* Assign the function pointer 
*/ 
func = blurga; 
/** 
* Call the function "blurga" through the function pointer "func" 
*/ 
func(funcArray); /* or (*func)(funcArray); */ 
+1

+1 para tratar de explicar cómo leer tales expresiones y ejemplos. –

+0

+1, nice one :) –

+0

+1 para el bloque de análisis al principio. ¡Bonito! –

2

Geordi es un bot C++, lo que permite entrenar esto:

<litb> geordi: {} void (*func)(int(*[ ])()); 
<litb> geordi: -r << ETYPE_DESC(func) 
<geordi> lvalue pointer to a function taking a pointer to a pointer to a nullary function 
     returning an integer and returning nothing 

Se pueden hacer muchas cosas útiles, como mostrar todos los parámetros-declaraciones (Esto, de hecho, es sólo coincidencia de nombres de primas C++ regla gramatical):

<litb> geordi: show parameter-declarations 
<geordi> `int(*[ ])()`. 

Vamos a hacerlo en la dirección opuesta:

<litb> geordi: {} int func; 
<litb> geordi: make func a pointer to function returning void and taking array of pointer to 
     functions returning int 
<litb> geordi: show 
<geordi> {} void (* func)(int(*[])()); 

Ejecuta todo lo que le dé, si lo solicita. Si usted está capacitado, sino simplemente olvidado algunas de las reglas paréntesis de miedo, también se puede mezclar C++ y descripciones de los tipos de estilo Geordi:

<litb> geordi: make func a (function returning void and taking (int(*)()) []) * 
<geordi> {} void (* func)(int(*[])()); 

Que se diviertan!

Cuestiones relacionadas