进行C语言的编程时,大家经常要用到类似JAVA, .NET高级语言中的Vector或ArrayList之类的数据结构,这里提供一则实例告诉大家如何生成这样的数据结构。
#ifndef __DN_DA__
#define __DN_DA__
#include <tchar.h>
#include <assert.h>
#define DN_DYNAMIC_ARRAY(ITEM, ARRAY_NAME) /
typedef struct _##ARRAY_NAME{ /
unsigned int count; /
unsigned int capacity; /
ITEM **array; /
} ARRAY_NAME
DN_DYNAMIC_ARRAY(void, DS_VOID_ARRAY);
DN_DYNAMIC_ARRAY(TCHAR, STRING_ARRAY);
void *dynamicNewItem(DS_VOID_ARRAY *pArray, UINT nItemSize);
void dynamicDeleteItem(DS_VOID_ARRAY *pArray, UINT index);
BOOL dynamicDeleteItemByValue(DS_VOID_ARRAY *pArray, PVOID pItem);
BOOL dynamicDeleteStringByValue(DS_VOID_ARRAY *pArray, LPCTSTR pItem);
void dynamicFreeItems(DS_VOID_ARRAY *pArray);
__inline void dynamicInitStrings(STRING_ARRAY *pStrings)
{
pStrings->count = 0;
pStrings->capacity = 0;
pStrings->array = NULL;
}
__inline TCHAR* dynamicNewString(STRING_ARRAY *pStrings, UINT len)
{
return (TCHAR *)dynamicNewItem((DS_VOID_ARRAY*)pStrings, sizeof(TCHAR) * len);
}
__inline TCHAR* dynamicDupString(STRING_ARRAY *pStrings, const TCHAR *psz)
{
TCHAR* p = (TCHAR *)dynamicNewItem((DS_VOID_ARRAY*)pStrings, sizeof(TCHAR) * ((unsigned)_tcslen(psz) + 1));
if(p != NULL){
_tcscpy(p, psz);
}
return p;
}
__inline void dynamicDestroyStrings(STRING_ARRAY *pStrings)
{
dynamicFreeItems((DS_VOID_ARRAY*)pStrings);
}
#define DARRAY_INIT_SIZE 4
#define DARRAY_EXPANDED_SIZE 4
__inline void *dynamicNewItem(DS_VOID_ARRAY *pArray, UINT nItemSize)
{
void *pItem;
assert(pArray != NULL);
if(pArray->capacity == 0){
pArray->array = (void **)malloc(sizeof(void*) * DARRAY_INIT_SIZE); //allocate the slot
if(pArray->array == NULL){
return NULL;
}
else{
pArray->capacity = DARRAY_INIT_SIZE;
}
}
if(pArray->capacity == pArray->count ){ //capacity == count, we need expand the slot
void *p = realloc(pArray->array, sizeof(void*) * (pArray->capacity + DARRAY_EXPANDED_SIZE));
if(p == NULL){
return NULL;
}
pArray->array = (void**)p;
pArray->capacity = pArray->capacity + DARRAY_EXPANDED_SIZE;
}
pItem = malloc(nItemSize);
if(pItem == NULL){
return NULL;
}
memset(pItem, 0, nItemSize);
pArray->array[pArray->count ++] = pItem;
return pItem;
}
__inline void dynamicDeleteItem(DS_VOID_ARRAY *pArray, UINT index)
{
UINT i;
assert(pArray != NULL);
assert(index >= 0 && index < pArray->count);
free(pArray->array[index]);
for( i = index; i < pArray->count - 1; i ++){
pArray->array[ i ] = pArray->array[i + 1];
}
pArray->array[pArray->count - 1] = NULL;
pArray->count --;
}
__inline BOOL dynamicDeleteItemByValue(DS_VOID_ARRAY *pArray, PVOID pItem)
{
UINT i;
assert(pArray != NULL);
for( i = 0; i < pArray->count; i ++){
if(pArray->array[i] == pItem){
dynamicDeleteItem(pArray, i);
return TRUE;
}
}
return FALSE;
}
__inline BOOL dynamicDeleteStringByValue(DS_VOID_ARRAY *pArray, LPCTSTR pItem)
{
UINT i;
assert(pArray != NULL);
for( i = 0; i < pArray->count; i ++){
if( _tcscmp((LPTSTR)(pArray->array[i]), pItem) == 0 ){
dynamicDeleteItem(pArray, i);
return TRUE;
}
}
return FALSE;
}
__inline void dynamicFreeItems(DS_VOID_ARRAY *pArray)
{
UINT i;
assert(pArray != NULL);
for( i = 0; i < pArray->count; i ++){
assert(pArray->array[i] != NULL);
free(pArray->array[i]);
}
if((void*)pArray->array != NULL){
free((void*)pArray->array);
}
pArray->capacity = 0;
pArray->count = 0;
pArray->array = (void **)NULL;
}
#endif