附加题-stack的理解
这次的附加题推荐的博客是http://www.ruanyifeng.com/blog/2013/11/stack.html阮一峰的,感觉讲的深入浅出,比较适合对计算机刚刚接触的人;
下面谈谈感想:
这边文章主要讲了stack的三种理解:
第一个是咱们常说的用于算法的栈,这种栈结构非常适合做一些有意思的题,而且栈的思想最主要,先进后出。
第二个就是在函数层面的栈,这里指的就是在函数调用时候出现的栈,即每次调用生成一个新的数据空间来存放新的函数并赋初始值,而每次调用玩函数后则会释放掉函数的空间。
第三个就是在系统层面的栈,主要是通过对比栈和堆的概念来提出的,这里的栈指的不光是函数等而是整个代码的层次结构,这里面的栈主要强调的是数据大小的确定性和作用域的关系,即每出现一个新的作用域便会生成一个新的栈空间来存这个作用域的东西,并且前提是这个作用域的所用变量的大小都是已知的,相对于堆的不可知大小概念提出。此外还主要讲了进程和线程与栈的关系,即每个线程单独占用一个栈,但是可以分享堆里面的内容。
自己的理解:
实话说按我自己的理解,这三点讲的都是一点,只不过是栈的三种不同的应用而已,而且在这学期的编译课还重点讲了系统层次的栈,所以感觉内容还是比较适合初学者的,其核心思想都是后进先出,这边博客唯一增加的知识就是线程与栈的关系。但是这篇文章却没有解释具体的结构关系,比如父域生成一个线程,那么新生成的线程是如何开辟新空间的?是在原来的栈的基础上生成?还是在一个新开辟的占空间里面生成?这些作者都没有说。而且我还看了评论,大多数有经验的编程者都能发现该博客中的漏洞,比如不严谨的说法如堆的调用比栈慢,却没有详细的解释为什么?是操作系统的原因还是索引效率的问题还是cache与主存的速度导致的?都不得而知。所以个人觉得这边博客的意义不大。
对于上面的问题我自己上网进行的调查
参考http://blog.csdn.net/echoisland/article/details/6403763
结论如下:
1.首先解释新生成的线程如何与栈的具体关系:
首先我们知道线程是CPU在高速运行时不断切换其运行状态来让人们直观地认为是并发的但实际上是顺序执行的一种概念,而当系统切换线程的时候会自动切换线程的栈,也就是切换SS/ESP寄存器,这样我才想可能新线程是在新的栈生成一块区间的而不是在原来的栈
2.解释为什么栈会比堆运行的更快:
首先清理一下概念的关系,这里说的运行的更快不是指硬件层面的块,而是至设计层面的块。举个例子就像从北京到天津,同样的距离同样的交通工具,如果你走直线一定会比走去曲线来得更快,这就是我所说的设计层面的东西。
栈:
由于栈是有空间限制的,也是连续的,所以当程序调用栈的时候地址的顺序调用和顺序执行,即后进先出,1234按顺序进,但是无论怎么样都不会出现抽出的顺序是3124这就是我说的地址的顺序调用和顺序执行。
堆:
由操作系统的一个链表来存放空闲地址,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲 结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
读到这里想必你已经有谱了,如果你要给堆分配空间首先要做的是遍历链表,这一定会比栈按地址顺序来操作麻烦得多
此外不光设计模式的因素在还有硬件的因素,例如
void main()
{
char a = ;
char c[] = "";
char *p ="";
a = c[];
a = p[];
return;
}
执行这样一段代码,我们看一看他相应的汇编代码
: a = c[];
8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 4D FC mov byte ptr [ebp-],cl
: a = p[];
0040106D 8B EC mov edx,dword ptr [ebp-14h]
8A mov al,byte ptr [edx+]
FC mov byte ptr [ebp-],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符。从这一过程我们可以猜想到机组课上的原理,即第二种多一步的操作应该是把主存中的内容读取到缓存cache中以方便之后对此变量的快速操作。堆和栈虽然都是存放在内存中,但是我们知道内存也是分等级的越接近CPU的内存越快越小,所以我猜想堆和栈存放在不同等级的cache中,这也是他们读取速度不同的原因,因为读取堆的内容要钱把他传到更接近CPU一级的cache中这个过程会浪费一点时间。
说了这么多都是对堆和栈的深刻理解,要是一般编程的话需要理解的就是能知道大小的就由栈来存放,不知道大小的就由堆来存放。
有人可能问了
void main()
{
char a = ;
char c[] = "";
char *p ="";
a = c[];
a = p[];
return;
}
这段代码为什么*p指向的内容是由堆存放的呢?
我们要明白对于c[]来说,编译器首先统计变量长度,然后存放到c[]的变量中,但是*p不同他是指针他需要知道的长度通过指针的类型即char就能确定所以指针是存放在栈中,而指针指向的内容的长度是事先不知道的,所以内容存放在堆中。
有人可能又问了这里的*p长度不是知道的吗?
没错这里面的长度是知道的,但是编译器处理的是通用的情况,一般人建立指针来对数据进行操作都是因为不知道空间大小,像这种情况完全可以用数组代替,大都市情况是这样的
char *p;
p=(char*)malloc(sizeof(char)*n);
所以为了处理这种情况,编辑器不可能会先判断内容能不事先确定大小的,索性统一处理成不知道的样式。
个人理解,如有错误欢迎拍砖。一定及时纠正。
附加题-stack的理解的更多相关文章
- [课程相关]附加题——stack的理解
一.stack的三种解释 stack有三种解释,我个人理解如下. 1.用户自定义的stack 用户自定义的stack就是一般意义上的后进先出队列,从名字上就能理解了,stack由下向上增长,有一个顶指 ...
- 《剑指Offer》附加题_用两个队列实现一个栈_C++版
在<剑指Offer>中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即"用两个队列实现一个栈". 在计算机数据结构中,栈的特点是后进先出,即最后被压入(push ...
- 第五周课后作业——热门软件创新分析+附加题1&附加题3
鉴于我们寝室都热衷于手游,所以本次热门软件创新分析我就来分析一下几款热门的抽卡型手游. 阴阳师(后文简称YYS)——剧情画风唯美,配音引人入胜 作为网易公司研发的一款3D日式和风回合制游戏,YYS ...
- PairProject 电梯调度 【附加题】
[附加题] 改进电梯调度的interface 设计, 让它更好地反映现实, 更能让学生练习算法, 更好地实现信息隐藏和信息共享. 目前的设计有什么缺点, 你会如何改进它? 1.之前判断电梯是否闲置的函 ...
- 阿里巴巴集团2016校园招聘-Python工程师笔试题(附加题+部分答案)
前言 第一次网上笔试,被虐的很惨.一是不太习惯,最主要的是还是自己对Python的掌握,还不够熟练.下面是这次阿里笔试相关信息 笔试时间是,2015年8月23日,10:00——12:00 对于笔试题, ...
- 软件工程 --- Pair Project: Elevator Scheduler [电梯调度算法的实现和测试] [附加题]
软件工程 --- Pair Project: Elevator Scheduler [电梯调度算法的实现和测试] [附加题] 首先,在分组之前,我和室友薛亚杰已经详细阅读了往届学长的博客,认为电梯调度 ...
- pair work-Elevator Schedule附加题
[电梯调度算法的实现和测试] [附加题] 首先,我要感谢周敏轩同学和薛亚杰,吴渊渊小组.UI的编写是在两个小组成员的共同努力下完成的,希望在第二次结对编程中能够再一起对UI界面进行更新和完善.UI编写 ...
- 【SE】Week3 : 四则运算式生成评分工具Extension&Release Version(附加题)
[附加题]第四阶段目标 - 界面模块,测试模块和核心模块的松耦合. 写到这里我只想吐槽一句,哪天我能写出功能复杂且真正松耦合的模块,我应该就不用写代码了吧[手动再见.. 当然这只是强调下松耦合和代码复 ...
- 软件工程-pair work[附加题]
首先,在分组之前,我和室友周敏轩已经详细阅读了往届学长的博客,认为电梯调度这个项目应该先做UI会比较好一点,于是动手展开了UI的编写;但分组结果并没有如我们所愿,但我们依然共同进行了UI的编写,希望在 ...
随机推荐
- VS2012 开发SharePoint 2013 声明式workflow action(activity)之 HelloWorld
本文讲述VS2012 开发SharePoint 2013 声明式workflow action 之 HelloWorld. 使用VS2012开发客户化的workflow action是SharePoi ...
- 02-语言入门-02-ASCII码排序
题目地址: http://acm.nyist.net/JudgeOnline/problem.php?pid=4 描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个 ...
- n人比赛,可轮空,比赛轮数和场数
#include<stdio.h> int chang(int x,int s){ ) return s; ) ; !=){ s+=(x-)/; )/,s); } else{ s+=x/; ...
- yeoman错误提示
运行 yo angular 出现如下提示: $ yo angular grunt-cli: The grunt command line interface. (v0.1.9) Fatal error ...
- trackr: An AngularJS app with a Java 8 backend – Part III
这是最后我们对trackr系列的一部分.在过去的两的博文中,我们已经向您展示我们使用的工具和框架构建后端和前端.如果你错过了前面的帖子现在你可能会想读他们赶上来. Part I – The Backe ...
- UVa 10652 (简单凸包) Board Wrapping
题意: 有n块互不重叠的矩形木板,用尽量小的凸多边形将它们包起来,并输出并输出木板总面积占凸多边形面积的百分比. 分析: 几乎是凸包和多边形面积的裸题. 注意:最后输出的百分号前面有个空格,第一次交P ...
- ASP.NET MVC @helper使用说明
简单的 @helper 方法应用场景 Razor中的@helper语法让您能够轻松创建可重用的方法,此方法可以在您的视图模板中封装输出功能.他们使代码能更好地重用,也使代码更具有可读性. 在我们定义@ ...
- 转:MVC3系列:~Html.BeginForm与Ajax.BeginForm
Html.BeginForm与Ajax.BeginForm都是MVC架构中的表单元素,它们从字面上可以看到区别,即Html.BeginForm是普通的表单提交,而Ajax.BeginForm是支持异步 ...
- [Sciter系列] MFC下的Sciter–1.创建工程框架
Sciter SDK中提供的Win32下例程很多,唯独使用很多(对我个人而言)的MFC框架下Sciter程序的构建讲的很少,虽然MFC有这样那样的诟病,但是不可否认的是编写一般的小项目,这仍然是大多数 ...
- AWK print学习
Awk是一种处理结构数据并输出格式化结果的编程语言, Awk 是其作者 "Aho,Weinberger,Kernighan" 的简称. Awk通常被用来进行格式扫描和处理.通过扫描 ...