¿Dos signos iguales en una línea?

¿Podría alguien explicar qué hace esto y cómo es un código C legal? Encontré esta línea en este código: http://code.google.com/p/compression-code/downloads/list , que es una implementación en C del algoritmo Vitter para la encoding adaptativa de Huffman

ArcChar = ArcBit = 0; 

De la función:

 void arc_put1 (unsigned bit) { ArcChar <<= 1; if( bit ) ArcChar |= 1; if( ++ArcBit < 8 ) return; putc (ArcChar, Out); ArcChar = ArcBit = 0; } 

ArcChar es un int y ArcBit es un unsigned char

El valor de la expresión (a = b) es el valor de b , por lo que puede encadenarlos de esta manera. También son asociativos por derecho, por lo que todo funciona.

Esencialmente

 ArcChar = ArcBit = 0; 

es (aproximadamente 1 ) lo mismo que

 ArcBit = 0; ArcChar = 0; 

ya que el valor de la primera asignación es el valor asignado, entonces 0 .

Con respecto a los tipos, aunque ArcBit es un ArcBit unsigned char el resultado de la tarea se ampliará a int .


1 No es exactamente lo mismo, sin embargo, como lo indica R .. en un comentario a continuación.

Establece ambas variables a cero.

 int i, j; i = j = 0; 

Lo mismo que escribir

 int i, j; j = 0; i = j; 

o escribiendo

 int i, j; i = 0; j = 0; 
 ArcChar = ArcBit = 0; 

La asignación es asociativa por la izquierda, por lo que es equivalente a:

 ArcChar = (ArcBit = 0); 

El resultado de ArcBit = 0 es el valor recién calculado, es decir, 0 , por lo que tiene sentido asignar ese 0 a ArcChar

Eso es sólo el encadenamiento del operador de asignación. La norma dice en 6.5.16 Assignment operators :

Un operador de asignación tendrá un lvalor modificable como su operando izquierdo. Un operador de asignación almacena un valor en el objeto designado por el operando izquierdo. Una expresión de asignación tiene el valor del operando izquierdo después de la asignación, pero no es un valor l. El tipo de una expresión de asignación es el tipo del operando izquierdo a menos que el operando izquierdo tenga un tipo calificado, en cuyo caso es la versión no calificada del tipo del operando izquierdo. El efecto secundario de actualizar el valor almacenado del operando izquierdo se producirá entre el punto de secuencia anterior y el siguiente.

Así que puedes hacer algo como:

 a=b=2; // ok 

Pero no esto:

 a=2=b; // error 

Asigna ArcBit a 0 , luego asigna ArcChar al valor de la expresión ArcBit = 0 (es decir, 0 )

Una operación de asignación (a = b) en sí misma devuelve un valor de r, que puede asignarse a otro valor de l; c = (a = b). Al final, tanto a como c tendrán el valor de b.

En algunos idiomas, las asignaciones son declaraciones : provocan que se realicen acciones, pero ellas mismas no tienen un valor. Por ejemplo, en Python 1 está prohibido escribir

 x = (y = 10) + 5 

porque la asignación y = 10 no se puede usar donde se espera un valor.

Sin embargo, C es uno de los muchos idiomas donde las asignaciones son expresiones : producen un valor, así como cualquier otro efecto que puedan tener. Su valor es el valor que se está asignando. La línea de código anterior sería legal en C.

El uso de dos signos de igual en una línea se interpreta así:

 ArcChar = (ArcBit = 0); 

Es decir: ArcChar asignar el valor de ArcBit = 0 , que es 0 , por lo que ambas variables terminan siendo 0 .


1 x = y = 0 es realmente legal en Python, pero se considera un caso especial de la statement de asignación, y tratar de hacer algo más complicado con las tareas fracasará.

Puede hacer esto: http://en.wikibooks.org/wiki/C_Programming/Variables

Además,

[a int] = 0; es posible.

[a char] = 0; es posible también

arcbit y arcchar es igual a 0.

La asignación en C es una expresión, no una statement. También puede asignar libremente valores de diferentes tamaños (caracteres sin signo a int y viceversa). Bienvenido al lenguaje de progtwigción C 🙂

Como dijo Hasturkun, esto se debe a la asociatividad del operador orden C Precedencia y asociatividad del operador