这段代码不明白,那为高手能给我讲讲两个结构体之间的关系,并把我不明白的地方讲讲?(有问号的地方)MsgCtrl_T* m_pMessage;void COperation::Edit()
{
::EditMsg(&m_pMessage,m_nType); //是通过引用传别名吗 ?
}
BOOL EditMsg(MsgCtrl_T **pptMsg,BYTE nType)
{
MsgCtrl_T **pptTmp = pptMsg; // 不明白?
MsgCtrl_T *ptTmp; *pptTmp = (MsgCtrl_T*)new ConnectConfirmCtrl_T;
memset(*pptTmp,0,sizeof(ConnectConfirmCtrl_T));
(*pptTmp)->wVersion = sizeof(ConnectConfirmCtrl_T); if (*pptTmp)
{
for (i = 0; i < MSG_LEVELS; i++)
{
switch (dlg.m_wLevel[i])
{
(*pptTmp)->wMsgID = dlg.m_wLevel[i];
(*pptTmp)->pPayLoad = NULL;
pptTmp = &((*pptTmp)->pPayLoad); // 不明白?
.....
}
} ptTmp = *pptMsg; // 不明白?
while (ptTmp)
{
switch(ptTmp->wMsgID)
{
..... 2个结构体定义如下:
typedef struct tagCtrlHead
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
char szData[1];
}Msg_T;typedef struct
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
}ConnectCtrl_T;
{
::EditMsg(&m_pMessage,m_nType); //是通过引用传别名吗 ?
}
BOOL EditMsg(MsgCtrl_T **pptMsg,BYTE nType)
{
MsgCtrl_T **pptTmp = pptMsg; // 不明白?
MsgCtrl_T *ptTmp; *pptTmp = (MsgCtrl_T*)new ConnectConfirmCtrl_T;
memset(*pptTmp,0,sizeof(ConnectConfirmCtrl_T));
(*pptTmp)->wVersion = sizeof(ConnectConfirmCtrl_T); if (*pptTmp)
{
for (i = 0; i < MSG_LEVELS; i++)
{
switch (dlg.m_wLevel[i])
{
(*pptTmp)->wMsgID = dlg.m_wLevel[i];
(*pptTmp)->pPayLoad = NULL;
pptTmp = &((*pptTmp)->pPayLoad); // 不明白?
.....
}
} ptTmp = *pptMsg; // 不明白?
while (ptTmp)
{
switch(ptTmp->wMsgID)
{
..... 2个结构体定义如下:
typedef struct tagCtrlHead
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
char szData[1];
}Msg_T;typedef struct
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
}ConnectCtrl_T;
typedef MsgCtrl_T* PMsgCtrl_T;
EditMsg就成了如下:
EditMsg(PMsgCtrl_T * ,... // 一维的指针,看着就舒服多了
typedef struct tagCtrlHead
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
char szData[1];
}MsgCtrl_T;
#include <iostream.h>typedef struct tagCtrlHead
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
char szData[1];
}MsgCtrltypedef struct
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead* pPayLoad;
}ConnectCtrl_T;MsgCtrl_T* m_pMessage;//定义一个指向tagCtrlHead(MsgCtrl)结构的指针变量void COperation::Edit()
{
::EditMsg(&m_pMessage,m_nType); /*是通过引用传别名吗 ?
这个不是通过引用传别名,
1,假设参数是* m_pMessage,这个是直接传递一个tagCtrlHead(MsgCtrl)结构体变量
2,假设参数是m_pMessage,这个是直接传递一个指向tagCtrlHead(MsgCtrl)结构的指针变量,
也就是相当于传递1那种情况的结构体变量的地址
3,参数是本题中的&m_pMessage,这个是传递m_pMessage的地址,也就是指针的指针。也就是
相当于传递2那种情况的m_pMessage的地址。
4,传递引用,假设EditMsg的声明原型如下:EditMsg(MsgCtrl & m_pMessage, 某类型 m_nType);
则在执行体中,即EditMsg(m_pMessage, m_nType)这种情况是传递引用。其实和2差不多*/}
BOOL EditMsg(MsgCtrl_T **pptMsg,BYTE nType)
{
MsgCtrl_T **pptTmp = pptMsg; // 不明白?
/* 假设int i=1;
int* pi = &i; pi指向i,也就是pi的值等于整型变量i的地址
int** ppi = π ppi指向pi,也就是ppi的值等于指针变量pi的地址
到此为止,继续解释一下,i,*pi,**ppi,他们是一样的,都是访问i,都是1
而pi=&i,ppi=&pi,也就是上面赋值时的那些解释。
下面假设一个函数EditMsg(int **ppi)
{
int **ppn=ppi;
分成两步来看:
第一步:int **ppn;
这就是首先定义一个指向指针的指针ppn,如果8明白,就这样想,ppn指向某个指针,而这个指针
又指向一个整数。当然ppi也是这样,
第二步:ppn=ppi;
ppi的值等于指针变量pi的地址,那么,ppn也指向指针变量pi(这一点我应该没有理解错误:))
也就是ppn=&pi; 你的跟这个一样了。只不过类型不是int了,而是MsgCtrl_T。
}*/
MsgCtrl_T *ptTmp; *pptTmp = (MsgCtrl_T*)new ConnectConfirmCtrl_T;
memset(*pptTmp,0,sizeof(ConnectConfirmCtrl_T));
(*pptTmp)->wVersion = sizeof(ConnectConfirmCtrl_T);if (*pptTmp)
{
for (i = 0; i < MSG_LEVELS; i++)
{
switch (dlg.m_wLevel[i])
{
(*pptTmp)->wMsgID = dlg.m_wLevel[i];
(*pptTmp)->pPayLoad = NULL;
pptTmp = &((*pptTmp)->pPayLoad); /* 不明白?
没有执行 pptTmp = &((*pptTmp)->pPayLoad);这句话之前:
pptTmp应该是指向一个指针变量,假设这个指针变量是pLOVE,那么,pLOVE又指向一个
MsgCtrl结构体类型的变量LOVE,
现在,先分析一下,LOVE == *pLOVE == **pptTmp == 一个MsgCtrl结构体类型的变量;
pLOVE == &LOVE;
pptTmp == &pLOVE;
好,pptTmp存储的是指针的指针,也就是上面解释的指向一个指针变量,而这个指针变量又
指向一个结构体。(我们知道*是取值操作。比如int i=1; int *pi =&i; 那么*pi的值就是i,就是1。
*pi也就是pi指向的地址的里的值,也就是i的地址里存储的i。*pi就是i
pi存储的是i的地址。*pi就是i) 开始执行:
那么*pptTmp就是什么呢?就是pptTmp指向的地址里的值,pptTmp指向哪里?指向pLOVE,也就是
pptTmp存储的是pLOVE的地址,那么,*pptTmp就是pLOVE了。 pLOVE又是一个指针,指向一个结构体LOVE,现在就很清楚了。假设我想取LOVE结构体的成员pPayLoad
,一种方法是LOVE.pPayLoad,另一种方法就是通过指针,pLOVE->pPayLoad两者是一样的。都可以
完成取结构体的成员变量或者调用结构体成员函数。 再下面就更好理解了,把这个pPayLoad成员的地址(通过&)赋给pptTmp
到此,结束。
*/.....
}
}ptTmp = *pptMsg; // 不明白?
/* 这个可以自己试着去分析一下喽:) */
while (ptTmp)
{
switch(ptTmp->wMsgID)
{
pptTmp = &((*pptTmp)->pPayLoad);
看现在的贴最新代码吧!
MsgCtrl_T* m_pMessage;void COperation::Edit()
{
::EditMsg(&m_pMessage,m_nType);
}BOOL EditMsg(MsgCtrl_T **pptMsg,BYTE nType)
{
MsgCtrl_T **pptTmp = pptMsg;//(1)pptTmp和pptMsg可以看成等价的吗?
MsgCtrl_T *ptTmp; if (!(*pptTmp)) // (2) *pptTmp是地址吗?
{
CTypeDlg dlg(nType);
if (dlg.DoModal() != IDOK)
{
AfxSetResourceHandle(hResource);
return FALSE;
}
for (i = 0; i < MSG_LEVELS; i++)
{
switch (dlg.m_wLevel[i])
{
case CHOICE_SCCP_CONNECT_REQ:
*pptTmp = (MsgCtrl_T*)new CRCtrl_T;
memset(*pptTmp,0,sizeof(CRCtrl_T));
(*pptTmp)->wVersion = sizeof(CRCtrl_T); // (3)*pptTmp是地址的话,怎么访问它的域啊?只有节点才有域吧?
break;
............ default:
break;
} if (*pptTmp)
{
(*pptTmp)->wMsgID = dlg.m_wLevel[i];
(*pptTmp)->pPayLoad = NULL;
pptTmp = &((*pptTmp)->pPayLoad);//(4)添加并移动节点吗?
}
}
}
ptTmp = *pptMsg; //(5)ptTmp是指针变量,与的关系是什么?后面的程序好理解了
while (ptTmp)
{
switch(ptTmp->wMsgID)
{ case CHOICE_SCCP_CONNECT_REQ:
pPage = new CConnectReq();
sheet.AddPage(pPage);
((CConnectReq*)pPage)->m_ptCr = (CRCtrl_T*)ptTmp;
break;
............
default:
break;
}
ptTmp = ptTmp->pPayLoad;//移动节点
} sheet.DoModal(); for (i = 0; i < sheet.GetPageCount(); i++)
delete sheet.GetPage(i); AfxSetResourceHandle(hResource);
return TRUE;
}
________
| |
|记录1 |
| |-->消息1 ---->消息2---->消息3
---------
|
|
V
________
| |
|记录2 |
| |-->消息1 ---->消息2---->消息3
---------
|
|
V
typedef struct tagCtrlHead
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
char szData[1];
}MsgCtrl_T;typedef struct
{
WORD wVersion;
WORD wMsgID;
tagCtrlHead *pPayLoad;
}ConnectConfirmCtrl_T;
这是个指向指针的指针;
typedef struct node{
int a;
char b;
}node;void main()
{
node first;
first.a = 5;
first.b = 'y';
node *pNode;
pNode = &first;
//这两句话是等价的
cout<< first.a <<endl;
cout<< pNode->a <<endl;//下面两句话也是等价的
cout<< first.b <<endl;
cout<< pNode->b <<endl;
}
cout<< pNode->a
当然理解呀!
但我不理解的是如下问题: 怪怪的
(3)*pptTmp是地址的话,怎么访问它的域啊?只有节点才有域吧?
pptTmp = &((*pptTmp)->pPayLoad);这一个肯定是一个指针指向,pPayLoad。
(*pptTmp)->pPayLoad 即获取pptMsg结构体中的pPayLoad的值,
&((*pptTmp)->pPayLoad)即获取pPayLoad的地址。
pPayLoad为指针,所以需要一个指针的指针变量来接受它即pptTmp