Как уменьшить выражение? Если я прав, x присваивает 0, если только x = 0; в противном случае x присваивает 1. Однако, как это может сократить?Как уменьшить выражение
x = (x = 0) ? 0 : 1
Как уменьшить выражение? Если я прав, x присваивает 0, если только x = 0; в противном случае x присваивает 1. Однако, как это может сократить?Как уменьшить выражение
x = (x = 0) ? 0 : 1
Держа в сторону все предположение часть, прежде всего позвольте мне сказать совершенно определенно, нет не определено поведение здесь.
Цитирование C11
, глава §6.5.15, Условный оператор (курсив мой)
Первый операнд; существует точка последовательности между ее оценкой и оценкой второго или третьего операнда (в зависимости от того, что оценивается). Второй операнд оценивается только в том случае, если первый сравнивает не равный 0; третий операнд оценивается только в том случае, если первое сравнивается с 0; результатом является значение второго или третьего операнда (в зависимости от того, что оценивается), [....]
, а затем результат присваивается LHS внешнего оператора присваивания.
заявление,
x = (x = 0) ? 0 : 1;
эквивалентно
x = 1;
, как x= 0
наконец имеет значение FALSE безоговорочно.
Связанные со ссылкой на стандарт, глава §6.5.16, операторы присваивания, (курсив мой )
Оператор присваивания сохраняет значение в объекте, обозначенном левого операнда. выражения присваивания имеет значение левого операнда после присваивания,
Примечание:
что сказало, связанный с понимания упомянутой в вопросе
x назначить 0, если только x = 0; в противном случае x назначить 1
неправ. Нет if..else..then проверка состояния категории присутствует в данном утверждении.
Попробуйте скомпилировать под GCC с предупреждениями, он скажет: «предупреждение: операция на« х »может быть неопределенной [-Wsequence-point]' ... –
@iharob хорошо, это интересно. Я хотел бы получить дополнительную информацию об этом. Где именно я читаю стандарт неправильно? (Надеюсь, вы не возражаете переформулировать комментарий, верно?) –
@molbdnilo Сэр, я не очень уверен, что я слежу за вами там, я все еще не понимаю, как окончательное задание вызывает проблему. Как мы видим, первый операнд условного вычисления сначала оценивается ('x' назначается), после этого ** имеется точка последовательности **, после чего вычисляется третий операнд, а затем получается результат , который снова присваивается той же переменной 'x'. Итак, как промежуточная точка промежуточной точки здесь невелика?Пожалуйста, поправьте меня, если я что-то упустил. –
Предполагая, что вы имели в виду x == 0
, это довольно короткий:
x = !!x;
Объяснение:
Если x
является 0
, !x
является 1
, так !!x
является 0
.
Если x
не является 0
, !x
является 0
, поэтому !!x
является 1
.
Если x = 0
является намеренным, код не определен.
Но вы можете сделать более короткий вариант, который хорошо определен и который я считаю, фиксирует намерение писателя:
x = 1;
поскольку значение x = 0
является 0
.
Самое интересное, что x = 0, только с одним значком равенства –
@VladokAC Итак, это было намеренно? Ответ обновлен. – molbdnilo
Да! Я видел ваш ответ, пожалуйста, объясните это! –
Если это именно тот, который вы опубликовали, это неопределенное поведение.
Выражение
x = (x = 0);
не определен, потому что x = 0
изменяет x
перед назначением его x
поэтому он сказал, что нет никакого смысла последовательности между двумя суб выражениями. Вы можете прочитать здесь sequence point.
Это эквивалентно
x = x++;
который многие программисты сразу определить, как неопределенное поведение, несмотря на то, что это труднее, чтобы увидеть его в x = (x = 0)
это та же самая проблема, есть побочные эффекты, возникающие в связи с x = 0
поэтому поведение не определены в этом случае.
Ummm .. не уверен, что я что-то упустил, но почему это UB? –
Чтобы быть более конкретным, есть точка Seq между 1-м и 2-м/3-м операндом, правильно? –
@iharob Я до сих пор не получил дело, есть точка последовательности, верно? –
Возможно, вопрос вне темы: Почему вы хотите, чтобы он был короче? Какая цель это служит? –
Это моя одна из hometasks –
просто 'x = 1;' ... – BLUEPIXY