起因

工作很少接触纯C项目,业余写着玩玩,不断雕琢

目标

纯C实现动态数组,提供方便易用泛型接口,避免依赖

实现

完全封装,隐藏结构体细节,不支持栈创建

拷贝存储,轻微性能代价换来易用性

vector.h

#ifndef VECTOR_H
#define VECTOR_H
#include <stddef.h> typedef struct Vector_ Vector; extern Vector* vector_new(size_t elem_size);
extern void vector_free(Vector* v);
extern size_t vector_length(Vector* v);
extern void vector_get(Vector* v, size_t pos, void* elem_out);
extern void vector_set(Vector* v, size_t pos, void* elem_in);
extern int vector_append(Vector* v, void* elem_in); // On failure, returns -1. #endif // VECTOR_H

vector.c

#include "vector.h"
#include <stdlib.h>
#include <string.h> typedef unsigned char byte; typedef struct Vector_ {
size_t count;
size_t max_count;
size_t elem_size;
byte* data;
} Vector; #define vector_max_size(v) ((v->elem_size)*(v->max_count)) Vector* vector_new(size_t elem_size) {
Vector* v = calloc(1, sizeof(Vector));
if (v) v->elem_size = elem_size;
return v;
} void vector_free(Vector* v) {
if(v->data) free(v->data);
free(v);
} size_t vector_length(Vector* v) {
return v->count;
} void vector_get(Vector* v, size_t pos, void* elem_out) {
if (pos < v->count) {
byte* p = v->data + v->elem_size * pos;
memcpy(elem_out, p, v->elem_size);
}
} void vector_set(Vector* v, size_t pos, void* elem_in) {
if (pos < v->count) {
byte* p = v->data + v->elem_size * pos;
memcpy(p, elem_in, v->elem_size);
}
} int vector_append(Vector* v, void* elem_in) {
if (v->count >= v->max_count) {
byte* data;
v->max_count = (v->max_count)?(v->max_count*2):(4);
data = realloc(v->data, vector_max_size(v));
if (!data) return -1;
v->data = data;
}
vector_set(v, v->count++, elem_in);
return 0;
}

测试

#include <stdio.h>
#include <stdlib.h>
#include "vector.h" int main(int argc, char *argv[]) {
Vector* v = vector_new(sizeof(int));
size_t v_len = 0;
int i, x, y;
for (i=0; i<10; i++) {
vector_append(v, &i);
}
v_len = vector_length(v);
printf("v_len:%d \n", v_len);
for (i=0; i<v_len; i++) {
vector_get(v, i, &x);
printf("%d:%d \t", i, x);
x *= 100;
vector_set(v, i, &x);
vector_get(v, i, &y);
printf("%d:%d \n", i, y);
}
vector_free(v);
return 0;
}
v_len:10
0:0 0:0
1:1 1:100
2:2 2:200
3:3 3:300
4:4 4:400
5:5 5:500
6:6 6:600
7:7 7:700
8:8 8:800
9:9 9:900

