使用变量后我知道后缀运算符增量值。 但在这种情况下,它是一个有效的声明吗?因为看起来我在返回语句之后修改了一个变量。
#include <iostream>
using namespace std;
int val = 0;
int foo()
{
return val++;
}
int main()
{
cout<<foo();
cout<<endl<<val;
}
任何详细说明都会有所帮助。
答案 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++;
}
它首先返回val
,0
,然后增加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]
}