C Приоритет оператора, проблема программирования после инкремента

Может кто-нибудь объяснить, почему вывод программы

0 1 1 3 1

void main(void)
{
      int i=-1,j=0,k=1,l=2,m;

      m=i++&&j++&&k++||l++;

      printf("%d %d %d %d %d",i,j,k,l,m);

}

Основная проблема заключается в том, «почему k не увеличивается».

К вашему сведению. Я компилирую программу в редакторе VC++ для Windows 7 32 бит. Спасибо заранее.


person Rohit    schedule 15.05.2013    source источник
comment
Для сложных выражений лучше использовать круглые скобки. Используйте круглые скобки так, как вы хотите оценивать выражения.   -  person Donotalo    schedule 15.05.2013
comment
См., например. эта ссылка.   -  person Some programmer dude    schedule 15.05.2013
comment
Ничто не вызывает у меня большей ностальгии, чем void main()   -  person Rüppell's Vulture    schedule 15.05.2013
comment
возможный дубликат Приоритет оператора и порядок оценки   -  person ecatmur    schedule 16.05.2013


Ответы (3)


Грубо:

Чтобы оценить i++&&j++, компилятор сначала вычислил i. Результат -1. -1 хранится во временной переменной. Затем i увеличилось.

Поскольку -1 не равно нулю, компилятор оценил j, что равно 0. Теперь компилятор оценил -1 && 0, что равно 0. Затем j увеличилось.

В этот момент i = 0 и j = 1. Оставшееся выражение: m=0&&k++||l++;

Чтобы вычислить 0&&k++, компилятор отметил, что первый операнд — 0. Результат должен быть 0, чтобы компилятор не оценивал k или k++. Оставшееся выражение: m=0||l++;

Я надеюсь, что вы можете сделать все остальное. :)

person Donotalo    schedule 15.05.2013
comment
Спасибо за объяснение, почему k не увеличивается! - person Rohit; 15.05.2013

Давайте разобьем это на отдельные операции:

  1. i++ && j++: это будет то же самое, что и -1 && 0, что является ложным (т. е. 0).
  2. i и j затем увеличиваются до 0 и 1 соответственно.
  3. 0 && k++: Ноль из предыдущей логической операции, результат ложный, так как первый оператор ложный.
  4. k не увеличивается из-за краткости логических операторов.
  5. 0 || l: Ноль все еще от предыдущей логической операции, это 0 || 2 и результат будет истинным, т.е. 1.
  6. l увеличивается до 3.
  7. Результат логических операций присваивается m, что теперь становится истинным (т.е. 1)

Все выражение приводит к увеличению i, j и l, а m становится 1. Просто результат, который вы видите.

person Some programmer dude    schedule 15.05.2013
comment
k не увеличивается из-за краткости логических операторов ---› как это решается? - person Rohit; 15.05.2013
comment
@PowerPC В таком выражении, как 0 && 1, результат гарантированно будет 0, поэтому правую часть оператора && оценивать не нужно. То же самое с 1 || 0, это всегда будет 1, и происходит то же самое. Все это указано в спецификации C. - person Some programmer dude; 15.05.2013
comment
Спасибо за подробное объяснение. - person Rohit; 15.05.2013
comment
@JoachimPileborg: +1 за объяснение - person Ayse; 15.05.2013

ваше значение рассчитывается, как показано ниже

m=((((i++)&&j++)&&k++)||l++); 

так как все ++ являются пост-инкрементом, поэтому при вычислении m все переменные имеют то же значение, что и вы инициализировали, но на следующей строке во время печати все они увеличиваются. Последнее значение || поэтому окончательное TRUE вернется к значению m.

person Dayal rai    schedule 15.05.2013