1. array.h



#ifndef array_H
#define array_H

#include <stddef.h>
#include <sys/types.h>
#include "delegate.h"

//动态数组,能够动态的进行扩容,支持多种数据类型,包括:int、struct等
typedef struct
{
void *data; //实际数组
size_t itemSize; //数组元素大小(字节)
size_t capacity; //数组容量
size_t size; //数组长度
} Array;

//数组元素比较器,s1=s2返回0,s1>s2 返回大于0,s1<s2返回小于0
//typedef int (*arrayItemCompare)(const void *p1, const void *p2, size_t n);

//定义该宏可以直观的看出数组元素的数据类型,比如:Array(int)
#define Array(type) Array

//获取指向数组第一个元素的指针
#define arrayData(array, type) \
(type *)((array)->data)

//获取指定索引的数组元素
#define arrayItem(array, type, index) \
(arrayData(array, type))[index]

//获取指定索引的数组元素的指针
#define arrayItemPtr(array, type, index) \
(arrayData(array, type) + index)

//修改指定索引的数组元素的值
#define arraySetItem(array, type, index, item) \
arrayItem(array, type, index) = item

#ifdef __cplusplus
extern "C"
{
#endif
int array_init(Array *array, size_t itemSize, size_t capacity);
void array_free(Array *array);
void array_clear(Array *array);
int array_expand(Array *array, size_t increment);
int array_shrink(Array *array);
size_t array_length(const Array *array);
int array_full(const Array *array);
void *array_getItem(const Array *array, size_t index);
void array_setItem(Array *array, size_t index, const void *item);
void array_add(Array *array, const void *item);
void array_insert(Array *array, const void *item, size_t index);
void array_remove(Array *array, const void *item, Comparison comparison);
void array_removeAll(Array *array, const void *item, Comparison comparison);
void array_removeAt(Array *array, size_t index);
void array_removeRange(Array *array, size_t fromIndex, size_t toIndex);
ssize_t array_firstIndexOf(const Array *array, const void *item, Comparison comparison);
ssize_t array_lastIndexOf(const Array *array, const void *item, Comparison comparison);
int array_contains(const Array *array, const void *item, Comparison comparison);
void array_sort(Array *array, Comparison comparison);
void array_sortDesc(Array *array, Comparison comparison);
int array_compare(const Array *arr1, const Array *arr2, Comparison comparison);
void array_copy(Array *dest, const Array *src);
void array_merge(Array *dest, const Array *src);
void array_reverse(Array *array);
#ifdef __cplusplus
}
#endif

#endif


2. array.c



#include "array.h"
#include <string.h>
#include <stdlib.h>

//初始化
int array_init(Array *array, size_t itemSize, size_t capacity)
{
if (array == NULL || itemSize <= 0)
return -1;

array->data = malloc(capacity * itemSize);
if (array->data == NULL)
return -1;

memset(array->data, 0, capacity * itemSize);
array->capacity = capacity;
array->size = 0;
array->itemSize = itemSize;
return 0;
}

//释放内存
void array_free(Array *array)
{
if (array == NULL)
return;

if (array->data != NULL)
{
free(array->data);
array->data = NULL;
}

array->size = 0;
array->capacity = 0;
array->itemSize = 0;
}

//清空数组
void array_clear(Array *array)
{
if (array == NULL)
return;

if (array->data != NULL)
memset(array->data, 0, array->capacity * array->itemSize);

array->size = 0;
array_shrink(array); //收缩数组
}

//扩充数组
int array_expand(Array *array, size_t increment)
{
if (array == NULL || increment <= 0)
return -1;

void *data = realloc(array->data, (increment + array->capacity) * array->itemSize);
if (data == NULL)
return -1;

array->data = data;
array->capacity += increment;
return 0;
}

//收缩数组
int array_shrink(Array *array)
{
if (array == NULL)
return -1;

if (array_full(array))
return -1;

size_t capacity;
if (array->size == 0)
capacity = 1;
else
capacity = array->size;

void *data = realloc(array->data, capacity * array->itemSize);
if (data == NULL)
return -1;

array->data = data;
array->capacity = capacity;
return 0;
}

//获取数组长度
size_t array_length(const Array *array)
{
if (array == NULL || array->data == NULL)
return 0;

return array->size;
}

//判断数据是否已满
int array_full(const Array *array)
{
if (array == NULL)
return -1;

return array->size == array->capacity;
}

//获取指定索引的元素,类似数组的下标访问
void *array_getItem(const Array *array, size_t index)
{
if (array == NULL || index >= array->size)
return NULL;

return (char *)array->data + index * array->itemSize;
}

