开发者

Two Equal Signs in One Line?

Could someone please explain what this does and how it is legal C code? I found this line in this code: http://code.google.com/p/compression-code/downloads/list, which is a C implementation of the Vitter algorithm for Adaptive Huffman Coding

ArcChar = ArcBit = 0;

From the function:

void arc_put1 (unsigned bit)
{
    ArcChar <<= 1;

    if( bit )
        ArcChar |= 1;

    if( ++ArcBit < 8 )
        return;开发者_开发百科

    putc (ArcChar, Out);
    ArcChar = ArcBit = 0;
}

ArcChar is an int and ArcBit is an unsigned char


The value of the expression (a = b) is the value of b, so you can chain them this way. They are also right-associative, so it all works out.

Essentially

ArcChar = ArcBit = 0;

is (approximately1) the same as

ArcBit = 0;
ArcChar = 0;

since the value of the first assigment is the assigned value, thus 0.

Regarding the types, even though ArcBit is an unsigned char the result of the assignment will get widened to int.


1   It's not exactly the same, though, as R.. points out in a comment below.


ArcChar = ArcBit = 0;

The assignment is left-associative, so it's equivalent to:

ArcChar = (ArcBit = 0);

The result of ArcBit = 0 is the newly-assined value, that is - 0, so it makes sense to assign that 0 to ArcChar


It sets both variables to zero.

int i, j;
i = j = 0;

The same as writing

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

or writing

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


That is just chaining of the assignment operator. The standard says in 6.5.16 Assignment operators:

An assignment operator shall have a modifiable lvalue as its left operand. An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue. The type of an assignment expression is the type of the left operand unless the left operand has qualified type, in which case it is the unqualified version of the type of the left operand. The side effect of updating the stored value of the left operand shall occur between the previous and the next sequence point.

So you may do something like:

a=b=2; // ok

But not this:

a=2=b; // error


An assignment operation (a = b) itself returns an rvalue, which can be further assigned to another lvalue; c = (a = b). In the end, both a and c will have the value of b.


It assigns ArcBit to 0, then assigns ArcChar to the value of the expression ArcBit = 0 (ie. 0)


In some languages, assignments are statements: they cause some action to take place, but they don't have a value themselves. For example, in Python1 it's forbidden to write

x = (y = 10) + 5

because the assignment y = 10 can't be used where a value is expected.

However, C is one of many languages where assignments are expressions: they produce a value, as well as any other effects they might have. Their value is the value that is being assigned. The above line of code would be legal in C.

The use of two equals signs on one line is interpreted like this:

ArcChar = (ArcBit = 0);

That is: ArcChar is beging assigned the value of ArcBit = 0, which is 0, so both variables end up being 0.


1 x = y = 0 is actually legal in Python, but it's considered a special-case of the assignment statement, and trying to do anything more complicated with assignments will fail.


Assignment in C is an expression, not statement. Also you can freely assign values of different size (unsigned char to int and vice versa). Welcome to C programming language :)


You can do this: http://en.wikibooks.org/wiki/C_Programming/Variables

Moreover,

[a int] = 0; is possible.

[a char] = 0; is possible too.

arcbit and arcchar equals 0.


As Hasturkun said, this is due to operator associativity order C Operator Precedence and Associativity

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