首页 > 其他分享 >c实现一个简单的vector

c实现一个简单的vector

时间:2023-11-05 17:57:04浏览次数:38  
标签:Vector 实现 items printf vector 简单 data size

用c语言实现了一个简单的Vector,支持泛型,能动态的改变自身大小的容器

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

typedef struct Vector {
    void* items; // 迭代器
    size_t items_size; // 单个元素大小
    size_t size; // 使用的大小(有多少个成员)
    size_t capacity; // 总容量
} Vector;

// 构造函数 实现vector初始化容量 分配内存
void Vector_constructor(Vector* vector, size_t items_size, size_t capacity) {
    
    vector->items_size = items_size;
    vector->size = 0;
    vector->capacity = capacity;
    vector->items = malloc(capacity * items_size);
    
    if (vector->items == NULL) {
        printf("Vector_constructor error!");
        exit(0);
    }
}

//析构函数 实现vector 释放内存,容量初始化
void Vector_destructor(Vector* vector) {
    
    free(vector->items);
    vector->items = NULL;
    vector->size = 0;
    vector->capacity = 0;
}

// 返回使用的大小
size_t Vector_size(Vector* vector) {
    return vector->size;
}

//返回容量
size_t Vector_capacity(Vector* vector) {
    return vector->capacity;
}

//返回数据指针
void* Vector_data(Vector* vector) {
    return vector->items;
}

// realloc 重新分配内存
void Vector_resize(Vector* vector, size_t newSize) {
    if (newSize > Vector_capacity(vector)) {
        void* new_items = realloc(Vector_data(vector), newSize * vector->items_size);

        if (!new_items) {
            printf("realloc error!\n");
            return;
        }

        vector->items = new_items;
        vector->capacity = newSize;
    }
    vector->size = newSize;
}

// 返回一个位置的指针,如果越界就扩容
void* Vector_at(Vector* vector, size_t index) {
    if (index >= Vector_capacity(vector)) {
        size_t newSize = index + 1;
        Vector_resize(vector, newSize);
    }

    return (char*)vector->items + (index * vector->items_size);
}

//插入元素
void Vector_set(Vector* vector, size_t index, void* data) {
    if (index >= vector->size) {
        Vector_resize(vector, index + 1);
        vector->size = index + 1;
    }
    void* item_ptr = (char*)vector->items + (index * vector->items_size);
    memcpy(item_ptr, data, vector->items_size);
}

int main() {
    Vector v;
    Vector_constructor(&v, sizeof(int), 2);

    int value0 = 0, value1 = 1;

    // 添加两个元素
    Vector_set(&v, 0, &value0);
    Vector_set(&v, 1, &value1);

    //单元测试
    //测试大小 测试数据有没有被添加成功
    assert(Vector_size(&v) == 2);
    for (int i = 0; i < 2; i++) {
        assert(("Test data", *((int*)Vector_data(&v) + i) == i));
    }
    //单元测试

    for (size_t i = 0; i < Vector_size(&v); i++) {
        printf("%d ", *((int*)Vector_data(&v) + i));
    }
    printf("\n");

    printf("Vector_size: %d", Vector_size(&v));    
    printf("\n");

    int valueN[15];
    for (int i = 2; i < 15; i++) {
        valueN[i] = i;
        Vector_set(&v, i, &valueN[i]);
    }

    //单元测试
    //测试大小 测试数组有没有成功扩容
    assert(Vector_size(&v) == 15);
    for (int i = 0; i < 15; i++) {
        assert(("Test data", *((int*)Vector_data(&v) + i) == i));
    }
    //单元测试

    for (size_t i = 0; i < Vector_size(&v); i++) {
        printf("%d ", *((int*)Vector_data(&v) + i));
    }
    printf("\n");

    printf("Vector_size: %d", Vector_size(&v));
    printf("\n");


    Vector_constructor(&v, sizeof(char), 2);

    char* s = (char*)"abc";

    for (size_t i = 0; i < 3; i++)
    {
        Vector_set(&v,i,s+i);
    }


    //单元测试
    //测试大小 测试泛型
    assert(Vector_size(&v) == 3);
    for (int i = 0; i < 3; i++) {
        assert(("Test data", *((char*)Vector_data(&v) + i) == s[i]));
    }
    //单元测试



    for (size_t i = 0; i < Vector_size(&v); i++) {
        printf("%c ", *((char*)Vector_data(&v) + i));
    }
    printf("\n");

    return 0;
}

