纯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) 链 ...
随机推荐
- 『无为则无心』Python基础 — 8、Python中的数据类型(数值、布尔、字符串)
目录 1.数据类型介绍 2.数值型(Number) 3.布尔型(bool) 4.None(空值) 5.常量 6.字符串(String) 1.数据类型介绍 (1)什么是数据类型 在生活中,我们日常使用的 ...
- 熬夜总结vue3中setUp函数的2个参数详解
1.setUp函数的第1个参数props setup(props,context){} 第一个参数props: props是一个对象,包含父组件传递给子组件的所有数据. 在子组件中使用props进行接 ...
- 没有指定非静态方法,Unity与Android通信错误
报错信息: AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='InstallApk' ...
- IPVS的ICMP报文处理-由内到外
这里主要明与NAT/Masq转发模式相关的ICMP报文处理,但也会提及由于出错引发的IPVS系统主动发送的ICMP报文. 1.ICMP由外到内处理流程入口 入口函数ip_vs_in实质上挂载在netf ...
- 乘风破浪,遇见下一代操作系统Windows 11,迄今为止最美版本,原生支持安卓应用
遇见下一代操作系统Windows 11 全新Windows体验,让您与热爱的人和事物离得更近. Windows一直是世界创新的舞台.它是全球企业的基石,助力众多蓬勃发展的初创公司变得家喻户晓.网络在W ...
- python之循环与判断
1,for 循环,语法 举例: for i in range(1, 5, 2): # 0,1,2,3,4 print(i) for a in range(5):# --(0,5,1) 0,1,2,3, ...
- Maven安装、配置及基础
简介: Maven是Apache公司的开源项目,是项目构建工具,用来管理依赖. Maven的优点: 同样的代码实现相同的功能,Maven项目没有Jar包,项目大小更小. maven的优点如何实现: 没 ...
- python二进制读写及特殊码同步
python对二进制文件的操作需要使用bytes类,直接写入整数是不行的,如果试图使用f.write(123)向文件中以二进制写入123,结果提示参数不是bytes类型. import os impo ...
- CentOS6.5 mini安装到VirtualBox虚拟机中
下载Oracle VM VirtualBox 下载下来安装 下载镜像 http://archive.kernel.org/centos-vault/6.5/isos/i386/CentOS-6.5-i ...
- linux学习之路第四天
用户和用户组的配置文件