//修改指定索引位置的元素
void array_setItem(Array *array, size_t index, const void *item)
{
if (array == NULL || index >= array->size)
return;

memcpy((char *)array->data + index * array->itemSize, item, array->itemSize);
}

//在数组末尾添加元素
void array_add(Array *array, const void *item)
{
if (array == NULL)
return;

if (array_full(array))
array_expand(array, array->capacity / 2);

memcpy((char *)array->data + array->size * array->itemSize, item, array->itemSize);
array->size++;
}

//在指定索引的位置上插入元素
void array_insert(Array *array, const void *item, size_t index)
{
if (array == NULL || index > array->size)
return;

if (array_full(array))
array_expand(array, array->capacity / 2);

if (index >= array->size) //add
{
memcpy((char *)array->data + array->size * array->itemSize, item, array->itemSize);
}
else //insert
{
void *src = (char *)array->data + index * array->itemSize;
void *dest = (char *)src + array->itemSize;
memmove(dest, src, (array->size - index) * array->itemSize);
memcpy(src, item, array->itemSize);
}
array->size++;
}

//删除满足指定条件的第一个元素
void array_remove(Array *array, const void *item, Comparison comparison)
{
if (array == NULL)
return;

size_t i;
for (i = 0; i < array->size; i++)
{
if (comparison((char *)array->data + i * array->itemSize, item, array->itemSize) == 0)
{
if (i != array->size - 1) //不是最后一个元素
{
void *src = (char *)array->data + (i + 1) * array->itemSize;
void *dest = (char *)array->data + i * array->itemSize;
memmove(dest, src, (array->size - i) * array->itemSize);
}

//最后一个元素,赋值为0
array->size -= 1;
memset((char *)array->data + array->size * array->itemSize, 0, array->itemSize);
break;
}
}
}

//删除所有满足指定条件的元素
void array_removeAll(Array *array, const void *item, Comparison comparison)
{
if (array == NULL)
return;

size_t i;
for (i = 0; i < array->size; i++)
{
if (comparison((char *)array->data + i * array->itemSize, item, array->itemSize) == 0)
{
if (i != array->size - 1) //不是最后一个元素
{
void *src = (char *)array->data + (i + 1) * array->itemSize;
void *dest = (char *)array->data + i * array->itemSize;
memmove(dest, src, (array->size - i) * array->itemSize);
}

//最后一个元素,赋值为0
array->size -= 1;
memset((char *)array->data + array->size * array->itemSize, 0, array->itemSize);
i--; //勿漏
}
}
}

//删除指定索引位置的元素
void array_removeAt(Array *array, size_t index)
{
array_removeRange(array, index, index);
}

//删除指定索引范围的元素
void array_removeRange(Array *array, size_t fromIndex, size_t toIndex)
{
if (array == NULL)
return;

if (fromIndex > toIndex)
return;

if (fromIndex >= array->size || toIndex >= array->size)
return;

size_t num = toIndex - fromIndex + 1;
size_t endIndex = array->size - 1;
if (toIndex != endIndex)
{
void *src = (char *)array->data + (toIndex + 1) * array->itemSize;
void *dest = (char *)array->data + fromIndex * array->itemSize;
memmove(dest, src, (endIndex - toIndex) * array->itemSize);
}

array->size -= num;
memset((char *)array->data + array->size * array->itemSize, 0, num * array->itemSize);
}

//获取满足指定条件的第一个索引,不存在时返回-1
ssize_t array_firstIndexOf(const Array *array, const void *item, Comparison comparison)
{
if (array == NULL)
return -1;

size_t i;
for (i = 0; i < array->size; i++)
{
if (comparison((char *)array->data + i * array->itemSize, item, array->itemSize) == 0)
return i;
}

return -1;
}

//获取满足指定条件的最后一个索引,不存在时返回-1
ssize_t array_lastIndexOf(const Array *array, const void *item, Comparison comparison)
{
if (array == NULL)
return -1;

ssize_t i;
for (i = array->size - 1; i >= 0; i--)
{
if (comparison((char *)array->data + i * array->itemSize, item, array->itemSize) == 0)
return i;
}

return -1;
}

//判读数组是否包含指定元素,存在返回大于0,不存在返回-1
int array_contains(const Array *array, const void *item, Comparison comparison)
{
return array_firstIndexOf(array, item, comparison);
}

