C语言(计算机专业应该知道的管理内存的数据结构)

1.用数组来管理内存

	int a;		     // 编译器分配4字节长度给a,并且把首地址和符号a绑定起来。
	int b[10];		// 编译器分配40个字节长度给b,并且把首元素首地址和符号b绑定起来。
  • 数组管理内存和变量其实没有本质区别,只是符号的解析方法不同。
  • 数组中第一个元素(b[0])就称为首元素;每一个元素类型都是int,所以长度都是4,其中第一个字节的地址就称为首地址;首元素b[0]的首地址就称为首元素首地址。
  • 数组定义时必须同时给出数组元素个数(数组大小),而且一旦定义再无法更改。


2.用结构体来管理内存

	我们要管理3个学生的年龄(int类型),怎么办?
	第一种解法:用数组		int ages[3];
	第二种解法:用结构体	
	struct ages
	{
		int    age1;
		int	   age2;
		int    age3;
	};
	struct ages age;    //实例化一个结构体变量age

先分析数组的优势和缺陷:

  •  优势:数组比较简单,访问用下标,可以随机访问。

  •  缺陷1:数组中所有元素类型必须相同;

  •  缺陷2 :数组大小必须定义时给出,而且一旦确定不能再改。

  • 结构体发明出来就是为了解决数组的第一个缺陷结构体中可以有不同类型的数据。

	struct people
	{
		int age;			// 人的年龄
		char name[20];		// 人的姓名
		int height;			// 人的身高
	};
	
	因为people的各个元素类型不完全相同,所以必须用结构体,没法用数组。


3.内存管理之栈(stack),队列,

先进后出 FILO   first in last out		栈       (类似一个只有一个开口的瓶子)
先进先出 FIFO   first in first out  	    队列     (类似一段水管)
  • 栈的特点是入口即出口,只有一个口,另一个口是堵死的。所以先进去的必须后出来。
  • 队列的特点是入口和出口都有,必须从入口进去,从出口出来,所以先进去的必须先出来,否则就堵住后面的。

栈的优点:栈管理内存,好处是方便,分配和最后回收都不用程序员操心,C语言自动完成。
栈的约束(预定栈大小不灵活,怕溢出)

首先,栈是有大小的。所以栈内存大小不好设置。如果太小怕溢出,太大怕浪费内存。(这个缺点有点像数组)
其次,栈的溢出危害很大,一定要避免。所以我们在C语言中定义局部变量时不能定义太多或者太大(譬如不能定义局部变量时。


4.内存管理之堆

C语言操作堆内存的接口(malloc free)

堆内存释放时最简单,直接调用free释放即可。	  void free(void *ptr);
堆内存申请时,有3个可选择的类似功能的函数:   malloc, calloc, realloc
	  void *malloc(size_t size);
	  void *calloc(size_t nmemb, size_t size);		// nmemb个单元,每个单元size字节
	  void *realloc(void *ptr, size_t size);		// 改变原来申请的空间的大小的

	譬如要申请10个int元素的内存:
	malloc(40);			    malloc(10*sizeof(int));
	calloc(10, 4);			calloc(10, sizeof(int));

堆这种内存管理方式特点就是自由(随时申请、释放;大小块随意)。堆内存是操作系统划归给堆管理器(操作系统中的一段代码,属于操作系统的内存管理单元)来管理的,然后向使用者提供API(malloc和free)来使用堆内存。

需要内存容量比较大时,需要反复使用及释放时,很多数据结构(譬如链表)的实现都要使用堆内存。

堆管理内存的特点(大块内存、手工分配&使用&释放)

 特点一:容量不限(常规使用的需求容量都能满足)。
 特点二:申请及释放都需要手工进行,手工进行的含义就是需要程序员写代码明确进行申请malloc及释放free。如果程序员申请内存并使用后未释放,这段内存就丢失了(在堆管理器的记录中,这段内存仍然属于你这个进程,但是进程自己又以为这段内存已经不用了,再用的时候又会去申请新的内存块,这就叫吃内存),称为内存泄漏


5.内存管理复杂数据结构链表、哈希表、二叉树、图等

链表是最重要的,链表在linux内核中使用非常多,驱动、应用编写很多时候都需要使用链表。所以对链表必须掌握,掌握到:会自己定义结构体来实现链表、会写链表的节点插入(前插、后插)、节点删除、节点查找、节点遍历等。(至于像逆序这些很少用,掌握了前面那几个这个也不难)。

哈希表不是很常用,一般不需要自己写实现,而直接使用别人实现的哈希表比较多。对我们来说最重要的是要明白哈希表的原理、从而知道哈希表的特点,从而知道什么时候该用哈希表,当看到别人用了哈希表的时候要明白别人为什么要用哈希表、合适不合适?有没有更好的选择?

二叉树、图等。对于这些复杂数据结构,不要太当回事。这些复杂数据结构用到的概率很小(在嵌入式开发中),其实这些数据结构被发明出来就是为了解决特定问题的,你不处理特定问题根本用不到这些,没必要去研究。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌入式_笔记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值