这次的附加题推荐的博客是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. ubuntu 乱码 改为英文

    http://878045653.blog.51cto.com/2693110/735654 解决方法: 改成全英文环境来解决 方格 乱码 : 用vim配置语言环境变量 vim / etc/envir ...

  2. 详谈 Jquery Ajax 异步处理Json数据.

    啥叫异步,啥叫Ajax.咱不谈啥XMLHTTPRequest.通俗讲异步就是前台页面javascript能调用后台方法.这样就达到了无刷新.所谓的Ajax.这里我们讲二种方法 方法一:(微软有自带Aj ...

  3. 通俗易懂的讲解iphone视图控制器的生命周期

    IOS 视图控制器的生命周期非常非常重要,所以我有必要写个文章来和大家一起探讨问题. 今天在学习视图控制器的生命周期,也看了一下网上的一些资料,但总觉得不是那么好理解,首先我们来看一张图: 先粗略讲一 ...

  4. UVa 437 (变形的LIS) The Tower of Babylon

    题意: 有n种类型的长方体,每种长方体的个数都有无限个.当一个长方体的长和宽分别严格小于另一个长方体的长和宽的时候,才可以把这个放到第二个上面去.输出这n种长方体能组成的最大长度. 分析: 虽说每种都 ...

  5. [反汇编练习] 160个CrackMe之016

    [反汇编练习] 160个CrackMe之016. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  6. LeetCode: Binary Tree Level Order Traversal && Binary Tree Zigzag Level Order Traversal

    Title: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to ...

  7. H264 TS/ES

    ES流(Elementary Stream): 也叫基本码流,包含视频.音频或数据的连续码流.       PES流(Packet Elementary Stream): 也叫打包的基本码流, 是将基 ...

  8. poj 2373 Dividing the Path

    Dividing the Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2858   Accepted: 1064 ...

  9. C#中的lock关键字

    前几天与同事激烈讨论了一下,有一点收获,记录起来. 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. ...

  10. Asp.net 将DataTable 或者DataSet 转换为Json 格式

    Web 开发中,将从数据库中取到的数据直接转换为 Json 格式的数据,在前台通过Ajax 无刷新显示在界面上,下面提供将DataTable 或者DataSet 转换为Json 的方法 /// < ...