堆栈是什么,第1张

在计算机领域,栈是一个不可忽视的概念,栈是一种数据结构。栈是数据项按顺序排列的数据结构,数据项只能在一端插入和删除。在单片机的应用中,栈是一个特殊的存储区域,其主要功能是临时存储数据和地址,通常用于保护断点和站点。

在计算机领域,栈是一个不可忽视的概念,栈是一种数据结构。栈是数据项按顺序排列的数据结构,数据项只能在一端插入和删除(称为top)。在单片机的应用中,栈是一个特殊的存储区域,其主要功能是临时存储数据和地址,通常用于保护断点和站点。

堆栈是什么,堆栈是什么,第2张

简介

堆栈是一个特殊的内存区域或寄存器,一端是固定的,另一端是浮动的。存储在这个存储区的数据是一种特殊的数据结构。所有数据只能在浮动端(称为栈顶)存储或取出,严格按照“先进先出”的原则访问。位于中间的元素只有在堆栈上部(后一个)的元素逐个移出后才能取出。在内存(随机存储器)中开辟一个区域作为栈,称为软件栈;由寄存器组成的栈称为硬件栈。

在单片机应用中,栈是一个特殊的存储区域,属于RAM 空的一部分。堆栈用于在函数调用和中断切换期间保存和恢复字段数据。堆栈中的对象有一个特点:堆栈中的第一个对象总是最后取出,通常称为filo-first-in/last-out。栈中定义了一些操作,最重要的两个是PUSH和POP。PUSH操作:栈指针(SP)增加1,然后在栈顶增加一个元素。POP (pop)操作相反。在pop中,由SP指示的内部ram单元的内容被发送到由直接地址(目的地位置)寻址的单元,然后堆栈指针(SP)递减1。这两个操作实现了数据项的插入和删除。

对比分析

栈是计算机科学领域中一种重要的数据结构,在许多数值计算领域中都有应用。表达式求值是编译器中常见的操作。在算术表达式求值过程中,需要使用栈来保存表达式的中间值和运算符,使得表达式中间运算过程的结果访问具有一定的自动化管理能力。大多数编译型编程语言都具有程序递归的特点,可以增强语言的表达能力,降低程序设计的难度。递归程序的递归深度通常是不确定的,因此需要将子程序的返回地址保存在堆栈的先进先出结构中,以保证子程序返回地址的正确使用顺序。在函数式编程语言中,不同子函数的参数类型和个数是不同的,编译器也是用栈来存储子程序的参数。

栈间分配空

栈(操作系统):由操作系统自动分配和释放,用于存储函数的参数值和局部变量的值。它像数据结构中的堆栈一样运行。

堆(操作系统):一般由程序员发布。如果程序员不发布,可能会在程序结束时被OS(操作系统)回收。分配方式类似链表。

区分介绍

爪哇

1.栈和堆都是Java在内存中存储数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接设置栈或堆。

2.栈的优点是访问速度比堆快,仅次于直接位于CPU的寄存器。但缺点是必须确定栈中数据的大小和寿命,缺乏灵活性。此外,堆栈数据不能在多个线程或堆栈之间共享,但堆栈中具有相等值的多个变量可以指向一个地址,详见第3点。堆的优点是可以动态分配内存大小,不需要提前告诉编译器生存期。Java垃圾收集器会自动收集这些未使用的数据。但缺点是运行时动态内存分配导致访问速度慢。

3.Java有两种类型的数据。

有八种基本类型,即int、short、long、byte、float、double、boolean、char(注意没有基本类型的字符串)。例如,该类型由int a= 3定义;长b = 255L的形式,称为自动变量。值得注意的是,自动变量存储文字值,而不是类的实例,也就是对类的引用。这里没有课。如int a = 3;这里的a是对int类型的引用,指向文字值3。这些文字值的数据在大小和寿命上是已知的(这些文字值固定地定义在一个程序块中,在程序块退出后字段值就消失了),它存在于堆栈中是为了追求速度。

