一条线上有两个相同的标志?

有人可以解释这是什么以及它是如何合法的C代码? 我在此代码中找到了这一行: http : //code.google.com/p/compression-code/downloads/list ,这是用于自适应霍夫曼编码的Vitter算法的C实现

ArcChar = ArcBit = 0; 

从function:

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

ArcChar是一个int ,ArcBit是一个unsigned char

表达式(a = b)的值是b的值,因此您可以通过这种方式链接它们。 它们也是正确联想的,所以一切顺利。

实质上

 ArcChar = ArcBit = 0; 

是(大约1 )相同

 ArcBit = 0; ArcChar = 0; 

因为第一个分配的值是指定值,因此为0

关于类型,即使ArcBitunsigned char ,赋值的结果也会扩展为int


1但是,正如R ..在下面的评论中指出的那样,它并不完全相同

它将两个变量都设置为零。

 int i, j; i = j = 0; 

和写作一样

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

或写作

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

赋值是左关联的,所以它相当于:

 ArcChar = (ArcBit = 0); 

ArcBit = 0的结果是新确定的值,即0 ,因此将该0分配给ArcChar

这只是赋值运算符的链接。 该标准在6.5.16 Assignment operators说:

赋值运算符应具有可修改的左值作为其左操作数。 赋值运算符将值存储在左操作数指定的对象中。 赋值表达式在赋值后具有左操作数的值,但不是左值。 赋值表达式的类型是左操作数的类型,除非左操作数具有限定类型,在这种情况下,它是左操作数类型的非限定版本。 更新左操作数的存储值的副作用应发生在前一个和下一个序列点之间。

所以你可以这样做:

 a=b=2; // ok 

但不是这个:

 a=2=b; // error 

它将ArcBit指定为0 ,然后将ArcChar指定给表达式ArcBit = 0 (即0 )的值

赋值运算(a = b)本身返回一个rvalue,可以进一步分配给另一个左值; c =(a = b)。 最后,a和c都将具有b的值。

在某些语言中,赋值是语句 :它们会导致某些操作发生,但它们本身没有值。 例如,在Python 1中禁止编写

 x = (y = 10) + 5 

因为在期望值的地方不能使用赋值y = 10

但是,C是分配是表达式的许多语言之一:它们产生一个值,以及它们可能具有的任何其他效果。 它们的值是指定的值。 上面的代码行在C中是合法的。

在一行上使用两个等号,解释如下:

 ArcChar = (ArcBit = 0); 

即: ArcChar正在分配ArcBit = 0的值,即0 ,因此两个变量最终都为0


1 x = y = 0在Python中实际上是合法的,但它被认为是赋值语句的特殊情况,并且尝试执行任何更复杂的赋值操作都将失败。

你可以这样做: http : //en.wikibooks.org/wiki/C_Programming/Variables

此外,

[a int] = 0; 是可能的。

[a char] = 0; 也有可能。

arcbit和arcchar等于0。

C中的赋值是表达式,而不是语句。 您也可以自由分配不同大小的值(unsigned char为int,反之亦然)。 欢迎使用C编程语言:)

正如Hasturkun所说,这是由于运营商关联性顺序C运算符优先级和相关性