我需要他的特点:

  • 可以长大的
  • 我要知道他有多大
  • 能够访问到单元

我可以自己做个接口「the interface」

#ifndef _ARR_H_
#define _ARR_H_
 
typedef struct {
	int *arr;
	int size;
} Arr;
 
Arr arr_create(int int_size);
void arr_free(Arr *a);
int arr_size(const Arr *a);
int* arr_at(Arr *a, int index);
void arr_inflate(Arr *a, int more_size);
 
#endif

主文件

#include "arr.h"
#include <stdlib.h>
 
// typedef struct {
//     int* arr;
//     int size;
// } Arr;
 
Arr arr_create(int int_size) {
    Arr a;
    a.size = int_size;
    a.arr = malloc(sizeof(int) * a.size);
    return a;
}
 
void arr_free(Arr* a) {
    free(a->arr);
    a->arr = NULL;
    a->size = 0;
}
 
// 这叫封装, 还是有用的(不懂)
int arr_size(const Arr* a) {
    return a->size;
}
 
// 为什么要返回地址, 而不是直接把值返回了?
// 因为地址的话, 我们可以让它做左值, 作赋值
int* arr_at(Arr* a, int index) {
    return &(a->arr[index]);
}
 
// malloc出来的东西没法长大, 但我们可以开一块新的出来
void arr_inflate(Arr* a, int more_size) {
    int* p = (int*)malloc(sizeof(int) * (a->size + more_size));
    for (int i = 0; i < a->size; i++) {
        p[i] = a->arr[i];
    }
    free(a->arr);
    a->arr = p;
    a->size += more_size;
}
 
int main() {
    Arr a = arr_create(100);
    printf("%d\n", arr_size(&a));
    *arr_at(&a, 0) = 10;
    arr_free(&a);
}

缺点

  • 当数据大了,每次增长都要复制, 会很慢
  • 有可能明明有足够的空间却申请失败

所以要是我每次新申请的区域我可以不动, 我可以在这之后链起来

链表