C 实现一个可用的vector

c 复制代码
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct vector {
  bool empty;
  bool full;
  size_t sizeof_data;
  void *data;
  void *top;
  void *tail;
  size_t len;
  size_t capacity;
};

// NOTE: init capacity what you need
// NOTE: really using index
struct vector *VectorNew(size_t data, size_t capacity) {
  struct vector *instance = (struct vector *)calloc(sizeof(struct vector), 1);
  if (instance == 0) {
    return 0;
  }
  instance->data = calloc(data, capacity);
  instance->empty = true;
  instance->len = 1;
  instance->sizeof_data = data;
  instance->top = instance->data;
  instance->tail = instance->data;
  instance->capacity = capacity;
  return instance;
}

int32_t VectorPush(struct vector *vec, void *data) {
  if (vec == 0 || data == 0) {
    return -1;
  }
  vec->empty = false;
  if (vec->len >= vec->capacity) {
    vec->full = true;
    return -2;
  }
  vec->len++;
  memcpy(vec->tail, data, vec->sizeof_data);
  vec->tail += vec->sizeof_data;
  return 0;
}

// NOTE: check again
int32_t isVectorFull(struct vector *vec) {
  if (vec == 0) {
    return -1;
  }
  if (vec->len >= vec->capacity)
    vec->full = true;
  return vec->full;
}

int32_t isVectorEmpty(struct vector *vec) {
  if (vec == 0) {
    return -1;
  }
  if (vec->len == 0) {
    vec->empty = true;
  }
  return vec->empty;
}

// NOTE: inefficiency
int32_t VectorPop(struct vector *vec, void *data) {
  if (vec == 0 || data == 0) {
    return -1;
  }
  if ((--vec->len) <= 1) {
    vec->empty = true;
    return -2;
  }
  memcpy(data, vec->top, vec->sizeof_data);
  memmove(vec->top, vec->top + vec->sizeof_data, (vec->len) * vec->sizeof_data);
  vec->tail = vec->top + vec->sizeof_data * vec->len;
  return 0;
}

int32_t VectorPop_back(struct vector *vec, void *data) {
  if (vec == 0 || data == 0) {
    return -1;
  }
  if (vec->len < 1) {
    vec->len = 1;
    vec->empty = true;
    return -2;
  }
  memcpy(data, vec->tail - vec->sizeof_data, vec->sizeof_data);
  vec->len--;
  vec->tail = vec->top + vec->len * vec->sizeof_data;
  return 0;
}

int32_t VectorSize(struct vector *vec) {
  if (vec == 0) {
    return -1;
  }
  return vec->len;
}

struct vector *VectorTail(struct vector *vec) {
  return vec->tail - vec->sizeof_data;
}

struct vector *VectorTop(struct vector *vec) { return vec->top; }

// NOTE: inefficiency
int32_t VectorDelete(struct vector *vec, int32_t index) {
  if (vec == 0) {
    return -1;
  }
  if (index > vec->len - 1) {
    return -2;
  }
  vec->len--;
  memmove(vec->data + index * vec->sizeof_data,
          vec->data + (index + 1) * (vec->sizeof_data),
          vec->sizeof_data * index);
  vec->len = vec->len < 1 ? 1 : vec->len;
  vec->top = vec->data;
  vec->tail = vec->top + vec->sizeof_data * vec->len;
  return 0;
}

int32_t VectorGet(struct vector *vec, int32_t index, void *data) {
  if (vec == 0) {
    return 0;
  }
  if (vec->len == 1) {
    return 0;
  }
  if (index != 0 && index > vec->len - 1) {
    return 0;
  }
  memcpy(data, vec->data + vec->sizeof_data * index, vec->sizeof_data);
  return 0;
}

int32_t VectorSet(struct vector *vec, int32_t index, void *data) {
  if (vec == 0 && data != 0) {
    return -1;
  }
  if (vec->len == 1) {
    return -3;
  }
  if (index != 0 && index > vec->len - 1) {
    return -2;
  }
  memcpy(vec->data + index * vec->sizeof_data, data, vec->sizeof_data);
  return 0;
}

int32_t VectorFree(struct vector *vec) {
  if (vec != 0)
    free(vec);
  vec = 0;
  return 0;
}

int32_t VectorResize(struct vector *vec, size_t capacity) {
  if (vec == 0) {
    return -1;
  }
  if (capacity <= vec->capacity) {
    return 0;
  }
  vec->data = realloc(vec->data, capacity * vec->sizeof_data);
  if (vec->data == 0) {
    return -1;
  }
  vec->top = vec->data;
  vec->tail = vec->top + vec->sizeof_data * vec->len;
  vec->capacity = capacity;
  return 0;
}

struct testData {
  char name[5];
  int32_t i;
  void *ptr;
};

int main(void) {
  struct vector *vec = VectorNew(sizeof(struct testData), 4);
  if (vec == 0) {
    printf("create vector err\n");
    return 0;
  }

  struct testData tmp[] = {"1234", 1};
  struct testData tmp_1[] = {"6790", 2};
  struct testData tmp_2[] = {"abde", 3};
  struct testData tmp_3[] = {"fgij", 4};

  VectorPush(vec, tmp);
  VectorPush(vec, tmp_1);
  VectorPush(vec, tmp_2);

  // char b;
  // while (VectorPop(vec, &b) == 0) {
  //   printf("b number:%d\n", b);
  // }
  // printf("vec len %ld\n", vec->len);
  // if (VectorGet(vec, 0) == 0 && isVectorEmpty(vec)) {
  //   printf("VEC EMPTY \n");
  // }

  struct testData ctmp;
  VectorPop_back(vec, &ctmp);
  printf("Pop back data %s\n", ctmp.name);

  for (int32_t i = 0; i < VectorSize(vec); i++) {
    VectorGet(vec, i, &ctmp);
    printf("ctmp %s\n", ctmp.name);
  }
  return 0;
}

有些算法容器,还真不是,随便用,那vector 来说,pop 的效率 和 resize 的效率都很低
关键C 没有可用,放心的 算法容器库,就目前
POP POP_BACK GET SET PUSH 都是没问题,突然发现一个小问题 无语

相关推荐
vortex5几秒前
解决 VSCode 中 C/C++ 编码乱码问题的两种方法
c语言·c++·vscode
luky!21 分钟前
算法--解决熄灯问题
python·算法
Xiao Fei Xiangζั͡ޓއއ22 分钟前
一觉睡醒,全世界计算机水平下降100倍,而我却精通C语言——scanf函数
c语言·开发语言·笔记·程序人生·面试·蓝桥杯·学习方法
鸽鸽程序猿27 分钟前
【算法】【优选算法】二分查找算法(下)
java·算法·二分查找算法
_OLi_28 分钟前
力扣 LeetCode 150. 逆波兰表达式求值(Day5:栈与队列)
算法·leetcode·职场和发展
远望清一色38 分钟前
基于MATLAB身份证号码识别
开发语言·图像处理·算法·matlab
子朔不言43 分钟前
[ARM-2D 专题]6.脏矩形定义的宏使用技巧和分析
c语言·arm开发·arm2d·显控开发-新龙微
BT-BOX2 小时前
STM32仿真proteus位带操作和keil增加头文件C文件
c语言·stm32·proteus
醉颜凉2 小时前
【NOIP提高组】潜伏者
java·c语言·开发语言·c++·算法
lapiii3582 小时前
图论-代码随想录刷题记录[JAVA]
java·数据结构·算法·图论