C语言学习总结之内存篇

程序运行为什么需要内存

程序员写程序的目的是什么?就是让我们写的程序在机器上运行,输出我们想要的结果。
程序包含代码和数据两个部分,内存是用来存储可变数据的,数据在程序中可分为全局变量和局部变量,所以内存对程序来说非常重要,对程序运行更是本质相关。
内存管理是我们写程序的时很重要的话题,像数据结构、算法都是为了合理利用内存。

如何管理内存

先从操作系统角度讲:操作系统掌握所有的硬件内存,因为内存很大,操作系统把内存分成一个一个页面,以页面为单位来管理,页面内用更细小的方式字节为单位对页面进行管理。操作系统对内存的管理非常复杂,非常不人性化,对于使用操作系统的人来说,不需要了解这些细节。操作系统给我们提供了内存管理的一些接口,我们只需要用API即可管理内存。
对于没有操作系统时,程序需要直接操作内存,编程者需要自己计算内存的使用与安排,如果不小心把内存用错了,结果需要自己承担。
栈是发明出来管理内存的,栈管理内存的特点就是小内存自动化,入口既是出口,所以先进后出(first in last out),队列的特点是入口和出口都有,必须从入口进去,从出口出来,所以先进去的必须先出来,否则就堵住后面的(first in first out)。
C语言中使用栈来保存局部变量。当我们定义局部变量时,编译器会在栈中分配一段空间给这个局部变量,这段栈内存的内存地址和我们定义的局部变量绑定,对应栈的操作就是入栈,分配时栈顶指针会移动给出空间,栈指针的移动和内存分配是自动的。当局部变量的生命周期结束时,销毁局部变量的操作就是弹栈,也叫出栈,也是栈顶指针移动将栈空间中与局部变量关联的空间释放,也是自动完成的。
栈管理内存好处是方便,在栈中通过移动栈指针提供内存空间,栈内存是反复使用的,所以使用栈来实现的局部变量如果不初始化,值就是随机的。栈是有大小的,栈内存大小不好控制,太小容易溢出,太大浪费内存,这个缺点有点像数组。栈溢出危害很大,所以当我们定义局部变量时不能定义太多或者太大,使用递归时一定要注意递归收敛。
当我们需要内存容量比较大时,需要反复使用及释放,这时候我们可以用另外一种管理内存方式堆。堆管理内存的方式是自由,随时申请随时释放,大小快随意。堆内存是操作系统划归给对管理器来管理的,操作系统提供API来使用堆内存。
堆使用的特点:容量不限,常规使用的都能满足。申请和释放都需要手动进行,在使用时不能忘记释放自己申请的堆内存,否则就会出现内存泄漏,这也是很多人认为高级语言比C语言优秀的地方。

内存编址与寻址

内存在逻辑上就是一个一个的格子,这些格子可以用来装东西,每个格子有一个编号,这个编号就是内存的地址,这个内存地址和这个格子的空间是一一对应且永久绑定的。这就是内存的编址方法。内存编址是以字节为单位。
内存是对齐访问的,例如我们定义一个int类型的变量,在内存中就必须分配四个字节来存储这个int类型的变量,如果在三十二位操作系统中,这四个字节就是连续且对齐的,这样效率就高,所以在三十二位操作系统中定义int比定义short效率还高。

C语言如何操作内存

在C语言中用变量名来访问内存的,例如:当我们定义了一个int类型的变量,其实是编译器帮我们申请了一个int类型的内存格子,格子大小占四字节,格子的地址是确定的,并把这个地址与这个变量绑定,之后对这个变量的操作就是对这个地址所对应的内存操作。
在C语言中可以通过指针来间接访问内存,指针也是C语言中的一种变量类型,跟普通变量没有任何区别,无论何种类型,其实都是对所表征内存的一种长度规定和解析方法。例如定义int a和int *p,a和p都代表一个内存地址,但是解析方法不同,a是int型,所以a的长度是四字节,解析方法按照int的规定来的,p是指针类型,解析方式就是p所代表的内存里存储了一个地址,这个地址所代表的内存单元中存放的是一个int类型的数。
用数组来管理内存其实和指针没有本质区别,只是符号的解析方法不同。当我们定义了一个数组int a[10],编译器做的操作就是把这个数组的首元素首地址和符号a绑定,这个数组的地址和这个数组的首元素首地址不是一个概念,虽然地址值相同。
数组的优势:数组比较简单,直接用下标随机对元素进行访问,劣势:数组中元素的类型必须相同,数组的大小必须定义时给出,而且一旦确定不能更改。在一些高级语言中可以改变数组的大小,其实用了一种障眼法,重新定义一个新数组,把之前数组里的元素拷贝到新数组里,从而达到对数组大小的控制。
由于数组于生带来的缺陷,结构体运用而生。结构体可以存储不同类型的元素。结构体内嵌函数指针可以实现面向对象,包含了函数指针的结构体类似于面向对象中的class,结构体中变量类似与class中的成员变量,函数指针类似与成员方法。
善于总结才会进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值