另外,栈还有一个重要的特殊性,就是栈中存储的数据是可以共享的。假设我们同时定义:
int a = 3;
int b = 3;
编译器首先处理int a = 3;;首先,它会在堆栈中创建一个变量为A的内存空,然后找出是否有文字值为3的地址。如果没有找到,它会打开一个存储文字值3的地址,然后将A指向3的地址。然后处理int b = 3;;创建B的引用变量后,由于栈中已经有一个文字值3,B会直接指向3的地址。这样,a和b都同时指向3。

尤其是这个文字值的引用和类对象的引用是不一样的。假设两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也立即反映了这个变化。相反,修改对文字的引用的值不会导致指向该文字的另一个引用的值发生变化。比如我们定义了A和B的值之后,设A = 4;那么,b就不等于4,或者说等于3。在编译器内,遇到a = 4;它将重新搜索堆栈中是否有文字值4,如果没有,则重新打开地址来存储值4;如果已经存在,请将A直接指向该地址。所以a值的变化不会影响B值..

另一种是包装类数据,如整数、字符串、双精度等。,它包装了相应的基本数据类型。所有这些类数据都存在于[堆]中。Java使用new()语句明确告诉编译器,它是在运行时根据需要动态创建的,因此更加灵活,但是它的缺点是需要更多的时间。4.字符串是一种特殊的包装数据。那可以用String str = new String(& # 8220;abc & # 8221);以创建的形式,也可以使用String str = & # 8220abc & # 8221;的形式(相比之下,在JDK 5.0之前,你从未见过Integer I = 3;因为类和文字不是通用的,除了String。在JDK5.0中,这个表达式是可以的!因为编译器在后台转换Integer i = new Integer(3)。前者是一个标准的类创建过程,即在Java中,一切都是对象,对象是一个类的实例,都是以new()的形式创建的。Java中的一些类,比如DateFormat类,可以通过它的getInstance()方法返回一个新创建的类,这似乎违背了这个原则。其实不是。这个类使用单例模式返回类的一个实例,只是这个实例是由类内部的new()创建的,而getInstance()从外部隐藏了这个细节。那为什么String str = & # 8220abc & # 8221;在中,实例不是由new()创建的,是否违反了上述原则?事实上没有。

4.关于字符串str = & # 8220abc & # 8221内功。Java内部将此语句转换为如下步骤:[String str = & # 8220;abc & # 8221,字符串字符串不连接]

(1)首先定义一个名为字符串到字符串类:stringstr的对象引用变量;

(2)[查明[栈]中是否有”的存储值;abc & # 8221地址,如果不是,开一个存款字面值是& # 8221;abc & # 8221然后创建一个String类的新对象o,把o的字符串值指向这个地址,在栈中这个地址旁边写下被引用的对象o。如果你已经有了& # 8221;abc & # 8221,找到对象o并返回o的地址.】【上面说数据存储在堆里,这篇文章说数据存储在栈里】【因为不是通过new()在这里创建的】

(3)将字符串指向对象o的地址。

值得注意的是,一般String类中的String值是直接存储的。但是喜欢String str = & # 8220abc & # 8221;在这种情况下,字符串值保存对堆栈中数据的引用!

为了更好地说明这个问题,我们可以用以下代码进行验证。将内容复制到剪贴板的代码:
String str 1 = & # 8221;abc & # 8221;
String str 2 = & # 8221;abc & # 8221;
System . out . println(str 1 = = str 2);//true
请注意,我们不使用字符串1。这里等于(str 2 );因为这将比较两个字符串的值是否相等。= =符号。根据JDK的说法,只有当两个引用都指向同一个对象时,才返回真值。这里我们想看的是str1和str2是否都指向同一个对象。结果显示,JVM创建了两个引用str1和str2,但只有一个对象,两个引用都指向这个对象。

我们再进一步,把上面的代码改成:复制内容到剪贴板代码:
String str 1 = & # 8221;abc & # 8221;
String str 2 = & # 8221;abc & # 8221;
str 1 = & # 8221;bcd & # 8221;
System . out . println(str 1+& # 8221;,”+str 2);//bcd,ABC
System . out . println(str 1 = = str 2);//false
也就是说赋值的改变导致类对象引用的改变,str1指向另一个新对象!而str2仍然指向原始对象。在上例中,当我们将str1的值更改为& # 8221;bcd & # 8221当JVM发现堆栈中没有存储该值的地址时,它会打开该地址,并创建一个字符串值指向该地址的新对象。

事实上,字符串类被设计成不可变的。如果想改变它的值,可以,但是JVM在运行时会根据新的值悄悄创建一个新的对象,然后将这个对象的地址返回给原类的引用。虽然这个创作过程是完全自动化的,但毕竟需要更多的时间。在对时间要求敏感的环境中,会产生一定的不利影响。

然后修改原代码:复制内容到剪贴板代码:
String str 1 = & # 8221;abc & # 8221;
String str 2 = & # 8221;abc & # 8221;
str 1 = & # 8221;bcd & # 8221;
String str 3 = str 1;
System . out . println(str 3);//BCD
String str 4 = & # 8221;bcd & # 8221;
System . out . println(str 1 = = str 4);//true
我们再来看看下面的代码。将内容复制到剪贴板的代码:String str 1 = new String(& # 8220;abc & # 8221);String str2 = & # 8220abc & # 8221;system . out . println(str 1 = = str 2);//false

String str1 = & # 8220abc & # 8221;String str 2 = new String(& # 8220;abc & # 8221);system . out . println(str 1 = = str 2);//false创建了两个引用。创建了两个对象。两个引用指向两个不同的对象。

上面两个代码表明,只要用new()创建一个新对象,就会在堆中创建,它的字符串是分开存储的。即使与堆栈中的数据相同,也不会与堆栈中的数据共享。

5.无法修改数据类型包装类的值。不仅字符串类的值不能修改,而且所有数据类型包装类都不能更改其内部值。

6.结论和建议:

(1)我们使用的是String str = & # 8220abc & # 8221;当以的格式定义一个类时,我们总是想当然地认为我们创建了一个字符串类的对象字符串。担心陷阱!该对象可能尚未创建。当然,创建了对字符串类的引用。至于这个引用是否指向一个新对象,必须根据上下文来考虑,除非通过new()方法显式创建一个新对象。因此,更准确地说,我们创建了一个指向string类对象的引用变量Str,它指向一个特定的值& # 8221;abc & # 8221的字符串类。意识到这一点对于消除程序中难以发现的bug非常有帮助。

(2)使用String str = & # 8220abc & # 8221;一定程度上可以提高程序的运行速度,因为JVM会根据栈中数据的实际情况自动决定是否需要新建一个对象。而对于Stringstr = new String(& # 8220;abc & # 8221);代码,都在堆中创建新对象,不管它们的字符串值是否相等,是否有必要创建新对象,从而增加了程序的负担。这个想法应该是享受元模式的想法,但是不知道这个模式是否应用在JDK这里的内部实现中。

(3)在比较包装类中的值是否相等时,使用equals()方法;当测试两个包装类的引用是否指向同一个对象时,请使用= =。

(4)由于String类的不可变性质,当String变量需要频繁改变其值时,应考虑StringBuffer类,以提高程序效率

理论知识

投保单

堆栈:

由系统自动分配。例如,在函数中声明一个局部变量int b;系统自动为栈中的B打开空。

堆:

程序员需要自己申请并注明大小,用c语言malloc函数

例如P1 =(char *)malloc(10);

在C++中使用新运算符

例如p2 =新字符[10];//(char *)malloc(10);

但是请注意,p1、p2本身在堆栈中。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 堆栈是什么

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情