2010-02-12 19 views
5

int * (*) (* int, int * (*)())tipo de int * (*) (* int, int * (*)())

me gustaría saber qué tipo es? , alguien puede dar un ejemplo de una declaración usando este tipo.

cualquier ayuda sería genial.

gracias.

+1

¿Qué idioma es ese par? C++? –

+1

Supuse que era C y lo etiqueté como tal. –

+0

guau, eso es bastante sádico ... –

Respuesta

19

Es un puntero a función que devuelve int* y acepta int* y puntero a función que devuelve int* (y acepta sin definir parámetros; ver comentarios).

Algunos ejemplos (no se ve muy bien, es sólo construido para contener la declaración mencionada):

#include <stdio.h> 

static int a = 10; 
int* f1() { 
    return &a; 
} 

static int b; 
int* f2(int *j, int*(*f)()) { 
    b = *j + *f(); 
    // this is just for demonstrational purpose, such usage 
    // of global variable makes this function not thread-safe 
    return &b; 
} 


int main(int argc, char *argv[]) { 
    int * (*ptr1)(); 
    int * (*ptr2) (int * , int * (*)()); 
    ptr1 = f1; 
    ptr2 = f2; 

    int i = 42; 
    int *pi = ptr2(&i, ptr1); 
    printf("%d\n", *pi); 

    return 0; 
} 

// prints 52 
+6

Estrictamente, ya que está etiquetado como C, acepta un número indefinido de parámetros. En C++ y la lista de parámetros vacíos significa que no hay parámetros, en C tendría que ser (nulo) para especificar eso. Arcano pero cierto ;-) – Clifford

+0

en realidad, creo que los parámetros no están especificados, suponiendo que esto es C. "(vacío)" no aceptaría ningún parámetro, como lo haría "()" en C++. – aib

0
typedef int* (*fptr)();  
int* foo(int* p1, fptr p2); 

Usted puede poner foo en ese tipo.

7

cdecl es su amigo:

$ cdecl explain 'int * (*x) (int * , int * (*)())' 
declare x as pointer to function (pointer to int, pointer to function returning pointer to int) returning pointer to int 
+11

sí, excepto que no funciona sin esa 'x' que ha agregado ya menos que comprenda la declaración en primer lugar, no sabría agregar la' x';) – ezpz

+1

Si no hay un identificador (que debería ser fácil de detectar), entonces puedes obtener 'cdecl' para explicarlo prefijándolo con' ('y sufijarlo con') x'. Luego dirá "lanzar x en ...' ", seguido de la explicación del tipo. – caf

2

Hmmm ... de acuerdo a cdecl.org que era un error de sintaxis - vamos a tratar

 
int * (*) (int *,int *(*)()) 
  • (int *, int ()()) - más interno (*)() - un puntero a la función int ()() - poi nter para funcionar sin parámetros, devolviendo el puntero a int
  • (int *, ...) - dos parámetros, uno de los cuales es un puntero a int, y el otro es puntero-a-función-sin-parámetros- return-pointer-to-int
  • (*) (...) - un puntero a la función con los parámetros
  • int * (*) (...) - un puntero a la función-retorno-puntero-a- int

Así: Es una función de puntero que tiene los dos parámetros que el primer parámetro es un puntero a int y el otro es puntero a la función-with-no-parámetros-volver-puntero-a -int, y su-return-pointer-to-int.

Editar: La declaración C que utilicé en ese sitio web - que no puso en un nombre de variable como en

 
int *(*x)(int *,int *(*)()) 

que volvió: declarar ax como puntero a la función (puntero a int , puntero a puntero de regresar a la función int) devolver el puntero a int

Espero que esto ayude, saludos, Tom.

1

Existe una técnica llamada "regla de derecha a izquierda" que puede ayudarlo a descifrar declaraciones complejas como estas. La regla funciona sustituyendo palabras clave en inglés por los atributos que aparecen en la declaración. Luego, cuando junte las palabras clave, la oración construida describirá la declaración.

He aquí los atributos y las palabras clave que se deben utilizar:

  • Cuando vea el atributo "función que devuelve" "()" el ​​uso de palabras clave
  • Cuando vea el atributo "[n]" uso palabra clave "matriz de n"
  • Cuando vea el atributo "*" el uso de palabras clave "puntero a"

Ahora aquí está la "regla derecha-izquierda":

  1. Comience con el identificador.
  2. Mire a la derecha de un atributo.
  3. Si no encuentra ninguno, mire a la izquierda.
  4. Una vez que se encuentra un atributo, sustituya su palabra clave en inglés.
  5. Continúa sustituciones de derecha a izquierda mientras trabajas para salir.
  6. Detener cuando haya alcanzado el tipo de datos en la declaración.

He aquí algunos ejemplos:

int n[10]; 

El identificador es n. El atributo de la derecha es [10], por lo tanto, utilice la palabra clave "matriz de 10". Luego, llega al tipo de datos int. Por lo tanto,

n es una "matriz de 10 enteros".

int *n[10]; 

El identificador es n. El atributo de la derecha es [10], por lo tanto, utilice la palabra clave "matriz de 10". Mire a la izquierda y el atributo es * así que use la palabra clave "puntero a". No hay más atributos. Todo lo que queda es el tipo de datos, que es int. Junte las palabras clave para obtener:

n es una "matriz de 10 punteros a enteros".

int (*pf)(); 

El identificador es pf. No hay ningún atributo inmediatamente a la derecha de pf. A la izquierda de pf es *. Entonces, la primera palabra clave es "apuntando a". A continuación, vuelva a la derecha y el atributo es (). Eso significa que la siguiente palabra clave es "función que devuelve". Ahora regrese a la izquierda al tipo de datos int. Poner las palabras clave en conjunto para obtener:

pf es un "puntero a una función que devuelve un int"

int *(*pf)(); 

pf es el identificador. No hay atributos a la derecha de pf. A la izquierda está *, por lo que la primera palabra clave es "puntero a". Volver a la derecha es (), por lo que la siguiente palabra clave es "función que devuelve". Volver a la izquierda es *, por lo que la siguiente palabra clave es "puntero a". A continuación, llegue al tipo de datos int:

pf es un "puntero a una función que devuelve un puntero a un int".

Este próximo ejemplo es como el anterior, pero esta vez hay algunos argumentos para la función pf. Los argumentos son int *x y int *(*y)(). Debería poder describir cada uno de estos argumentos en función de todo hasta ahora. Y una vez que lo que usted será capaz de describir todo el asunto:

int *(*pf)(int *x, int *(*y)()); 

pf es un puntero a una función que devuelve un puntero a un int. pf toma dos argumentos. El primer argumento x es un puntero a un int. El segundo argumento y es un puntero a una función que devuelve un puntero a un int.

0

¡Tal declaración es realmente utilizada! Considere la función de señal de la biblioteca estándar de C:

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

la página del manual explica señal es equivalente a la siguiente versión typedef'd:

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

una función que toma dos argumentos, y int y una función sig_t, y que devuelve la antigua función sig.