首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于返回声明的混淆

关于返回声明的混淆
EN

Stack Overflow用户
提问于 2014-02-16 09:10:54
回答 4查看 111关注 0票数 1
代码语言:javascript
运行
复制
int demo()
{
   static int i = 1;
   return i++;
}

int main()
{
    printf("%d %d %d\n", demo(), demo(), demo());
    return 0;
}  

产出:-

代码语言:javascript
运行
复制
3 2 1

在第一个demo调用期间,将返回1

我听说在执行return语句时,控制传递给calling函数,而不需要进一步执行called函数中的代码。

所以我的问题是,在我的代码中,当1在第一次调用中被返回时,为什么它的值会增加?

换句话说,我想知道在返回1之后,为什么要执行++

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-16 09:14:03

在此要牢记三点:

  1. 函数中的static变量第一次创建时就会持续到整个程序期间
  2. 返回的变量还带有后缀 ++运算符,意思是:“使用值(即返回它)并在之后递增它”:增量的值不返回。

这就是为什么这个变量对所发生的事情有“记忆”,并且会增加。

->为什么你看到的是"3 2 1“而不是”12 3"?

参数的计算顺序不知道“先验”,这要由编译器来决定,请参阅https://stackoverflow.com/a/12960263/1938163

如果您真的想知道该值如何可能首先返回,然后递增,请查看生成的asm代码:

代码语言:javascript
运行
复制
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)代替堆栈进行参数传递。

票数 0
EN

Stack Overflow用户

发布于 2014-02-16 09:19:32

代码语言:javascript
运行
复制
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之后也是如此。

代码语言:javascript
运行
复制
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
EN

Stack Overflow用户

发布于 2014-02-16 09:14:10

您的函数返回旧的i值并将其递增。由于您使用了static关键字,所以i的值是存储的,并可用于下一次调用(在调用之后它不会消失)。

我听说在执行return语句时,控制传递到调用函数,而不需要进一步执行被调用函数中的代码。

你听得对。但这并不意味着return语句返回的语句不执行。见一个例子:

代码语言:javascript
运行
复制
return a + b;  

现在执行该语句,然后首先对a+b进行评估,然后将其值返回给调用方。以类似的方式

代码语言:javascript
运行
复制
return i++;

得到执行,然后执行i++。它返回i的前一个值,并通过1来增加它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21809297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档