2012-06-06 9 views
8

Tengo dificultades para entender lo que significa la siguiente declaración. ¿Es esta declaración estándar?¿Qué es double * (* p [3]) (void * (*)()); ¿media?

double* (*p[3]) (void* (*)()); 

¿Alguien me puede ayudar a comprender el significado de esta declaración?

+1

Estoy contento de caminar en el mundo Java ... –

+7

... en lugar de correr en el mundo C? ;-) –

+0

Oli Charlesworth brindó una respuesta genéricamente útil. No cierres – DevSolar

Respuesta

9

Regla para la lectura de las declaraciones peludas: encontrar el identificador de más a la izquierda y avance hacia afuera , recordando que () y [] se unen antes de *, por lo T *a[N] es un vector de punteros a T, T (*a)[N] es un puntero a un array de T, T *f() es una función que devuelve un puntero a T y T (*f)() es un puntero a una función que devuelve T. Como un prototipo de función puede omitir nombres de parámetros, puede ver cosas como T *[N] o T (*)(). El significado es mayormente el mismo , solo pretende que hay un identificador de 0 de longitud.

Por lo tanto,

  p      -- p 
      p[3]     -- is a 3-element array 
     *p[3]     -- of pointers 
     (*p[3]) (   ) -- to functions 
     (*p[3]) (  (*)()) -- taking a pointer to a function 
     (*p[3]) ( * (*)()) -- returning a pointer 
     (*p[3]) (void* (*)()) -- to void 
     * (*p[3]) (void* (*)()) -- returning a pointer 
double* (*p[3]) (void* (*)()); -- to double 

Lo importante para llevar aquí es que se está declarando p como una matriz de ..., no es una función que devuelve ....

¿Cómo sería esa bestia en la práctica? Bueno, primero, necesitas tres funciones para señalar.Cada una de estas funciones tiene un único parámetro, que es un puntero a una función que devuelve un puntero para anular:

double *foo(void *(*)()); 
double *bar(void *(*)()); 
double *bletch(void *(*)()); 

double *(*p[3]) (void *(*)()) = {foo, bar, bletch}; 

cada uno de foo, bar y bletch sería llamar a la función pasó a ella y de alguna manera devolver un puntero a double.

También se quiere definir una o más funciones que satisfacen el tipo de parámetro para cada uno de foo, bar y bletch:

void *blurga() {...} 

por lo que si usted llama directamente foo, que se dice que como

double *pv; 
... 
pv = foo(blurga); 

para que pudiéramos imaginar una llamada como

double *pv = (*p[0])(blurga); 


1 - la diferencia es que en el contexto de una declaración parámetro de función, T a[] y T a[N] son idénticos a T *a; en los tres casos, a es un puntero aT, no una matriz de T. Tenga en cuenta que esto es solo verdadero en una declaración de parámetro de función. Por lo tanto, T *[] será idéntico a T **.

+0

muchas gracias! – Nick

10

Sólo tiene que utilizar http://cdecl.org:

declarar p como matriz de 3 de puntero a la función (puntero a función que devuelve un puntero a void) volviendo puntero a duplicar

Para obtener más información, consulte este artículo de MSDN : Interpreting more complex declarators.

Pero typedefs ayudarían:

typedef void *(*foo)();   // foo is a function-pointer type 
typedef double *(*bar)(foo); // bar is also a function-pointer type 
bar p[3]; 

(Obviamente, utilizar nombres apropiados en lugar de foo y bar!)

+2

Nunca había visto ese sitio antes de +1 –

+0

Tenga en cuenta que también puede obtener 'cdecl' como una herramienta de línea de comandos . –

+1

+1 para vincular la fuente de tu sabiduría en lugar de hacer que parezca que la has conjurado tú mismo. ;-) – DevSolar

2

Su p es una matriz de 3 punteros a una función que devuelve un double puntero, y tomando como argumento un puntero a otra función que devuelve un puntero void y que no toma argumentos.

Pero, no use esta sintaxis, intente usar typedef en su lugar.

+0

+1, porque para mí es la descripción más clara – Nick

+0

Yo también, pero me gusta el enlace de Oli que "proverbialmente me enseñó a pescar" :) –

1

Es una matriz (de tamaño 3) de punteros a funciones que devuelve el puntero al doble y toma otro puntero a la función como argumento.

Tipo de función cuyo puntero puede ser almacenado en la matriz: double *(func)(void* (*)())
Tipo de función cuyo puntero se puede pasar como argumento para func: void *(func1)(void)

+0

+1 porque esto es la descripción más fácil de entender (para mí). – ArjunShankar

Cuestiones relacionadas