2012-02-17 14 views
22
#include<stdio.h> 
#include<stdlib.h> 

int fun1() 
{ 
    printf("I am fun1."); 
    return 0; 
} 

int fun2(int fun()) 
{ 
    fun(); 
    return 0; 
} 

int main() 
{ 
    fun2(fun1); 
    return 0; 
} 

Se puede ejecutar el programa anterior. En lo que a mí respecta, puedo entender int fun2(int (*fun)()), pero no sé cómo funciona int fun2(int fun()). Gracias.Acerca de los punteros a las funciones en las declaraciones de funciones

+3

Esto es válido en C, C99 estricto, C++ 03 y C++ 11. Y estoy sorprendido –

Respuesta

32

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

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

Una conversión más famiiar sucede en el caso de la matriz cuando se declara como parámetro de la función. Por ejemplo, si has esto:

int f(int a[100]); 

Incluso en este caso 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 tipo de matriz se convierte en la función de puntero tipo, y el tipo de puntero, respectivamente, es porque el estándar no permite que la función y la matriz se pasen a una función, tampoco se puede devolver la función y la matriz de una función. En ambos casos, decaen en su versión de puntero.

El C++ 03 Standard dice en §13.1/3 (y es igual en C++ 11 también),

declaraciones de parámetros que difieren solamente en que uno es un tipo de función y el otro es un puntero al mismo tipo de función son equivalente. 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í:

+2

+1 Para observar la similitud con las matrices. – asaelr

+4

Buena respuesta. Además, ¡no tenía idea de que esto funcionó! –

+0

gracias. he estado confundido por un largo tiempo. – dragonfly

6

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

-3

Mirando a la misma en un nivel inferior (y en una arquitectura basada en x86):

int fun2(int fun()) 

int diversión() 's dirección se empuja en la pila y se pasa a fun2 (función).

int fun2(int (*fun)()) 

int diversión() 's puntero dirección se empuja en la pila y se pasa a la función fun2().

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

+0

¿Cuál es la diferencia entre la dirección de una función y la dirección del puntero de una función? O bien, ¿qué quiere decir con la frase "dirección del puntero"? –

+0

Por dirección de puntero me refiero a *** p *. Es decir, la dirección del puntero a la dirección de la función. – m0skit0

+0

¿Qué quiere decir con _ ** p_? ¿Eso se ve como algo que se puede quitar dos veces y se desreferencia dos veces? La dirección de un puntero a una función sería algo así como: 'int (* fnptr)(); int (** p)() = &fnptr; 'pero nada de eso aparece en la pregunta? –

3

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. Véase el párrafo C estándar:

(C99, 6.7.5.3p8) "Una declaración de un parámetro como '' función que devuelve el tipo '' se ajustará a '' puntero a una función que devuelve el tipo '', como en 6.3 .2.1. "

Cuestiones relacionadas