堆栈

将中缀表达式转换成后缀表达式

倖福魔咒の 提交于 2020-01-18 12:05:34
我们人脑很容易理解中缀表达式,但是中缀表达式在计算机并不好计算,所有我们要将中缀表达式转换成后缀表达式,因为后缀表达式是很容易计算的。为什么要写一个这样的程序呢?原因是我一开始想写一个计算机,它能够将输入的表达式的值计算出来。一开始觉得这样子的程序应该是很简单的,然后开始动手写,开始写了之后才发现并不是那么简单。后来我知道了后缀表达式,才知道原来要这样子才能将表达式的值计算出来。 言归正传 首先是将中缀表达式转换成后缀表达式的方法: 1、遇到操作数:直接输出(添加到后缀表达式中) 2、栈为空时,遇到运算符,直接入栈 3、遇到左括号:将其入栈 4、遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出 5、遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 6、最终将栈中的元素依次出栈,输出 看似很简单,但是写起来真的很头痛。为此我画了好多流程图。我觉得画流程图挺好的,能加深理解。 这次我决定用C 语言。 首先要做一些准备工作。 一、实现堆栈的数据结构,具有以下方法: 1. 初始化堆栈,返回堆栈指针 2. 压入一个元素 3. 弹出一个元素 我所实现的这个堆栈的栈顶元素是空的,它只用于指向堆栈的第一个元素,如果堆栈为空的则它指向NULL。 具体代码: //实现栈的数据结构 typedef struct Node {

呆萌数据结构 | 03 堆栈

