2012-02-04 19 views
5

Estoy tratando de llamar a una función que toma un argumento, void(*)(void*, int, const char*), pero no puedo entender cómo pasar esos argumentos a la función.Punteros a la función C++/C que devuelven el vacío *

Ejemplo:

void ptr(int); 
int function(int, int, void(*)(int)); 

Estoy tratando de llamar a la función como esta:

function(20, 20, ptr(20)); 

Es esto posible?

+0

Gracias a todos, me di cuenta. Aprendí mucho sobre los punteros a las funciones de esta pregunta. De nuevo, muchas gracias! –

Respuesta

9

Está haciendo una cosa incorrectamente: está intentando invocar su función 'ptr' antes de invocar 'función'.Lo que se suponía que hacer es pasar sólo un puntero a 'PTR' e invocar 'PTR' usando puntero pasado de 'función' de esa manera:

void ptr(int x) 
{ 
    printf("from ptr [%d]\n", x); 
} 

int function(int a, int b , void (*func)(int)) 
{ 
    printf("from function a=[%d] b=[%d]\n", a, b); 
    func(a); // you must invoke function here 

    return 123; 
} 


void main() 
{ 
    function(10, 2, &ptr); 
    // or 
    function(20, 2, ptr); 
} 

que da:

from function a=[10] b=[2] 
from ptr [10] 
from function a=[20] b=[2] 
from ptr [20] 

que es lo que quería

para

function(20, 20, ptr(20)); 

a trabajar - que tendría que tener algo como:

// 'ptr' must return sth (int for example) 
// if you want its ret val to be passed as arg to 'function' 
// this way you do not have to invoke 'ptr' from within 'function' 
int ptr(int); 
int function(int, int , int); 
1

La sintaxis correcta para la llamada a la función es:

function(20,20, &ptr); 

Si se siente perdido, probar algunos tutorials, o this

+4

En realidad, puede dejar '&' apagado si quiere –

+0

@SethCarnegie ¿a qué compilador se refiere? Por lo que recuerdo, gcc no es muy amigable con esto. De todos modos, parece más obvio lo que intentas decir cuando agregas '&' (mi opinión). – Vyktor

+1

gcc maneja eso (no coloca el '&') bien, y es estándar C. – Mat

4

El truco habitual es utilizar un typedef a la firma:

typedef void signature_t (void*, int, const char*); 

Observe que sin el typedef la sintaxis es como una declaración de función. Declara signature_t como typedef para funciones, por lo que siempre utilizará punteros a signature_t en la práctica.

A continuación, puede declarar su función "de orden superior", como

int function (int, int, signature_t*); 

Ver también this reply.

+3

¿No es correcta la sintaxis para ese 'typedef void (signature_t) (void *, int, const char *)'? De todos modos +1 para la idea 'typedef' :) – Vyktor

+1

@Vyktor: Los paréntesis no son necesarios aquí. La sintaxis en la respuesta es correcta. – jpalecek

+0

Actualicé mi respuesta con un aviso explicando la sintaxis. –

1

A menos que estoy totalmente de malinterpretar el código, están tratando de pasar un puntero de función con un argumento haciendo

function(20, 20, ptr(20)); 

Eso es incorrecto e ilegal. Con el fin de pasar una función como un parámetro en otra función que tiene que seguir la siguiente sintaxis

function(20, 20, &ptr); 

or 

function(20, 20, ptr); 

A pesar de que lo recomiendo salir de la '&' para facilitar la lectura

0

No se puede pasar PTR (20) a esta función, porque solo puede pasar el puntero a la función, pero no el puntero con el argumento. Puede leer sobre funtores y le ayudará con ese problema. O la otra solución es cambiar la firma a

int function(int, int, void(*)(void)); 

Y escribir la función

void ptr_wrap(void) {ptr(20);} 

para que pueda llamar function(20, 20, ptr_wrap);. Pero los funtores pueden resolver este problema de una manera más elegante.

0

ptr(20) es el valor de retorno de ptr, cuando pasa 20 a él. Si desea pasar la función (y no su valor de retorno), debe escribir solo function(20,20,ptr);

Cuestiones relacionadas