而C99做了很大改进,允许数组的[ ]中的值是整形变量或是整形表达式。这就解释了下面的情况:
这样的数组就被称之为“变长数组”。
可变数组(Resizeable Array)
数组的大小可“长大”,具体实现是在前期指定数组的大小,并在后期重新定义数组大小。使数组能在原大小的基础上“长大”,原来空间定义的数据不改变地拷贝到新定义的空间,并释放原空间,多出的未利用的空间即为新增空间。可变数组主要用于事先不明确所需数组的大小,需要在程序的中后段手工扩充的具体问题中。
为实现可变的功能必须满足以下条件:
1.可变大小
2.可得到数组的大小
3.可访问数组其中的单元
Interface(接口,封装一定功能的集合)
Array array_creat(int init_size);
void array_free(Array *a);
int array_size(const Array *a);
int *array_at(Array *a,int index);
void array_inflate(Array *a,int more_size);
需要建一个项目,包括array.h和array.c文件,具体步骤省略。
可变数组的缺陷:数组每次长大都需要申请新的内存空间,并需要拷贝原数组数据并释放它。
1.拷贝的时间呈线性增加
2.在内存受限的情况下(如单片机的内存空间),明明有足够的内存空间却不能再申请新的空间了。
//在一个大小为2n+Block_size的内存空间中,当前的数组空间大小是n,n-Block_size是之前数组现已被释放的空间,2Block_size是未利用的内存空间。
//对于下一个数组的创建所需空间是n+Block_size,n-Block_size和2Block_size都不够大,虽然他们相加正好是n+Block_size,但因为不连续所以不能创建。
对于第一个缺陷可以用memcpy函数来解决,
函数名: memcpy
功 能: 从源source中拷贝n个字节到目标destin中
用 法: void *memcpy(void *destin, void *source, unsigned n);
程序例:
#include <stdio.h>
#include <string.h>
int main(void)
{
char src[] = "*****";
char dest[] = "0123456709";
char *ptr;
printf("destination before memcpy: %s\n", dest);
ptr = memcpy(dest, src, strlen(src)); //这里用一个变量ptr来测试memcpy是否正常复制成功
if (ptr)
printf("destination after memcpy: %s\n", dest);
else
printf("memcpy failed\n");
return 0;
}
链表(Linked list)
链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。
链表的提出主要在于顺序存储中的插入和删除的时间复杂度是线性时间的,而链表的操作则可以是常数时间的复杂度。
OTHERS:
1、链接存储方法
链接方式存储的线性表简称为链表(Linked List)。
链表的具体存储表示为:
① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
注意:链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。
2、链表的结点结构
┌——┬——┐
| data | next |
└——┴——┘
数据域---存放数据元素
指针域---存放下一个结点地址
注意:
①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
②每个结点只有一个链域的链表称为单链表(Single Linked List)。
3、头指针head和终端结点指针域的表示
单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。
注意:链表由头指针唯一确定,单链表可以用头指针的名字来命名。
终端结点无后继,故终端结点的指针域为空,即NULL。
4、单链表的一般图示法
由于我们常常只注重结点间的逻辑顺序,不关心每个结点的实际位置,可以用箭头来表示链域中的指针
线性表
线性表是一种基本的顺序存储数据结构,线性表都是以栈、队列、字符串等特殊线性表的形式来使用的
在实现线性表数据元素的存储方面,一般可用顺序存储结构和链式存储结构两种方法。链式存储结构包含在线性链表中,另外栈、队列和串也是线性表的特殊情况,又称为受限的线性结构。
线性表中所有的元素所占的存储空间是连续的,线性表中常用的有链表和顺序表,顺序表所占的存储空间必须连续,链表没有这个要求,连续指的是存储空间的连续