Подтвердить что ты не робот

Операция оператора Pre & post приращения в C, С++, Java и С#

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Это не реальный пример. Это просто теоретический вопрос о том, как работают эти языки.

В чем заключаются различия между C/С++, С# и Java, когда дело доходит до операторов post и pre increment?

Это то, что я получаю с VС++ 10, Java 1.6 и С# 4

int a = 2;
int b = a++ + a++;
int c = ++a + a++ + a++;

      +-----+------+------+----+
      |  C  | C++  | Java | C# |
+-----+-----+------+------+----+
| a   |  7  |  7   |   7  |  7 |
+-----+-----+------+------+----+
| b   |  4  |  4   |   5  | 5  |
+-----+-----+------+------+----+
| c   | 15  |  15  |  16  | 16 |
+-----+-----+------+------+----+
4b9b3361

Ответ 1

Java и С# оценивают выражения слева направо, а побочные эффекты видны сразу.

В С++ порядок оценки подвыражений неуточнен, а изменение одного и того же объекта дважды без промежуточной точки последовательности - это поведение undefined.

Ответ 2

У меня нет времени написать подробное описание различий между С++, C, С# и Java. Я просто скажу, что поведение С# для операторов pre и post increment полностью указано (в однопоточных сценариях, если вы хотите узнать о его атомарности, гарантии о наблюдениях за порядками чтения и записи в многопроцессорные слабые модели памяти и т.д., вы сами делаете это исследование.) Это не полностью указано в C и С++; компилятор имеет широкую свободу действий, чтобы делать все, что угодно, с переупорядочивающими побочными эффектами. Я никогда не использовал Java, поэтому я не собираюсь подвергать сомнению, что делает Java.

Для получения дополнительной информации о том, что С# вам следует прочитать спецификацию С#. Для короткого взятия, прочитайте мой ответ на этот вопрос:

В чем разница между я ++ и ++ i?

Для еще более короткого взятия:

Подвыражения в выражении С# логически сгруппированы по приоритетности и ассоциативности, а затем независимо от слева направо. (Так, например, A() + B() * C() оценивает A(), то B(), то C(). Тот факт, что умножение "предшествует" добавление не имеет значения, подвыражения всегда оцениваются слева направо.)

Если оценка подвыражения вызывает побочный эффект из-за подвыражения pre или post increment, побочный эффект происходит непосредственно перед созданием результата.

Ответ 3

В С++ это поведение undefined, поэтому любой ответ будет правильным. Подробнее см. Undefined поведение и точки последовательности.

Не уверен в других языках, но я ожидаю, что этот код тоже будет неправильным.

EDIT:
См. Ответ Эрика Липперта о С#. Он опровергает мое предположение о поведении С#.

Ответ 4

В С++ по крайней мере это поведение undefined. Цитирование стандарта С++:

Между предыдущей и следующей точками последовательности скалярный объект должен иметь значение, которое его хранимое значение изменялось не более одного раза путем оценки выражения.

Ответ 5

Модель памяти Java обеспечивает порядок загрузки и хранения, поэтому она должна быть одинаковой на любом JVM (я полагаю).

Похоже, что С++ имеет тот же порядок операций, но как только вы используете его дважды на линии, вы начинаете работать с другими вещами (Влад находится прямо там). Если вы попробуете другие компиляторы С++, вы можете найти ответы на них.

Я уверен, что С# имеет тот же порядок операций, но я предполагаю, что у них есть модель памяти (например, Java), которая обеспечивает согласованность, но здесь у меня мало знаний.

Ответ 6

Мне нравится этот вопрос и нашел очень хорошие объяснения, но я просто хочу объяснить этот вопрос тем, насколько он оценивается:

Я буду говорить только о java и c/С++, поскольку у меня нет knoledge о С#

Заявления оцениваются следующими способами:

В java

Заявление ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||| Трассировка

int a= 2;                     a=2
int b= a++ + a++;             a=2, a=3

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=6

here value of a=7

В C/С++

Отслеживание сообщений

int a= 2;                     a=2
int b= a++ + a++;             a=2, a=2

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=5

here value of a=7

Короче говоря, выражение java идет слева направо, поэтому на втором "a" оно будет извлекать новое значение, а в c/С++ оно сначала оценит целочисленное выражение, а затем увеличит все операнды оператора.