纯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
posted @ 2019-09-17 13:52  wuyaSama  阅读(520)  评论(0编辑  收藏  举报