1-1程序运行为什么需要内存

一、内存这个大话题

1.1、程序运行为什么需要内存

1.1.1、计算机程序运行的目的

计算机是用来干什么的?我们为什么需要不断编写程序?计算机就是用来计算的,而计算的话,我们就需要给它数据,最终通过计算得到一个结果。而这些数据的一个计算过程就是程序。程序就是我们设定的一些计算的步骤。
程序 = 代码 + 数据;
代码 = 函数;
数据 = 变量(全局变量、局部变量);
那么可以得到结论:程序运行的目的有两个:结果,过程(比如在C语言中凡是返回值为void就是这种情况)在程序的运行过程中代码只需要被执行(读取)而不需要被修改,而数据就要要求可读可写。用函数来类比:函数的形参,实参就是数据(在函数体内部也有一些临时数据),函数的返回值就是结果,执行过程就是过程。所以在认识和写一个函数时,就围绕是要结果还是要过程展开,要首先搞清楚需要一些什么数据?返回一个什么样的结果?最后看为得到这个结果,如何实现这个过程。

int  add(int  a, int  b)
{
return  a + b;
}//这个函数执行重在结果
void  add(int  a,int  b)
{
int c;
c = a + b;
printf(“c = %d.\n”,c);
}//这个函数执行重在过程
int  add(int  a,int  b)
{
int c;
c = a + b;
printf(“c = %d.\n”,c);
return  c;
}//这个函数执行重在过程,也重在过程

1.1.2、计算机程序运行过程

程序是由很多函数和数据组成的,程序的运行本质就是函数的执行,而函数的本质就是数据的加工过程。

1.1.3 、冯诺依曼结构和哈佛结构

冯诺依曼结构是:数据和代码放在一起;
哈佛结构是:数据和代码分开存放;
什么是代码:函数;
什么是数据:全局变量、局部变量;
在S5PV210中运行的Linux系统上,运行应用程序时,这时候所有的应用程序的代码和数据都在DRAM,所以这种结构就是冯诺依曼结构;在单片机中,我们把程序代码烧写在Flash(NorFlash)中,然后程序在Flash中原地运行,程序中所涉及到的数据(全局变量、局部变量)不能放在Flash中,必须放在RAM(SRAM)中。这就叫哈佛结构。

1.1.4、 动态内存DRAM和静态内存SRAM

SRAM:静态内存,特点就是容量小、价格高,优点是不需要软件初始化直接上电就能用;CPU内部的cache都是SRAM。
DRAM:动态内存,特点就是容量大、价格低,缺点就是上电后不能直接使用,需要软件初始化后才可以使用。

1.1.5、 总结:为什么需要内存呢?

内存是用来存储可变数据的或者可读代码的(冯诺依曼结构中数据和代码都放入内存,而哈佛结构不是),数据在程序中表现为全局变量、局部变量等(在gcc中,其实常量也是存储在内存中的)(大部分单片机中,常量是存储在flash中的,也就是在代码段),对我们写程序来说非常重要,对程序运行更是本质相关;所以内存对程序来说几乎是本质需求。越简单的程序需要越少的内存,而越庞大越复杂的程序需要更多的内存。内存管理是我们写程序时很重要的话题。我们以前学过的很多编程的知识其实都是为了内存,譬如说数据结构(数据结构是研究数据如何组织的,数据是放在内存中的)和算法(算法是为了用更优秀更有效的方法来加工数据,既然跟数据有关就离不开内存)。

1.1.6、 深入思考:如何管理内存(无OS时,有OS时)

对于计算机来说,内存容量越大则可能性越大,所以大家都希望自己的电脑内存更大。我们写程序时如何管理内存就成了很大的问题。如果管理不善,可能会造成程序运行消耗过多的内存,这样迟早内存都被你这个程序吃光了,当没有内存可用时程序就会崩溃。所以内存对程序来说是一种资源,所以管理内存对程序来说是一个重要技术和话题。
先从操作系统角度讲:操作系统掌握所有的硬件内存,因为内存很大,所以操作系统把内存分成1个1个的页面(其实就是一块,一般是4KB),然后以页面为单位来管理。页面内用更细小的方式来以字节为单位管理。操作系统内存管理的原理非常麻烦、非常复杂、非常不人性化。那么对我们这些使用操作系统的人来说,其实不需要了解这些细节。操作系统给我们提供了内存管理的一些接口,我们只需要用API即可管理内存。譬如在C语言中使用malloc、 free这些接口来管理内存。
没有操作系统时:在没有操作系统(其实就是裸机程序)中,程序需要直接操作内存,编程者需要自己计算内存的使用和安排。如果编程者不小心把内存用错了,错误结果需要自己承担。
从语言角度来讲:不同的语言提供了不同的操作内存的接口。
譬如汇编:根本没有任何内存管理,内存管理全靠程序员自己,汇编中操作内存时直接使用内存地址(譬如0xd0020010),非常麻烦;
譬如C语言:C语言中编译器帮我们管理直接内存地址,我们都是通过编译器提供的变量名等来访问内存的,操作系统下如果需要大块内存,可以通过API(malloc free)来访问系统内存。裸机程序中需要大块的内存需要自己来定义数组等来解决。
譬如C++语言:C++语言对内存的使用进一步封装。我们可以用new来创建对象(其实就是为对象分配内存),然后使用完了用delete来删除对象(其实就是释放内存)。所以C++语言对内存的管理比C要高级一些,容易一些。但是C++中内存的管理还是靠程序员自己来做。如果程序员new了一个对象,但是用完了忘记delete就会造成这个对象占用的内存不能释放,这就是内存泄漏。
Java/C#等语言:这些语言不直接操作内存,而是通过虚拟机来操作内存。这样虚拟机作为我们程序员的代理,来帮我们处理内存的释放工作。如果我的程序申请了内存,使用完成后忘记释放,则虚拟机会帮我释放掉这些内存。听起来似乎C# java等语言比C/C++有优势,但是其实他这个虚拟机回收内存是需要付出一定代价的,所以说语言没有好坏,只有适应不适应。当我们程序对性能非常在乎的时候(譬如操作系统内核)就会用C/C++语言;当我们对开发程序的速度非常在乎的时候,就会用Java/C#等语言。

特别说明:由于看了朱有鹏老师的C语言精讲收获很多,所以将笔记分享给大家,本专栏中的文章皆来自于朱有鹏老师的C语言专题精讲的笔记,此外,我在里面也添加了自己学习C语言的一些总结和收获,若有错误请大家指正。学习使我快乐,分享令我愉悦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非主流的豆瓣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值