valores una todas tipos retornan que llamar lenguaje las funciones funcion ejemplos como c associativity

una - tipos de funciones en lenguaje c



Asociatividad del operador de llamada de función en C (3)

Estaba repasando el tema de la asociatividad de los operadores C.

Allí me encontré con este hecho de que el operador de llamada a función () tiene una asociatividad de izquierda a derecha. Pero la asociatividad solo viene a jugar cuando múltiples operadores de la misma precedencia ocurren en una expresión. Pero no pude encontrar ningún ejemplo relacionado con el operador de llamada de función en el que la asociatividad juegue un papel crucial.

Por ejemplo, en la declaración a = f(x) + g(x); , el resultado depende del orden de evaluación y no de la asociatividad de las dos llamadas de función. De manera similar, la llamada f(g(x)) evaluará primero la función g() y luego la función f() . Aquí tenemos una llamada de función anidada y, nuevamente, la asociatividad no desempeña ningún papel.

Los otros operadores de C en este grupo de prioridad son el subíndice de matriz [] , postfix ++ y postfix -- . Pero no pude encontrar ningún ejemplo que involucre una combinación de estos operadores con () donde la asociatividad juega un papel importante en la evaluación de expresiones.

Entonces, mi pregunta es si la asociatividad de la llamada de función definida como de izquierda a derecha afecta alguna expresión en C? ¿Alguien puede dar un ejemplo donde la asociatividad del operador de llamada a función () sí importa en la evaluación de expresión?


Además de la respuesta de @GrzegorzSzpetkowski, también puede tener lo siguiente:

void foo(void) { } int main(void) { void (*p[1])(void); p[0] = foo; p[0](); return 0; }

Esto crea una matriz de punteros de función, por lo que puede utilizar el operador de subíndice de matriz con el operador de llamada de función.


Aquí hay un ejemplo, donde la asociatividad izquierda-derecha del operador de llamada de función es importante:

#include <stdio.h> void foo(void) { puts("foo"); } void (*bar(void))(void) // bar is a function that returns a pointer to a function { puts("bar"); return foo; } int main(void) { bar()(); return 0; }

La llamada a la función:

bar()();

es equivalente a:

(bar())();


La declaración que la aplicación de función asocia a la izquierda es completamente redundante en la definición del lenguaje C. Esta "asociatividad" está implícita en el hecho de que una lista de argumentos de función aparece a la derecha de la expresión de la función en sí misma y debe estar entre paréntesis . Esto significa que para una expresión de función dada, nunca puede haber ninguna duda sobre el alcance de su lista de argumentos: se extiende desde el paréntesis de apertura obligatorio después de la expresión de la función hasta el paréntesis de cierre correspondiente.

La expresión de función (que a menudo es solo un identificador, pero puede ser más complicada) podría ser una llamada de función (simple), como en f(n)(1,0) . (Por supuesto, esto requiere que el valor devuelto por f(n) sea ​​algo que luego pueda llamarse con la lista de argumentos (1,0) , para la cual C tiene algunas posibilidades y C ++ mucho más, pero estas son consideraciones semánticas que solo vienen para jugar después del análisis, por lo que deben ignorarse para la discusión de la asociatividad.) Esto significa que la regla de sintaxis para llamadas de función es recursiva por la izquierda (la parte de la función puede ser una llamada de función); esto puede formularse diciendo "llamadas de función asociadas a la izquierda", pero el hecho es obvio. Por el contrario, la parte derecha (lista de argumentos) no puede ser una llamada de función (simple) debido a los paréntesis requeridos, por lo que no puede haber una recursión correcta.

Por ejemplo, considere (a)(b)(c) (donde coloco un paréntesis redundante para sugerir simetría y posible ambigüedad). Aquí en sí mismo (b)(c) podría tomarse la llamada de b (entre paréntesis redundante) con el argumento c ; sin embargo, tal llamada no puede interpretarse como el argumento de a , ya que eso requeriría paréntesis adicionales como en (a)((b)(c)) . Entonces, sin ninguna mención de asociatividad, está claro que (a)(b)(c) solo puede significar que a se llama con el argumento b , y el valor resultante se llama con el argumento c .