起因

工作很少接触纯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. Task05:SQL高级处理

    5.1 窗口函数 5.1.1 窗口函数概念及基本的使用方法 窗口函数也称为OLAP函数.OLAP 是OnLine AnalyticalProcessing 的简称,意思是对数据库数据进行实时分析处理. ...

  2. 实验1、初入Flask

    实验介绍 1. 实验内容 Flask是一个用Python编写的Web应用程序框架.Armin Ronacher带领一个名为Pocco的国际Python爱好者团队开发了Flask.Flask基于Werk ...

  3. 【Java】Debug断点调试常用技巧

    Debug操作技巧 Show Execution Point 将光标回到当前断点停顿的地方 Step Over 执行当前行代码,并将运行进度跳转到下一行. Step Into 进入到当前代码行的方法内 ...

  4. 理解Spring:AOP的原理及手动实现

    引入 到目前为止,我们已经完成了简易的IOC和DI的功能,虽然相比如Spring来说肯定是非常简陋的,但是毕竟我们是为了理解原理的,也没必要一定要做一个和Spring一样的东西.到了现在并不能让我们松 ...

  5. 无规矩不成方圆,聊一聊 Spring Boot 中 RESTful 接口设计规范

    在设计接口时,有很多因素要考虑,如接口的业务定位,接口的安全性,接口的可扩展性.接口的稳定性.接口的跨域性.接口的协议规则.接口的路径规则.接口单一原则.接口过滤和接口组合等诸多因素,本篇文章将简要分 ...

  6. LuatOS | 全新在线模拟器,随时随地发挥创意

    LuatOS --运行在嵌入式硬件的实时操作系统,开启全新物联网生态. 聚焦嵌入式应用生态,内置功能可支持绝大多数物联网应用场景.深度整合Lua语言,只需少量内存和Flash空间就能运行.不局限于合宙 ...

  7. VueX理解

    什么是Vuex? 官方说法:Vuex 是一个专为 Vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 个人理解:Vue ...

  8. 2021年Wordpress手把手教你做个独立站——部署篇

    2021年Woocommerce电商主题的安装部署教程 Woocommerce是一个Wordpress的一个流行的电商插件.完成Wordpress的安装即已完成80%.剩下的便是去寻找一款合适的自己喜 ...

  9. Redis短结构

    本章将介绍3种非常有价值的降低Redis内存占用的方法.降低Redis的内存占用有助于减少创建快照和加载快照所需的时间.提升载入AOF文件和重写AOF文件时的效率.缩短从服务器进行同步所需的时间,并且 ...

  10. 二QT中使用QTimer定时器

    QT中的定时器类叫QTimer(5.8以上版本才有),构造函数只需要提供父对象的指针 使用的话,需要调用QTImer的start方法,该方法以毫秒单位,每过指定毫秒时间,该类对象就会发出一个timeo ...