【写作日期】 2007年1月2日
【写作作者】 bzhkl
【作者邮箱】 it6688@yahoo.com.cn
【使用工具】 OD vc++6.0
【破解平台】 XP
【软件下载】 自己编译
【写作动机】 上次写了个《逆向一个最简单的程序》觉得能学到东西 呵呵 所以这次又写了一篇菜文 再说后天要考数据结构了 顺便复习一下 呵呵 不要笑话啊只想自己学点东西 谁觉得有用的话拿去看吧
源代码是 老罗的缤纷天地上的程序在下面 昨晚小研究了一下 主函数中加了 消息框 好下断点 当然也可以不用断点 在GetCommandLineA下面没有几行就能看到mian函数
00401080 > \55 push ebp
00401081 . 8BEC mov ebp,esp
00401083 . 6A FF push -1
00401085 . 68 39FB4100 push writepro.0041FB39 ; SE 处理程序安装
0040108A . 64:A1 0000000>mov eax,dword ptr fs:[0]
00401090 . 50 push eax
00401091 . 64:8925 00000>mov dword ptr fs:[0],esp
00401098 . 83EC 54 sub esp,54
0040109B . 53 push ebx
0040109C . 56 push esi
0040109D . 57 push edi
0040109E . 8D7D A0 lea edi,dword ptr ss:[ebp-60]
004010A1 . B9 15000000 mov ecx,15
004010A6 . B8 CCCCCCCC mov eax,CCCCCCCC
004010AB . F3:AB rep stos dword ptr es:[edi]
004010AD . 8BF4 mov esi,esp
004010AF . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
004010B1 . 68 28204300 push writepro.00432028 ; |Title = "note"
004010B6 . 68 20204300 push writepro.00432020 ; |Text = "begin"
004010BB . 6A 00 push 0 ; |hOwner = NULL
004010BD . FF15 D4C24300 call dword ptr ds:[<&USER32.Mess>; \MessageBoxA
004010C3 . 3BF4 cmp esi,esp
004010C5 . E8 B67A0000 call writepro.00408B80 ; 检验堆栈平衡
004010CA . 8D4D E4 lea ecx,dword ptr ss:[ebp-1C] ; ebp-1c为头节点的地址
004010CD . E8 60FFFFFF call writepro.00401032 ; 构造函数 把各个成员初始化为零
004010D2 . C745 FC 00000>mov dword ptr ss:[ebp-4],0
004010D9 . C745 F0 00000>mov dword ptr ss:[ebp-10],0 ; for循环中的 计数器 i
004010E0 . EB 09 jmp short writepro.004010EB
004010E2 > 8B45 F0 mov eax,dword ptr ss:[ebp-10] ; 循环开始
004010E5 . 83C0 01 add eax,1
004010E8 . 8945 F0 mov dword ptr ss:[ebp-10],eax
004010EB > 837D F0 0A cmp dword ptr ss:[ebp-10],0A ; i > 10? 大于就跳出循环
004010EF . 7D 11 jge short writepro.00401102
004010F1 . 8B4D F0 mov ecx,dword ptr ss:[ebp-10] ; 下面功能是 i+1 作为要插入的值 并作为参数
004010F4 . 83C1 01 add ecx,1
004010F7 . 51 push ecx
004010F8 . 8D4D E4 lea ecx,dword ptr ss:[ebp-1C] ; ecx 头节点记录数据个数的地址 也为对象的地址
004010FB . E8 0FFFFFFF call writepro.0040100F ; AddTail
00401100 .^ EB E0 jmp short writepro.004010E2
00401102 > 8BF4 mov esi,esp
00401104 . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401106 . 68 28204300 push writepro.00432028 ; |Title = "note"
0040110B . 68 1C204300 push writepro.0043201C ; |Text = "end"
00401110 . 6A 00 push 0 ; |hOwner = NULL
00401112 . FF15 D4C24300 call dword ptr ds:[<&USER32.Mess>; \MessageBoxA
00401118 . 3BF4 cmp esi,esp
0040111A . E8 617A0000 call writepro.00408B80
0040111F . C745 E0 00000>mov dword ptr ss:[ebp-20],0
00401126 . C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
0040112D . 8D4D E4 lea ecx,dword ptr ss:[ebp-1C]
00401130 . E8 E9FEFFFF call writepro.0040101E
00401135 . 8B45 E0 mov eax,dword ptr ss:[ebp-20]
00401138 . 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
0040113B . 64:890D 00000>mov dword ptr fs:[0],ecx
00401142 . 5F pop edi
00401143 . 5E pop esi
00401144 . 5B pop ebx
00401145 . 83C4 60 add esp,60
00401148 . 3BEC cmp ebp,esp
0040114A . E8 317A0000 call writepro.00408B80
0040114F . 8BE5 mov esp,ebp
00401151 . 5D pop ebp
00401152 . C3 ret
构造函数
00401190 /> \55 push ebp
00401191 |. 8BEC mov ebp,esp
00401193 |. 83EC 44 sub esp,44
00401196 |. 53 push ebx
00401197 |. 56 push esi
00401198 |. 57 push edi
00401199 |. 51 push ecx
0040119A |. 8D7D BC lea edi,dword ptr ss:[ebp-44]
0040119D |. B9 11000000 mov ecx,11
004011A2 |. B8 CCCCCCCC mov eax,CCCCCCCC
004011A7 |. F3:AB rep stos dword ptr es:[edi]
004011A9 |. 59 pop ecx ; ecx 为对象的地址
004011AA |. 894D FC mov dword ptr ss:[ebp-4],ecx ; 这四句的意思是 mov [ecx], 0 即类对象的nCount = 0
004011AD |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
004011B0 |. C700 00000000 mov dword ptr ds:[eax],0
004011B6 |. 8B4D FC mov ecx,dword ptr ss:[ebp-4]
004011B9 |. C741 04 00000>mov dword ptr ds:[ecx+4],0 ; ecx+4为类类对象的第二个成员变量m_pNodeHead 初始化为NULL
004011C0 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
004011C3 |. 5F pop edi
004011C4 |. 5E pop esi
004011C5 |. 5B pop ebx
004011C6 |. 8BE5 mov esp,ebp
004011C8 |. 5D pop ebp
004011C9 \. C3 ret AddTail函数
00401230 /> \55 push ebp
00401231 |. 8BEC mov ebp,esp
00401233 |. 83EC 44 sub esp,44
00401236 |. 53 push ebx
00401237 |. 56 push esi
00401238 |. 57 push edi
00401239 |. 51 push ecx
0040123A |. 8D7D BC lea edi,dword ptr ss:[ebp-44]
0040123D |. B9 11000000 mov ecx,11
00401242 |. B8 CCCCCCCC mov eax,CCCCCCCC
00401247 |. F3:AB rep stos dword ptr es:[edi]
00401249 |. 59 pop ecx
0040124A |. 894D FC mov dword ptr ss:[ebp-4],ecx ; ebp-4 对象的地址
0040124D |. 8B45 08 mov eax,dword ptr ss:[ebp+8] ; 传进来的的第一个参数 要插入的数
00401250 |. 50 push eax
00401251 |. 8B4D FC mov ecx,dword ptr ss:[ebp-4] ; 对象的 地址
00401254 |. E8 D4FDFFFF call writepro.0040102D ; GetCount 函数
00401259 |. 50 push eax ; m_nCount 作为参数
0040125A |. 8B4D FC mov ecx,dword ptr ss:[ebp-4] ; 结点数目的地址 也是对象的地址
0040125D |. E8 D5FDFFFF call writepro.00401037 ; InsertAfter函数
00401262 |. 5F pop edi
00401263 |. 5E pop esi
00401264 |. 5B pop ebx
00401265 |. 83C4 44 add esp,44
00401268 |. 3BEC cmp ebp,esp
0040126A |. E8 11790000 call writepro.00408B80
0040126F |. 8BE5 mov esp,ebp
00401271 |. 5D pop ebp
00401272 \. C2 0400 ret 4
InsertAfter 函数 004012D0 > \55 push ebp
004012D1 . 8BEC mov ebp,esp
004012D3 . 6A FF push -1
004012D5 . 68 69FB4100 push writepro.0041FB69 ; SE 处理程序安装
004012DA . 64:A1 0000000>mov eax,dword ptr fs:[0]
004012E0 . 50 push eax
004012E1 . 64:8925 00000>mov dword ptr fs:[0],esp
004012E8 . 83EC 60 sub esp,60
004012EB . 53 push ebx
004012EC . 56 push esi
004012ED . 57 push edi
004012EE . 51 push ecx
004012EF . 8D7D 94 lea edi,dword ptr ss:[ebp-6C]
004012F2 . B9 18000000 mov ecx,18
004012F7 . B8 CCCCCCCC mov eax,CCCCCCCC
004012FC . F3:AB rep stos dword ptr es:[edi]
004012FE . 59 pop ecx ; ecx 为对象的地址
004012FF . 894D F0 mov dword ptr ss:[ebp-10],ecx
00401302 . 68 C8000000 push 0C8 ; /Arg4 = 000000C8
00401307 . 68 C05D4300 push writepro.00435DC0 ; |Arg3 = 00435DC0
0040130C . 6A 01 push 1 ; |Arg2 = 00000001
0040130E . 6A 08 push 8 ; |Arg1 = 00000008
00401310 . E8 2B7C0000 call writepro.00408F40 ; \writepro.00408F40
00401315 . 83C4 10 add esp,10 ; 上面的是分配内存函数 比如new int 把4作为参数 这里类成员占8字节 所以有个参数8 别的参数什么意思不太懂 高手讲讲撒
00401318 . 8945 D8 mov dword ptr ss:[ebp-28],eax ; [ebp-28]接受返回的地址
0040131B . C745 FC 00000>mov dword ptr ss:[ebp-4],0
00401322 . 837D D8 00 cmp dword ptr ss:[ebp-28],0 ; 创建节点内存成功? p==NULL?
00401326 . 74 0D je short writepro.00401335 ; 失败则调
00401328 . 8B4D D8 mov ecx,dword ptr ss:[ebp-28] ; ecx为新分配节点的地址
0040132B . E8 DAFCFFFF call writepro.0040100A ; 分配一个节点调用的构造函数 数据成员都赋值为0
00401330 . 8945 D4 mov dword ptr ss:[ebp-2C],eax ; 下面ebp-2c, ebp-24 ebp-20 都为新分配的节点地址 编译器真罗唆
00401333 . EB 07 jmp short writepro.0040133C
00401335 > C745 D4 00000>mov dword ptr ss:[ebp-2C],0
0040133C > 8B45 D4 mov eax,dword ptr ss:[ebp-2C]
0040133F . 8945 DC mov dword ptr ss:[ebp-24],eax
00401342 . C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401349 . 8B4D DC mov ecx,dword ptr ss:[ebp-24]
0040134C . 894D E0 mov dword ptr ss:[ebp-20],ecx
0040134F . 837D E0 00 cmp dword ptr ss:[ebp-20],0
00401353 . 75 0C jnz short writepro.00401361
00401355 . C745 E8 00000>mov dword ptr ss:[ebp-18],0
0040135C . E9 AD000000 jmp writepro.0040140E
00401361 > 8B55 E0 mov edx,dword ptr ss:[ebp-20] ; 新节点地址
00401364 . 8B45 0C mov eax,dword ptr ss:[ebp+C] ; 传进来的参数 要插入的位置
00401367 . 8902 mov dword ptr ds:[edx],eax ; pNewNode->data = 参数;
00401369 . 8B4D F0 mov ecx,dword ptr ss:[ebp-10] ; 对象的地址
0040136C . 8379 04 00 cmp dword ptr ds:[ecx+4],0 ; 检查对象的第二个成员变量 m_pNodeHead是不是空
00401370 . 75 1C jnz short writepro.0040138E
00401372 . 8B55 E0 mov edx,dword ptr ss:[ebp-20] ; 头节点为空的情况 新建结点的地址
00401375 . C742 04 00000>mov dword ptr ds:[edx+4],0 ; 新建节点指针区域赋值为0
0040137C . 8B45 F0 mov eax,dword ptr ss:[ebp-10] ; 对象的地址
0040137F . 8B4D E0 mov ecx,dword ptr ss:[ebp-20] ; 新建的节点的地址
00401382 . 8948 04 mov dword ptr ds:[eax+4],ecx ; 相当于m_pNodeHead = pNewNode
00401385 . C745 E8 01000>mov dword ptr ss:[ebp-18],1 ; ebp-18 为保存 nCount的变量
0040138C . EB 73 jmp short writepro.00401401 ; 处理完没有头节点情况
0040138E > 837D 08 01 cmp dword ptr ss:[ebp+8],1 ; 判断传进来的参数 小于1的话异常 参考ASSERT(1 <= pos && pos <= m_nCount);
00401392 . 7C 0A jl short writepro.0040139E
00401394 . 8B55 F0 mov edx,dword ptr ss:[ebp-10]
00401397 . 8B45 08 mov eax,dword ptr ss:[ebp+8]
0040139A . 3B02 cmp eax,dword ptr ds:[edx] ; 比较 插入的位置 和 对象的m_nCount pos <= m_nCount?
0040139C . 7E 17 jle short writepro.004013B5
0040139E > 68 DB000000 push 0DB ; /Arg3 = 000000DB
004013A3 . 68 54204300 push writepro.00432054 ; |Arg2 = 00432054
004013A8 . 68 30204300 push writepro.00432030 ; |Arg1 = 00432030 ASCII "1 <= pos && pos <= m_nCount"
004013AD . E8 0E780000 call writepro.00408BC0 ; \writepro.00408BC0
004013B2 . 83C4 0C add esp,0C
004013B5 > 8B55 F0 mov edx,dword ptr ss:[ebp-10] ; 对象的地址 也是节点数目的地址
004013B8 . 8B42 04 mov eax,dword ptr ds:[edx+4] ; eax = 下一个节点的地址
004013BB . 8945 E4 mov dword ptr ss:[ebp-1C],eax ; ebp-1c 是保存下一个节点地址的局部变量
004013BE . C745 EC 01000>mov dword ptr ss:[ebp-14],1 ; ebp-14 记录已经比较了几个节点 即源代码中的i
004013C5 . EB 09 jmp short writepro.004013D0
004013C7 > 8B4D EC mov ecx,dword ptr ss:[ebp-14] ; 循环开始 下面三行功能为 i++
004013CA . 83C1 01 add ecx,1
004013CD . 894D EC mov dword ptr ss:[ebp-14],ecx
004013D0 > 8B55 EC mov edx,dword ptr ss:[ebp-14] ; edx 已经比较的个数
004013D3 . 3B55 08 cmp edx,dword ptr ss:[ebp+8] ; 比较已经比较的节点数目和要插入的位置(传进来的参数) i < pos?
004013D6 . 7D 0B jge short writepro.004013E3 ; i >= pos 跳出循环
004013D8 . 8B45 E4 mov eax,dword ptr ss:[ebp-1C] ; eax 为当前节点的指针区域
004013DB . 8B48 04 mov ecx,dword ptr ds:[eax+4] ; ecx为下一个节点的指针 因为eax=[ebp-1c]为下一个节点的地址
004013DE . 894D E4 mov dword ptr ss:[ebp-1C],ecx ; 在循环中 ebp-1c 保存了下一个节点的指针
004013E1 .^ EB E4 jmp short writepro.004013C7 ; 循环结束
004013E3 > 8B55 E0 mov edx,dword ptr ss:[ebp-20] ; edx 新分配的节点的地址
004013E6 . 8B45 E4 mov eax,dword ptr ss:[ebp-1C] ; 插入地址前一个节点的指针
004013E9 . 8B48 04 mov ecx,dword ptr ds:[eax+4] ; ecx 为要插入节点前一个节点的指针指向的地址 即源代码中的pTmpNode->next;
004013EC . 894A 04 mov dword ptr ds:[edx+4],ecx ; 新节点的指针指向要插入节点的后一个节点 即源代码中的pNewNode->next = pTmpNode->next
004013EF . 8B55 E4 mov edx,dword ptr ss:[ebp-1C] ; 插入地址前一个节点的指针
004013F2 . 8B45 E0 mov eax,dword ptr ss:[ebp-20] ; 新分配的节点的地址
004013F5 . 8942 04 mov dword ptr ds:[edx+4],eax ; 插入地址前一个节点的指针指向新分配的节点
004013F8 . 8B4D 08 mov ecx,dword ptr ss:[ebp+8] ; 下面的功能为传进来的参数加1 并保存在据不变量ebp-10中 最后赋值给EAX作为返回值
004013FB . 83C1 01 add ecx,1
004013FE . 894D E8 mov dword ptr ss:[ebp-18],ecx
00401401 > 8B55 F0 mov edx,dword ptr ss:[ebp-10] ; 类对象的地址
00401404 . 8B02 mov eax,dword ptr ds:[edx] ; eax = m_nCount 这四行的功能是递增记录节点个数
00401406 . 83C0 01 add eax,1
00401409 . 8B4D F0 mov ecx,dword ptr ss:[ebp-10] ; 类对象的地址
0040140C . 8901 mov dword ptr ds:[ecx],eax ; m_nCount++
0040140E > 8B45 E8 mov eax,dword ptr ss:[ebp-18] ; 返回值
00401411 . 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00401414 . 64:890D 00000>mov dword ptr fs:[0],ecx
0040141B . 5F pop edi
0040141C . 5E pop esi
0040141D . 5B pop ebx
0040141E . 83C4 6C add esp,6C
00401421 . 3BEC cmp ebp,esp
00401423 . E8 58770000 call writepro.00408B80
00401428 . 8BE5 mov esp,ebp
0040142A . 5D pop ebp
0040142B . C2 0800 ret 8 //write.h文件中的代码
///////////////////////////////////////////////////////////////////////////////
//
// FileName : slist.h
// Version : 0.10
// Author : Luo Cong
// Date : 2004-12-29 9:58:38
// Comment :
//
///////////////////////////////////////////////////////////////////////////////
#ifndef __SINGLE_LIST_H__
#define __SINGLE_LIST_H__
#include <assert.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define DEBUG_NEW new (_NORMAL_BLOCK, THIS_FILE, __LINE__)
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifdef _DEBUG
#ifndef ASSERT
#define ASSERT assert
#endif
#else // not _DEBUG
#ifndef ASSERT
#define ASSERT
#endif
#endif // _DEBUG
template<typename T>
class CNode
{
public:
T data;
CNode<T> *next;
CNode() : data(T()), next(NULL) {}
CNode(const T &initdata) : data(initdata), next(NULL) {}
CNode(const T &initdata, CNode<T> *p) : data(initdata), next(p) {}
};
template<typename T>
class CSList
{
protected:
int m_nCount;
CNode<T> *m_pNodeHead;
public:
CSList();
CSList(const T &initdata);
~CSList();
public:
int IsEmpty() const;
int GetCount() const;
int InsertBefore(const int pos, const T data);
int InsertAfter(const int pos, const T data);
int AddHead(const T data);
int AddTail(const T data);
void RemoveAt(const int pos);
void RemoveHead();
void RemoveTail();
void RemoveAll();
T& GetTail();
T GetTail() const;
T& GetHead();
T GetHead() const;
T& GetAt(const int pos);
T GetAt(const int pos) const;
void SetAt(const int pos, T data);
int Find(const T data) const;
};
template<typename T>
inline CSList<T>::CSList() : m_nCount(0), m_pNodeHead(NULL)
{
}
template<typename T>
inline CSList<T>::CSList(const T &initdata) : m_nCount(0), m_pNodeHead(NULL)
{
AddHead(initdata);
}
template<typename T>
inline CSList<T>::~CSList()
{
RemoveAll();
}
template<typename T>
inline int CSList<T>::IsEmpty() const
{
return 0 == m_nCount;
}
template<typename T>
inline int CSList<T>::AddHead(const T data)
{
CNode<T> *pNewNode;
pNewNode = new CNode<T>;
if (NULL == pNewNode)
return 0;
pNewNode->data = data;
pNewNode->next = m_pNodeHead;
m_pNodeHead = pNewNode;
++m_nCount;
return 1;
}
template<typename T>
inline int CSList<T>::AddTail(const T data)
{
return InsertAfter(GetCount(), data);
}
// if success, return the position of the new node.
// if fail, return 0.
template<typename T>
inline int CSList<T>::InsertBefore(const int pos, const T data)
{
int i;
int nRetPos;
CNode<T> *pTmpNode1;
CNode<T> *pTmpNode2;
CNode<T> *pNewNode;
pNewNode = new CNode<T>;
if (NULL == pNewNode)
{
nRetPos = 0;
goto Exit0;
}
pNewNode->data = data;
// if the list is empty, replace the head node with the new node.
if (NULL == m_pNodeHead)
{
pNewNode->next = NULL;
m_pNodeHead = pNewNode;
nRetPos = 1;
goto Exit1;
}
// is pos range valid?
ASSERT(1 <= pos && pos <= m_nCount);
// insert before head node?
if (1 == pos)
{
pNewNode->next = m_pNodeHead;
m_pNodeHead = pNewNode;
nRetPos = 1;
goto Exit1;
}
// if the list is not empty and is not inserted before head node,
// seek to the pos of the list and insert the new node before it.
pTmpNode1 = m_pNodeHead;
for (i = 1; i < pos; ++i)
{
pTmpNode2 = pTmpNode1; //pTmpNode2 在前 pTmpNode1 在后
pTmpNode1 = pTmpNode1->next;
}
pNewNode->next = pTmpNode1;
pTmpNode2->next = pNewNode;
nRetPos = pos;
Exit1:
++m_nCount;
Exit0:
return nRetPos;
}
// if success, return the position of the new node.
// if fail, return 0.
template<typename T>
inline int CSList<T>::InsertAfter(const int pos, const T data)
{
int i;
int nRetPos;
CNode<T> *pTmpNode;
CNode<T> *pNewNode;
pNewNode = new CNode<T>;
if (NULL == pNewNode)
{
nRetPos = 0;
goto Exit0;
}
pNewNode->data = data;
// if the list is empty, replace the head node with the new node.
if (NULL == m_pNodeHead)
{
pNewNode->next = NULL;
m_pNodeHead = pNewNode;
nRetPos = 1;
goto Exit1;
}
// is pos range valid?
ASSERT(1 <= pos && pos <= m_nCount);
// if the list is not empty,
// seek to the pos of the list and insert the new node after it.
pTmpNode = m_pNodeHead;
for (i = 1; i < pos; ++i)
{
pTmpNode = pTmpNode->next;
}
pNewNode->next = pTmpNode->next;
pTmpNode->next = pNewNode;
nRetPos = pos + 1;
Exit1:
++m_nCount;
Exit0:
return nRetPos;
}
template<typename T>
inline int CSList<T>::GetCount() const
{
return m_nCount;
}
template<typename T>
inline void CSList<T>::RemoveAt(const int pos)
{
ASSERT(1 <= pos && pos <= m_nCount);
int i;
CNode<T> *pTmpNode1;
CNode<T> *pTmpNode2;
pTmpNode1 = m_pNodeHead;
// head node?
if (1 == pos)
{
m_pNodeHead = m_pNodeHead->next;
goto Exit1;
}
for (i = 1; i < pos; ++i)
{
// we will get the previous node of the target node after
// the for loop finished, and it would be stored into pTmpNode2
pTmpNode2 = pTmpNode1;
pTmpNode1 = pTmpNode1->next;
}
pTmpNode2->next = pTmpNode1->next; //pTmpNode2 是前一个
Exit1:
delete pTmpNode1;
--m_nCount;
}
template<typename T>
inline void CSList<T>::RemoveHead()
{
ASSERT(0 != m_nCount);
RemoveAt(1);
}
template<typename T>
inline void CSList<T>::RemoveTail()
{
ASSERT(0 != m_nCount);
RemoveAt(m_nCount);
}
template<typename T>
inline void CSList<T>::RemoveAll()
{
int i;
int nCount;
CNode<T> *pTmpNode;
nCount = m_nCount;
for (i = 0; i < nCount; ++i)
{
pTmpNode = m_pNodeHead->next;
delete m_pNodeHead;
m_pNodeHead = pTmpNode;
}
m_nCount = 0;
}
template<typename T>
inline T& CSList<T>::GetTail()
{
ASSERT(0 != m_nCount);
int i;
int nCount;
CNode<T> *pTmpNode = m_pNodeHead;
nCount = m_nCount;
for (i = 1; i < nCount; ++i)
{
pTmpNode = pTmpNode->next;
}
return pTmpNode->data;
}
template<typename T>
inline T CSList<T>::GetTail() const
{
ASSERT(0 != m_nCount);
int i;
int nCount;
CNode<T> *pTmpNode = m_pNodeHead;
nCount = m_nCount;
for (i = 1; i < nCount; ++i)
{
pTmpNode = pTmpNode->next;
}
return pTmpNode->data;
}
template<typename T>
inline T& CSList<T>::GetHead()
{
ASSERT(0 != m_nCount);
return m_pNodeHead->data;
}
template<typename T>
inline T CSList<T>::GetHead() const
{
ASSERT(0 != m_nCount);
return m_pNodeHead->data;
}
template<typename T>
inline T& CSList<T>::GetAt(const int pos)
{
ASSERT(1 <= pos && pos <= m_nCount);
int i;
CNode<T> *pTmpNode = m_pNodeHead;
for (i = 1; i < pos; ++i)
{
pTmpNode = pTmpNode->next;
}
return pTmpNode->data;
}
template<typename T>
inline T CSList<T>::GetAt(const int pos) const
{
ASSERT(1 <= pos && pos <= m_nCount);
int i;
CNode<T> *pTmpNode = m_pNodeHead;
for (i = 1; i < pos; ++i)
{
pTmpNode = pTmpNode->next;
}
return pTmpNode->data;
}
template<typename T>
inline void CSList<T>::SetAt(const int pos, T data)
{
ASSERT(1 <= pos && pos <= m_nCount);
int i;
CNode<T> *pTmpNode = m_pNodeHead;
for (i = 1; i < pos; ++i)
{
pTmpNode = pTmpNode->next;
}
pTmpNode->data = data;
}
template<typename T>
inline int CSList<T>::Find(const T data) const
{
int i;
int nCount;
CNode<T> *pTmpNode = m_pNodeHead;
nCount = m_nCount;
for (i = 0; i < nCount; ++i)
{
if (data == pTmpNode->data)
return i + 1;
pTmpNode = pTmpNode->next;
}
return 0;
}
#endif // __SINGLE_LIST_H__ //write.cpp中的代码
#include <iostream>
#include <windows.h>
#include "write.h"
using namespace std;
int main()
{
::MessageBox(0, "begin", "note", MB_OK);
int i;
int nCount;
CSList<int> slist;
for(i = 0; i < 10; i++)
slist.AddTail(i+1);
::MessageBox(0, "end", "note", MB_OK);
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课