可变数组_C语言快速入门与计算机二级备考

实现可变数组

  • 数组本身可以用变量去定义,但变量的值必须是固定的

    要求用代码实现可变长度的数组,长度可以增长,并且能知道其当前确切长度,并能访问到其中各个单元

实现可变数组的头文件

  • 包含可变数组的结构与实现可变数组功能的函数原型

    #ifndef _ARRAY_H_
    #define _ARRAY_H_
    
    typedef struct{
    	int *array;
    	int size;
    } 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
    

实现可变数组的函数

  • 创建数组
    #include "array.h"
    #include <stdio.h>
    #include <stdlib.h>
    
    Array array_create(int init_size);//创建一个数组
    {
    	Array a;//创建名为a的结构Array,作为函数中的临时结构体
    	a.array=(int*)malloc(sizeof(int)*init_size);//令a中的array指针强制类型转换为int类型指针,并利用malloc分配init_size个int大小的
    	a.size=init_size;//传入的值作为数组大小
    	return a;//将这个结构a传出
    }
    Array sth = array_create(100);//应用例:创建了一个名为sth,长度为100的可变数组
    
  • 回收数组
    void array_free(Array *a);//用于回收数组的空间
    {
    	free(a->array);//将a中的array所指内存空间释放
    	a->array = NULL;//a中的array指针指零
    	a->size=0;//a中的size归零
    }
    array_free(&sth);//应用例:将刚刚的数组sth释放
    

可变数组的数据访问

  • 获取数组的大小
    int array_size(const Array *a);//获得数组的大小
    {
    	return a->size;//直接将记录数组长度的变量返回
    } 
    printf("%d",array_size(&sth));//不直接用sth.size,而是写入函数中,称作封装,是为了保护代码以及便于修改
    
  • 访问数组中的单元
    const BLOCK_SIZE = 20;//可变数组长度每次加1再复制全部浪费性能,故引入BLOCK概念,一次增加一个BLOCK的单元
    
    int* array_at(Array *a, int index);//访问数组的某个单元
    {
    	if (index >= a->size){
    		array_inflate(a,(index/BLOCK_SIZE+1)*BLOCK_SIZE-(a->size));
    //当要求访问的单元下标数超出数组长度时,配合数组增长函数,使数组增长
    	}
    	return &(a->array[index]);//返回的是指针
    }
    
    printf("%d",*array_at(&sth,0));//输出可变数组sth的第0位,由于函数返回的是指针,故需要*取所指变量
    *array_at(&sth,0)=10;//使用指针的好处是可直接使用这一句话为sth数组的0位赋值
    
    //或者也可以将修改数组的某个单元的操作同样封装起来,如下
    void array_set(Array *a, int index, int value)
    {
    	a->array[index] = value;
    }
    
  • 可变数组的自动增长
    void array_inflate(Array *a, int more_size);//改变数组长度
    {
    //创建函数时molloc的内存空间无法再改动,所以可变数组的原理是:再申请一块新的空间
    //与上述的array_at函数配合,需要增长的数组长度more_size即index/BLOCK_SIZE+1)*BLOCK_SIZE-(a->size)
    //这个数值为:需要访问下标数在除BLOCK大小后再+1个BLOCK,得总共所需BLOCK数,再乘上BLOCK_SIZE得这些BLOCK总共的单元数,最后减去原来已有的长度a->size
    	int *p =(int*)molloc(sizeof(int)*(a->size + more_size));
    	int i;
    	for(i=0;i<a->size;i++){
    	p[i]=a->array[i];//将原来在a中的内容复制到p
    	}//也可以用mencpy(dest,src,strlen(src)+1)函数进行复制,效率更高
    	free(a->array);//释放原来a占用的空间
    	a->array=p;//将a中指针指向新的p
    	a->size += more_size;//让数组的原长度加上增加的长度数据
    }
    
    //可无限向数组录入信息的代码
    int cnt = 0;//记录录入数
    int number= 0;//记录录入值
    while(number!=-1)//规定输入-1时停止录入
    {
    	scanf("%d",&number);
    	if(number!=-1)
    		*array_at(&sth,cnt++)=number;
    //以能够根据录入数增长的变量cnt为下标,当cnt>size时能够自动增长
    }
    

可变数组的缺陷

  • 数组增长时申请新内存并清除原内存的做法,在内存受限的平台上容易导致有足够内存,但无法继续申请的情况(因为前面的内存被废弃了,新申请的空间在原空间之后)
  • 可以通过链表的方式,不再需要拷贝同时可以充分离开内存

posted on   无术师  阅读(32)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

统计

点击右上角即可分享
微信分享提示