标签:Vector,实现,items,printf,vector,简单,data,size
From: https://www.cnblogs.com/nyyyddddn/p/17810807.html

相关文章

  • Spring自定义数据校验并实现国际化功能
    通常,当我们需要验证用户输入时,SpringMVC提供标准的预定义验证器。我们会引入spring-boot-starter-validation依赖来实现数据校验功能。但是,当我们需要验证特定类型的输入时,我们就需要创建自己的自定义校验逻辑。这里我们取一个相对简单的校验手机号码的功能来实现。为了校验手......
  • eframe 持久化实现
    在Native平台上,eframe将应用程序的指定信息存储在文件系统中,并由开发者决定启动时是否需要加载这些此前保存的应用程序信息.在Web平台,这些信息则存储在浏览器的local-storage中.这篇文章将以Native平台为例,探究以下几个问题:持久化是怎样实现的?持久化的时......
  • 基础排序——数组和链表实现(C)
    一、数组实现①选择排序从index=0开始,每一轮找到一个最小的元素,然后交换num[index]和num[min]的位置,直至数组遍历完。得到一个升序数组。voidselectSort(int*num,intn){for(inti=0;i<n;i++){intmin=i;for(intj=i+1;j<n;j++){......
  • 《信息安全系统设计与实现》第九周学习笔记
      《信息安全系统设计与实现》第九周学习笔记第五章定时器及时钟服务硬件定时器定时器是由时钟源和可编程计数器组成的硬件设备。时钟源通常是一个晶体振荡器,会产生周期性电信号,以精确的频率驱动计数器。使用一个倒计时值对计数器进行编程,每个时钟信号减1。当计数减为0时......
  • 《信息安全系统设计与实现》第八次学习笔记
    第五章:定时器及时钟服务硬件定时器定时器是由时钟源和可编程计数器组成的硬件设备。时钟源通常是一个晶体振荡器,会产生周期性电信号,以精确的频率驱动计数器。使用一个倒计时值对计数器进行编程,每个时钟信号减1。当计数减为0时,计数器向CPU生成一个定时器中断,将计数值重新加载到......
  • 《信息安全系统设计与实现》第九周学习笔记
    硬件定时器定时器是由时钟源和可编程计数器组成的硬件设备。时钟源通常是一个晶体振荡器,会产生周期性电信号,以精确的频率驱动计数器。使用一个倒计时值对计数器进行编程,每个时钟信号减1。当计数减为0时,计数器向CPU生成一个定时器中断,将计数值重新加载到计数器中,并重复倒计时。......
  • 信息安全系统设计与实现学习笔记8
    学习笔记8-重点总结1.定时器及时钟服务1.1硬件定时器由时钟源和可编程计数器组成的硬件设备。时钟源通常是晶体振荡器,驱动计数器以精确的频率。计数器周期称为定时器刻度,是系统的基本计时单元。1.2个人计算机定时器实时时钟(RTC)提供时间和日期信息,即使在关机时也能......
  • 引用与vector
    今天写线段树合并的时候,忽然想到可以用vector存树,这样就不用算空间了。然后有了下面代码:voidmodify(int&u,intl,intr,intp,intk){ if(!u)u=newnode(); if(l==r){ tr[u].max+=k; tr[u].id=p; return; } intmid=(l+r)>>1; if(p<=mid)modify(tr[u].ls,l,m......
  • python实现PDF文件指定页码号裁剪
    代码importPyPDF2out_pdf=PyPDF2.PdfFileWriter()dst_file=f'output.pdf'withopen('input.pdf','rb')assrc_file: reader=PyPDF2.PdfFileReader(src_file) pages=reader.numPages forpinrange(12): #这里是获取源PDF前12页,......
  • fibnacci数列递归实现
    1.什么是fibnacci数列斐波那契数列(Fibonaccisequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(LeonardoFibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……不难发现,前两项的值各为1,从第三项起,每一项都是前两项的和。2.fibnacci数......