用过VC的人可能都用过其中各种各样的Array类,在我也常用到,这让我编写程序方便了很多。
做电力自动化的同行可能都知道,咱这行兴组态这个方法,不管理是做什么软件,都要组态一把,呵呵,说来笑话,直到今天我也没有真正的找到组态这一个词的明确解释。我一直把它理解为“不需要程序员修改程序,调试人员或用户就可以完成新的系统监控”。即使是使用DOS5.0做为操作系统的产品或是没有操作系统的产品,我们一样要组态、再组态。
最近这段时间在开发一个嵌入式的组态系统,使用DOS5.0,开发环境为Borlandc 3.1。为了在这样一个系统上实现我的组态功能,可是费了我不少心事设计,其中一项就是要解决画面的显示问题。组态系统要求用户自己设计画面,那么我们就来设计一个可以修改的监控画面,在VC开发后台时我使用Array类来保存监控画面的每一个对象,可是在BC31中呢,多少年都没有用过它了,我不知道它是不是也有Array类,有的话,这个类应该怎么用,与其再查找学习,不如自己动手编写一个,看样子,我是一个标准的CODE MAN,不管什么东东总想自己来写。
不过还好,当年在学校的中数据结构还是没有白学。问题很快得到解决。
我使用了一个双向链表解决这个问题,用它来实现结点的添加和删除实在太方便了。
下面就是这个类的源代码部分,在此贴出,也希望和我一样,爱号、狂热于程序设计的朋友批抨指正。
首先贴上来的是我的一个数据类型定义,习惯了VC,就按VC的格式转换一下,当然,有经验的一看就知道是学UCOS的,呵呵,这点我承认,伟大的思想家鲁迅教育我们:要取其精华
/*
********************************************************
*
* (c) Copyright 2003,Hu Wenjin
* All Right Reserved
*
* WRITE USE ANSI c
*
* File: datadef.h
* Auther: Hu Wenjin
* Data: 11.4.2003
*********************************************************
*/
/*
*********************************************************
* DATA TYPES DEFINE
*********************************************************
*/
#if !defined( _DATADEF_H )
#define _DATADEF_H
typedef signed long INT;
typedef unsigned long DWORD;
typedef INT BOOL;
typedef unsigned char bool;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef unsigned long UINT;
typedef unsigned long DWORD;
typedef DWORD COLORREF;
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned int INT16U;
typedef signed int INT16S;
typedef unsigned long INT32U;
typedef signed long INT32S;
typedef char* LPCTSTR;
#define TRUE 1
#define FALSE 0
#define true 1
#define false 0
typedef struct
{
LONG left;
LONG top;
LONG right;
LONG bottom;
}RECT;
#endif
再接下来的,当然是 .h 文件了
#if !defined( _PTRARRAY_H )
#define _PTRARRAY_H
#include "datadef.h"
/*
*************************************************************************
FILE: PtrArray.h
AUTHER: HuWenjin
DATA: 9.27,2004
Discrption:
Modification:
1.
*************************************************************************
*/
typedef struct
{
void* m_pObj; //结点中包含的数据指针
void* m_pParent; //上一个结点
void* m_pChild; //下一个结点
int m_nIndex; //本结点在队列中的位置
BOOL m_bDeleted; //本结点是否被删除
}ST_OBJ;
class CJinPtrArray
{
public:
CJinPtrArray( );
virtual ~CJinPtrArray( );
public:
void* SetAt(int nIndex,void* pObj); //修改指定点的对象指针为新指针
int GetCount( ); //获取总数
int Append( void* pObj ); //添加一个,从删除队列中添加,如果没有测再重新生成5个一组
int DeleteAt( int nIndex ); //删除指定,没有释放内存,保留下次使用(5个结点一组)
void* GetAt( int nIndex ); //获取指定的对象
int RemoveAll( ); //清空全部结点数据,结点没有释放内存,保留下次使用
protected:
ST_OBJ* m_pData; //对象指针
int m_nCount; //对象总数
protected:
int MemFree( ); //从内存中删除所有的数据
void* Sort( int nIndex = 0 ); //删除对象后排序,重设对列中的序号
};
#endif
最后就是CPP文件了
/**************************************************************************
FILE: PtrArray.CPP
AUTHER: HuWenjin
DATA: 9.27,2004
Discrption:
Modification:
1.
**************************************************************************/
#include "Includes.h"
#include "PtrArray.h"
///////////////////////////////////////////////////////////////////////////
// CJinPtrArray
CJinPtrArray::CJinPtrArray( )
{
m_pData = NULL;
m_nCount = 0 ;
}
CJinPtrArray::~CJinPtrArray()
{
MemFree( );
}
int CJinPtrArray::MemFree( )
{
ST_OBJ* pObj;
ST_OBJ* pObjNext;
pObj = m_pData;
while( 1 )
{
if( !pObj )
break;
pObjNext = (ST_OBJ*)pObj->m_pChild;
delete pObj;
pObj = pObjNext;
}
return 0;
}
int CJinPtrArray::GetCount( )
{
return m_nCount;
}
int CJinPtrArray::RemoveAll( )
{
ST_OBJ* pObj = m_pData;
while( 1 )
{
if( !pObj )
break;
pObj->m_bDeleted = TRUE;
pObj->m_nIndex = -1;
pObj = (ST_OBJ*)pObj->m_pChild;
}
m_nCount = 0 ;
return 0;
}
int CJinPtrArray::Append( void* pObjAdd )
{
ST_OBJ* pObj = m_pData;
if( !pObjAdd )
return -1;
// 查找是否有空闲内存区,如果有则加入
while( 1 )
{
if( !pObj )
break;
if( pObj->m_bDeleted == TRUE )
{
pObj->m_pObj = pObjAdd;
pObj->m_bDeleted = FALSE;
pObj->m_nIndex = m_nCount;
m_nCount ++;
return ( m_nCount-1 );
}
pObj = (ST_OBJ*)pObj->m_pChild;
}
// 没有空闲内存区,则再申请1个数据区加入
pObj = NULL;
pObj = new ST_OBJ;
if( !pObj )
return -1;
pObj->m_bDeleted = FALSE;
pObj->m_pObj = pObjAdd;
pObj->m_nIndex = m_nCount;
m_nCount ++;
pObj->m_pParent = NULL;
pObj->m_pChild = m_pData;
if( m_pData )
m_pData->m_pParent = pObj;
// 保存当前的指针做为 ROOT 指针
m_pData = pObj;
return pObj->m_nIndex;
}
int CJinPtrArray::DeleteAt( int nIndex )
{
ST_OBJ* pObj = m_pData;
while( 1 )
{
if( !pObj )
break;
if( pObj->m_nIndex == nIndex )
{
pObj->m_bDeleted = TRUE;
pObj->m_nIndex = -1;
m_nCount --;
//删除对象后应重新排序设定新序号
Sort(nIndex);
return m_nCount;
}
pObj = (ST_OBJ*)pObj->m_pChild;
}
return -1;
}
void* CJinPtrArray::GetAt( int nIndex )
{
ST_OBJ* pObj = m_pData;
while( 1 )
{
if( !pObj )
break;
if( pObj->m_nIndex == nIndex )
return pObj->m_pObj;
pObj = (ST_OBJ*)pObj->m_pChild;
}
return NULL;
}
void* CJinPtrArray::Sort( int nIndex )
{
ST_OBJ* pObj = m_pData;
while( 1 )
{
if( !pObj )
break;
if( pObj->m_nIndex < nIndex )
goto NEXT_TIME;
else if( pObj->m_nIndex > nIndex )
pObj->m_nIndex -- ;
NEXT_TIME:
pObj = (ST_OBJ*)pObj->m_pChild;
}
return m_pData;
}
void* CJinPtrArray::SetAt(int nIndex, void *pTagObj)
{
ST_OBJ* pObj = m_pData;
void* pOldTagObj = NULL;
while( 1 )
{
if( !pObj )
break;
if( pObj->m_nIndex == nIndex )
{
pOldTagObj = pObj->m_pObj;
pObj->m_pObj = pTagObj;
return pOldTagObj;
}
pObj = (ST_OBJ*)pObj->m_pChild;
}
return NULL;
}
好了,大家可以看到整个程序并不是很长,应该还是很好理解的。
在内存使用上,如果用户分配了20个空间,然后又删除的话,程序并没有马上释放内存,只是修改它的标识,因为用户可能马上又要用到多出的空间。
所有的空间,在对象析构时释放。
最后 -----
欢迎大家常来我的BLOG:HTTP://BLOG.CSDN.NET/SAIMEN
我的个人网站: HTTP://WWW.5701.COM
本文地址:http://com.8s8s.com/it/it25475.htm