这段代码不明白,那为高手能给我讲讲两个结构体之间的关系,并把我不明白的地方讲讲?(有问号的地方)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;

解决方案 »

  1.   

    这是一个指针的指针的问题,用typedef可以简化一下
    typedef MsgCtrl_T* PMsgCtrl_T;
    EditMsg就成了如下:
      EditMsg(PMsgCtrl_T * ,... // 一维的指针,看着就舒服多了
      

  2.   

    我是楼主!  第1个结构体我敲错了,应该定义如下:
    typedef struct tagCtrlHead
    {
    WORD wVersion;
    WORD wMsgID;
    tagCtrlHead *pPayLoad;
    char szData[1];
    }MsgCtrl_T;
      

  3.   

    #include "stdafx.h"
    #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 = &pi;     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)
            {  
                 
      

  4.   

    这句很不好理解! 
    pptTmp = &((*pptTmp)->pPayLoad);
      

  5.   

    我是楼主!
    看现在的贴最新代码吧!
    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;
      

  6.   

    MsgCtrl_T **pptTmp = pptMsg;  // 不明白?
    这是个指向指针的指针;
      

  7.   

    能理解吗?下面的:
    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;
    }
      

  8.   

    first.a <<endl;
      cout<< pNode->a 
      当然理解呀!
      但我不理解的是如下问题:  怪怪的
      (3)*pptTmp是地址的话,怎么访问它的域啊?只有节点才有域吧?
      

  9.   

    这句很不好理解! 
    pptTmp = &((*pptTmp)->pPayLoad);这一个肯定是一个指针指向,pPayLoad。
      

  10.   

    关键是**p指针的指针,把楼主搞昏了。*pptTmp为 pptTmp指针指向的空间的值也即pptMsg实体的地址,
    (*pptTmp)->pPayLoad 即获取pptMsg结构体中的pPayLoad的值,
    &((*pptTmp)->pPayLoad)即获取pPayLoad的地址。
    pPayLoad为指针,所以需要一个指针的指针变量来接受它即pptTmp