//数组升序排序(直接插入排序法,使用自定义比较器)
void array_sort(Array *array, Comparison comparison)
{
if (array == NULL || array->size == 0)
return;

void *tmp = malloc(array->itemSize);
size_t i;
ssize_t j;

for (i = 1; i < array->size; i++) //默认第一个元素有序,需n-1次插入
{
if (comparison((char *)array->data + i * array->itemSize, (char *)array->data + (i - 1) * array->itemSize, array->itemSize) < 0)
{
memcpy(tmp, (char *)array->data + i * array->itemSize, array->itemSize);
j = i - 1;

//查找插入位置
while (j >= 0 && comparison((char *)array->data + j * array->itemSize, tmp, array->itemSize) > 0)
{
//元素后移
//memcpy((char *)array->data + (j + 1) * array->itemSize, (char *)array->data + j * array->itemSize, array->itemSize);
j--;
}

//元素后移
void *src = (char *)array->data + (j + 1) * array->itemSize;
void *dest = (char *)src + 1 * array->itemSize;
memmove(dest, src, array->itemSize * (i - j - 1));

//插入元素
memcpy((char *)array->data + (j + 1) * array->itemSize, tmp, array->itemSize);
}
}

free(tmp);
}

//数组降序排序(直接插入排序法,使用自定义比较器)
void array_sortDesc(Array *array, Comparison comparison)
{
if (array == NULL || array->size == 0)
return;

void *tmp = malloc(array->itemSize);
size_t i;
ssize_t j;

for (i = 1; i < array->size; i++) //默认第一个元素有序,需n-1次插入
{
if (comparison((char *)array->data + i * array->itemSize, (char *)array->data + (i - 1) * array->itemSize, array->itemSize) > 0)
{
memcpy(tmp, (char *)array->data + i * array->itemSize, array->itemSize);
j = i - 1;

//查找插入位置
while (j >= 0 && comparison((char *)array->data + j * array->itemSize, tmp, array->itemSize) < 0)
{
//元素后移
//memcpy((char *)array->data + (j + 1) * array->itemSize, (char *)array->data + j * array->itemSize, array->itemSize);
j--;
}

//元素后移
void *src = (char *)array->data + (j + 1) * array->itemSize;
void *dest = (char *)src + 1 * array->itemSize;
memmove(dest, src, array->itemSize * (i - j - 1));

//插入元素
memcpy((char *)array->data + (j + 1) * array->itemSize, tmp, array->itemSize);
}
}

free(tmp);
}

//数组比较(使用自定义比较器),相同返回0,大于返回大于0,小于返回小于0
int array_compare(const Array *arr1, const Array *arr2, Comparison comparison)
{
if (arr1 == arr2)
return 0;

if (arr1 == NULL || arr2 == NULL)
return -1;

if (arr1->size != arr2->size)
return -1;

int res;
size_t i;
for (i = 0; i < arr1->size; i++)
{
res = comparison((char *)arr1->data + i * arr1->itemSize, (char *)arr2->data + i * arr2->itemSize, arr1->itemSize);
if (res != 0)
break;
}

return res;
}

//复制数组
void array_copy(Array *dest, const Array *src)
{
if (dest == NULL || src == NULL)
return;

//src的大小比dest的容量还要大,需要扩容
if (src->size > dest->capacity)
array_expand(dest, src->size - dest->capacity);

memcpy(dest->data, src->data, src->size * src->itemSize);
dest->size = src->size;
}

//数组合并
void array_merge(Array *dest, const Array *src)
{
if (dest == NULL || src == NULL)
return;

if (dest->size + src->size > dest->capacity)
array_expand(dest, (dest->size + src->size - dest->capacity) * 2);

memcpy((char *)dest->data + dest->size * dest->itemSize, src->data, src->size * src->itemSize);
dest->size += src->size;
}

//数组反转
void array_reverse(Array *array)
{
if (array == NULL || array->size <= 1)
return;

void *tmp = malloc(array->itemSize);
size_t i;

for (i = 0; i < array->size / 2; i++)
{
memcpy(tmp, (char *)array->data + i * array->itemSize, array->itemSize);
memcpy((char *)array->data + i * array->itemSize, (char *)array->data + (array->size - i - 1) * array->itemSize, array->itemSize);
memcpy((char *)array->data + (array->size - i - 1) * array->itemSize, tmp, array->itemSize);
}

free(tmp);
}


 3. main.c



#include "array.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct tag
{
char epc[24];
unsigned short rssi;
unsigned short antennaId;
} Tag;

int tagCompareByRssi(const void *s1, const void *s2, size_t n)
{
Tag *t1 = (Tag *)s1;
Tag *t2 = (Tag *)s2;

if (t1->rssi == t2->rssi)
return 0;
else if (t1->rssi > t2->rssi)
return 1;
else
return -1;
}

