++ i和i ++之间的区别

时间:2009-11-05 05:26:16

标签: c++

  

可能重复:
  What is more efficient i++ or ++i?
  How do we explain the result of the expression (++x)+(++x)+(++x)?
  Difference between i++ and ++i in a loop?

我正在尝试这两个程序:

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

输出= 22,因为i ++将给出10而++我将评估为12。

但是

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

输出= 24

我猜应该是23,还是有些东西我无法看到?

10 个答案:

答案 0 :(得分:19)

注意:您正在调用未定义的行为(在序列点之间修改变量两次)

答案 1 :(得分:6)

根据C ++ 03标准5/4,有问题的程序的行为未定义:

  

除非另有说明,否则单个运算符的操作数和indi的子表达式的评估顺序除外   视频表达式以及副作用发生的顺序是未指定的。   53)   之间的   和下一个序列点标量对象的评估值最多只能修改一次   一个表达。此外,只能访问先前值以确定要存储的值。   对于完整的子表达式的每个允许排序,应满足本段的要求   表达;否则行为未定义。

答案 2 :(得分:4)

这看起来很有趣,所以我看了一下反汇编(MSVC ++ 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会导致未定义的行为。

答案 3 :(得分:2)

变量永远不应该在一个语句中增加多次,因为没有定义编译器的行为。

为避免副作用,请为您的示例制作两个语句。

例1:k = i ++; k + = ++ i;

示例2:k = ++ i; k + = ++ i;

如果您这样做,您的代码将正常运行。

答案 4 :(得分:0)

我猜测在计算加法语句之前,两个预增量运算符都在运行。因此24.

一切都取决于编译器如何看待你正在做的事情,但我猜这就是你所看到的。

答案 5 :(得分:0)

i ++是后增量,++ i是预增量。声明完成后,i ++将增加i。

在您的示例中说明:

示例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

答案 6 :(得分:-1)

++我将给出结果i = i + 1。如果i = 10则在k =(++ i)+(++ i); 表达式(++ i)将给出递增的值,这意味着第一次递增将发生但是在i ++的情况下,在表达式之后i的增量将受到影响。

所以我= 10

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

 10    11   12

 10    +  12=22  

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

 11   11  12

  11   +  12=23

答案 7 :(得分:-1)

++i通常返回对变量本身的引用,因此第二个修改也会影响保存第一次修改结果的内存。 (另一方面,后增量i++必须返回值的副本才能正常工作。)

C ++中++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;
  }
};

答案 8 :(得分:-2)

++我发生在计算整个表达式之前,i ++发生在之后。 在第一个例子中,一个增量发生在计算值之前,所以“i”变为21,你得到21 + 21.在最后一个例子中,两个都发生在之前,所以“i”变为22,你得到22 + 22。

答案 9 :(得分:-2)

要确定这一点,请执行以下步骤。

1)。所有++i都已确定。

2)。然后,i的值将用于++ii++的每个术语。

3)。所有i++都已确定。

第一种情况:

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

1)++i中有一个,所以在此步骤结束时i = 11(一次)。

2)现在变为k = (11)+(11);

3)i++中有一个因此在此步骤结束时i = 12(一次)。

第二种情况:

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

1)++i中有一个,所以在这一步结束时i = 12(两次)。

2)现在变为k = (12)+(12);

3)i++中有一个因此在此步骤结束时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

希望这有帮助。