2012-03-01 18 views
20

¿Por qué una expresión i = 2 devuelve 2? ¿Cuál es la regla en la que se basa?¿Qué devuelve una tarea?

printf("%d\n", i = 2); /* prints 2 */

estoy en el dominio C después de pasar mucho tiempo en Java/C#. Perdona mi ignorancia

Respuesta

12

La regla es devolver el operando de la derecha de = convertido al tipo de la variable a la que está asignado.

int a; 
float b; 
a = b = 4.5; // 4.5 is a double, it gets converted to float and stored into b 
// this returns a float which is converted to an int and stored in a 
// the whole expression returns an int 
+0

Podría dar una referencia?Oli Charlesworth dice que en C99 es el valor del operando de la izquierda, ¿entonces esto sería una diferencia con C++? – Benoit

+0

http://msdn.microsoft.com/en-us/library/b0zx90af(v=vs.80).aspx por ejemplo. – foxx1337

+0

Por lo tanto, esto está en contradicción con su respuesta (rvalue => lvalue, lado derecho => lado izquierdo). – Benoit

33

Se evalúa -2 porque así es como el estándar define. De C11 Standard, sección 6.5.16:

una expresión de asignación tiene el valor del operando de la izquierda después de la asignación

Es para permitir cosas como esta:

a = b = c; 

(aunque no hay algunos debaten si el código así es bueno o no).

Dicho sea de paso, este comportamiento se replica en Java (y apostaría que es lo mismo en C# también).

+0

gracias. Ok, pero no he visto a alguien usar eso en Java. – Nemo

+0

En general, estoy de acuerdo con esto cuando 'a' y' b' son realmente lo mismo, en lugar de simplemente tener el mismo valor. Utilizo el mismo razonamiento para decidir entre 'int presentValue, previousValue;' vs. 'int myAge; int myHeight; '. Los valores actuales y anteriores nunca deben tener diferentes tipos, mientras que puedo elegir usar un 'float' para mi altura en lugar de' int'. Solo otra capa de intención que puede ser capturada. – altendky

+0

Enlace actualizado por @SurajJain a C11. Lo que este constructo * también * permite es el (mucho más útil) 'if ((ptr = func())! = NULL)' ... – DevSolar

3
  1. Asignar el valor 2 a i
  2. Evaluar la variable i y mostrarlo
2

En C (casi) todos los expresiones tienen 2 cosas
1) un valor
2) un efecto secundario

El valor de la expresión

2 

es 2; su efecto secundario es "ninguno";

El valor de la expresión

i = 2 

es 2; su efecto secundario es "cambiar el valor en el objeto llamado i a 2";

+0

Totalmente * 50% * de posibles expresiones C son '(vacío)' seguido de otra expresión (para ciertos valores de "proporción de un conjunto infinito"). ¿Cuentan que tienen un valor, o no? ;-) –

+0

No, las expresiones '(void)' no tienen valor. Por ejemplo: la expresión 'libre (puntero)' no tiene valor. – pmg

+0

@pmg: 'free (puntero)' de hecho no tiene ningún valor, pero no es inútil, aunque muchos programadores consideran que no vale la pena el esfuerzo. – chqrlie

1

Considera la expresión primero y luego imprime la variable más a la izquierda.

ejemplo:

int x,y=10,z=5; 
printf("%d\n", x=y+z); // firstly it calculates value of (y+z) secondly puts it in x thirdly prints x 

Nota:

x++ se Postfix y ++x es tan prefijo:

int x=4 , y=8 ; 
printf("%d\n", x++); // prints 4 
printf("%d\n", x); // prints 5 
printf("%d\n", ++y); // prints 9 
+0

* sabes que los cálculos se hacen de derecha a izquierda. * No realmente. Los cálculos se pueden hacer en cualquier orden, incluidas las asignaciones. Los valores de argumento se calculan antes de llamar a la función, pero esa es la única suposición que puede hacer. Lo importante de entender es el concepto de punto de secuencia. – chqrlie

+0

¡Eres el hombre correcto! pero me refiero a los simples como x = y + z, edité la respuesta, gracias. –