纯C语言(C89)实现动态数组
起因
工作很少接触纯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)实现动态数组的更多相关文章
- (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)
目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...
- C语言基础 - 实现动态数组并增加内存管理
用C语言实现一个动态数组,并对外暴露出对数组的增.删.改.查函数 (可以存储任意类型的元素并实现内存管理) 这里我的编译器就是xcode 分析: 模拟存放 一个 People类 有2个属性 字符串类型 ...
- C语言实现使用动态数组实现循环队列
我在上一篇博客<C语言实现使用静态数组实现循环队列>中实现了使用静态数组来模拟队列的操作. 因为数组的大小已经被指定.无法动态的扩展. 所以在这篇博客中,我换成动态数组来实现. 动态数组能 ...
- C语言实现使用动态数组来构造栈结构
我在面前一篇博客<C语言实现使用静态数组来构造栈结构>中使用了静态数组来模拟栈的操作.静态数组的大小是在代码中写死的.是存储在用户栈上面的,使用起来不灵活.在这篇博客中我会使用动态数组来构 ...
- 使用java语言实现一个动态数组(详解)(数据结构)
废话不多说,上代码 1.从类名开始(我真是太贴心了) public class Array<E> 首先数组类需要带有泛型,这个不多说.需要注意的是在java中,数组只能存放同一个类型的. ...
- 纯C语言(C89)实现简单链表
起因 工作很少接触纯C项目,业余写着玩玩,不断雕琢 目标 纯C实现简单链表,提供方便易用泛型接口,避免依赖 实现 完全封装,隐藏结构体细节,不支持栈创建 拷贝存储,轻微性能代价换来易用性 list.h ...
- Go 语言入门 3-动态数组(slice)的特性及实现原理
go 语言中的动态数组(slice),是基于数组实现的,可以相比数组而言更加的灵活.其他语言的 slice 通常仅是一个 API, 但是 go 语言的 slice 不仅仅是一种操作, 也是一种数据结构 ...
- c语言 动态数组
C语言中,在声明数组时,必须明确告诉编译器数组的大小,之后编译器就会在内存中为该数组开辟固定大小的内存.有些时候,用户并不确定需要多大的内存,使用多大的数组,为了保险起见,有的用户采用定义一个大数组的 ...
- 线性表之顺序存储结构(C语言动态数组实现)
线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...
随机推荐
- 【NX二次开发】Block UI 枚举
属性: 常规 类型 描述 BlockID String 控件ID Enable Logical 是否可操作 Group Logical ...
- Pytorch Dataset和Dataloader 学习笔记(二)
Pytorch Dataset & Dataloader Pytorch框架下的工具包中,提供了数据处理的两个重要接口,Dataset 和 Dataloader,能够方便的使用和加载自己的数据 ...
- OO unit3 summary
Unit3 JML(Java Modeling Language) 是用于对 Java 程序进行规格化设计的一种表示语言,它对于方法内部具体是如何实现的并无要求,只是对方法的接口以及行为进行限制, ...
- 03 Git 以及 其 GUI TortoiseGit 的下载与安装
前面也说过嘛,要紧跟大佬们的步伐--选择最受欢迎的版本控制系统. 而根据 [JetBrains](JetBrains: Essential tools for software developers ...
- github push pull error port 443: Timed out
最近github只有开代理才能打开,但是即使能打开,进行push或者pull会经常报类似error port 443: Timed out的错误,网上搜了很久才找到解决办法. 首先要查询当前本机使用的 ...
- Unity异步加载进度条
先上代码: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngi ...
- 海康威视摄像头入侵+fofa(CVE-2017-7921)
海康威视摄像头入侵+fofa(CVE-2017-7921) By:Jesse 重保期间实在是太无聊,于是就找了个海康威视的摄像头日日玩,结果一玩就是一天呢哈哈哈. 1.漏洞编号 CVE-2017-79 ...
- 12、创建mysql用户及赋予用户权限
1.通过help命令查看grant的用法: CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON db1.* ...
- hdu 2159 二维完全背包
Problem Description 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.现 ...
- Redis 底层数据结构之整数集合
文章参考:<Redis 设计与实现>黄建宏 整数集合 整数集合时集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合数量不多时,就会使用整数集合 typedef struct i ...