Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 关于返回语句的混淆_C_Return - Fatal编程技术网

C 关于返回语句的混淆

C 关于返回语句的混淆,c,return,C,Return,输出:- int demo() { static int i = 1; return i++; } int main() { printf("%d %d %d\n", demo(), demo(), demo()); return 0; } 在第一次demo调用期间,返回1 我听说,当执行return语句时,控制权会传递给调用的函数,而不会进一步执行调用的函数中的代码 所以我的问题是,在我的代码中,当第一次调用返回1时,为什么它的值会递增 换句话说,我想知道在

输出:-

int demo()
{
   static int i = 1;
   return i++;
}

int main()
{
    printf("%d %d %d\n", demo(), demo(), demo());
    return 0;
}  
在第一次
demo
调用期间,返回
1

我听说,当执行
return
语句时,控制权会传递给
调用的
函数,而不会进一步执行
调用的
函数中的代码

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


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

这里要记住三点:

  • 静态
    函数中的变量在程序第一次创建时,会在整个过程中持续存在

  • 返回的变量还有后缀++运算符,这意味着:“使用值(即返回值)并在其后递增”:递增的值不会返回

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

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

    参数的求值顺序“先验”未知,由编译器决定,请参阅


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

    3 2 1
    

    64位ABI使用寄存器(RDI、RSI、RDX、RCX、R8和R9)而不是堆栈来传递参数。

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

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

    你没听错。但这并不意味着
    return
    语句返回的语句不执行。请参见一个示例:

    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"
    
    现在执行此语句,然后首先计算
    a+b
    get,然后将其值返回给调用者。以类似的方式

    return a + b;  
    
    执行get executed,然后执行
    i++
    。它返回以前的
    i
    值,并将其递增
    1

    return i++;
    
    demo_i()
    的执行顺序取决于语言

    现在,使用
    static
    关键字。
    静态变量
    在程序的整个过程中始终保持在
    堆栈上
    ,即使在
    函数
    结束并且
    返回值之后也是如此

    int demo()
    {
       static int i = 1;
       return i++;
    }
    
    int main()
    {
        printf("%d %d %d\n", demo1(), demo2(), demo3());
        return 0;
    }  
    
    希望这有帮助

    […]我想知道,在返回1之后,为什么要执行++

    后缀运算符由C标准定义为如下工作方式:

    6.5.2.4后缀递增和递减运算符

    [……]

    2后缀++运算符的结果是操作数的值。结果出来之后 获取时,操作数的值将递增。(即,适当的 类型已添加到其中。)


    因此,在执行
    return
    之前,
    i
    是递增的,但由于后缀操作的结果是“原始”值,
    return
    返回此“原始”值。

    postfix++返回旧值,并递增变量。不要混淆这两个概念。增量是运算符的副作用。编译此程序时,请使用gcc的
    -Wall
    选项,它将向您显示行为可能未定义的警告!与不久前的提问非常相似。@Elazar:但在我的例子中,当返回值时,它是如何递增的,因为控件现在位于它的实现定义的
    main()
    @JoachimPileborg中。请告诉我
    eax
    是什么意思?eax是一个寄存器,一个足够小的内存位置,可以包含一个值或一个地址。它们不是变量,当您设置一个变量时,它会一直存在,直到您再次更改它,因此在上面的示例中,它用于移动静态变量值。
    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 .