Разница между ++ я и я ++

Возможные дубликаты:
Что эффективнее я ++ или ++ i?
Как объяснить результат выражения (++ x) + (++ x) + (++ x)?
Разница между я ++ и ++ я в цикле?

Привет, я пытаюсь использовать эти две программы

void fun(){
     int k=0;
     int i=10;
     k = (i++)+(++i);
     cout<<k<<endl;

}
Output = 22 as i++ will give 10 and ++i will evaluate into 12

но

void fun(){
     int k=0;
     int i=10;
     k = (++i)+(++i);
     cout<<k<<endl;

}
Output = 24

Это должно быть 23, я думаю, или есть sth, что я не могу видеть

Заранее спасибо

Ответы

Ответ 1

Примечание: вы вызываете поведение undefined (дважды изменяя переменную между точками последовательности)

Ответ 2

В соответствии с С++ 03 Standard 5/4 поведение рассматриваемых программ undefined:

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

Ответ 3

Это казалось действительно интересным, поэтому я заглянул в разборку (MSVС++ 2008)

     k = (++i)+(++i);
0122413C  mov         eax,dword ptr [i] 
0122413F  add         eax,1 
01224142  mov         dword ptr [i],eax 
01224145  mov         ecx,dword ptr [i] 
01224148  add         ecx,1 
0122414B  mov         dword ptr [i],ecx 
0122414E  mov         edx,dword ptr [i] 
01224151  add         edx,dword ptr [i] 
01224154  mov         dword ptr [k],edx 

Как вы можете видеть, он дважды увеличивает i, а затем добавляет i к себе. То же самое происходит, если есть несколько экземпляров (++i).

В любом случае, поскольку стандарт ничего не гарантирует, изменение i более одного раза приведет к поведению undefined.

Ответ 4

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

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

Пример 1: k = я ++; k + = ++ i;

Пример 2: k = ++ i; k + = ++ i;

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

Ответ 5

Я предполагаю, что оба оператора pre-increment работают до того, как вычисляется оператор добавления. следовательно, 24.

Все зависит от того, как компилятор видит, что вы делаете, но я предполагаю, что вы видите.

Ответ 6

i ++ - это пост-инкремент, ++ я - pre-increment. я ++ будет увеличивать я после завершения инструкции.

Чтобы проиллюстрировать в ваших примерах:

Пример 1:

k = 0
i = 10

i += 1
k = i + i  // 11 + 11
i += 1

Пример 2:

k = 0
i = 10

i += 1
i += 1
k = i + i  // 12 + 12

Ответ 7

++ я даст результат я = я + 1. Если я = 10, то в k = (++ i) + (++ i); выражение (++ i) даст добавочное значение, означающее, что произойдет первое приращение, но в случае я ++ приращение будет влиять на я после выражения.

So я = 10

k = (i ++) + (++ i);

 10    11   12

 10    +  12=22  

k = (++ i) + (++ i);

 11   11  12

  11   +  12=23

Ответ 8

++i обычно возвращает ссылку на самую переменную, поэтому вторая модификация также влияет на память, которая содержит результат от первой модификации. (Post-increment i++, с другой стороны, должен возвращать копию значения для правильной работы.)

Типичное определение ++i в С++ (с использованием перегрузки оператора) было бы

struct Foo{
  //...
  Foo const & operator++(){ //this implements ++i
    //do something to increment
    return *this;
  }
  Foo operator++(int){ //this implements i++
    Foo old(*this);
    //do something to increment
    return old;
  }
};

Ответ 9

++ я происходит до вычисления всего выражения, а я ++ - после. В первом примере один из приращений происходит до вычисления значения, поэтому "i" становится равным 21, и вы получаете 21 + 21. В последнем примере оба случаются раньше, поэтому "i" становится 22, и вы получаете 22 + 22.

Ответ 10

Чтобы определить это, выполните следующий шаг.

1). Определяется все ++i.

2). Значение я затем используется для каждого термина, который равен ++i и i++.

3). Определяется все i++.

Первый случай:

     int k=0;
     int i=10;
     k = (i++)+(++i);

1) Существует один из ++i, поэтому на конце этого шага я = 11 (один раз).

2) Теперь он становится k = (11)+(11);

3) Существует один из i++, поэтому на конце этого шага я = 12 (один раз).

Второй случай:

     int k=0;
     int i=10;
     k = (++i)+(++i);

1) Существует один из ++i, поэтому на конце этого шага я = 12 (дважды).

2) Теперь он становится k = (12)+(12);

3) Существует один из i++, поэтому на конце этого шага я = 12 (нулевое время).

Создаю тестовый код:

#include <stdio.h>
int main(void) {
    int K=0;
    int I=10;
    K = (I++)+(++I);
    printf("I: %d; K: %d\n", I, K);

    K=0;
    I=10;
    K = (++I)+(++I);
    printf("I: %d; K: %d\n", I, K);
}

При выполнении результат:

I: 12; K: 22
I: 12; K: 24

Надеюсь, что это поможет.