为什么这段代码会返回0& 1?

时间:2015-03-25 01:26:59

标签: c++ c postfix-operator

使用变量后我知道后缀运算符增量值。 但在这种情况下,它是一个有效的声明吗?因为看起来我在返回语句之后修改了一个变量。

#include <iostream>

using namespace std;

int val = 0;

int foo()
{
        return val++;
}

int main()
{
        cout<<foo();
        cout<<endl<<val;
}

任何详细说明都会有所帮助。

4 个答案:

答案 0 :(得分:6)

return val++首先返回val然后递增它不完全正确。表达式val++会增加val的值,但 会将 计算为旧值val

您可以将postfix ++视为使用辅助变量来保存旧值的函数:

int temp = val; // save old value to temp
++val;          // increment actual value
return temp;    // evaluate to old value

答案 1 :(得分:2)

是的,它有效。

不要将其视为返回val,然后再将其递增。

相反,您将返回操作val++的结果。

答案 2 :(得分:2)

好的,val是一个全局变量,正如您可能会注意到的那样。

致电foo()时,

int foo()
{
    return val++;
}

它首先返回val0然后增加val的值,因此val = 1

引用Zenith的话,

  

表达式val++会增加val的值,但会在递增之前将计算为val的值。

现在,当你cout val时,val显然为1,因此输出是合理的。

答案 3 :(得分:1)

为了查看编译器代表代码的确切步骤,我检查了反汇编。

00324C2E行将全局变量“val”的值复制到CPU的eax寄存器中。

00324C33行将eax中的值复制到“foo”函数的本地堆栈空间。

00324C39行将全局变量“val”的值复制到CPU的ecx寄存器中。

00324C3F行将ecx寄存器中的值加1。

00324C42行将ecx寄存器中的递增值复制回全局变量“var”。

00324C48行将未受影响的值副本复制到CPU的eax寄存器中,该副本存储在“foo”函数的本地堆栈空间中(参见上面的00324C33行)。它被复制到eax寄存器,因为它是返回给调用函数的值(在这种情况下是“main”)。

因此,从foo()返回0,但是在foo()返回后,全局变量“val”包含1。


int foo()
{
  00324C10  push        ebp  
  00324C11  mov         ebp,esp  
  00324C13  sub         esp,0C4h  
  00324C19  push        ebx  
  00324C1A  push        esi  
  00324C1B  push        edi  
  00324C1C  lea         edi,[ebp-0C4h]  
  00324C22  mov         ecx,31h  
  00324C27  mov         eax,0CCCCCCCCh  
  00324C2C  rep stos    dword ptr es:[edi]  
      return val++;
  00324C2E  mov         eax,dword ptr ds:[0032F320h]  
  00324C33  mov         dword ptr [ebp-0C4h],eax  
  00324C39  mov         ecx,dword ptr ds:[32F320h]  
  00324C3F  add         ecx,1  
  00324C42  mov         dword ptr ds:[32F320h],ecx  
  00324C48  mov         eax,dword ptr [ebp-0C4h]  
}