堆栈 订阅
在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。 展开全文
在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。
信息
外文名
Stack
定    义
一种数据项按序排列的数据结构
特    点
先进后出
中文名
堆栈
学    科
计算机
应    用
内存分配
堆栈简介
堆栈是一个特定的存储区或寄存器,它的一端是固定的,另一端是浮动的 [1]  。对这个存储区存入的数据,是一种特殊的数据结构。所有的数据存入或取出,只能在浮动的一端(称栈顶)进行,严格按照“先进后出”的原则存取,位于其中间的元素,必须在其栈上部(后进栈者)诸元素逐个移出后才能取出。在内存储器(随机存储器)中开辟一个区域作为堆栈,叫软件堆栈;用寄存器构成的堆栈,叫硬件堆栈。单片机应用中,堆栈是个特殊存储区,堆栈属于RAM空间的一部分,堆栈用于函数调用、中断切换时保存和恢复现场数据。堆栈中的物体具有一个特性:第一个放入堆栈中的物体总是被最后拿出来, 这个特性通常称为先进后出 (FILO—First-In/Last-Out)。 堆栈中定义了一些操作, 两个最重要的是PUSH和POP。 PUSH(入栈)操作:堆栈指针(SP)加1,然后在堆栈的顶部加入一 个元素。POP(出栈)操作相反,出栈则先将SP所指示的内部ram单元中内容送入直接地址寻址的单元中(目的位置),然后再将堆栈指针(SP)减1。这两种操作实现了数据项的插入和删除。
收起全文
精华内容
下载资源
问答
  • 堆栈

    千次阅读 2020-01-21 21:58:54
    堆栈的抽象数据类型描述 类型名称:堆栈(stack) 数据对象集: 一个有0个元素的又穷线性表。 操作集: 长度为MaxSize的堆栈S属于Stack, 堆栈元素item 属于 ElementType 1、Stack CreateStack(int MaxSize): ...

    堆栈的抽象数据类型描述

    类型名称:堆栈(stack)

    数据对象集: 一个有0个元素的又穷线性表。

    操作集: 长度为MaxSize的堆栈S属于Stack, 堆栈元素item 属于
    ElementType

    1、Stack CreateStack(int MaxSize): 生成空堆栈, 其最大长度为MaxSize;

    2、int IsFull (Stack S, int MaxSize): 判断堆栈S是否已满;

    3、void Push(Stack S, ElementType item): 将元素item压入堆栈;

    ***4、ElementType Pop(Stack S): 删除并返回栈顶元素;

    在这里插入图片描述

    展开全文
  • JavaScript执行堆栈

    万次阅读 2019-05-10 08:01:59
    我们首先看JavaScript的函数底层工作原理 一个函数运行的信息被存储在它的执行上下文里。...与它关联的执行上下文被一个叫做执行上下文堆栈的特殊数据结构保存; 执行嵌套调用; 嵌套调用结束后...

    我们首先看JavaScript的函数底层工作原理
    一个函数运行的信息被存储在它的执行上下文里。
    执行上下文是一个内部数据结构,它包含一个函数执行时的细节:当前工作流在哪里,当前的变量,this的值(这里我们不使用它),以及其他一些内部细节。
    每个函数有嵌套调用时,下面的事情会发生:

    • 当前函数被暂停;
    • 与它关联的执行上下文被一个叫做执行上下文堆栈的特殊数据结构保存;
    • 执行嵌套调用;
    • 嵌套调用结束后,之前的执行上下文从堆栈中恢复,外部函数从停止的地方继续执行。
      我们看看调用pow(2, 3)都发生了什么。
      pow(2, 3)
      在调用pow(2, 3)的开始,执行上下文会存储变量:x = 2, n = 3,执行流程在函数的第1行。
      我们将其描绘如下:
      在这里插入图片描述
      这是函数开始执行的时候,条件 n == 1结果为否,所以流程进入if的第二分支。
    function pow(x, n) {
    	if (n == 1) {
    		return x;
    	} else {
    		return x * pow(x, n - 1);
    	}
    }
    alert(pow(2, 3));
    

    变量相同,但是函数变化了,所以现在上下文是:
    在这里插入图片描述
    为了计算x * pow(x, n - 1),我们需要用新的参数pow(2, 2)自调用pow。
    pow(2, 2)
    为了执行嵌套调用,JavaScript会记住执行上下文堆栈中的当前执行上下文。
    这里我们调用相同的函数pow,但是没关系。所有函数的处理都是一样的:
    1.当前上下文被「记录」在堆栈的顶部;
    2.为子调用创建新上下文;
    3.当子调用结束后 —— 前一上下文从堆栈弹出,继续执行。
    下面是进入子调用pow(2, 2)的上下文堆栈:
    在这里插入图片描述
    新的当前执行上下文位于顶部(加粗),前面的在下方。
    在我们完成子调用后—— 很容恢复前面的上下文,因为它保留这变量和代码停止时的准确位置。图中我们使用了单词「行」,但实际比这更精确。
    pow(2, 1)
    重复该过程:在第5行生成新的子调用,现在使用参数x = 2, n = 1。
    新的执行上下文被创建,前一个被压入堆栈顶部:
    在这里插入图片描述
    此时,有俩个旧的上下文和一个当前正在运行的给pow(2, 1)的上下文。
    出口
    在 pow(2, 1) 时,不像之前,条件 n == 1 成了是,所以 if 的第一分支生效:

    function pow(x, n) {
    	if (n == 1) {
    		return x;
    	} else {
    		return x * pow(x, n - 1);
    	}
    }
    

    此时不再有嵌套调用,所以函数结束,返回2。
    函数结束后,它的执行上下文不再有用,会在内存中移除。前一上下文从栈顶恢复:
    在这里插入图片描述
    恢复执行pow(2, 2),它有子调用pow(2, 1)的结果,所以它也可以结束x * pow(x, n - 1) 的执行,返回 4。
    然后前一上下文被恢复:
    在这里插入图片描述
    当它结束后,我们得到结果pow(2, 3) = 8。
    递归深度是:3。
    从上面的图解可以看到,递归深度等于堆栈中上下文的最大个数。
    注意内存要求。上下文消耗内存,在我们的例子中,求n次放需要存储n个上下文,以便减一后的n使用。
    而循环算法更省内存:

    function pow(x, n) {
    	let result = 1;
    	for (let i = 0; i < n; i++) {
    		result *= x;
    	}
    	return result;
    }
    

    迭代pow仅使用一个上下文,在处理中修改i和result。它的内存要求比较小,且固定不依赖n。
    任何递归都可以用循环来重写。循环变体一般更加有效。
    但有时重写很难,尤其是函数根据条件使用不同的子调用,然后合并它们的结果,或者分支比较复杂。而且有些优化可能没有必要,完全不值得。
    递归能提供更简洁的代码,容易理解和维护。优化并不是处处需要,大多数时候我们需要一个好代码,这就是它被使用的原因。

    展开全文
  • 关于堆栈

    万次阅读 多人点赞 2019-09-05 17:15:07
    写这篇博客的时候,我总会想到之前面试被怼的经历。 面试官最后总结出来一句话:你总是知其然不知其所以然!太浮于表面了 确实,了解一项知识之前首先应该明确: 1.它是什么?...堆栈到底是什么? ...

    每次看到这篇博客的时候,都能想到之前面试被怼的经历。面试官最后总结出来一句话:你总是知其然不知其所以然!太浮于表面了。今天的面试就到这里了,你还有什么想问的吗~~

    确实,了解一项知识或者技术之前首先应该明确:

    1. 它是什么?
    2. 它为什么会出现(或者说它解决了什么)?
    3. 我们要怎么去使用它?

    堆和栈到底是什么?

    首先栈和堆(托管堆)都存在于进程的虚拟内存中。栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域。
    堆(Heap)是应用程序在运行的时候请求操作系统分配给自己内存,一般是申请/给予的过程。由于从操作系统管理的内存分配所以在分配和销毁时都要占用时间,所以用堆的效率低的多!但是堆的好处是可以做的很大,C/C++对分配的Heap是不初始化的。

    栈Stack
    可以将栈想象成一堆从顶向下堆叠的盒子(如下图左边),当每调用一次方法时,我们将应用程序中所要发生的事情记录在栈顶的一个盒子中,而我们每次只能够使用栈顶的那个盒子。当我们栈顶的盒子被使用完之后,或者说方法执行完毕之后,我们将抛开这个盒子然后继续使用栈顶上的新盒子

    1. 栈中存储值类型。
    2. 栈上是向下填充的,数据只能从栈的顶端插入和删除(先进后出原则)。把数据放入栈顶称为入栈(push),从栈顶删除数据称为出栈(pop)
    3. 栈是自行维护的,也就是说内存自动维护栈,当栈顶的盒子不再被使用,它将被抛出。
    4. 栈的空间较小,但访问速度快

    堆栈
    堆Heap
    堆不分先进后出还是先进先出,堆没有任何访问限制(上图右),它就像是你的书架,所有的书都排列在书架上,当你想看某一本书的时候,可以随时找到一本我们需要的书,从书架上把它拿下来。
    而栈就像一串糖葫芦,你总是会先吃到最上面那个山楂(如果你习惯从下面开始吃的话当我没说-.-)

    1. 堆(也叫做托管堆)存储引用类型。
    2. 堆受垃圾处理器GC管理
    3. 堆没有访问限制
    4. 堆的空间较大,但访问速度没有栈快

    这里要说一下引用类型存储在堆里其实并不全面,引用类型的本身储存在堆里面,引用地址则储存在栈里。就像上面说的书架:
    书架里面有很多本书,引用类型的对象本身就相当于书,而引用地址就像是一个指向(比如第三排从左往右数第3本),它指明了某本书在书架的具体位置,这样我们就可以根据这个指向轻松的拿到书了。
    如果还不理解的话

    //a代表 最适合c#入门的书
    string a = "C# 7.0 in a Nutshell";
    
    //b代表 学c#必看的书
    string b = a;
    

    上面声明引用类型变量a和b的时候究竟发生了什么呢:
    首先第一句声明a的代码:“C# 7.0 in a Nutshell"被存储在堆里面,并生成一个指向它的地址保存在栈里面。
    第二句又声明了一个变量b,这里的 b = a其实就是把a存储在栈里的引用地址复制了一份给了b,而对应的值C# 7.0 in a Nutshell还是只有一份。

    堆和栈的清理:
    栈是自上往下压入,使用时从上往下依次去拿,所以栈里的数据就像是弹夹里的子弹,打完就没了。(内存会自动清理掉已使用过的数据)
    而堆则是由GC进行管理:垃圾收集器的基本算法很简单

    1. 将所有的托管内存标记为垃圾
    2. 寻找正被使用的内存块,并将他们标记为有效
    3. 释放所有没有被使用的内存块
    4. 整理堆以减少碎片

    也就是说,当需要清理内存的时候,GC会去找那些很久没有引用地址指向的内存块,把它们清理掉。

    为什么要有堆栈(或者说它解决了什么)?

    栈:为了存放运行时的局部变量,参数,返回数据,返回地址等。
    堆:栈的性能非常高,但是对于所有的变量来说还不太灵活,而且变量的生命周期必须嵌套。
    通常我们希望使用一种方法分配内存来存储数据,并且方法退出后很长一段时间内数据仍然可以使用。此时就要用到堆(托管堆)。

    展开全文
  • 堆栈寻址

    千次阅读 2020-04-03 12:49:05
    堆栈寻址 堆栈寻址:操作数存放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。 堆栈是寄存器(或专用寄存器组)中一块特定的按"后进先出(LIFO)" 原则管理的存储区,该存储区中被读/写单元的地址是用一个特定的寄存器...

    堆栈寻址

    堆栈寻址:操作数存放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。
    堆栈是寄存器(或专用寄存器组)中一块特定的按"后进先出(LIFO)"
    原则管理的存储区,该存储区中被读/写单元的地址是用一个特定的寄存器给出的,该寄存器称为堆栈指针(SP)
    在这里插入图片描述

    硬堆栈和软堆栈

    在这里插入图片描述

    展开全文
  • 堆栈溢出

    千次阅读 2019-03-26 22:10:13
    堆栈:是一个在计算机科学中经常使用的抽象数据类型,堆栈是一块保存数据的连续内存。 一个名为堆栈指针(SP)的寄存器指向堆栈的顶部,堆栈的底部在一个固定的地址。 堆栈中的物体具有一个特性: 最后一个放入堆栈中的...
  • 堆栈的C语言实现

    千次阅读 2017-10-18 13:26:35
    堆栈
  • 51单片机 堆栈堆栈指针

    千次阅读 多人点赞 2018-10-04 14:36:29
    堆栈是一种执行“先入后出”算法的数据结构。是在内存中的一个存储区域,数据一个一个顺序地存入(也就是“压入—PUSH”)这个区域之中。  有一个地址指针(堆栈指针)总指向最后一个压入堆栈的数据所在的存储单元...
  • 调用堆栈

    千次阅读 2018-10-22 14:57:53
    一个调用堆栈 是一个解释的机制(如在Web浏览器中的JavaScript解释器)是来跟踪其位置的调用多种脚本功能, 以及目前正在运行,哪些功能是从函数中调用等。 当脚本调用函数时,解释器将其添加到调用堆栈,然后开始...
  • 堆栈

    2019-10-01 13:26:34
    滴水逆向三期—堆栈图 什么叫逆向? 比如说有一块内存,内存里面存储的就是数据,那我们所谓的逆向就是来分析这个数据到底是什么 堆栈图: 比如给个地址0x401168 打开DTDebug: ctrl+g 将地址打上后 ok: 看到定位...
  • 任务堆栈

    2017-03-07 08:44:14
    每个任务都有自己的堆栈空间。堆栈必须声明为OS_STK类型,并且由连续的内存空间组成。用户可以静态分配堆栈空间(在编译的时候分配)也可以动态地分配堆栈空间(在运行的时候分配)。静态堆栈声明如程序清单 L4.4和4.5所...
  • 深入理解任务堆栈以及堆栈溢出

    千次阅读 2019-05-26 23:56:18
    在多任务操作系统中创建任务时,都需要指定该任务的堆栈大小,那么这个堆栈的作用时什么呢?什么情况下需要用到堆栈,以及大小不够时会产生什么异常呢? 1 任务状态 简单分为运行态,就绪态,阻塞态。 运行态:...
  • 1. 设置堆栈空间大小在使用STM32编程时,一般情况下我们不会关注堆栈空间的大小,因为在STM32的启动文件中,已经帮我们预先设置好了堆栈空间的大小。一般默认的启动代码中,Stack栈的大小为:0x400(1024Byte),...
  • 顺序堆栈

    2017-03-20 16:02:26
    堆栈示意图 堆栈进出原则 先进后出 数据集合 堆栈的数据集合的元素可以表示为任意的类类型。 操作集合 (1)入栈push(obj):把数据元素obj插入堆栈; (2)出栈pop():出栈,删除的数据元素由函数返回; (3)取栈顶...
  • 根据汇编指令画堆栈

    万次阅读 2020-06-04 19:14:06
    3. 记录此时的堆栈位置,开始画堆栈图。 4. 参数入栈,再次记录栈顶位置。 5. 函数调用处地址压栈,栈顶 + 4。地址为此行指令执行结束后的地址,通过指令宽度(当前地址加当前指令长度:此处为5字节)计算出来。 6....
  • 另类堆栈

    千次阅读 2017-06-23 21:55:43
    习题3.14 另类堆栈 (15分) 在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满? 函数接口定义: bool Push( ...
  • ARM满堆栈与空堆栈简明理解

    千次阅读 2018-05-18 08:21:43
    初学ARM指令时,如果从字面上理解满堆栈和空堆栈很有可能会歪曲它们的意思。可以想象一下,“满堆栈”就是一个满的堆栈,不能再存储数据了;而“空堆栈”就是一个空的堆栈,没有被使用的堆栈,呵呵,这样理解的话那...
  • 内存中的堆栈和数据结构堆栈区别

    千次阅读 2019-06-26 16:43:19
    堆栈的认识1.内存中的堆栈代码区静态数据区栈区堆区2.数据结构中的堆栈 内存中的堆栈和数据结构堆栈不是一个概念,可以说内存中的堆栈是真实存在的物理区,数据结构中的堆栈是抽象的数据存储结构。 1.内存中的堆栈 ...
  • 满递减堆栈

    千次阅读 2020-01-19 03:33:19
    满递减堆栈 定义:堆栈指针指向栈顶元素,且堆栈由高地址向低地址方向增长。
  • 前言在嵌入式应用开发过程中,由于MCU的存储资源有限,因此堆栈空间大小的设定极为关键。堆栈空间设置过大则会造成资源的浪费,堆栈空间设置过小则可能导致堆栈溢出等问题。如何设定一个合理的堆栈空间大小困扰着...
  • 硬件堆栈:或许也可以称作系统堆栈,是位于片内RAM区。有人说,只要能使用PUSH,POP指令的单片机,都可以说含有硬件堆栈。这样的说法我个人觉得不是很全面。通过指令进行压栈和出栈操作只是系统堆栈中的一种操做。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 88,420
精华内容 35,368
热门标签
关键字:

堆栈