Esto (tenga en cuenta el operador de coma ):
#include <iostream>
int main() {
int x;
x = 2, 3;
std::cout << x << "\n";
return 0;
}
salidas 2 .
Sin embargo, si usa return
con el operador de coma, esto:
#include <iostream>
int f() { return 2, 3; }
int main() {
int x;
x = f();
std::cout << x << "\n";
return 0;
}
salidas 3 .
¿Por qué el operador de coma se comporta de manera diferente con return
?
Respuestas:
Según la precedencia del operador , el operador coma tiene una precedencia menor que
operator=
, por lo quex = 2,3;
es equivalente a(x = 2),3;
. (La precedencia del operador determina cómo se vinculará el operador a sus argumentos, más estrictos o más flexibles que otros operadores según sus precedentes).Tenga en cuenta que la expresión de coma está
(x = 2),3
aquí, no2,3
.x = 2
se evalúa al principio (y se completan sus efectos secundarios), luego se descarta el resultado, luego3
se evalúa (no hace nada de hecho). Por eso el valor dex
es2
. Tenga en cuenta que3
es el resultado de toda la expresión de coma (es decirx = 2,3
), no se utilizará para asignarx
. (Cámbielo ax = (2,3);
,x
se le asignará con3
).Para
return 2,3;
la expresión coma es2,3
,2
se evalúa entonces su resultado se descarta, y luego3
se evalúa y se devuelve como el resultado de toda la expresión de coma, que es devuelto por la instrucción de retorno más tarde.Información adicional sobre Expresiones y declaraciones
x = 2,3;
es una declaración de expresión ,x = 2,3
es la expresión aquí.return 2,3;
es la declaración de salto ( declaración de retorno ),2,3
es la expresión aquí.fuente
for
bucles cuando, extrañamente, puede hacer que el código sea más claro en cálculos numéricos.i += 1, j += 2
en un bucle for. Alguien decidió que la gramática de C ++ (o más bien la gramática de C, ya que esta parte se copió de allí) ya es lo suficientemente complicada sin intentar definir que la precedencia de la coma es más alta que la asignación cuando escribe, ¡x = 2, 3
pero más baja cuando escribex = 2, y = 3
!El operador de coma (también conocido como separación de expresión ) se evalúa de izquierda a derecha. Entonces
return 2,3;
es equivalente areturn 3;
.La evaluación de
x = 2,3;
se(x = 2), 3;
debe a la precedencia del operador . La evaluación sigue siendo de izquierda a derecha y toda la expresión tiene el valor 3 con el efecto secundario dex
asumir el valor 2.fuente
return 2,3
yreturn (2,3)
son iguales. Creí que lo primero debería ser(return 2),3
.return 2
es una declaración (como por ejemplo, las formadas porfor,while,if
), no una expresión. No se puede escribir, por ejemplo,f(return 2)
o2+return 2
. Entonces,(return 2),3
es sintácticamente inválido.return 2, 3
ser interpretado como(return 2), 3
.return
solo puede ocurrir en los siguientes casos: (a)return
expression_opt;
, y (b)return
braced-init-list;
.Esta declaración:
x = 2,3;
está compuesto por dos expresiones :
> x = 2 > 3
Dado que la precedencia del operador ,
=
tiene más precedencia que la coma,
, por lo quex = 2
se evalúa y después3
. Entoncesx
será igual a2
.En el
return
lugar:int f(){ return 2,3; }
La sintaxis del idioma es:
return <expression>
La nota
return
no es parte de la expresión.Entonces, en ese caso, las dos expresiones que se evaluarán serán:
> 2 > 3
Pero solo
3
se devolverá el segundo ( ).fuente
<expression>
como explícitamente opcional (desde una perspectiva gramatical).x=2,3
. Ambos literales2
y3
están en la parte inferior del árbol de análisis, al igual que el identificadorx
. Todas estas son expresiones válidas individualmente. Medios de prioridad de operadores que=
se produce menor en el árbol de análisis, y combina las dos expresionesx
y2
en el cuarto de expresiónx=2
. Finalmente, la quinta expresión está formada por el operador de coma que une sus dos ladosx=2
y3
. Sin embargo, afirma incorrectamente que la precedencia de los operadores determina el orden de evaluación. No es así. El orden de evaluación se determina mediante reglas de secuenciación.Intente aplicar el enfoque simplista resaltando la precedencia entre paréntesis:
( x = 2 ), 3;
return ( 2, 3 );
Ahora podemos ver el operador binario "," trabajando de la misma manera en ambos, de izquierda a derecha.
fuente
x = 2, 3
es en sí mismo una expresión, mientras que parareturn
lo esreturn <expression>
. Entonces los lees como(x = 2, 3)
y(2, 3)
.