【C 语言】可变数组

背景

  • C 语言本身并不支持数组随计算发生变化,所以可以使用 malloc 创建新的空间,并让旧数组指向新空间的方式,实现变相的扩容。
  • 由于 malloc 创建空间,是向后创建的,所以每次扩容时,都会在前面留下空白的空间,此时就造成了空间的浪费,此缺点可以利用链表进行弥补。
  • 可以自定函数将可变数组的对应功能进行封装,方便使用。
  • 本文中的具体实现参考了浙大翁恺老师的 C 语言课程,链接已在本文末尾给出,如果有地方看不懂可以自己去看视频了解或者私信我。

结构定义及相关函数声明(array.h)

#ifndef __ARRAY_H
#define __ARRAY_H

typedef struct Array {
    
    int *array_;    // 数组指针 
    int size_;   // 数组大小 
    
} Array;

Array array_Create(int size);   // 创建数组 
void array_Free(Array *array);  // 释放数组 
int array_Size(const Array *array); // 获取数组可用空间 
int array_Check_Index(Array *array, int index);   // 检查索引是否超出范围  
int* array_At(Array *array, int index);  // 获取数组对应空间的地址 
int array_Get(Array *array, int index);   // 获取数组中对应索引的数据 
void array_Set(Array *array, int index, int value); // 对数组的指定位置赋值 
void array_Inflate(Array *array, int more_size);    // 数组空间的增长 

#endif 

函数定义(array.c)

#include <stdlib.h>
#include <string.h>	// 利用 memcpy 复制数组
#include "array.h"

#define BLOCK_SIZE 20	// 当索引超出范围时,增加 x 空间

Array array_Create(int size) {   // 创建数组 

    Array temp;
    temp.array_ = (int*)malloc(sizeof(int) * size);
    temp.size_ = size;
    
    return temp;
}

void array_Free(Array *array) {  //  释放数组 
    free(array -> array_);
    array -> array_ = NULL;
    array -> size_ = 0; 
}

int array_Size(const Array *array) { // 获取数组可用空间 
    return array -> size_;
}

int array_Check_Index(Array *array, int index) {  // 检查索引是否超出范围 

    if (index >= array -> size_) { 
        array_Inflate(array, (index / BLOCK_SIZE + 1) * BLOCK_SIZE - array -> size_);    // 根据索引增长 n 组 BLOCK,防止多次拷贝数组 
    } else if (index < 0) {
        index = 0;
    } 
    
    return index;
}

int* array_At(Array *array, int index) {  // 获取数组对应空间地址 
    //index = array_Check_Index(array, index);
    //return &(array -> array_[index]); 
    return &(array -> array_[array_Check_Index(array, index)]); 
}

int array_Get(Array *array, int index) {  // 获取数组中对应索引的数据 

    return array -> array_[array_Check_Index(array, index)];
}

void array_Set(Array *array, int index, int value) {  // 对数组的指定位置赋值 
    //index = array_Check_Index(array, index);
    //array -> array_[index] = value; 
    array -> array_[array_Check_Index(array, index)] = value; 
}

void array_Inflate(Array *array, int more_size) {    // 数组空间的增长 
    
    array -> size_ = array -> size_ + more_size;
    int *new_array = (int*)malloc(sizeof(int) * array -> size_); // 根据增加/减少的空间创建新数组 
    
    memcpy(new_array, array -> array_, sizeof(int) * (array -> size_ - more_size)); // 将旧数组中的数据拷贝到新数组 
    /*  与 memcpy 功能相同,但是理论上库函数的效率要比自己编写的函数高 
    for (int i = 0; i < array -> size_ - more_size; i++) {   
        new_array[i] = array -> array_[i];
    }
    */
    free(array -> array_);   // 释放旧数组 
    array -> array_ = new_array; // 指向新数组 
}

测试(main.c)

#include <stdio.h>
#include "array.h"

int main(int argc, char *argv[]) {
    
    Array array = array_Create(2);
    
    printf("当前可变数组的空间为:%d\n", array_Size(&array));
    
    int cut = 0;
    while (1) {
        
        scanf("%d", array_At(&array, cut++));

        if (array_Get(&array, cut - 1) == -1) {
            break;
        }
    }
    
    printf("当前可变数组的空间为:%d\n", array_Size(&array));
    
    for (int i = 0; i < array_Size(&array); i++) {
        if (array_Get(&array, i) == -1) {
            break;
        }
        printf("%d ", array_Get(&array, i));
    }
    printf("\n");

	system("pause");
    
	return 0;
}

参考资料

C 语言程序设计进阶-翁恺

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值