User Tools

Site Tools


Go-like dynamic array

“Go-like”, хаха =) На самом деле алгоритм динамического массива используеться повсеместно лет 50, наверное. Поведение массива можно адаптировать под свои цели. =)

“Go-like”, haha =) Actually, dynamic array algorithm is used everywhere for about 50 years. Behavior of the array can be adapted to your purposes. =)

goslice.c
/*
 * Copyright 2023 Oleg Borodin  <borodin@unix7.org>
 */
 
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
 
typedef int elem_t;
 
typedef struct {
    int     size;
    int     capa;
    elem_t  *data;
} slice_t;
 
#define INIT_SIZE 5
 
void slice_init(slice_t *slice, int capa) {
    if (capa < 1) capa = INIT_SIZE;
    slice->data = malloc(sizeof(elem_t) * capa);
    slice->capa = capa;
    slice->size = 0;
}
 
int slice_add_elem(slice_t *slice, elem_t elem) {
    if (slice->size == slice->capa) {
        slice->data = realloc(slice->data, slice->capa * 2);
    }
    slice->data[slice->size++] = elem;
    return 0;
}
 
int slice_get_elem(slice_t *slice, elem_t *elem, int num) {
    if (num > slice->size) return -1;
    *elem = slice->data[num];
    return 0;
}
 
int slice_cut_end(slice_t *slice, int end) {
    if (end > slice->size) return -1;
    int capa = end * 2;
    if (capa < 1) capa = INIT_SIZE;
    slice->data = realloc(slice->data, capa * 2);
    slice->size = end;
    slice->capa = capa;
    return 0;
}
 
int slice_append_slice(slice_t *base, slice_t *addit) {
    int new_capa = base->capa + addit->size;
    if (new_capa == base->capa) {
        base->data = realloc(base->data, new_capa + new_capa / 10);
    }
    memcpy(&(base->data[base->size]), &(addit->data[0]), addit->size * sizeof(elem_t));
    base->size += addit->size;
    return 0;
}
 
 
int main(int argc, char **argv) {
 
    slice_t slice;
    slice_init(&slice, 5);
    int count = 12;
    for (int i = 0; i < count; i++) {
        slice_add_elem(&slice, i);
    }
    for (int i = 0; i < count; i++) {
        elem_t elem;
        slice_get_elem(&slice, &elem, i);
        printf("orig arr: elem %d = %d\n", i, elem);
    }
    count = 5;
    slice_cut_end(&slice, count);
    for (int i = 0; i < count; i++) {
        elem_t elem;
        slice_get_elem(&slice, &elem, i);
        printf("cutt arr: elem %d = %d\n", i, elem);
    }
 
    slice_t slice2;
    slice_init(&slice2, 5);
    count = 5;
    for (int i = 0; i < count; i++) {
        slice_add_elem(&slice2, i + 50);
    }
    slice_append_slice(&slice, &slice2);
 
    for (int i = 0; i < slice.size; i++) {
        elem_t elem;
        slice_get_elem(&slice, &elem, i);
        printf("cat arr: elem %d = %d\n", i, elem);
    }
 
    return 0;
}

Out

$ "./slice"
orig arr: elem 0 = 0
orig arr: elem 1 = 1
orig arr: elem 2 = 2
orig arr: elem 3 = 3
orig arr: elem 4 = 0
orig arr: elem 5 = 5
orig arr: elem 6 = 6
orig arr: elem 7 = 7
orig arr: elem 8 = 8
orig arr: elem 9 = 9
orig arr: elem 10 = 10
orig arr: elem 11 = 11

cutt arr: elem 0 = 0
cutt arr: elem 1 = 1
cutt arr: elem 2 = 2
cutt arr: elem 3 = 3
cutt arr: elem 4 = 4

cat arr: elem 0 = 0
cat arr: elem 1 = 1
cat arr: elem 2 = 2
cat arr: elem 3 = 3
cat arr: elem 4 = 4
cat arr: elem 5 = 50
cat arr: elem 6 = 51
cat arr: elem 7 = 52
cat arr: elem 8 = 53
cat arr: elem 9 = 54