【问题标题】:Difficulty debugging my linked-list in my C program在我的 C 程序中调试我的链表有困难
【发布时间】:2017-01-01 12:24:43
【问题描述】:

我有这个结构包含指向相同结构类型 (peca) 的链接。问题是当我尝试在不同的函数中使用 peca->penext 时,调试器显示结构 peca 没有链接到下一个或上一个。我做错了什么?

typedef struct peca{
    int index;
    int esquerda;
    int direita;
    int disponibilidade;
    struct peca *penext;
    struct peca *peant;
}PECA;

typedef struct mao{
    int index;
    int tamanho;
    PECA *ppeca;
    struct mao *pnext;
}MAO;

typedef struct jogada{
    int index;
    PECA *ppeca;
    struct jogada *pnext;
}JOGADA;

typedef struct jogo{
    int nr_maos;
    MAO *pmao;
    JOGADA *pjog;
}JOGO;

void init_jogada(JOGADA *pj) {
pj->ppeca = (PECA *) malloc(sizeof(PECA) * 28);
PECA *paux = pj->ppeca;
  for (int i = 0; i < 28; ++i) {
    paux->index = i;
    paux->disponibilidade = 1;
    if (i == 0)
    {
        paux->peant = NULL;
        paux->penext = paux++;
    }
    else if (i == 27)
    {
        paux->peant = paux--;
        paux->penext = NULL;
    }
    else
    {
        paux->penext = paux++;
        paux->peant = paux--;
    }
    paux++;
  }


}

【问题讨论】:

标签: c struct linked-list


【解决方案1】:

增加指向 PECA 的指针的方式很狡猾,这可能是破坏代码的原因。由于我说葡萄牙语,我可以判断peant 的意思是pelast,所以我可以推断它是一个双链表。

您的双链表绝对是多余的,因为您的片段(PECA 是英文片段)位于数组中。链表用于遍历一个序列,其中项目在内存中稀疏存储,数组将项目彼此相邻,这就是为什么您可以使用索引取消引用项目。

这就是我认为你正在做的事情:

    paux->penext = paux++; 
    /* Here you set the next, why increment the pointer while assigning?
       paux++ changes the value of paux. You might not want that here */

也许您不知道 paux++ 或 ++paux 或 paux-- 或 --paux 确实改变 paux 指向的位置。

这是您更正的代码:

  for (int i = 0; i < 28; ++i) {
    paux->index = i;
    paux->disponibilidade = 1;
    if (i == 0)
    {
        paux->peant = NULL;
        paux->penext = paux +1;
    }
    else if (i == 27)
    {
        paux->peant = paux - 1;
        paux->penext = NULL;
    }
    else
    {
        paux->penext = paux + 1;
        paux->peant = paux - 1;
    }
    /* Ok! Now we really want to increment paux, to use in the next iteration */
    paux++;
  }

【讨论】:

    【解决方案2】:

    作为一般规则,不要在 for 循环中创建特殊情况。把if (i==0)里面的代码放在循环之前,if (i==27)里面的代码放在循环外面。它使循环本身对读者来说更简单,并避免在您更改迭代次数而忘记更改条件时出现问题。

    如果您不在循环内修改paux,您的代码看起来会简单得多。使用迭代器i 访问对象。如果你真的想使用paux 来简化你的语法,要么让它成为迭代器,要么在循环的开头分配它:

    paux = pj-&gt;ppeca + i;

    然后你可以用paux + 1paux - 1找到下一个和上一个。

    但是你真的需要下一个/上一个指针吗?如果没有看到其余的代码,这对您来说可能是一个愚蠢的问题,但是当您的元素已经分配到数组中时,为什么会有一个类似于双向链表的结构呢?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      • 2015-09-29
      • 1970-01-01
      相关资源
      最近更新 更多