1、创建头文件
/*********************
* array.h *
*********************/
#ifndef _ARRAY_H_ //避免重复声明
#define _ARRAY_H_
typedef struct{
int *array; //数组指针
int size; //数组大小
} Array; //为提高可读性,定义结构类型的数组Array,而非指针*Array
Array array_create(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); //数组扩增
#endif
2、函数实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "array.h"
const int BLOCK_SIZE = 20; //数组每次增长的单元个数
//创建初始大小的数组
Array array_create(int init_size)
{
Array a;
a.array = (int*)malloc(init_size*sizeof(int));
a.size = init_size; //数组初试大小
return a;
}
//释放数组内存空间
void array_free(Array *a)
{
free(a.array);
a.array = NULL; //等价于 a->array = NULL;
a.size = 0;
}
//封装
int array_size(const Array *a)
{
return a.size;
}
//访问可变数组的数据,可读可写
int* array_at(Array *a, int index)
{
if( index >= a.size ){
array_inflate(a, (index/BLOCK_SIZE + 1)*BLOCK_SIZE - a.size); //计算index在第几个block里,增长到合适的长度使得index恰好在最后一个block里
}
return &(a->array[index]);
}
//数组扩增
void array_inflate(Array *a, int more_size)
{
int *p = (int*)mallc((a.size + more_size)*sizeof(int)); //创建新的动态数组p
memcpy(p, a.array, a.size); //复制原数组数据至新数组
free(a.array); //释放原有数组内存空间
//a.array指向新的数组
a.array = p;
a.size += more_size;
}
int main()
{
Array a = array_create(100); //创建初始长度为100的整型数组
printf("%d\n", array_size(&a));
*array_at(&a, 0) = 10;
printf("%d\n", *array_at(&a, 0));
//持续读入,长度不够则数组自动增长
int cnt = 0;
while( (scanf("%d", array_at(&a, cnt++)) != EOF);
array_free(&a);
return 0;
}
3、可变数组的缺陷
- 每次数组扩增,都需要重新分配新的动态内存:
- 数据拷贝耗费时间;
- 有内存但无法再申请空间(先在原内存空间后面申请新的空间,再在释放原内存空间)
尝试原内存空间不变,分配新的内存存储数据,将新的内存与原内存区域链接起来,可解决此问题。