Порядок операций в C. ++ по сравнению с | =, который происходит сначала?

У меня есть следующий код, который я прочитываю:

if( (i%2) == 0 ){ 
    *d = ((b & 0x0F) << 4); 
}
else{
    *d++ |= (b & 0x0F); 
};

Я смотрю конкретно на else оператор и задающийся вопросом в том, какой порядок это происходит? У меня нет регулярного компилятора C, таким образом, я не могу протестировать это. Когда мы выполняем *d++ |= (b & 0x0F);, в каком порядке это происходит?

5
задан Tadeusz A. Kadłubowski 21 May 2010 в 08:58
поделиться

7 ответов

++ применяется к указателю d , а не к присвоенному значению l, * d .

Если вы действительно хотите, вы можете думать об этом так:

  1. Значение b - побитовое И: ed с константой 0x0f
  2. Результирующий битовый шаблон выполняется поразрядное ИЛИ: ed на значение, на которое указывает d .
  3. Указатель d увеличивается до следующего значения.
11
ответ дан 18 December 2019 в 07:53
поделиться

++ произойдет до | = . Операторы присваивания находятся внизу диаграммы приоритета.

2
ответ дан 18 December 2019 в 07:53
поделиться

Согласно http://www.cppreference.com/wiki/operator_precedence

он оценит (b & 0x0F), затем применит | = к нему и назначит его * b, наконец, увеличивает значение, на которое указывает * b.

0
ответ дан 18 December 2019 в 07:53
поделиться

Выражение * d ++ | = (b & 0x0F) распадается следующим образом:

  1. Выражения * d ++ и b & 0x0F каждый раз оценивается (порядок, в котором они оцениваются, не указан; компилятор может оценить b & 0x0F до * d ++ , поскольку результат не зависят от порядка, в котором происходит вычисление);
  2. Результат (b & 0x0F) побитовый или с результатом * d ++ ;
  3. результат побитовой операции «ИЛИ» сохраняется в месте, на которое изначально указывает d;
  4. В какой-то момент во всем этом значение d обновляется.

Выражение * d ++ анализируется как * (d ++) ; т.е. вы разыменовываете результат выражения d ++ . Выражение d ++ оценивается как текущее значение d и в некоторой неуказанной точке перед следующей точкой последовательности (в данном случае концом оператора) , значение d обновляется. Побочный эффект обновления d не должен применяться немедленно; это может произойти до или после задания.

0
ответ дан 18 December 2019 в 07:53
поделиться

Сначала выполняется правая часть | = , затем выполняется присвоение * d | = , затем d увеличивается. Обычно, когда у вас есть код, который вызывает подобные вопросы, вы должны просто переписать его для ясности.

2
ответ дан 18 December 2019 в 07:53
поделиться

++. Однако пост-инкремент (т.е. d++ здесь) эквивалентен этому (temp=d, d++, temp).

0
ответ дан 18 December 2019 в 07:53
поделиться

d++ возвращает значение d, которое было до его увеличения. Затем оно разыменовывается *, и именно на это место выполняется |=. Таким образом, данные в месте перед инкрементом d будут содержать (b & 0x0F).

В общем, если порядок операций в строке кода не ясен с первого взгляда, рефакторите строку на составляющие ее операции, пока они не станут ясными. Сгенерированный код не становится быстрее или компактнее только от того, что в одну строку языка Си втиснуто много операций! Нет никаких веских причин жертвовать понятностью таким образом. Замените строку на

*d |= (b & 0x0F); 
d++;
5
ответ дан 18 December 2019 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: