2011-08-30 18 views
14

¿Podría alguien explicar qué hace esto y cómo es el código C legal? He encontrado 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 Adaptive Huffman Coding¿Dos signos iguales en una línea?

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

Respuesta

18

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

Esencialmente

ArcChar = ArcBit = 0; 

es (aproximadamente) el mismo que

ArcBit = 0; 
ArcChar = 0; 

ya que el valor de la primera assigment es el valor asignado, por lo tanto 0.

En cuanto a los tipos, aunque ArcBit es unsigned char, el resultado de la asignación se ampliará a int.


No es exactamente la misma, sin embargo, como R .. señala en un comentario más abajo.

+0

Gracias para explicar el tema de tipo de datos. – user807566

+6

No es lo mismo que la versión de dos instrucciones, que tiene un punto de secuencia entre las dos asignaciones. Esto puede marcar la diferencia si los dos lvalues ​​son '* ptr1' y' * ptr2' y apuntan al mismo lugar (en el que la versión de declaración única tendría UB) o si ambos son 'volátiles' y te importa el orden en que se realizan las asignaciones. –

+0

Ah, maldición. Y ahora no puedo borrar: -/ – Joey

3

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

3

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

+0

Interesante. No me di cuenta de que devolvió un valor. Gracias. – user807566

4

Establece ambas variables a cero.

int i, j; 
i = j = 0; 

lo mismo que escribir

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

o escribir

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

En algunos idiomas, las asignaciones son declaraciones : provocan algún tipo de acción se lleve a cabo, pero no lo hacen tener un valor en sí mismos. Por ejemplo, en Python está prohibido escribir

x = (y = 10) + 5 

ya que la asignación y = 10 no se puede utilizar cuando 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 le asigna. 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 se beging asigna el valor de ArcBit = 0, que es 0, por lo que ambas variables terminan siendo 0.


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

+0

Buena explicación. Gracias. – user807566

5
ArcChar = ArcBit = 0; 

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

ArcChar = (ArcBit = 0); 

El resultado de ArcBit = 0 es el valor assined recientemente, que se - 0, así que tiene sentido para asignar a esa 0-ArcChar

1

asignación en C es una expresión, no comunicado. También puede asignar libremente valores de diferentes tamaños (char sin signo a int y viceversa). Bienvenido al lenguaje de programación C :)

5

Eso es solo un encadenamiento del operador de asignación. El estándar dice en 6.5.16 Assignment operators:

Un operador de asignación debe tener un valor l modificable como su operando izquierdo. Un operador de asignación almacena un valor en el objeto designado por el operando de la izquierda. 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 de el operando izquierdo. El efecto secundario de actualizar el valor almacenado del operando izquierdo será entre el punto de secuencia anterior y el siguiente.

Por lo que puede hacer algo como:

a=b=2; // ok 

Pero no esto:

a=2=b; // error 
Cuestiones relacionadas