2012-04-13 30 views
7

¿Es posible usar expresiones de función en C? Por ejemplo, tengo el siguiente fragmento de código (dentro de la función main):¿C soporta expresiones de función?

void print_line(char *data) { 
    printf("%s\n", data); 
} 

// print all elements in my_list 
list_foreach(&my_list, print_line); 

me gustaría hacer algo como esto en su lugar:

list_foreach(&my_list, void (char *data) { 
    printf("%s\n", data); 
}); 

se parece en algo que es posible en C?

+0

No me malinterpreten, pero es por eso que me encanta C++, ¡esto le da esto y más por un precio más barato que C! – AraK

+1

@AraK: ¿Por un precio más bajo que C? ¿Qué significa "más barato" aquí? La forma de C++ es probablemente más lenta, ¿no? – thejh

+1

Más barato aquí significa que el compilador puede colapsar la abstracción para obtener el máximo rendimiento. Compare, por ejemplo, el uso de un funtor (o lambda), con el uso de indicadores de función. La introducción de alias no ayuda mucho a producir el mejor código. – AraK

Respuesta

7

En una palabra, No. Al menos no en una sintaxis similar a Javascript. Los punteros de función son lo más cerca que puede llegar. Hay muy poca diferencia entre los dos sintácticamente. Si está buscando el comportamiento de cierres o funciones internas, definitivamente no los verá pronto.

1

Definitivamente nada que ver con bloques Objective-C, cierres, etc. Pero, ¿qué ocurre con el uso de punteros de función en su lugar?

+1

Eso es lo que estaba haciendo en su primer fragmento de código. – Chuck

+0

@Chuck hmm ... en realidad sí. –

4

No en la norma C, no. Apple ha introducido una característica llamada bloques que le permitirá hacer esto y se ha enviado para su estandarización, pero aún no está allí (si alguna vez lo logrará). la sintaxis de Apple se ve así:

list_foreach(my_list, ^(char *data) { 
    printf("%s\n", data); 
}); 

Se trata básicamente funciona la sintaxis de puntero con * sustituido por ^ (e inferencia para el tipo de retorno en las expresiones).

+0

Oh, eso suena interesante. Bueno, mientras no pueda usarlo en gcc, probablemente no lo use. :( – thejh

+0

¿Dónde puedo encontrarlo? ¿Es una extensión de gcc C para la arquitectura de Apple u otro compilador? – Jack

+0

@Jack: Está en el fork ahora no compatible de Apple de GCC y también está en Clang (http://clang.llvm.org) , que tiene a Apple como su principal patrocinador corporativo. (Si usa Clang, creo que querrá pasar el indicador -fblocks para habilitar la extensión de idioma). – Chuck

2

No se puede hacer eso en la llanura C. Sin embargo, usted puede fingir con esta macro:

#define FOR_EACH(type, x, array, size, code) \ 
       do { \ 
         int i; \ 
         for (i=0; i<size; ++i) { \ 
         type x = array[i]; \ 
         code \ 
         } \ 
       } while(0) 

int main() 
{ 
    int arr[] = {0,1,2,3,4,5,6}; 
    FOR_EACH(int, x, arr, 7, printf("%d ", 1 << x);); 

    return 0; 
} 

EDITAR
He ejemplo para ser más portátil re-codificado - GCC sin utilizar bloques extensión.