2012-05-25 8 views
31

Tenga en cuenta las siguientes typedefs:C sintaxis para funciones que devuelven punteros de función

typedef int (*f1)(float); 
typedef f1 (*f2)(double); 
typedef f2 (*f3)(int); 

f2 es una función que devuelve un puntero a función. Lo mismo con f3, pero el tipo de función, el puntero al que devuelve f3, es f2. ¿Cómo puedo definir f3 sin los typedefs? Sé que los typedefs son la manera más limpia y fácil de entender para definir f3. Sin embargo, mi intención aquí es comprender mejor la sintaxis C.

+2

C o C++? Porque C++ tiene algunas formas más fáciles de expresar tales cosas. – Puppy

+7

[cdecl es tu amigo] (http://cdecl.ridiculousfish.com/?q=declare+f3+as+pointer+to+function+%28int%29+returning++pointer+to+function+%28double%29+ return + puntero + a + función +% 28float% 29 + return + int) –

+0

cdecl.org solo traduce de c-sintaxis a inglés. No es muy útil ir por el otro lado, ya que tienes que redactar tu declaración perfectamente en la forma que espera, y no es así como funciona el inglés o cualquier otro lenguaje natural. –

Respuesta

105

de inicio con su declaración de f1:

int (*f1)(float); 

¿Quieres f2 ser un puntero a una función que devuelve f1, por lo que sustituir f1 en la declaración anterior con la declaración de f2:

int (*  f1 )(float); 
      | 
     +-----+-----+ 
     |   | 
     v   v 
int (*(*f2)(double))(float); 

La declaración se lee como

 f2     -- f2 
     *f2     -- is a pointer 
     (*f2)( )   -- to a function 
     (*f2)(double)   -- taking a double parameter 
    *(*f2)(double)   -- returning a pointer 
    (*(*f2)(double))( ) -- to a function 
    (*(*f2)(double))(float) --  taking a float parameter 
int (*(*f2)(double))(float) --  returning int 

se repite el proceso para f3:

int (*(* f2 )(double))(float); 
      | 
     +---+----+ 
     |  | 
     v  v 
int (*(*(*f3)(int))(double))(float); 

que dice lo

  f3       -- f3 
     *f3       -- is a pointer 
     (*f3)( )      -- to a function 
     (*f3)(int)      -- taking an int parameter 
     *(*f3)(int)      -- returning a pointer 
     (*(*f3)(int))( )   -- to a function 
     (*(*f3)(int))(double)   --  taking a double parameter 
    *(*(*f3)(int))(double)   --  returning a pointer 
    (*(*(*f3)(int))(double))( ) --  to a function 
    (*(*(*f3)(int))(double))(float) --  taking a float parameter 
int (*(*(*f3)(int))(double))(float); --  returning int 
+9

+1, ya que esto realmente responde a la pregunta original, que era sobre la sintaxis correcta en C ... – Macmade

+9

Cuando su martillo es C, todo alrededor parece un pulgar ... – Spook

+1

Esta respuesta debe ser impresa en masa y distribuida en escuelas de ingeniería informática, es la forma más simple y mejor de entender la sintaxis de la declaración de los indicadores de función, ¡gracias John Bode! –

7

Al igual que con typedef, solo coloca la definición de su función en lugar de su nombre.

Así es como f2 se vería así:

typedef int (*(*f2)(double))(float); 

Usted puede hacer f3 como un ejercicio, ya que estoy asumiendo que esto es tarea;)

+6

El Sr. downvoter necesita mejores habilidades de análisis C. – Blindy

+0

La respuesta que das está disponible con una búsqueda en Google. Sin embargo, la sintaxis para más de un nivel (puntero de función de retorno de puntero a función de retorno de función) no es muy fácil de encontrar. Y la referencia de la tarea no estaba justificada. – keveman

+2

Es exactamente lo mismo, reemplace 'f2' en mi forma con su typedef' f3'. No estoy seguro de lo que quiere decir con la búsqueda de Google, su sintaxis básica de C ... – Blindy

12

En C++, el milagro de las plantillas puede hacer esta un poco más fácil.

#include <type_traits> 

std::add_pointer< 
    std::add_pointer< 
     std::add_pointer< 
      int(float) 
     >::type(double) 
    >::type(int) 
>::type wow; 
+3

+1 para el "wow" :-) –

+0

La pregunta era acerca de la sintaxis C, incluso si la publicación fue etiquetada con C++, por lo que no es relevante en mi humilde opinión ... Pero buena respuesta por cierto. :) – Macmade

+1

Esto es quizás más limpio que no utilizar ningún tipo de ayudas (ni 'typedef' o' add_pointer'), pero el enfoque 'typedef' es aún más limpio (en mi humilde opinión). –

5

Just do not no. Se puede hacer, pero será muy confuso. Los Typedef están ahí para facilitar la escritura y la lectura de este código corto.

Una función f que no tiene argumentos y devuelve un puntero a función int (*)(float) probablemente sería algo así (no probado):

int (*f())(float); 

A continuación, el resto sólo tiene que seguir añadiendo entre paréntesis hasta que quede como Lisp.

+0

+1: Simplemente no lo hagas. La apariencia lispish de la respuesta de John Bode es 'nuff dijo. –

0

Uso std::function:

typedef std::function<int(float)> f1; 
typedef std::function<f1(double)> f2; 
typedef std::function<f2(int)> f3; 

o

typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3; 
4

aprender el the right-left rule:

La regla de "derecha-izquierda" es una regla totalmente regular para descifrar C declaraciones. También puede ser útil para crearlos.

Cuestiones relacionadas