纯C语言(C89)实现动态数组的更多相关文章

  1. (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)

    目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...

  2. C语言基础 - 实现动态数组并增加内存管理

    用C语言实现一个动态数组,并对外暴露出对数组的增.删.改.查函数 (可以存储任意类型的元素并实现内存管理) 这里我的编译器就是xcode 分析: 模拟存放 一个 People类 有2个属性 字符串类型 ...

  3. C语言实现使用动态数组实现循环队列

    我在上一篇博客<C语言实现使用静态数组实现循环队列>中实现了使用静态数组来模拟队列的操作. 因为数组的大小已经被指定.无法动态的扩展. 所以在这篇博客中,我换成动态数组来实现. 动态数组能 ...

  4. C语言实现使用动态数组来构造栈结构

    我在面前一篇博客<C语言实现使用静态数组来构造栈结构>中使用了静态数组来模拟栈的操作.静态数组的大小是在代码中写死的.是存储在用户栈上面的,使用起来不灵活.在这篇博客中我会使用动态数组来构 ...

  5. 使用java语言实现一个动态数组(详解)(数据结构)

    废话不多说,上代码 1.从类名开始(我真是太贴心了) public class Array<E> 首先数组类需要带有泛型,这个不多说.需要注意的是在java中,数组只能存放同一个类型的. ...

  6. 纯C语言(C89)实现简单链表

    起因 工作很少接触纯C项目,业余写着玩玩,不断雕琢 目标 纯C实现简单链表,提供方便易用泛型接口,避免依赖 实现 完全封装,隐藏结构体细节,不支持栈创建 拷贝存储,轻微性能代价换来易用性 list.h ...

  7. Go 语言入门 3-动态数组(slice)的特性及实现原理

    go 语言中的动态数组(slice),是基于数组实现的,可以相比数组而言更加的灵活.其他语言的 slice 通常仅是一个 API, 但是 go 语言的 slice 不仅仅是一种操作, 也是一种数据结构 ...

  8. c语言 动态数组

    C语言中,在声明数组时,必须明确告诉编译器数组的大小,之后编译器就会在内存中为该数组开辟固定大小的内存.有些时候,用户并不确定需要多大的内存,使用多大的数组,为了保险起见,有的用户采用定义一个大数组的 ...

  9. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

随机推荐

  1. 【NX二次开发】获取面的类型 UF_MODL_ask_face_type

    源码: extern DllExport void ufsta(char *param, int *returnCode, int rlen) { UF_initialize(); int face_ ...

  2. MySQL的可重复读级别能解决幻读问题吗?

    之前在深入了解数据库理论的时候,了解到事务的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了. 但是对于幻读, ...

  3. 从0到1用react+antd+redux搭建一个开箱即用的企业级管理后台系列(基础篇)

    背景 ​ 最近因为要做一个新的管理后台项目,新公司大部分是用vue写的,技术栈这块也是想切到react上面来,所以,这次从0到1重新搭建一个react项目架子,需要考虑的东西的很多,包括目录结构.代码 ...

  4. 关于安装运行MYSQL8.0简单使用及注意事项 On Docker Desktop & WSL2

    背景介绍 MYSQL是业界非常流行的一款关系型数据库系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.MySQL所使用的SQL语言是用于访问数据 ...

  5. 42、mysql数据库(函数)

    1.mysql中提供的内置函数: (1)数学函数: 1)ROUND(x,y): 返回参数x的四舍五入的有y位小数的值.x不可转换时返回0,x为null时返回null. 2)RAND(): 返回0到1内 ...

  6. JS刷新窗口的几种方式

    浮层内嵌iframe及frame集合窗口,刷新父页面的多种方法   <script language=JavaScript>       parent.location.reload(); ...

  7. yolov5 AssertionError: Image Not Found解决方案

    运行yolov5 train.py报错:AssertionError: Image Not Found ../data/images/xxx.png 运行环境     一开始在笔记本上用显卡跑训练是可 ...

  8. 编译x86_64 Linux内核并基于QEMU运行

    编译并运行内核镜像 安装包准备 $ sudo apt install git $ sudo apt install build-essential kernel-package fakeroot li ...

  9. 基于uni-app全端弹框组件uaPopup「兼容h5+小程序+app端|nvue」

    uniapp兼容多端自定义模态弹框组件UAPopup ua-popup 一款轻量级的uniapp自定义弹窗组件.汇集了android.ios和微信弹窗效果(msg消息.alert提示框.dialog对 ...

  10. Python分析【公众号】历史评论,看看大家的留言情况!

    大家好,我是辰哥~~~ 辰哥玩公众号有一段时间了,这期文章分析一波读者的留言情况,不仅可以对公众号的各位铁粉一目了然,还可以通过分析的结果对公众号的经营进行更好的规划.如读者留言的内容通常是内容是什么 ...