Два равных знака в одной строке?
Может кто-нибудь объяснить, что это делает и как это законный код C? Я нашел эту строку в этом коде: http://code.google.com/p/compression-code/downloads/list, которая является реализацией C алгоритма Vitter для Адаптивное кодирование Хаффмана
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
Ответы
Ответ 1
Значение выражения (a = b)
- это значение b
, поэтому вы можете связать их таким образом. Они также являются право-ассоциативными, поэтому все работает.
По существу
ArcChar = ArcBit = 0;
(приблизительно 1) совпадает с
ArcBit = 0;
ArcChar = 0;
так как значение первого присваивания является назначенным значением, таким образом 0
.
Что касается типов, хотя ArcBit
является unsigned char
, результат присваивания будет расширен до int
.
1 Это не совсем то же самое, поскольку, как указывает R.., в комментарии ниже.
Ответ 2
ArcChar = ArcBit = 0;
Назначение лево-ассоциативное, поэтому оно эквивалентно:
ArcChar = (ArcBit = 0);
Результат ArcBit = 0
- это новое значение, то есть - 0
, поэтому имеет смысл назначить 0
на ArcChar
Ответ 3
Это просто цепочка оператора присваивания. Стандарт говорит в 6.5.16 Assignment operators
:
Оператор присваивания должен иметь модифицируемое значение lval в качестве его левого операнда. Оператор присваивания сохраняет значение в объекте, обозначенном левым операндом. выражение присваивания имеет значение левого операнда после назначения, но не является именующий. Тип выражения присваивания - это тип левого операнда, если только левый операнд имеет квалифицированный тип, в этом случае это неквалифицированная версия типа левый операнд. Побочный эффект обновления сохраненного значения левого операнда должен между предыдущей и следующей точками последовательности.
Итак, вы можете сделать что-то вроде:
a=b=2; // ok
Но не это:
a=2=b; // error
Ответ 4
Он устанавливает обе переменные в ноль.
int i, j;
i = j = 0;
То же, что и запись
int i, j;
j = 0;
i = j;
или писать
int i, j;
i = 0;
j = 0;
Ответ 5
Он присваивает ArcBit
0
, затем присваивает ArcChar
значение выражения ArcBit = 0
(т.е. 0
)
Ответ 6
Сама операция присваивания (a = b) возвращает значение r, которое может быть дополнительно присвоено другому lvalue; c = (a = b). В конце, и a, и c будут иметь значение b.
Ответ 7
В некоторых языках присваивания представляют собой утверждения: они вызывают какое-либо действие, но сами не имеют значения. Например, в Python 1 запрещено писать
x = (y = 10) + 5
потому что назначение y = 10
не может использоваться там, где ожидается значение.
Однако C является одним из многих языков, где присваивания представляют собой выражения: они дают значение, а также любые другие эффекты, которые они могут иметь. Их значение - это значение, которое назначается. Вышеупомянутая строка кода будет легальной в C.
Использование двух знаков равенства на одной строке интерпретируется следующим образом:
ArcChar = (ArcBit = 0);
То есть: ArcChar
запрашивает значение ArcBit = 0
, которое равно 0
, поэтому обе переменные в конечном итоге составляют 0
.
1x = y = 0
на самом деле является законным в Python, но он рассматривает особый случай оператора присваивания, и попытка сделать что-либо более сложное с назначением не удастся.
Ответ 8
Вы можете сделать это:
http://en.wikibooks.org/wiki/C_Programming/Variables
Кроме того,
[a int] = 0;
.
[a char] = 0;
также возможно.
arcbit и arcchar равны 0.
Ответ 9
Как сказал Хастуркун, это связано с порядком ассоциативности операторов
C Приоритет операторов и ассоциативность
Ответ 10
Назначение в C является выражением, а не выражением. Также вы можете свободно назначать значения разного размера (без знака char для int и наоборот). Добро пожаловать на язык программирования C:)