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

use*_*566 17 c

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

ArcChar = ArcBit = 0;
Run Code Online (Sandbox Code Playgroud)

从功能:

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

    if( bit )
        ArcChar |= 1;

    if( ++ArcBit < 8 )
        return;

    putc (ArcChar, Out);
    ArcChar = ArcBit = 0;
}
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*oey 23

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

实质上

ArcChar = ArcBit = 0;
Run Code Online (Sandbox Code Playgroud)

是(大约1)相同

ArcBit = 0;
ArcChar = 0;
Run Code Online (Sandbox Code Playgroud)

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

关于类型,即使ArcBitunsigned char分配的结果也会扩大到int.


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

  • 它与两个语句版本不完全相同,后者在两个赋值之间有一个序列点.如果两个左值是'*ptr1`和`*ptr2`并且它们碰巧指向同一个地方(其中一个语句版本将具有UB)或者它们都是"易失性"并且你关心作业发生的顺序. (7认同)
  • (`UB` 代表 Undefined Behavior 我现在明白了) (2认同)

mur*_*att 6

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

int i, j;
i = j = 0;
Run Code Online (Sandbox Code Playgroud)

和写作一样

int i, j;
j = 0;
i = j;
Run Code Online (Sandbox Code Playgroud)

或写作

int i, j;
i = 0;
j = 0;
Run Code Online (Sandbox Code Playgroud)


Arm*_*yan 6

ArcChar = ArcBit = 0;
Run Code Online (Sandbox Code Playgroud)

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

ArcChar = (ArcBit = 0);
Run Code Online (Sandbox Code Playgroud)

结果ArcBit = 0是新assined价值,那就是- 0,因此是很有意义来指派0ArcChar


Ama*_*9MF 5

赋值操作(a = b)本身返回一个右值,可以将其进一步赋值给另一个左值;c = (a = b)。最终a和c都会有b的值。


Sad*_*que 5

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

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

所以你可以这样做:

a=b=2; // ok
Run Code Online (Sandbox Code Playgroud)

但不是这个:

a=2=b; // error
Run Code Online (Sandbox Code Playgroud)