int demo()
{
static int i = 1;
return i++;
}
int main()
{
printf("%d %d %d\n", demo(), demo(), demo());
return 0;
}
输出: -
3 2 1
在第一次demo
通话期间,会返回1
。
我听说当执行return
语句时,控件会传递给calling
函数,而不会在called
函数中进一步执行代码。
所以我的问题是,在我的代码中,在第一次调用时返回1
时,为什么它的值会递增?
换句话说,我想知道在返回1
之后,为什么要执行++
?
答案 0 :(得分:1)
int demo()
{
static int i = 1;
return i++;
}
int main()
{
printf("%d %d %d\n", demo1(), demo2(), demo3());
return 0;
}
demo_i()
的执行顺序取决于语言。
现在,使用static
关键字。
Static variables
stack
会在整个计划期间持续function
,即使在returns
结束且Due to this , 1st time : i=1
return 1 , increment to 2 .
2nd time : i=2
return 2 , increment to 3 .
3rd time : i=3
return 3 , increment to 4 .
之后也是如此。
{{1}}
希望这有帮助!
答案 1 :(得分:0)
这里要记住三点:
static
个函数在第一次创建时会持续整个程序的持续时间
返回的变量也有 postfix ++运算符,这意味着:“使用该值(即返回它)并将其递增”AFTERWARDS“:不返回递增的值。
这就是为什么这个变量对所发生的事情有“记忆”并且会增加。
- >你为什么看到“3 2 1”而不是“1 2 3”?
评估参数的顺序不是'先验',而是由编译器决定,参见https://stackoverflow.com/a/12960263/1938163
如果您真的想知道如何首先返回值然后递增,请查看生成的asm代码:
demo(): # @demo()
movl demo()::i, %eax # move i and put it into eax
movl %eax, %ecx # Move eax into ecx -> eax will be used/returned!
addl $1, %ecx # Increment ecx
movl %ecx, demo()::i # save ecx into i -> this is for the next round!
ret # returns!
main: # @main
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $0, -4(%rbp)
callq demo() # Call demo()
movl %eax, -8(%rbp) # save eax in rbp-8 (contains 1, demo::i is 2 for the next round)
callq demo() # Call demo()
movl %eax, -12(%rbp) # save eax in rbp-12 (contains 2, demo::i is 3 for the next round)
callq demo() # Call demo()
leaq .L.str, %rdi # load str address
movl -8(%rbp), %esi # esi points to 1
movl -12(%rbp), %edx # edx points to 2
movl %eax, %ecx # move eax (3) into ecx (demo::i is 4 but doesn't get used)
movb $0, %al # needed by the ABI to call printf
callq printf # call printf() and display 3 2 1
movl $0, %ecx
movl %eax, -16(%rbp)
movl %ecx, %eax
addq $16, %rsp
popq %rbp
ret
demo()::i:
.L.str:
.asciz "%d %d %d\n"
64位ABI使用寄存器(RDI,RSI,RDX,RCX,R8和R9)代替堆栈进行参数传递。
答案 2 :(得分:0)
您的函数返回i
的旧值并递增它。由于您使用了static
关键字,因此i
的值已存储并可供下次调用(调用后不会消失)。
我听说当执行
return
语句时,控制传递给调用函数,而不会在被调用函数中进一步执行代码。
你听到了。但这并不意味着return
语句返回的语句不会被执行。查看示例:
return a + b;
现在执行此语句然后首先评估a+b
,然后将其值返回给调用者。
return i++;
执行,然后执行i++
。它返回先前的i
值并将其递增1
。
答案 3 :(得分:0)
[...]我想知道在返回1后,为什么要执行++?
后缀运算符由C标准定义为:
6.5.2.4后缀增量和减量运算符
[...]
2 postfix ++运算符的结果是操作数的值。结果之后 获得后,操作数的值递增。 (即,适当的值1 类型被添加到它。)
所以在执行return
之前i
是递增的,但由于后缀操作的结果是“原始”值,return
会返回此“原始”值。