这次的附加题推荐的博客是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的理解的更多相关文章

  1. [课程相关]附加题——stack的理解

    一.stack的三种解释 stack有三种解释,我个人理解如下. 1.用户自定义的stack 用户自定义的stack就是一般意义上的后进先出队列,从名字上就能理解了,stack由下向上增长,有一个顶指 ...

  2. 《剑指Offer》附加题_用两个队列实现一个栈_C++版

    在<剑指Offer>中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即"用两个队列实现一个栈". 在计算机数据结构中,栈的特点是后进先出,即最后被压入(push ...

  3. 第五周课后作业——热门软件创新分析+附加题1&附加题3

    鉴于我们寝室都热衷于手游,所以本次热门软件创新分析我就来分析一下几款热门的抽卡型手游.   阴阳师(后文简称YYS)——剧情画风唯美,配音引人入胜 作为网易公司研发的一款3D日式和风回合制游戏,YYS ...

  4. PairProject 电梯调度 【附加题】

    [附加题] 改进电梯调度的interface 设计, 让它更好地反映现实, 更能让学生练习算法, 更好地实现信息隐藏和信息共享. 目前的设计有什么缺点, 你会如何改进它? 1.之前判断电梯是否闲置的函 ...

  5. 阿里巴巴集团2016校园招聘-Python工程师笔试题(附加题+部分答案)

    前言 第一次网上笔试,被虐的很惨.一是不太习惯,最主要的是还是自己对Python的掌握,还不够熟练.下面是这次阿里笔试相关信息 笔试时间是,2015年8月23日,10:00——12:00 对于笔试题, ...

  6. 软件工程 --- Pair Project: Elevator Scheduler [电梯调度算法的实现和测试] [附加题]

    软件工程 --- Pair Project: Elevator Scheduler [电梯调度算法的实现和测试] [附加题] 首先,在分组之前,我和室友薛亚杰已经详细阅读了往届学长的博客,认为电梯调度 ...

  7. pair work-Elevator Schedule附加题

    [电梯调度算法的实现和测试] [附加题] 首先,我要感谢周敏轩同学和薛亚杰,吴渊渊小组.UI的编写是在两个小组成员的共同努力下完成的,希望在第二次结对编程中能够再一起对UI界面进行更新和完善.UI编写 ...

  8. 【SE】Week3 : 四则运算式生成评分工具Extension&Release Version(附加题)

    [附加题]第四阶段目标 - 界面模块,测试模块和核心模块的松耦合. 写到这里我只想吐槽一句,哪天我能写出功能复杂且真正松耦合的模块,我应该就不用写代码了吧[手动再见.. 当然这只是强调下松耦合和代码复 ...

  9. 软件工程-pair work[附加题]

    首先,在分组之前,我和室友周敏轩已经详细阅读了往届学长的博客,认为电梯调度这个项目应该先做UI会比较好一点,于是动手展开了UI的编写;但分组结果并没有如我们所愿,但我们依然共同进行了UI的编写,希望在 ...

随机推荐

  1. [转载]深入理解JAVA的接口和抽象类

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...

  2. WebClient+Fiddler2完美搭配下载远程页面信息

    WebClient可以下载远程页面信息,这个大家应该都知道,核心代码如下: WebClient web = new WebClient(); string url = String.Format(&q ...

  3. WebService只能在本地使用,无法通过网络访问的解决办法

    问题描述:WebService只能在本地使用,无法通过网络访问. 解决方案:在web.config的<system.web></system.web>中间加入如下配置节内容: ...

  4. UVa 10129 (并查集 + 欧拉路径) Play on Words

    题意: 有n个由小写字母的单词,要求判断是否存在某种排列使得相邻的两个单词,前一个单词末字母与后一个单词首字母相同. 分析: 将单词的两个字母看做节点,则一个单词可以看做一条有向边.那么题中所求的排列 ...

  5. UVALive 4043 Ants(二分图完美匹配)

    题意:每个蚁群有自己的食物源(苹果树),已知蚂蚁靠气味辨别行进方向,所以蚁群之间的行动轨迹不能重叠.现在给出坐标系中n个蚁群和n棵果树的坐标,两两配对,实现以上要求.输出的第 i 行表示第 i 个蚁群 ...

  6. 纯CSS3带动画效果导航菜单

    随着互联网的发展,网页能表现的东西越来越多.由最开始单纯的文字和链接构成的网页,到后来的表格布局,再到div+css模式,现在发展到了html+css3.网页能表达的东西越来越多,css3兴起已经很多 ...

  7. UVA 10537 The Toll! Revisited 过路费(最短路,经典变形)

    题意:给一个无向图,要从起点s运送一批货物到达终点e,每个点代表城镇/乡村,经过城镇需要留下(num+19)/20的货物,而经过乡村只需要1货物即可.现在如果要让p货物到达e,那么从起点出发最少要准备 ...

  8. QPS、PV和需要部署机器数量计算公式(转)

    术语说明: QPS = req/sec = 请求数/秒 [QPS计算PV和机器的方式] QPS统计方式 [一般使用 http_load 进行统计] QPS = 总请求数 / ( 进程总数 *   请求 ...

  9. LeetCode: Combination Sum I && II && III

    Title: https://leetcode.com/problems/combination-sum/ Given a set of candidate numbers (C) and a tar ...

  10. 面试题 IQ

    现在有一大块金条,它可以分为七小块金条.是这样子的,工人为你工作7天,每天都将获得一小块金条,你要做的就是发工资,切割大块金条的次数最多两次,你有什么方法让工人每天都获得一小块金条呢?