我想知道为什么我们使用术语"推"和"弹出"来添加/删除堆栈中的项目?是否有一些物理比喻导致这些术语变得普遍?
我唯一的建议就像弹簧式手枪杂志一样,轮子被"推"进去,可以"弹出",但这似乎有点不太可能.
第二个堆栈琐事问题:为什么大多数CPU实现调用堆栈在内存中向下增长而不是向上?
对于你的第二个问题,维基百科有一篇关于控制堆栈的CS哲学的文章:
http://en.wikipedia.org/wiki/LIFO
而对于第一个,也在维基百科上:
一个经常使用的比喻是在春天装载的自助餐厅堆栈中的一堆盘子的想法.在这样的堆叠中,只有顶板是可见的并且用户可以访问,所有其他板都保持隐藏.当添加新板时,每个新板成为堆叠的顶部,将每个板隐藏在下面,将堆叠板向下推.当顶板从堆叠中移除时,可以使用它们,板弹回,并且第二板成为堆叠的顶部.这个比喻说明了两个重要的原则:后进先出原则是一个原则; 第二个是隐藏堆栈的内容.只有顶板是可见的,因此要查看第三块板上的内容,必须移除第一块和第二块板.这也可以写成FILO-First In Last Out,即
我相信弹簧加载的板堆是正确的,作为术语PUSH和POP的来源.
特别是麻省理工学院东校区公共娱乐场在1957 - 1967年的时间框架内有一堆弹簧堆叠的板块.术语PUSH和POP将由Tech Model Railroad Club使用.我认为这是起源.
Tech Model Railroad Club肯定影响了数字设备公司(DEC)PDP-6的设计.PDP-6是第一批在硬件中具有面向堆栈指令的机器之一.说明书是PUSH,POP,PUSHJ,POPJ.
http://ed-thelen.org/comp-hist/pdp-6.html#Special%20Features
对于第二个问题:小型系统上的汇编程序员倾向于编写从内存中的低地址开始的代码,并随着更多代码的增加而扩展到更高的地址.
因此,使堆栈向下增长允许您在物理内存的顶部启动堆栈,并允许两个内存区域朝向彼此增长.这简化了这种琐碎环境中的内存管理.
即使在具有隔离ROM/RAM的系统中,固定数据分配也是最容易从下到上构建的,因此取代了上述解释的代码部分.
虽然这种琐碎的存储器方案已经非常罕见,但硬件实践仍在继续.
把它想象成一台pez饮水机.你可以推出一个新的.然后把它从顶部弹出.
当我认为推和弹时,这总是我的想法.(虽然可能不是很历史)
你问自己PEZ究竟是什么? 查看评论.
头韵总是很有吸引力(看我在那里做了什么?),这些话很简短,有说服力,有启发性.旧的BASIC命令peek和poke也是如此,它们具有并行k的额外优势.
一个常见的物理比喻是自助餐盘式分配器,其中一个弹簧加载的板堆使得你可以从顶部取下一个盘子,但是下一个盘子上升到相同的位置.
重新提出你的"第二个琐碎的问题":我在定义"向上"和"向下"的含义时看到了相当大的不一致!从早期开始,一些制造商和作者在页面顶部绘制了具有低地址的存储器图(可能模仿了读取页面的顺序),而其他制造商和作者则将高地址放在页面顶部(可能是模仿图纸坐标)或建筑物中的地板).
当然,堆栈的概念(以及可寻址存储器的概念)与这些视觉隐喻无关.可以实现在任一方向上"增长"的堆栈.事实上,我经常看到下面的技巧(在裸机级别实现中)用于共享两个堆栈之间的内存区域:
+---+---+-------- -------+--+--+--+ | | | -> ... <- | | | | +---+---+-------- -------+--+--+--+ ^ ^ Stack 1 both stacks Stack 2 base "grow" toward base the middle
所以我的答案是,堆栈在概念上永远不会 "向下"或"向上"增长,而只是从它们的基础增长.单个堆栈可以在任一方向上实现(或者在任何方向上实现,如果它使用具有垃圾收集的链接表示,在这种情况下,元素可以在节点空间中的任何位置).