2015-03-25 95 views
-2

我知道使用变量后的postfix运算符增量值。 但在这种情况下,这是否是一个有效的陈述?因为它看起来像我在它的return语句后修改一个变量。为什么这段代码返回0&1?

#include <iostream> 

using namespace std; 

int val = 0; 

int foo() 
{ 
     return val++; 
} 

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

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

+1

'val'是一个全局变量。 – 2015-03-25 01:29:39

+6

而不是在return语句后面想'val ++'递增'val' *,可以这样想:'val ++'将'val'的原始值保存到某个看不见的temp中,然后增加'val'中的值,然后使用不可见的temp作为“返回”值。 – WhozCraig 2015-03-25 01:45:10

回答

6

说的是return val++先是返回val然后递增就是不是真的。表达式val++递增val的值,但是评估到旧值val

你可以把后缀++作为使用一个辅助变量来保存旧值的函数:

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

是的,它是有效的。

不要以为它会返回val,然后再递增。

取而代之,您将返回操作val++的结果。

2

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

当你调用foo()

int foo() 
{ 
    return val++; 
} 

它将返回 val首先,这是 0,并且 val 然后增量的值,因此 val = 1

如引述天顶,

表达val++递增的val值,但是递增之前评估到的val值。

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

1

为了见编译器已经代表你的代码的具体步骤,我检查拆解。

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

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

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

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

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

行00324C48将存储在“foo”函数的本地堆栈空间(参见上面的行00324C33)中的值的未受影响的副本复制到CPU的eax寄存器中。它被复制到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] 
} 
+0

刚刚意识到我的答案并不是一个很好的解释,但作为Zenith答案中的精彩解释(不需要补充IMO)的补充更好。我只是喜欢拆卸东西。 :) – 2015-03-25 02:52:56

相关问题