Два знака равенства в одной строке? - PullRequest
17 голосов
/ 30 августа 2011

Может ли кто-нибудь объяснить, что это делает и как это допустимый код C?Я нашел эту строку в этом коде: http://code.google.com/p/compression-code/downloads/list,, который является реализацией C алгоритма Виттера для Адаптивного кодирования Хаффмана

ArcChar = ArcBit = 0;

Из функции:

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

Ответы [ 10 ]

22 голосов
/ 30 августа 2011

Значением выражения (a = b) является значение b, поэтому вы можете связать их таким образом. Они также прямо-ассоциативны, так что все получается.

По существу

ArcChar = ArcBit = 0;

(приблизительно 1 ) совпадает с

ArcBit = 0;
ArcChar = 0;

, поскольку значением первого назначения является присвоенное значение, таким образом, 0.

Что касается типов, даже если ArcBit является unsigned char, результат назначения будет расширен до int.


1 Это не точно то же самое, хотя, как указывает R в комментарии ниже.

6 голосов
/ 30 августа 2011
ArcChar = ArcBit = 0;

Назначение является левоассоциативным, поэтому оно эквивалентно:

ArcChar = (ArcBit = 0);

Результатом ArcBit = 0 является вновь присвоенное значение, то есть - 0, поэтому имеет смысл присвоить этому 0 значение ArcChar

.
6 голосов
/ 30 августа 2011

Устанавливает обе переменные в ноль.

int i, j;
i = j = 0;

То же, что и написание

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

или письмо

int i, j;
i = 0;
j = 0;
5 голосов
/ 30 августа 2011

Это просто цепочка оператора присваивания. Стандарт говорит в 6.5.16 Assignment operators:

Оператор присваивания должен иметь изменяемое значение lvalue в качестве своего левого операнда. Оператор присваивания сохраняет значение в объекте, обозначенном левым операндом. Выражение присваивания имеет значение левого операнда после присваивания, но не является именующий. Тип выражения присваивания является типом левого операнда, если только левый операнд имеет квалифицированный тип, в этом случае это неквалифицированная версия типа левый операнд. Побочный эффект обновления сохраненного значения левого операнда должен происходит между предыдущей и следующей точкой последовательности.

Так что вы можете сделать что-то вроде:

a=b=2; // ok

Но не это:

a=2=b; // error
3 голосов
/ 30 августа 2011

Операция присваивания (a = b) сама возвращает значение r, которое может быть далее присвоено другому значению lvalue;с = (а = б).В конце и a и c будут иметь значение b.

3 голосов
/ 30 августа 2011

Он присваивает ArcBit 0, затем ArcChar присваивает значение выражения ArcBit = 0 (т. Е. 0)

1 голос
/ 30 августа 2011

Назначение в C - это выражение, а не выражение. Также вы можете свободно присваивать значения разного размера (unsigned char для int и наоборот). Добро пожаловать на язык программирования C:)

1 голос
/ 30 августа 2011

Как сказал Хастуркун, это связано с порядком ассоциативности операторов С приоритетом операторов и ассоциативностью

1 голос
/ 30 августа 2011

Вы можете сделать это: http://en.wikibooks.org/wiki/C_Programming/Variables

Более того,

[a int] = 0; возможно.

[a char] = 0; тоже возможно.

arcbit и arcchar равен 0.

1 голос
/ 30 августа 2011

В некоторых языках присваивания являются утверждениями : они вызывают действие, но сами по себе не имеют значения. Например, в Python 1 запрещено писать

x = (y = 10) + 5

потому что присвоение y = 10 не может использоваться там, где ожидается значение.

Однако C - один из многих языков, где присваивания являются выражениями : они производят значение, а также любые другие эффекты, которые они могут иметь. Их значение - это значение, которое присваивается. Приведенная выше строка кода будет допустимой в C.

Использование двух знаков равенства в одной строке интерпретируется следующим образом:

ArcChar = (ArcBit = 0);

То есть: ArcChar beging присваивается значение ArcBit = 0, которое равно 0, поэтому обе переменные в итоге получат 0.


1 x = y = 0 на самом деле допустимо в Python, но считается специальным случаем оператора присваивания, и попытка сделать что-либо более сложное с присваиваниями завершится неудачей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...