首页
学习
活动
专区
圈层
工具
发布

C记忆
EN

Stack Overflow用户
提问于 2019-10-16 23:43:25
回答 2查看 140关注 0票数 1
  1. 计算机如何在内存中保存每个已更改的'i'值并打印出来?
  2. 在此代码中使用了多少字节?24个字节(i = 5、4、3、2、1、0)?

以下代码打印: 1,2,3,4,5。

代码语言:javascript
复制
#include <stdio.h>

void test(int i)
{
    if (i == 0) return;
    test(i - 1);
    printf("%d\n", i);
}

int main(void)
{
    test(5);
    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2019-10-17 02:27:37

现代CPU体系结构上的“堆栈”是一个内存区域(每个线程都是分开的),除其他外,存储函数调用时的返回地址、函数调用参数、非静态局部变量(通常按该顺序,但并不总是这样)。每次用C(和大多数现代语言)调用任何函数时,返回地址(即将被调用的函数完成执行后跳转到的地址)被推到堆栈上,堆栈指针被地址的大小(假设堆栈长大)递增,然后每个函数参数被推入堆栈,堆栈指针再次被每个参数的大小递增。当每个函数局部变量都被分配空间时,堆栈指针在被推到堆栈上时会随着该变量的大小而增加。当函数返回时,堆栈指针被推到堆栈上的每个变量的大小值“解缠绕”,因为它们是从堆栈中弹出的。接下来,函数调用参数从堆栈中弹出,并且堆栈指针再次根据每个参数的大小减少。最后,函数跳转到返回地址,该返回地址在调用函数时最初被推送到堆栈,然后弹出,堆栈指针根据地址的大小减少。我们现在已经准备好执行函数调用之后的任何代码,堆栈指针就在函数调用之前的位置。

在递归函数调用的情况下,每个嵌套函数调用的返回地址、函数调用参数和函数局部变量都被推入堆栈,但在最终递归函数调用返回之前不会从堆栈中弹出。它们从堆栈中弹出的顺序与它们被推到堆栈上的顺序相反(由于堆栈本质上是Last,LIFO,数据结构)。

假设这是在32位CPU上执行的,并且'int‘是4个字节,那么每个递归函数调用的返回地址加上一个函数参数将被推到堆栈上。在最大的堆栈利用率(在test(0)返回之前),我们将有6x递归调用( 5,4,3,2,1,0)和32位(4字节)返回地址,加上每个调用的4字节参数,因此6* (4 + 4) = 48字节。

票数 2
EN

Stack Overflow用户

发布于 2019-10-17 00:21:17

test的每个实例都有自己的i实例。调用函数时,存储当前函数的当前执行环境,并为新函数设置上下文。当该新函数返回时,调用函数的上下文将被还原。

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

https://stackoverflow.com/questions/58423013

复制
相关文章

相似问题

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