Объяснение до / после увеличения - PullRequest
2 голосов
/ 20 января 2012

Пожалуйста, будьте осторожны со мной и не стреляйте в меня, поскольку я все еще новичок.

Я полностью сбит с толку и не могу на всю жизнь понять, почему, когда я бегуэтот код:

int y = 9;
cout << "++y = " << ++y << "\n--y = " << --y << "\ny++ = " << y++ << "\ny-- = " << y-- << "\n";
cout << "y = " << y << "\n";

я получаю следующие результаты:

y = 9
++y = 9
--y = 9
y++ = 8
y-- = 9
y = 9

вместо этих результатов:

y = 9
++y = 10
--y = 9
y++ = 9
y-- = 10
y = 9

Что я получаю из этого кода:

int y = 9;
cout << "y = " << y << "\n";
cout << "++y = " << ++y << "\n";
cout << "--y = " << --y << "\n";
cout << "y++ = " << y++ << "\n";
cout << "y-- = " << y-- << "\n";
cout << "y = " << y << "\n";

Может ли кто-нибудь объяснить - простыми словами, насколько это возможно - что происходит в первом коде, чтобы он печатал результат таким образом?

Ответы [ 3 ]

11 голосов
/ 20 января 2012

Простое правило заключается в том, что вы не должны увеличивать одно и то же местоположение более одного раза в любом заданном выражении.Поэтому вам не следует кодировать cout << y++ << ++y << endl;, который содержит два приращения y (при условии объявления int y;).

Подробнее читайте о точках последовательности и неопределенное поведение в стандарте C ++ .

Есть много связанных вопросов.Смотрите на них больше!

3 голосов
/ 20 января 2012

Когда согласно правилам операция * должна быть посчитана до +, а ++ до *, это будет так.

 a*b++ + c // first b++ (returns **old** b), than a*b, than ...+c

Но когда у вас есть ++ * a--, никто не может сказать, какой из двух операндов, a ++ или a--, будет вычислен первым.Согласно стандарту ANSII, даже если вы используете один и тот же переводчик, результат каждый раз непредсказуем.

цитата из стандарта C ++ ANSII:

За исключением особо отмеченных случаев, порядок вычисления операндов отдельных операторов и подвыражений отдельных выражений, а также порядок возникновения побочных эффектов не определен.,Между предыдущей и следующей точкой последовательности скалярному объекту должно быть сохранено его значение, измененное не более одного раза при оценке выражения.Кроме того, предварительное значение должно быть доступно только для определения значения, которое будет сохранено.Требования этого параграфа должны выполняться для каждого допустимого упорядочения подвыражений полного выражения;в противном случае поведение не определено.[Пример:

      i = v[i++];      // the behavior is undefined
      i = 7, i++, i++; // `i' becomes 9

      i = ++i + 1;     // the behavior is undefined 
      i = i + 1;       // the value of 'i' is incremented

Точки последовательности:

  • в конце вычисления полного выражения (полное выражение - это выражение выражения или любое другое выражение, которое не являетсяподвыражение в любом большем выражении);
  • в операторах ||, &&,?: и запятых;
  • и при вызове функции (после оценки всех аргументов и непосредственно перед фактическим вызовом).

Итак, ||является точкой последовательности, но << нет.</p>

2 голосов
/ 20 января 2012

Мультитульная версия первого кода должна быть:

  y = 9;
  cout << "y-- = " << y-- << "\n";
  cout << "y++ = " << y++ << "\n"
  cout << "--y = " << --y << "\n"
  cout << "++y = " << ++y << "\n"
  cout << "y = " << y << "\n";
...