template<class TYPE> class CTArray


{//动态数组类
private:
UINT nSize; // actual size
UINT nGrow; // grow factor

protected:
UINT nItems; // number of elements (as it appears to the user)
TYPE* pData; // pointer to array of data

public:
// blank constructor

CTArray()
{ Init(); }
// copy constructor

CTArray(CTArray& Src)
{ Init(); Copy(Src); }
// typed copy constructor
CTArray(const TYPE* pSrc, UINT nCount = 1)

{
Init();
SetLength(nCount);
for (UINT u = 0; u < nItems; u++) pData[u] = pSrc[u];
}

// typed initializing constructor
CTArray(UINT nCount, TYPE Src)

{
Init();
SetLength(nCount);
for (UINT u = 0; u < nItems; u++) pData[u] = Src;
}

// operators

const TYPE& operator[](UINT nIndex) const
{ return pData[nIndex]; }

TYPE& operator[](UINT nIndex)
{ return pData[nIndex]; }

CTArray& operator=(CTArray& Src)
{ Copy(Src); return *this; }

// initialise

void Init()
{ pData = NULL; nSize = nItems = 0; nGrow = 8; }

// release data

virtual void Clear(void)
{ if (pData != NULL) delete [] pData; Init(); }

// copy from other
void Copy(CTArray& Src)

{
Clear();
SetLength(Src.Length());
for (UINT u = 0; u < nItems; u++) pData[u] = Src.pData[u];
}

// grow factor get/set

UINT GrowFactor(void) const
{ return nGrow; }

void SetGrowFactor(UINT nNewGrow)
{ nGrow = nNewGrow; if (nGrow == 0) nGrow = 1; }

// length (items) get

UINT Length(void)
{ return nItems; }
// set length regrow or shrink
virtual bool SetLength(UINT nLength, bool bForce = false)

{
if (nLength == 0)

{
Clear();
return true;
}
// alloc new storage
TYPE* pNewData = NULL;
UINT nNewSize = ((nLength / nGrow) + 1) * nGrow;//新数组大小
// grow only if either the amount we need is greater than what we have
// already or if the amount is <= 1/2, whatever's smaller
if (nNewSize > nSize || nNewSize <= nSize / 2 || bForce)

{
//创建新数组
if ((pNewData = new TYPE[nNewSize]) == NULL)
return false;
// now copy the old elements into the new array, up to the old
// number of items or to the user-set new length, whichever's
// smaller
for (UINT u = 0; u < nItems && u < nLength; u++)
pNewData[u] = pData[u];
// update all the current info
if (pData != NULL)
delete [] pData;
pData = pNewData;
nSize = nNewSize;
}
nItems = nLength;
return true;
}
// set w/bounds check but no grow
virtual bool Set(UINT nIndex, TYPE Src) const

{
if (nIndex >= nItems || pData == NULL)
return false;

pData[nIndex] = Src;

return true;
}

// get w/bounds check but no grow
virtual bool Get(TYPE& Dst, UINT nIndex) const

{
if (nIndex >= nItems || pData == NULL)
return false;

Dst = pData[nIndex];

return true;
}

// get all elements to a typed pointer; do not forget to delete
// such pointer after no longer needed
UINT GetAll(TYPE*& pDst)

{
pDst = new TYPE[nItems];

for (UINT u = 0; u < nItems; u++)
pDst[u] = pData[u];

return nItems;
}

// get all elements to an unknown size pointer of specified size; the
// pointer must be initialized by the caller
UINT GetAll(void* pDst, int nSize)

{
for (UINT u = 0; u < nItems; u++)
memcpy((void*)((BYTE*)pDst + u * nSize), (void*)(&pData[u]), nSize);

return nItems;
}

// remove element at given position
virtual bool Remove(UINT nIndex)

{
if (nItems == 0 || pData == NULL)
return false;

// starting with the element we are removing, work up
// copying each next value down to the current spot
for (UINT u = nIndex; u < nItems - 1 ; u++)
pData[u] = pData[u + 1];

// this will either simply change the nItems value or realloc and
// free some memory
SetLength(nItems - 1);

return true;
}
// insert element at given position
virtual void Insert(TYPE Src, UINT nIndex)

{
// first, make room
SetLength(nItems + 1);

// starting with the last element work back until we get to the one
// we are inserting at and copy forward
for (UINT u = nItems - 1; u > nIndex; u--)
pData[u] = pData[u - 1] ;

// finally insert new value
pData[nIndex] = Src;
}

// append element to the end of array
virtual int Append(TYPE Src)

{
// first, make room
SetLength(nItems + 1);

// insert new value
pData[nItems - 1] = Src;

return nItems;
}

// blank append
virtual int Append()

{
// just make room
SetLength(nItems + 1);
return nItems;
}

// finder with mem compare and optional start
int Find(TYPE Src, UINT nStart = 0)

{
for (UINT u = nStart; u < nItems; u++)

{
if (memcmp(&pData[u], &Src, sizeof(TYPE)) == 0)
return (int)u;
}

return -1;
}

// swap
void Swap(UINT i, UINT j)

{
if (i >= nItems || j >= nItems || i == j)
return;

TYPE Tmp = pData[i];
pData[i] = pData[j];
pData[j] = Tmp;
}

// sort wrapper with callback and method
void Sort(int (__cdecl* compare)(const void* p1, const void* p2), int nMethod = 0)

{
switch (nMethod)

{
case 1:

{
// sort the array with fixed starting items, by comparing neighbors
for (UINT i = 0; i < nItems - 1; i++)

{
// skip a neighbor that is in order (as determined by a non-zero
// return from the compare function)
if (compare((const void*)&pData[i], (const void*)&pData[i + 1]))
continue;

// search for an item matching the last starting item
UINT j = i + 1;
while (!compare((const void*)&pData[i], (const void*)&pData[j]) && j < nItems - 1)
j++;
// swap the matching item to be right below the starting item
if (j <= nItems - 1)
Swap(i + 1, j);
}
break;
}
default:
qsort(pData, nItems, sizeof(TYPE), compare);
break;
}
}

// destructor

~CTArray()
{ Clear(); }
};

typedef CTArray<DWORD> DWORDARRAY;



【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述