Acerca de los punteros a las funciones en declaraciones de funciones

#include #include int fun1() { printf("I am fun1."); return 0; } int fun2(int fun()) { fun(); return 0; } int main() { fun2(fun1); return 0; } 

El progtwig anterior puede ejecutarse. En lo que a mí respecta, puedo entender int fun2(int (*fun)()) , pero no sé cómo funciona int fun2(int fun()) . Gracias.

Cuando escribes int fun2(int fun()) , el parámetro int fun() convierte en int (*fun)() , se vuelve exactamente equivalente a esto:

 int fun2(int (*fun)()); 

Una conversión más familiar ocurre en el caso de una matriz cuando la declaras como parámetro de función. Por ejemplo, si tienes esto:

 int f(int a[100]); 

Incluso aquí el tipo de parámetro se convierte en int* , y se convierte en esto:

 int f(int *a); 

La razón por la cual el tipo de función y el tipo de matriz se convierten en tipo de puntero a función y tipo de puntero, respectivamente, es porque el Estándar no permite que la función y matriz pasen a una función, ni tampoco puede devolver función y matriz desde una función. En ambos casos, decaen en su versión de puntero.

El estándar C ++ 03 dice en §13.1 / 3 (y es lo mismo en C ++ 11 también),

Las declaraciones de parámetros que difieren solo en eso es un tipo de función y el otro es un puntero al mismo tipo de función son equivalentes . Es decir, el tipo de función se ajusta para convertirse en un puntero al tipo de función (8.3.5) .

Y una discusión más interesante está aquí:

  • Referencia a la syntax de la función – con y sin &

int fun2(int (*fun)()) e int fun2(int fun()) son exactamente iguales. Cuando declara un argumento de función a partir de un tipo de función, el comstackdor lo usa como si fuera un puntero al mismo tipo de función.

Estas dos definiciones de funciones son equivalentes en C:

  int fun2(int fun()) { ... } 

y

  int fun2(int (*fun)()) { ... } 

En la primera función, el parámetro se ajusta a un puntero de función. Ver párrafo estándar C:

(C99, 6.7.5.3p8) “La statement de un parámetro como ” función que devuelve tipo ” se ajustará a ” puntero al tipo de retorno de función ”, como en 6.3.2.1.”

Mirándolo en un nivel inferior (y en una architecture basada en x86):

 int fun2(int fun()) 

La dirección de int fun () se inserta en la stack y se pasa a la función fun2 ().

 int fun2(int (*fun)()) 

La dirección del puntero de int fun () se inserta en la stack y se pasa a la función fun2 ().

El resultado es el mismo, excepto que con el segundo, pasas la dirección de la diversión () por referencia, y en la primera la pasas por valor.