int tagCompareByEpc(const void *s1, const void *s2, size_t n)
{
Tag *t1 = (Tag *)s1;
Tag *t2 = (Tag *)s2;

return strcmp(t1->epc, t2->epc);
}

void printTagArray(const Array(Tag) * tags)
{
if (tags == NULL || tags->size == 0)
{
printf("empty tags\n\n");
return;
}

size_t i;
Tag *tag;
for (i = 0; i < tags->size; i++)
{
tag = (Tag *)array_getItem(tags, i);
printf("tags[%d], epc = %s, rssi = %d\n", (int)i, tag->epc, tag->rssi);
}
printf("\n");
}

void printIntArray(const Array(int) * array)
{
if (array == NULL || array->size == 0)
{
printf("empty int array\n\n");
return;
}

size_t i;
//int *ptrInt;
for (i = 0; i < array->size; i++)
{
//ptrInt = (int *)array_getItem(array, i);
//printf("array[%d], value=%d\n", *ptrInt);
printf("array[%d], value = %d\n", (int)i, arrayItem(array, int, i));
}
printf("\n");
}

void test_tagArray()
{
printf("\n########## Tag Array ##########\n");

Array(Tag) tags;
array_init(&tags, sizeof(Tag), 100);

Tag tag1;
strcpy(tag1.epc, "11111111");
tag1.antennaId = 1;
tag1.rssi = 70;
array_add(&tags, &tag1);

Tag tag2;
strcpy(tag2.epc, "22222222");
tag2.antennaId = 2;
tag2.rssi = 90;
array_insert(&tags, &tag2, 0);

Tag tag3;
strcpy(tag3.epc, "33333333");
tag3.antennaId = 1;
tag3.rssi = 80;
array_add(&tags, &tag3);

Tag tag4;
strcpy(tag4.epc, "44444444");
tag4.antennaId = 3;
tag4.rssi = 80;
array_insert(&tags, &tag4, 2);

Tag tag5;
strcpy(tag5.epc, "55555555");
tag5.antennaId = 1;
tag5.rssi = 85;
array_insert(&tags, &tag5, 0);

printf("tags, size: %d:\n", (int)tags.size);
printTagArray(&tags);

printf("first index of rssi %d: %d\n", tag3.rssi, (int)array_firstIndexOf(&tags, &tag3, tagCompareByRssi));
printf("last index of rssi %d: %d\n", tag3.rssi, (int)array_lastIndexOf(&tags, &tag3, tagCompareByRssi));
printf("first index of epc %s: %d\n", tag3.epc, (int)array_firstIndexOf(&tags, &tag3, tagCompareByEpc));
printf("\n");

printf("tags after sort:\n");
array_sort(&tags, tagCompareByRssi); //自定义排序
printTagArray(&tags);

printf("tags after reverse:\n");
array_reverse(&tags);
printTagArray(&tags);

printf("tags after remove:\n");
array_removeAt(&tags, 0);
array_remove(&tags, &tag4, tagCompareByEpc);
printTagArray(&tags);

printf("tags after clear:\n");
array_clear(&tags);
printTagArray(&tags);

array_free(&tags); //释放内存
}

void test_intArray()
{
printf("\n########## int Array ##########\n");

Array(int) *arr = (Array(int) *)malloc(sizeof(Array)); //动态分配
array_init(arr, sizeof(int), 2);

int i1 = 20;
int i2 = 30;
int i3 = 10;
int i4 = 40;
int i5 = 30;
int i6 = 50;

array_add(arr, &i1);
array_add(arr, &i2);
array_add(arr, &i3);
array_insert(arr, &i4, 0);
array_insert(arr, &i5, 1);
array_insert(arr, &i6, arr->size);

printf("int array, size: %d:\n", (int)arr->size);
printIntArray(arr);

printf("first index of %d: %d\n", i2, (int)array_firstIndexOf(arr, &i2, memcmp));
printf("last index of %d: %d\n", i2, (int)array_lastIndexOf(arr, &i2, memcmp));
printf("first index of %d: %d\n", i6, (int)array_firstIndexOf(arr, &i6, memcmp));
printf("\n");

printf("inr array after sort:\n");
array_sortDesc(arr, memcmp);
printIntArray(arr);

printf("int array after reverse:\n");
array_reverse(arr);
printIntArray(arr);

printf("int array after remove:\n");
array_removeAt(arr, 0);
array_remove(arr, &i4, memcmp);
printIntArray(arr);

printf("int array after clear:\n");
array_clear(arr);
printIntArray(arr);

array_free(arr); //释放内存
free(arr); //释放内存
}

int main(int argc, char **argv)
{
test_intArray();
test_tagArray();

return 0;
}