Оператор программирования C ++ - PullRequest
12 голосов
/ 14 января 2010

Почему этот код всегда выдает x=2?

unsigned int x = 0;
x++ || x++ || x++ || x++ || ........;
printf("%d\n",x);

Ответы [ 10 ]

30 голосов
/ 14 января 2010

1-й x++ меняет x на 1 и возвращает 0
2-й x++ меняет x на 2 и возвращает 1

в этот момент или короткое замыкание возвращает true и оставляет x равным 2.

11 голосов
/ 14 января 2010

х ++ || х ++ || х ++ || х ++ || ........;

  • Сначала x ++ сначала оценивается как 0 для условной проверки, а затем увеличивается. Итак, первое условие не выполняется, но x увеличивается до 1.
  • Теперь вычисляется второй x ++, который оценивается как 1 для условной проверки, а x увеличивается до 2. Поскольку выражение оценивается до 1 (true), нет необходимости идти дальше.
9 голосов
/ 14 января 2010

Из-за короткого замыкания в оценке булевых выражений и из-за того, что || является точкой последовательности в C и C ++.

5 голосов
/ 14 января 2010

|| короткое замыкание. Оценивается слева, когда найдено истинное значение (отличное от нуля), оно прекращает оценку, поскольку выражение теперь истинно и никогда не может снова быть ложным.

Сначала x++ оценивается в 0 (поскольку это постинкремент), во втором - 1, что верно, и до того, что вы сделали!

2 голосов
/ 14 января 2010

Когда вы оцениваете «a || b || c || d || e || ...», вы можете прекратить оценку при первом ненулевом значении, которое вы найдете.

Первый «x ++» оценивается как 0, увеличивается с x на 1, и вычисление выражения продолжается. Второй x ++ оценивается как 1, увеличивается с x на 2, и в этот момент вам не нужно смотреть на остальную часть оператора OR, чтобы знать, что это будет истина, поэтому остановитесь.

1 голос
/ 14 января 2010

Оператор || вычисляет левое выражение, а если оно равно 0 (ложь), то оно вычисляет правое выражение. Если левая сторона не равна 0, то она вообще не будет оценивать правую сторону.

В выражении x++ || x++ || x++ || ... вычисляется первый x++; он оценивается как 0, а x увеличивается до 1. Оценивается вторая x++; он оценивается как 1, а x увеличивается до 2. Поскольку второе x++ оценивается как ненулевое значение, ни одно из оставшихся x++ выражений не оценивается.

1 голос
/ 14 января 2010

Поскольку первый «x ++ || x ++» оценивается как «true» (что означает, что он не равен нулю, поскольку «0 || 1» имеет значение true. Поскольку все они являются логическими операторами OR, остальные операции OR игнорируются.

Mike

1 голос
/ 14 января 2010

Из-за ранней оценки сравнений.

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

 0++ | 1++

Компилятор прекращает сравнение, как только x == 1, затем отправляет инкременты, делая x == 2

1 голос
/ 14 января 2010

Потому что логическое ИЛИ замыкает накоротко, когда истина найдена.

Итак, первый x ++ возвращает 0 (ложь), потому что это постинкремент. (х = 1) Второй x ++ возвращает 1 (true) - короткие замыкания. (х = 2)

Отпечатки х = 2;

0 голосов
/ 14 января 2010

пытается заменить || на | .--

Это короткое замыкание логических операторов.

Это та же самая причина, когда вы делаете

if (returns_true() || returns_true()){ }

returns_true будет вызван только один раз.

...