2016-11-28 8 views
2

Как уменьшить выражение? Если я прав, x присваивает 0, если только x = 0; в противном случае x присваивает 1. Однако, как это может сократить?Как уменьшить выражение

x = (x = 0) ? 0 : 1 
+1

Возможно, вопрос вне темы: Почему вы хотите, чтобы он был короче? Какая цель это служит? –

+0

Это моя одна из hometasks –

+3

просто 'x = 1;' ... – BLUEPIXY

ответ

3

Держа в сторону все предположение часть, прежде всего позвольте мне сказать совершенно определенно, нет не определено поведение здесь.

Цитирование 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 проверка состояния категории присутствует в данном утверждении.

+0

Попробуйте скомпилировать под GCC с предупреждениями, он скажет: «предупреждение: операция на« х »может быть неопределенной [-Wsequence-point]' ... –

+0

@iharob хорошо, это интересно. Я хотел бы получить дополнительную информацию об этом. Где именно я читаю стандарт неправильно? (Надеюсь, вы не возражаете переформулировать комментарий, верно?) –

+0

@molbdnilo Сэр, я не очень уверен, что я слежу за вами там, я все еще не понимаю, как окончательное задание вызывает проблему. Как мы видим, первый операнд условного вычисления сначала оценивается ('x' назначается), после этого ** имеется точка последовательности **, после чего вычисляется третий операнд, а затем получается результат , который снова присваивается той же переменной 'x'. Итак, как промежуточная точка промежуточной точки здесь невелика?Пожалуйста, поправьте меня, если я что-то упустил. –

7

Предполагая, что вы имели в виду x == 0, это довольно короткий:

x = !!x; 

Объяснение:

Если x является 0, !x является 1, так !!x является 0.
Если x не является 0, !x является 0, поэтому !!x является 1.

Если x = 0 является намеренным, код не определен.

Но вы можете сделать более короткий вариант, который хорошо определен и который я считаю, фиксирует намерение писателя:

x = 1; 

поскольку значение x = 0 является 0.

+1

Самое интересное, что x = 0, только с одним значком равенства –

+0

@VladokAC Итак, это было намеренно? Ответ обновлен. – molbdnilo

+0

Да! Я видел ваш ответ, пожалуйста, объясните это! –

0

Если это именно тот, который вы опубликовали, это неопределенное поведение.

Выражение

x = (x = 0); 

не определен, потому что x = 0 изменяет x перед назначением его x поэтому он сказал, что нет никакого смысла последовательности между двумя суб выражениями. Вы можете прочитать здесь sequence point.

Это эквивалентно

x = x++; 

который многие программисты сразу определить, как неопределенное поведение, несмотря на то, что это труднее, чтобы увидеть его в x = (x = 0) это та же самая проблема, есть побочные эффекты, возникающие в связи с x = 0 поэтому поведение не определены в этом случае.

+2

Ummm .. не уверен, что я что-то упустил, но почему это UB? –

+0

Чтобы быть более конкретным, есть точка Seq между 1-м и 2-м/3-м операндом, правильно? –

+2

@iharob Я до сих пор не получил дело, есть точка последовательности, верно? –