C语言中动态数组的构造实例

来源:互联网 发布:精仿苹果6s淘宝网 编辑:程序博客网 时间:2024/05/15 12:10

进行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