为什么这个代码 returns 0 & 1?

Why this code returns 0 & 1?

我知道后缀运算符在使用变量后增加值。 但在这种情况下,这是一个有效的陈述吗?因为看起来我正在修改它的 return 语句后的变量。

#include <iostream>

using namespace std;

int val = 0;

int foo()
{
        return val++;
}

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

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

是的,有效。

不要认为它是返回 val 然后递增它。

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

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

当您调用 foo(),

int foo()
{
    return val++;
}

会先returnval,也就是0然后递增val,因此 val = 1.

正如 Zenith 所引用的那样,

The expression val++ increments the value of val, but evaluates to the value of val before incrementing.

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

return val++ 首先 returns val 然后递增它是 不完全正确的 。表达式 val++ 增加 val 的值,但 计算 val 的旧值。

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

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

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

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

第 00324C33 行将值从 eax 复制到 "foo" 函数的本地堆栈 space。

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

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

第 00324C42 行将增量值从 ecx 寄存器复制回您的全局变量 "var"。

00324C48 行将存储在 "foo" 函数的本地堆栈 space 中的值的未受影响副本复制到 CPU 的 eax 中(参见上面的 00324C33 行)登记。它被复制到 eax 寄存器,因为它是返回给调用函数的值(在本例中为 "main")。

因此,从 foo() 返回 0,但全局变量 "val" 在 foo() 返回后包含 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]  
}