1、计算机程序=代码+数据
冯诺依曼结构:数据和代码放在一起(C语言中代码其实就是函数,数据就是变量)。
哈佛结构:数据和代码分开存在。
例:linux系统中,代码和数据都在DRAM中,这就是冯诺依曼结构。
而单片机中,代码在Flash中,数据在RAM中,这就是哈佛结构。
2、内存分动态内存(DRAM)和静态内存(SRAM)
是用来存储可变数据的,即变量。(也有例外:gcc中常量也存在内存,而大部分单片机中,常量都是存在Flash中)。
内存管理一般以页面为单位,一页一般为4kb,页面内部以字节为单位管理。
例:C语言通过API接口管理内存(如malloc/free)。
C++用new/delete。
JAVA通过虚拟机来操作内存。
3、32位系统,内存最多为4G,即2的32次方。因为32位系统的数据线与地址线均为32条,而地址线的条数就决定了
内存地址的划分数量。
4、内存位宽
内存本身的硬件实现有位宽限制,内存芯片之间可以进行串联和并联。从逻辑上讲内存的位宽是任意的。
位 1bit ,字节 8bit ,半字 (一般为16bit) ,字 (一般为32bit) 。系统和平台不一样,字的大小也不一样。
5、内存划分
内存实际上划分为一个一个的小单元,每一个单元的编号就是内存地址,编程中指挥联系到内存地址,因为内存
地址与内存单元是一一对应,相互绑定的。
内存编制是以字节为单位的,即每个地址对应的空间大小为8bit。
6、数据类型
int 整形(该类型与CPU本身的数据位宽是一样的)
数据类型与内存相匹配,才能有最好的性能,例如32位系统中编程就推荐使用int型变量,这样访问内存效率最高。
C语言中数据类型的本质含义:表示一个内存格子的长度和解析方法。函数名的实质就是这一段代码的首地址。
指针变量和普通变量,例如 int a和int *p,a和p都代表一个内存地址。
7.数组
数组首元素a[0]的首地址就称为首元素首地址。
数据结构就是研究如何组织(在内存中排布)数据,如何加工数据。
最简单的数据结构,数组(可以管理多个类型相同,意义相关的变量)
数组的优点:可随机访问。
数组的缺点:元素类型必须相同,数组大小必须定义时给出。
C语言结构体内嵌指针可以实现面向对象。(linux就是利用C语言写的,具有面向对象功能的系统)
在JAVA等高级语言中,有一些语法技巧可以更改数组的大小,但其实这只是一种障眼法。它的工作
原理是:先重新创建一个新的数组大小为要更改后的数组,然后将原数组的所有元素复制进新的数组,
然后释放掉原数组,最后返回新的数组给用户。
8.内存管理
栈(stack)C语言中用来保存局部变量,栈管理内存,分配和回收都是C语言自动完成。
因为栈中的内存是反复使用的,所以定义局部变量时,如果没有初始化该变量,则该变量的值是随机的。
约束:栈的大小是固定的,太小容易溢出,太大浪费内存。为避免栈溢出,C语言中定义局部变量时不能
定义太多或太大,使用递归来解决问题时一定要注意递归收敛。
堆(heap)
随时申请、释放,大小块随意。堆内存由操作系统划归给堆管理器来管理,向使用者(用户进程)提供
API(malloc/free)来使用堆内存。
堆管理内存,需要手动申请和释放,如果申请了之后忘记了释放,会容易造成内存泄漏。
void *malloc (size_t size);
void *calloc (size_t nmemb,size_t size);//nmemb个单元,每个单元size字节
void *realloc (void *ptr,size_t size);//改变原来申请的空间的大小
堆内存申请是必须给定大小,然后一旦申请完成大小不变,如果要更改,只能通过
realloc接口。realloc的实现原理类似于上面说的JAVA中的可变大小的数组的方式。