int main() {
int a=1,b;
cout<<(a++)*(++a)<<endl;
}
Почему выводится число 3?
Должно быть вроде: 2*3=6
C/C++
Инкремент и декремент
не должно быть 6 а должно быть именно 3.
Вначале а = 1
первая часть (а++) - a++ - берем значение, потом инкрементируем, получается 1 (а в переменную записали 2
вторая часть (++а) - ++а - инкрементируем, потом берем значение, было 2, стало 3, её и забрали.
дальше думаю всё понятно, 1*3=3
Вначале а = 1
первая часть (а++) - a++ - берем значение, потом инкрементируем, получается 1 (а в переменную записали 2
вторая часть (++а) - ++а - инкрементируем, потом берем значение, было 2, стало 3, её и забрали.
дальше думаю всё понятно, 1*3=3
Нургали Дюсембаев
Спасибо большое!
Компилятор C++ имеет право менять порядок вычисления подвыражений. И точку внутри вычисления выражения, в которой производится инкремент / декремент, компилятор тоже выбирает сам. Когда в C++ пишешь (a++)*(++a), ты не можешь гарантировать, что a++ выполнится раньше, чем ++a. И, более того, в одном и том же компиляторе при задании разных уровней оптимизации порядок может быть разным.
Потому, твой код - это классический пример UB (undefined behavior, неопределённое поведение).
В соответствии со стандартом C++ в случае UB компилятор имеет право делать что угодно: хоть вернуть погоду на Марсе, хоть вообще выкинуть все вычисления, содержащие UB.
Не хочешь постоянно наступать на грабли - запомни одно простое правило: значение каждой переменной внутри выражения МОЖЕТ МЕНЯТЬСЯ НЕ БОЛЕЕ ОДНОГО РАЗА. При этом надо помнить, что присваивание - это тоже изменение значения внутри выражения.
P.S. И, кстати, в языках с выполнением выражений строго слева направо как раз 3 и будет.
Потому, твой код - это классический пример UB (undefined behavior, неопределённое поведение).
В соответствии со стандартом C++ в случае UB компилятор имеет право делать что угодно: хоть вернуть погоду на Марсе, хоть вообще выкинуть все вычисления, содержащие UB.
Не хочешь постоянно наступать на грабли - запомни одно простое правило: значение каждой переменной внутри выражения МОЖЕТ МЕНЯТЬСЯ НЕ БОЛЕЕ ОДНОГО РАЗА. При этом надо помнить, что присваивание - это тоже изменение значения внутри выражения.
P.S. И, кстати, в языках с выполнением выражений строго слева направо как раз 3 и будет.
*** .g.b.
Хм... хорошая идея для прогноза погоды на Марсе. Маску пригодится!
Это называется "неопределенное поведение"
Видимо одна из форм компилятора решает выражение так
1.(a++) возвращает значение 1, переменная принимает значение 2
2.(++a) переменная принимает значение 3, возвращает значение 3
3. 1*3=3
4. выводим на консоль значение 3
Видимо одна из форм компилятора решает выражение так
1.(a++) возвращает значение 1, переменная принимает значение 2
2.(++a) переменная принимает значение 3, возвращает значение 3
3. 1*3=3
4. выводим на консоль значение 3
Ленивые жопы придумали си и си++ и не описали правила правильного их использования.
Отсель десятилетиями проблемы с выстрелом в свою ногу.
Отсель десятилетиями проблемы с выстрелом в свою ногу.
Сергей Снычев
Даже математики никак не могут определить
2*3 это два умножить на три или три умножить на два
А куда уж тут компилятору-то с человеком тягаться?
2*3 это два умножить на три или три умножить на два
А куда уж тут компилятору-то с человеком тягаться?
Происходят действия:
(1, увеличить на 1) * (2 увеличить на 1)
(1, увеличить на 1) * (2 увеличить на 1)
Похожие вопросы
- Вопрос про математические процессы инкрементов и декрементов с префиксами и постфиксами. C++
- Инкремент и декремент
- Почему операции инкремента и декремента - унарные?
- Авто инкремент в mySQL ?
- C#. ++x или x++ В чем разница при записи инкремента этими двумя способами?
- C++. Как работает постфиксный инкремент?