医疗电子技术网|技术阅读
登录|注册

您现在的位置是:医疗电子技术网 > 技术阅读 > 关于堆栈的深入理解

关于堆栈的深入理解

广告

对于堆栈的味道,一直就跟猪八戒吃啥来着,从没有细细地品尝过。发了下狠心,各个网页看了很多,这里就把我东抓西拼的东西整理整理。

 

一  这些个概念怎么来的以及怎么记得住

这里,只限于整理我个人对堆/栈/堆栈在内存管理方面的理解。其他,在数据结构方面讲的堆/栈目前不在我整理范围之内。

这里提了三个概念: 堆,栈,以及堆栈。我把堆栈的概念等同了。所以,接下来只要把两个概念弄清楚就可以了:

 

先说由来。由于我的工作大部分是和单片机相关的,因此也是基于嵌入式的这个方面的理解。

每片MCU有一定的内存,这些内存分:程序存储区;数据存储区。举例就是:我们写的每行代码,都会保存到程序存储区里面;而定义的一些全局变量,静态变量,局部变量之类的,就保存到数据存储区。

程序存储区,对于写代码的人来说,可以说是黑盒子:只要你的代码不超过程序代码空间,everything will be fine. 代码究竟是如何执行的,取决于你的编程思想,就是说,你让程序往东走,它就会往东走;让它原地踏步,它也会照做;前提是你的代码要写好。所以,对于编程经 验成熟的人,同样的算法,他可能会少敲几行代码,并且算法出错的几率少一些;不怎么会编程的人,就多敲几行,多测试一下。研究深一些的人,可能还会对代码 执行效率深入研究。我决定就此止步。继续黑盒子的话题,程序员的代码会烧写到程序存储区里面,至于哪条语句存哪里,这个是不用研究的。反正,一旦发现软件 没按照你设计的那样跑,基本就是程序自身的问题,不是存放程序的存储区的问题。

数据存储区,让程序员发挥的空间就很大了。由于程序是动态地执行的,执行的结果是怎么样,会产生什么数据就不是一个确定的事情。

举个例子说说这个程序和数据之间的表象吧。举例的事件就是:一个MP3播放器的上/下键的操作。加入在播放器里有10首歌,若当前是第3首,那 么按下[上]键后,应该是播放第2首。因此,实现播放第2首的,就是程序员写程序实现的,他的代码让[上]键实现了能从第3首切换到第2首的操作。这里, 表现的就是代码。而且,这个代码是确切的行为,从第3首按了[上]键之后,一定是播放到第2首。这个是确切的行为,如果不能实现,就是代码有bug了,需 要改正。终于可以扯到数据了。第2首是什么歌呢? 就是说第2首歌的内容是什么呢? 当然在程序员写代码的时候,他是不知道的,他要做的,就是预先开一片数据空间,以存放歌曲相关的数据。这片数据空间,想放什么就放什么,是灵活的。听烦了 这几首歌以后,再更换其它音频文件就是了。再说具体一点,程序就相当于修的一条路,让车可以在上面跑;但车上面装了什么,程序员是不知道的。

 

女人就是啰嗦啊。女人的话题也是可以转得很快的。

属于数据存储区的范畴,也可以算是数据管理的手段或方法。基于此,不能一概而论,说哪个手段高明一些;他们也是基于现实的需要而产生的。黑格尔说:存在就是合理的。

这样的概念大家都不陌生:军队的管理是很严格的,很死板的;但是对于一些年轻的技术公司来说,员工就享有很高的自由度。

如果我说,墙角边整齐地摆放着10本书; 以及墙角边的书凌乱地放着。你闭上眼睛,能区分出两种画面吗? 如果没有,就不用往下看了。

栈的特性,就是严格/有序/规范的。栈的英文就是Stack. 如果我说,there are books stacked in that corner,你应该能知道书是怎么放的吧。

相反,堆呢,就是自由/灵活/随意的。堆的英文是Heap. 如果我说,there are books heaped in that corner,你应该能知道书是怎么放的吧。 

 

二  get closer to the real STACK/HEAP。

: 由系统自动分配和回收的。

: 由程序员分配和回收的。

基于第一部分的理解,不用想都知道,作为“堆”的数据空间,也必须是灵活的,因为成千上万的程序员在写什么程序是未知的。但可知道的一点,就是他们是跑在确定的某个OS里面的。

因此,也不过就是给系统管理的数据空间起了个名字,就;给程序员使用的空间,起了个名,就

我接下来就会废话:起什么名字都不重要,重要的是,我们得对这两种数据存储区的管理的机制由来,方法有深刻认识;这样,即便几个世纪以后它们更名为阿猫阿狗了,我们依然能认知它们。

 

举例: 

void Check_Pro_Code( uint8  style )

{

   uint8 i;

 

   switch( style )

   {

   ......

   }

}

 

void main( )

{

   uint8 j = 1;

   

   Check_Pro_Code( j );        

}

 

在main()函数里调用了Check_Pro_Code(...)函数,事先要对j进行入栈操作;当然这里函数调用的时候,涉及到几个入栈操作:程序的下一个执行地址;局部变量;形参。

这里,我就没有深入介绍了。

 

实在很惭愧的是,我写的嵌入式软件里,没有涉及到任何和操作相关的。我就是那样一个人,CM3内核里也没有移植操作系统,实在是汗颜,因为本人对RTOS实在是未曾涉猎。所以,我这里对于堆的介绍,是没有任何实战鹰眼的。并且为了我就了一下。你说,这样算学术造假吗?

void main( )

{

int j=10;

int *p;

 

p = malloc( 10 );      

 图二,如何知道自己的工程用了多少堆栈

 

广告

关于立创商城

立创商城(WWW.SZLCSC.COM)是嘉立创集团旗下一家品种齐全、自营库存、质量有保障的电子元器件垂直商城,自建6000多平米现代化元器件仓库,现货库存超35000种。立创商城所有元器件均由原厂或代理商正规渠道采购,保证原装正品。

采购元器件推荐上立创商城,注册后可领取15元无门槛使用优惠券,如需业务编号请填写“N”,或直接点击阅读原文