【问题标题】:How does the stack work?堆栈如何工作?
【发布时间】:2013-02-16 13:46:31
【问题描述】:

我有几个关于堆栈的问题。我不了解堆栈的一件事是“弹出”和“推送”的想法。假设我有整数 a 和 b,堆栈上的 a 高于 b。据我了解,要访问 b,必须将 a 从堆栈中弹出才能访问 b。那么“a”从堆栈中弹出时存储在哪里。

另外,如果栈内存比堆内存访问效率更高,为什么堆内存的结构不像栈?谢谢。

【问题讨论】:

  • 堆的结构不像堆栈,因为你不能像堆栈那样构造内存,并且仍然将它用于堆的用途。

标签: memory-management stack heap-memory


【解决方案1】:

a 存储在您决定存储它的任何位置。 :-) 您需要提供一个变量,当您删除它时将值存储在堆栈顶部(a),然后删除下一项(b)并将其存储在不同的变量中以使用它,然后将第一个值 (a) 推回堆栈。

想象一下你左边柜台上的一堆脏盘子。你拿起一个来洗(从“脏”堆里拿出来),洗干净,晾干,然后放在右边干净的堆顶上(推一下)。

如果您想从任一堆栈的顶部到达第二个盘子,您必须移动最上面的一个才能到达它。所以你把它捡起来(弹出),暂时放在某个地方,拿起下一个盘子(弹出它)并把它放在某个地方,然后把你取出的第一个放回堆上(把它推回堆栈上)。

如果您无法用盘子来描绘它,请使用一副真正的扑克牌(或棒球卡或一叠纸 - 任何您可以整齐堆放(“堆叠”)的东西)并将其放在您的办公桌上左手。然后执行我上一段中的步骤,将单词“plate”替换为“card”并实际执行这些步骤。

所以要访问b,你声明一个变量来存储a,弹出a并将其保存在该变量中,将b弹出到它自己的变量中,然后将a推回堆栈。

【讨论】:

  • 那么你存放盘子的临时地方在哪里?
  • 再次阅读我在上一段中写的内容,并思考一下。用盘子想象它,左手拿起顶盘(一个临时存储位置,在编程中是一个变量),抓住你右边的下一个(一个不同的变量),然后把你左边的那个手回到桩上。
【解决方案2】:

让我们来看看你的案例。

你有一个堆栈,上面有 n 个元素,最后一个是 a,b 在下面。

pop 操作返回弹出的值,所以如果你想访问从顶部开始的第二个 b,你可以这样做:

var temp = stack.pop()
var b = stack.pop()
stack.push(temp)

但是,堆栈很少会以这种方式使用。它是一个 LIFO 队列,在像 LIFO 队列一样访问时效果最佳。

您似乎更愿意使用基于随机索引访问的集合。 该集合可能会存储在堆上。希望它澄清了堆栈弹出/推送。

【讨论】:

    【解决方案3】:

    那么“a”从堆栈中弹出时存储在哪里。

    这取决于。它转到正在读取堆栈的程序决定的地方。它可以存储值,忽略它,打印它,任何东西。

    如果栈内存比堆内存访问效率更高,为什么 堆内存不是和栈一样吗?

    访问堆栈并不比访问堆更有效,这取决于使用情况。程序的流程变得越来越深,就像堆栈一样。在主流语言中,局部变量、参数和返回地址存储在堆栈结构中,因为这种结构更容易实现我们所说的函数堆栈帧的语义。一个函数可以非常高效地访问它自己的栈帧,但不一定是它的调用函数的栈帧,也就是整个栈。

    另一方面,如果以这种方式实现堆,则效率会很低,因为希望堆能够访问并可能删除任何地方的项目,而不仅仅是从其顶部/底部。

    【讨论】:

      【解决方案4】:

      我不是专家,但你可以把它想象成Tower of Hanoi 谜题。要访问较低的磁盘,您可以“弹出”它上面的磁盘并将它们放置在其他地方 - 在这种情况下,在其他堆栈上,但在编程的情况下,它可能只是一个简单的变量或指针或任何东西。当您获得所需的物品后,可以将其他物品放回堆栈或完全移动到其他地方。

      【讨论】:

      • 好的,谢谢。但是我还是不明白已经“弹出”的变量放在哪里了。
      • @Iowa15 我还是不明白。。我脑子里和你有同样的问题。
      猜你喜欢
      • 2018-02-25
      • 2014-08-16
      • 2015-09-15
      • 1970-01-01
      • 2012-01-03
      • 2011-02-10
      • 2011-01-16
      • 2011-05-12
      • 1970-01-01
      相关资源
      最近更新 更多