两盒软妹~` 提交于 2020-01-18 03:25:03
原文来自 萌一小栈 有一堆书,一本叠一本地放入箱子里,最后放入的,一定是在最上面,对不对。取书的时候,规定只能从上面一本一本地取,如果要拿最先放入箱子里的那本书,也就是最下面的那本书,只能先把上面的拿出来。 什么是堆栈(Stack) 上面说的就是我们今天要讲的堆栈,也可以简单叫做栈。堆栈是很常用很基础的数据结构。堆栈涉及到的概念如果下。 栈顶,就是最上面的一个元素。 压栈(Push),就是将一个元素放入栈中。 弹出(Pop),就是将栈顶的元素从堆栈中拿出来。 就像上面往箱子里放书一样,最先放入堆栈的元素,在最下面,最后放入的元素,在最上面,而取元素,只能从上面一个一个取,不能从中间抽取元素。 堆栈有什么用呢 那栈有什么用呢,举几个简单的例子。我们用的很多软件,都有撤销功能对不对,其实,那个就可以用堆栈来实现。将每一步操作时的状态,保存到堆栈中,当用户要撤销时,就从堆栈中拿出最近的一个状态进行恢复,也就是最后放入堆栈中 (栈顶) 的状态数据。是不是很熟悉? 后面要学到的树的遍历,深度优先搜索,也是用堆栈来实现的。 总之呢,记住一句话, 先进后出(Fist in last out) 或者 后进先出(Last in first out) 就可以完美诠释堆栈这种数据结构。 自己动手实现一下 很多编程语言已经实现了堆栈(Stack)结构,但是呢,我们这里自己实现一下,加深理解。代码使用 C#

IDA F5堆栈不平衡的处理

↘锁芯ラ 提交于 2020-01-17 08:00:59
IDA F5堆栈不平衡的处理 1.引出问题 F5时出现如图错误,一般是程序代码有一些干扰代码,让IDA的反汇编分析出现错误。比如用push + n条指令 + retn来实际跳转,而IDA会以为retn是函数要结束,结果它分析后发现调用栈不平衡,因此就提示sp analysis failed. 我们选择抖音老版本的libcms.so作为分析案例,假设Java代码如下 static { System.loadLibrary("cms"); } public native int getUserInfo(); 我们想要分析getUserInfo这个函数,函数被声明为native,这代表了它是一个native方法,真正的代码逻辑由C/C++等native语言实现,它来自名为cms的库,由静态代码块中的System.loadLibrary加载进内存。在加载和寻找动态库时,Java会判断系统并扩展库名,在Windows平台下cms会被扩展成libcms.dll,Android作为基于linux的系统,则会依照linux被扩展成libcms.so,也就是我们常说的xxx SO库,解压APK取出libcms.so库,我们使用ida打开,默认加载,注意观察IDA左下角,地址值不变化时即加载完毕。 如何找到getUserInfo函数的实现代码?按照惯例,查看Exports栏——函数导出表

逆向分析之核心代码的分析

故事扮演 提交于 2020-01-17 03:38:19
   博客 个人感觉分析正常的(没有花指令)反汇编代码最大的挑战就是难以分清反汇编出的代码是用户的代码还是库的代码,还是编译器插入的代码。克服这一关需要丰富的经验。因此,逆向的入门大多数是难倒在这一关上。 1、识别一个函数   程序都是以函数为一个单位。函数内的多条代码使函数完成了特定的功能,在分析当中也是以一个函数作为一个分析单位。在分析时,应当尽可能多的分析出这个函数所完成的具体功能。   反汇编中的函数一般都有如下格式:    1.1 第一种函数格式   push ebp   mov esp,ebp   ....   pop ebp   ret    1.2 第二种函数格式   这种函数没有特定的格式,但可以肯定是在函数的末尾肯定有ret语句。 2、识别函数的返回值,形参,局部变量 函数一般是使用eax寄存器来保存返回值。但是一些编译器可能用其他的方式来传递返回值,因此,在分析程序的前期,需要确定该程序是用什么编译器进行编译的(通过PEId可以产看),才能确定其返回值是用什么方式进行传递的。 函数的形参个数可以通过函数平衡多少字节的栈空间来推理出。因为存在着许多的传参方式,所以这种方法并不是绝对正确的,因此要先观察出一个函数的传参方式是何种方式。 和函数的传参方式息息相关的函数调用方式:   不同的调用方式平衡堆栈的方式是不同的。C方式调用时,是调用者进行堆栈平衡。传参时

Linux内核分析课程笔记(一)

牧云@^-^@ 提交于 2020-01-17 02:29:49
linux内核分析课程笔记(一) 冯诺依曼体系结构 冯诺依曼体系结构实际上就是存储程序计算机。 从两个层面来讲: 从硬件的角度来看,冯诺依曼体系结构逻辑上可以抽象成CPU和内存,通过总线相连。CPU上有一些寄存器,IP(Instruction Pointer)是一个指针,总是指向内存的某一块区域CS(Code Segment),CPU即从IP指向的地址取一条指令进行执行,执行完之后IP自增1,加到下一条指令(逻辑意义上的1,因为有些指令系统是变长指令) 从程序员的角度来看,存储程序计算机。CPU从程序员的角度可以抽象成一个无条件的for循环,总是执行下一条指令。 for(;;){ next instruction(); } API(Application Program Interface) ABI(Application Binary Interface) 32位的x86中EIP的三条特性: 每条指令执行完成后EIP自加1 指令的长度不同 EIP还可能会被一些指令修改,如:CALL、RET、JMP以及条件JUMP x86汇编基础 x86寄存器 有8位、16位和32位的寄存器。 16位:AX、BX、CX、DX、BP、SI、DI、SP 32位:EAX(累加器)、EBX(基地址寄存器)、ECX(计数寄存器)、EDX(数据寄存器)、EBP(堆栈基址指针)、ESI与EDI(变址寄存器)

JVM相关相关知识点

丶灬走出姿态 提交于 2020-01-16 13:38:05
1.jvm基本结构 编译器会将我们编写的Java文件编译成 .class 文件,JVM会加载并执行 .class 文件。下面的图展示了JVM的整体架构 1,类加载子系统负责动态加载类,在运行时(而非编译时),当一个类初次被引用的时候,它将被加载、链接、初始化。 2,运行时数据区,运行时数据区可以划分为五个区域: 方法区:全局共享资源,所有的类级别的数据都会存储到这里,包括静态变量。 堆区:线程共享的资源,所有的对象和其对应的实例变量和数组都被存储在这个区域。 堆栈区:不共享资源,对于每个线程,将创建单独的运行时堆栈。对于每个方法调用,将在堆栈存储器中产生一个条目,称为堆栈帧。 PC寄存器:每个线程都有单独的PC寄存器,用于保存当前执行指令的地址。一旦执行指令,PC寄存器将被下一条指令更新 本地方法堆栈:本地方法堆栈保存本地方法信息。对于每个线程,将创建一个单独的本地方法堆栈。 3,执行引擎读取字节码并逐个执行 2.类加载 类的生命周期: 加载<将.class文件加载到内存> 连接(验证<验证字节码文件正确性> 准备<给类的静态变量分配内存并赋予默认值> 解析<类装载器装入类所引用的其他所有类> 初始化<给类的静态变量赋予正确的初始值执行静态代码块>-- 使用 卸载 类加载器的种类: 启动类加载器(bootstrap classloader):加载re目录的类 扩展类加载器

【C#】堆、栈和堆栈的区别

*爱你&永不变心* 提交于 2020-01-16 05:22:10
导读: 今天看视频,就看到了堆、栈这一块了。记得当年初相见(VB视频),劈头盖脸一阵蒙,什么都不知道,那时候师傅叫我挂起来,说我随着学习的进度,慢慢的就会懂了。现在,学到了这里,想着自己对自己从前的问题进行解答。可能解答的不够完整不够好,等到我又学了新东西,又有了想法的时候,再回头更改。嘿嘿,先看看当年的问题哈。 一:基本定义 堆( heap ): 堆是一种经过排序的树形数据结构,每个结点都有一个值。 栈( stack) : 它是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。(PS:颇有砌墙的砖——后来者居上的赶脚。) 堆栈 :由堆和栈的概念,可以清晰的知道:堆栈,是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。 PS: 结合查阅的资料,通常所说的堆栈,实际上更偏向于指栈。 二、基本对比 1,申请方式 heap:程序员自己申请,并指明大小。 stack:由系统分配。 2,申请效率 原为: heap:效率较高,速度较快,但程序员无法对其进行控制。 stack:由new分配的内存,相对效率和速度都较低,且容易产生碎片,但由于是程序员自己申请操作,灵活性强,使用方便。 更改:2017-08-23 3:25pm stack:效率较高,速度较快,但程序员无法对其进行控制。 heap:由new分配的内存,相对效率和速度都较低

内存堆和栈的区别

本小妞迷上赌 提交于 2020-01-16 05:19:17
在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到。但对于很多的初学着来说,堆栈是一个很模糊的概念。 堆栈:一种数据结构、一个在程序运行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中的堆栈一词混为一谈。我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不清堆栈,所以我想有必要给大家分享一下我对堆栈的看法,有说的不对的地方请朋友们不吝赐教,这对于大家学习会有很大帮助。 数据结构的栈和堆 首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈。 堆和栈都是一种数据项按序排列的数据结构。 栈就像装数据的桶或箱子 我们先从大家比较熟悉的栈说起吧,它是一种具有 后进先出 性质的数据结构,也就是说后存放的先取,先存放的后取。 这就如同我们要取出放在箱子里面底下的东西(放入的比较早的物体),我们首先要移开压在它上面的物体(放入的比较晚的物体)。 堆像一棵倒过来的树 而堆就不同了,堆是一种 经过排序的树形数据结构 ,每个结点都有一个值。 通常我们所说的堆的数据结构,是指二叉堆。 堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。 由于堆的这个特性,常用来实现优先队列,堆的存取是随意,这就如同我们在图书馆的书架上取书,虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样

JS堆栈与拷贝

二次信任 提交于 2020-01-16 04:33:08
一.堆栈的定义 1.栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。 结论:后进先出(Last In First Out),简称为LIFO线性表。栈的应用有:数制转换,语法词法分析,表达式求值等 2.队列(Queue)也是一种运算受限的线性表,它的运算限制与栈不同,是两头都有限制,插入只能在表的一端进行(只进不出),而删除只能在表的另一端进行(只出不进),允许删除的一端称为队尾(rear),允许插入的一端称为队头 (Front),队列的操作原则是先进先出的,所以队列又称作FIFO表(First In First Out)。 由于栈和队列也是线性表,栈和队列有顺序栈和链栈两种存储结构,这两种存储结构的不同,则使得实现栈的基本运算的算法也有所不同。 二.JS堆栈研究 1、栈(stack)和堆(heap) stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。 2、基本类型和引用类型 (1) 基本类型 :存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。 5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。 (2) 引用类型 :存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置

精讲 JVM架构体系介绍

随声附和 提交于 2020-01-15 11:39:37
每个Java开发人员都知道字节码将由JRE(Java Runtime Environment)执行。但是许多人并不知道JRE是Java虚拟机(JVM)的实现,它可以分析字节码,解释代码并执行它。作为开发人员,了解JVM的体系结构非常重要,因为它使我们能够更高效地编写代码。 通过优锐课的jvm分享,在本文中,我们将更深入地了解Java中的JVM体系结构以及JVM的不同组件。分享给大家参考学习。 什么是JVM? 虚拟机是物理机的软件实现。Java是根据WORA(可在任何地方写入一次)的概念开发的,可在VM上运行。编译器将Java文件编译为Java .class文件,然后将该.class文件输入到JVM中,JVM会加载并执行该类文件。下图是JVM的体系结构图。 JVM体系结构图 JVM如何工作? 如上面的架构图所示,JVM分为三个主要子系统: 1.类加载器子系统 2.运行时数据区 3.执行引擎 1.类加载器子系统 Java的动态类加载功能由类加载器子系统处理。它加载链接,并在运行时(而非编译时)首次引用类时初始化类文件。 1.1加载 类将由该组件加载。引导类装入器、扩展类装入器和应用程序类装入器是有助于实现它的三个类装入器。 1.引导程序类加载器–负责从引导类路径加载类,除了rt.jar此加载程序将获得最高优先级。 2.扩展类加载器–负责加载ext文件夹中的类 3.应用程序类加载器