目录
本系列文章由江山(csdn名:补不补布)自己写成,当中用到引用时都已经标记出来,如果出现版权问题,请直接联系我修改。当然,技术在于分享,欢迎大家转载,不过请注明出处。最后,如果出现有错误的地方欢迎大家指正。
一、前言
- 本文章引用了很多其他文章的叙述和代码。会在之后标注出来。
- 我们在百度找不到结果的时候一定要注意,学习搜索英文结果。我搜索到的很多英文网站最大的好处就是,广告少。链接和资料比较丰富。我也需要向这些歪果仁学习,将每一篇博客写的清楚,把能够推荐的完网站列出来,供大家一起学习。
- 目的:
- 这篇文章主要是将栈(stack)和堆(heap)的区别。
- 附经典的模拟出栈和入栈操作代码。
二、资料、网站和链接:
前人栽树,后人乘凉:
注意,本文中的代码基于2,很多理论则是来源于1里面的叙述。
蓝字都是链接,可以直接点
三、C语言中怎么存储变量
我们如果学习过汇编语言就会知道,c函数传递参数是通过栈实现的。但是,我们不仅仅需要传递给c函数参数,有些时候也需要申请一些自己的地址空间来使用。这就是stack和heap的区别来源所在。
栈(stack)和堆(heap)都是用来存储变量的容器,只不过操作方式和特性有所不同而已
四、stack(栈)
4.1、为啥叫栈
我们在使用c语言函数的时候,当然会申请一些变量,既然有变量,那么就需要内存来存储这些变量的值。那么,栈就出现了。栈在中文里面是住宿的地方的意思,放在计算机中作为存储变量的容器也就很好理解了。而在英文里面,stack的翻译是:放成整齐的一叠(或一摞、一堆)。这样就很好理解了,一摞数据。这个栈就是放一摞数据的容器。
4.2、c什么时候用栈(stack)
- 试想一下,我们在c函数中经常申请变量。既然有变量就有地址,有地址就会占用空间。那么假如我们的地址申请的太多,而且没有被释放的话,最后会不会导致地址不够用了?
其实是不用担心的,因为在函数里面申请的变量,会被放在这个叫做栈的地方。 - 通俗的来说,我们把自己当作古代的财主,用一个函数就像是去一个地方旅游,旅游当然要住地方。住的地方就叫做栈(stack),行李(变量)太多了就需要放在栈里面。但是一旦我们旅游完了,cpu也就是我们的伙计就会自动把行李拿出来。当然,我们这种大老爷,对于这些行李(变量)是要还是不要,是不一定的。(看自己是不是需要这些变量继续工作)
4.3、栈的特性:
- 这样说,就可以理解栈这个东西了,特性如下:
- 使用函数时,自动申请。(旅馆又不是你家的)
- 函数结束时,自动释放。(旅馆又不是你家的)所以,栈只在函数运行期间存在。
- 有一定的大小限制。(旅馆又不是你家的,大小由老板决定)
- 当然,这些个鬼旅馆还有一些烦人的规矩,不过人在屋檐下不得不低头。我们每放一个行李进去,就叫做入栈,拿一个行李出来就叫做出栈。还有一个神奇的规矩,先放的行李必须最后拿出来。你问他为什么,他说你家每次吃大米?难道非要去舀最下面的米?你还就没办法反驳。
- 这是栈的规矩:
- 先进后出,后进先出( “LIFO” (last in, first out))。
- 申请变量叫做入栈。
- 当函数结束时,所有变量删除。也就叫做出栈
4.4、示范代码:
#include <stdio.h>
double multiplyByTwo (double input) {
double twice = input * 2.0;
return twice;
}
int main (int argc, char *argv[])
{
int age = 30;
double salary = 12345.67;
double myList[3] = {
1.2, 2.3, 3.4};
printf("double your salary is %.3f\n", multiplyByTwo(salary));
return 0;
}
五、heap(堆)
5.1、堆的通俗说法
-
想一下,如果我们那么有钱,有时候出去玩难道不能多带一点自己的行李嘛?可是多带一点,问题就大了。旅馆放不下啦。这个时候,我们就需要租一辆车,为什么是租?因为你不可能把车开的到美国去,当你到了美国的时候,难道你还在用中国的车?所以,要记得,随时用,随时释放。这个车的容量够大,但是问题也来了,我们需要车的时候,要让人把它开过来,不要的时候就需要人把它开走。不然,这么多的行李跟着自己,玩的也不开心。
-
当然,这里也是分情况的,如果老板们真的需要随身带很多东西,可以买一架私人飞机。这样的话,这个飞机就可以跟着你到世界各地,这个也就是全局变量了。
这就是heap把,我们在需要的时候可以申请,容量够大,但是我们要记得,不要的时候要及时删除。
5.2、堆的特性
- 下面是堆的特性:
- 可以使用全局变量。
- 没有内存大小限制
- 获取比较慢
- 内存空间使用并不是很有效,多次申请释放后,内存可能会碎片化。
- 需要自己管理内存。
- 变量可以重新申请内存
5.3、这里是一个示范代码:
#include <stdio.h>
#include <stdlib.h>
double *multiplyByTwo (double *input) {
double *twice = malloc(sizeof(double));
*twice = *input * 2.0;
return twice;
}
int main