Как работает оператор?: В C? - PullRequest
       38

Как работает оператор?: В C?

10 голосов
/ 11 февраля 2020

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

#include<stdio.h>

int main(void)
{
  int b=12, c=11;
  int d = (b == c++) ? (c+1) : (c-1);
  printf("d = %i\n", d);
}

Я не уверен, почему результат равен ‍‍‍ d = 11.

Ответы [ 5 ]

6 голосов
/ 11 февраля 2020

In int d = (b == c++) ? (c+1) : (c-1);:

  • Значение c++ является текущим значением c, 11. Отдельно c увеличивается до 12.
  • b == 11 ложно, поскольку b равно 12.
  • Поскольку (b == c++) ложно, используется (c-1). Кроме того, к этому моменту должно быть завершено приращение от c до 12.
  • Поскольку c равно 12, c-1 равно 11.
  • d инициализируется этим значением , 11.
5 голосов
/ 11 февраля 2020

Согласно стандарту C (6.5.15 Условный оператор)

4 Первый операнд вычисляется; между оценкой и оценкой второго или третьего операнда существует точка последовательности (в зависимости от того, что оценивается). Второй операнд оценивается, только если первый сравнивается с неравным 0; третий операнд оценивается, только если первый сравнивается равным 0; результатом является значение второго или третьего операнда (в зависимости от того, что вычислено), преобразованного в тип, описанный ниже. 1009 * переменная b сравнивается со значением переменной c, поскольку оператор постинкрементного возврата возвращает значение своего операнда перед его увеличением.

Поскольку значения не равны друг другу (b устанавливается равным 12, а c устанавливается равным 11), тогда вычисляется подвыражение (c-1).

В соответствии с кавычкой существует точка последовательности после оценки состояния оператора. Это означает, что после оценки условия c имеет значение 12 после применения оператора постинкрементной переменной c. В результате переменная d инициализируется значением 1 (12 - 1).

4 голосов
/ 11 февраля 2020

В обычном if-выражении ваш код будет выглядеть следующим образом:

int b=12, c=11;
int d;

if (b == c++)
   d = c+1;
else
   d = c-1;

Подсказка заключается в том, что c увеличивается после проверки состояния. Таким образом, вы входите в состояние else, но c уже имеет значение 12.

4 голосов
/ 11 февраля 2020

Поскольку условие является ложным, следовательно, произойдет случай false: c-1, но, поскольку вы увеличили c в условии на c++, следовательно, c теперь равно 12. Таким образом, результат 12 - 1, который равен 11.

РЕДАКТИРОВАТЬ: что OP неправильно понял, был пост-приращение.

Так что на самом деле происходит так:

#include<stdio.h>
int main(void)
{
  int b=12, c=11;
  int d;

  if (b == c) { // 12 == 11 ? -> false
    c = c + 1;
    d = c + 1;
  } else { // this executes since condition is false
    c = c + 1; // post increment -> c++ -> c = 12 now
    d = c - 1; // 12 - 1 = 11 -> d = 11
  }
  printf("d = %i\n", d);
}
1 голос
/ 11 февраля 2020

См. Тернарный оператор.

Синтаксис

условие? value_if_true: value_if_false

Итак, вы написали

int d = (b == c++) ? (c+1) : (c-1);

В этой ситуации результатом будет 11, потому что после проверки if значение 'c' увеличивается (c + 1 = 12) и только после этого он устанавливает значение 'd' как c (12) -1, равное 11.

Если вы использовали, например:

int d = (b == ++c) ? (c+1) : (c-1);

Значение «c» будет увеличено перед проверкой оператора, поэтому оно будет истинным, а значение «d» будет равно c (12) +1, что равно 13.

...