一生一世学坛

 找回密码
 立即注册
搜索
查看: 7342|回复: 0
打印 上一主题 下一主题

C实现Array数组结构

[复制链接]

334

主题

385

帖子

6830

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6830
跳转到指定楼层
楼主
发表于 2019-6-17 20:12:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
C实现Array数组结构

头文件:
#ifndef __ARRAY_H__
#define __ARRAY_H__

#include <stdio.h>
#include <stdlib.h>

typedef struct Array
{
    // p指针的空间大小
    size_t size;
    // p指针已经使用的空间大小
    size_t len;
    // 数据类型的大小
    size_t typeSize;
    // 值复制函数
    void(*dup)(void *ptr, void *key);
    // 值释放函数
    void(*free)(void *ptr);
    // 值比较函数
    int(*match)(void *ptr, void *key);
    // 存放数据的指针
    void   *p;
}Array;

#define arraySetDupMethod(a, m) ((a)->dup = (m))
#define arraySetFreeMethod(a, m) ((a)->free = (m))
#define arraySetMatchMethod(a, m) ((a)->match = (m))

#define arrayGetDupMethod(a) ((a)->dup)
#define arrayGetFree(a) ((a)->free)
#define arrayGetMatchMethod(a) ((a)->match)

//创建数组
Array* arrayCreate();

//数组初始化,数组指针   最大容量    每个元素的大小
void arrayInit(Array *array, int size, int typeSize);

//数组中插入值   数组指针   插入位置   插入的元素
int arrayInsert(Array *array, size_t pos, void *const value);

//数组中查找元素的位置
size_t arraySearchValue(Array *array, void* const value);

//获取指定位置的元素
void* arrayIndex(Array *array, size_t index);

//修改指定位置的元素的值
int arrayModify(Array *array, size_t pos, void *const value);

//返回数组中实际有多少元素
size_t arrayLen(Array *array);

//返回数组的最大容量
size_t arraySize(Array *array);

//清空数组,释放所有空间
void arrayEmpty(Array *array);

//删除数组中指定的值,只删除找到的第一个
void arrayDelValue(Array *array, void *value);

//删除数组中指定位置的元素
void arrayDelIndex(Array *array, size_t pos);

#endif // !__ARRAY_H__



实现文件:
#include "Array.h"

#include <string.h>
#include <stdbool.h>

Array* arrayCreate()
{
    struct Array *array = NULL;
    array = malloc(sizeof(*array));
    if (NULL == array)
    {
        return NULL;
    }

    array->p = NULL;

    array->size = 0;
    array->typeSize = 0;
    array->len = 0;

    array->dup = NULL;
    array->free = NULL;
    array->match = NULL;

    return array;
}

void arrayInit(Array *array, int size, int typeSize)
{
    if (NULL == array
        || typeSize <= 0
        || size < 0)
    {
        return;
    }

    void *p = calloc(1, size* typeSize);
    if (NULL == p)
    {
        return;
    }

    array->p = p;
    array->len = 0;
    array->size = size;
    array->typeSize = typeSize;
}

int arrayInsert(Array *array, size_t pos, void *const value)
{
    if (NULL == array)
    {
        return -1;
    }

    if (array->len >= array->size)
    {
        return -2;
    }

    if (pos > array->size || pos <= 0)
    {
        return -3;
    }

    char *pBegin = array->p;
    for (size_t i = array->len; i > pos - 1; --i)
    {
        void *pNew = pBegin + i * array->typeSize;
        void *pOld = pBegin + (i - 1) *array->typeSize;
        if (NULL != array->dup)
        {
            array->dup(pNew, pOld);
        }
        else
        {
            memcpy(pNew, pOld, array->typeSize);
        }
    }

    void *pCopy = (void*)(pBegin + ((pos - 1) * array->typeSize));
    if (NULL != array->dup)
    {
        array->dup(pCopy, value);
    }
    else
    {
        memcpy(pCopy, value, array->typeSize);
    }
    ++array->len;
    return 0;
}

size_t arraySearchValue(Array *array, void* const value)
{
    if (NULL == array)
    {
        return -1;
    }

    char *pBegin = array->p;
    size_t i = 0;
    for (; i < array->len; ++i)
    {
        int nCmp = 0;
        if (NULL != array->match)
        {
            nCmp = array->match(pBegin + i * array->typeSize, value);
        }
        else
        {
            nCmp = memcmp(pBegin + i * array->typeSize, value, array->typeSize);
        }

        if (nCmp == 0)
        {
            break;
        }
    }

    return i;
}

void* arrayIndex(Array *array, size_t index)
{
    if (NULL == array)
    {
        return NULL;
    }

    if (index > array->len
        || index <= 0)
    {
        return NULL;
    }

    char *pBegin = array->p;
    return pBegin + array->typeSize * (index - 1);
}

int arrayModify(Array *array, size_t pos, void *const value)
{
    if (NULL == array)
    {
        return -1;
    }
    if (pos > array->len
        || pos <= 0)
    {
        return -2;
    }

    char *pBegin = array->p;
    void *pOld = pBegin + (pos - 1) * array->typeSize;
    if (NULL != array->dup)
    {
        array->dup(pOld, value);
    }
    else
    {
        memcpy(pOld, value, array->typeSize);
    }

    return 0;
}

size_t arrayLen(Array *array)
{
    if (NULL == array)
    {
        return 0;
    }

    return array->len;
}

size_t arraySize(Array *array)
{
    if (NULL == array)
    {
        return 0;
    }

    return array->size;
}

void arrayEmpty(Array *array)
{
    if (NULL == array)
    {
        return;
    }

    free(array->p);
    array->p = NULL;
    free(array);
    array = NULL;
}

void arrayDelValue(Array *array, void *value)
{
    if (NULL == array)
    {
        return;
    }

    char* pBegin = array->p;
    bool bCopy = false;
    for (size_t i = 0; i < array->len; ++i)
    {
        if (!bCopy)
        {
            int nCmp = 0;
            if (NULL != array->match)
            {
                nCmp = array->match(pBegin + i * array->typeSize, value);
            }
            else
            {
                nCmp = memcmp(pBegin + i * array->typeSize, value, array->typeSize);
            }

            if (0 == nCmp)
            {
                bCopy = true;
                continue;
            }
        }
        else
        {
            void *pOld = pBegin + (i + 1) * array->typeSize;
            void *pNew = pBegin + i * array->typeSize;
            if (NULL != array->dup)
            {
                array->dup(pNew, pOld);
            }
            else
            {
                memcpy(pNew, pOld, array->typeSize);
            }
        }
    }

    if (bCopy)
    {
        --array->len;
    }
}

void arrayDelIndex(Array *array, size_t pos)
{
    if (NULL == array)
    {
        return;
    }

    if (pos > array->len || pos <= 0)
    {
        return;
    }

    char* pBegin = array->p;
    for (size_t i = pos - 1; i < array->len - 1; ++i)
    {
        void *pOld = pBegin + (i + 1) * array->typeSize;
        void *pNew = pBegin + i * array->typeSize;
        if (NULL != array->dup)
        {
            array->dup(pNew, pOld);
        }
        else
        {
            memcpy(pNew, pOld, array->typeSize);
        }
    }

    --array->len;
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|分享学习  

GMT+8, 2024-5-17 14:42 , Processed in 0.046661 second(s), 6 queries , File On.

声明:本站严禁任何人以任何形式发表违法言论!

本站内容由网友原创或转载,如果侵犯了您的合法权益,请及时联系处理!© 2017 zamxqun@163.com

皖公网安备 34010402700634号

皖ICP备17017002号-1

快速回复 返回顶部 返回列表