【问题标题】:Interpreting the loop condition of custom circular doubly linked list解读自定义循环双向链表的循环条件
【发布时间】:2018-04-10 10:05:12
【问题描述】:

我在结构中有一个列表,

struct A{
    list B;
};

我也有一个指向这个结构的指针,比如

struct A *a;

现在,假设列表已经实现,其元素的类型为elem

然后,我执行以下操作 -

(i) 我在nodeLelem 类型的指针)中获得列表的头部

elem * nodeL = list_get_head(&(a->B));

(ii) 我现在以这种方式遍历列表:

while(nodeL != (elem *)(&a->B)){ // did not get this part ----- I
    ; //some code here
    nodeL = list_get_next(&(a->B), nodeL);
}

假设list_get_head 获得指向列表头的指针,list_get_next 获得指向传递的第二个参数elem 的下一个元素的指针。

现在我的问题是:

  1. 我的循环条件是什么?我希望循环到什么列表? (见I)也就是说,如果&(a->B)是列表开始的地址,那么这里的&a->B是什么?

我认为这应该循环到列表末尾,但似乎这不是 while 循环条件正在做的事情。另外,这是一个循环双向链表。

【问题讨论】:

  • 代码前定义的&A->Bstructuresome variable中的A是什么?
  • "->" 的优先级高于 "&",所以 &(A->B)&A->B 完全一样。
  • @ShashankSingh 我已经修改了我的代码 - 对不起这个错误。现在就来看看
  • @Sigismondo 你确定吗?所以两者的意思是一样的?
  • 是的,我确定!在这两种情况下,这只是指向列表的指针。只需谷歌搜索“运算符优先级”,或在 test.c 源代码中测试它...... :)

标签: c list doubly-linked-list circular-list


【解决方案1】:
elem* x = list_get_head(&a->B);
elem* y = (elem *)(&a->B);

首先,xy 在您的情况下有何不同?

为了完全有效,list 的第一个成员必须是 elem* 类型。我个人会假设这是列表的头部,但是你的while循环永远不会被输入,所以它一定是尾部???但是你在循环中考虑的第一个元素是尾巴......

空列表如何表示?空指针?如果是这样,这不在您的代码中。

while(nodeL != (elem *)(&a->B))

没有得到这部分

想法很简单:我们从头开始迭代,只要没有到达头再次,我们仍然在循环中......但问题是,你必须区分两种情况:

  1. 当前节点是循环开始的头部
  2. 迭代完所有元素后,当前节点为头

我现在建议对迭代进行不同的处理:

elem* nodeL = list_get_head(&a->B);
if(nodeL) // based on assumption(!): otherwise, empty list
{
    do
    {
        //some code here
        nodeL = list_get_next(&a->B, nodeL);
    }
    while(nodeL != list_get_head(&a->B));
}

一个元素被保证在列表中,所以我们可以无条件地使用它(因此是一个 do-while 循环)。然后我们迭代到下一个元素,直到我们再次到达起点。我用另一个电话 list_get_head 替换了可疑演员,使整个事情更安全(也不再依赖假设)。

【讨论】:

  • 是的,你完全正确,谢谢,我也意识到我必须这样处理它。感谢代码
【解决方案2】:

不清楚你是否在谈论std::list。但是由于您提到不熟悉的list_get_headlist_get_next,我认为这是一个非标准实现。

所以猜测是:在列表中,头部也是一个元素。条件while(nodeL != (elem *)(&A->B)) 看起来像是在检查循环何时返回到循环列表的头部。

但是,有两个观察结果:

  1. 列表的元素通常从堆或内存池中分配。因此,如果B 是头部,它应该是一个指针。除非是typedef elem * list

  2. 循环可能不会运行,因为nodeL 已经在前面了。

【讨论】:

  • C 中没有 std::list ......除此之外,std::list 也不是循环的(至少不一定)。
  • 谢谢,是的,看起来我的循环在这种情况下不会运行
  • 不,这不是 std::list
  • 因为名字,我只提到了std::list。
【解决方案3】:

假设您有一个variable 和一个pointerstructure

A var;
A* pntr;

现在要访问structure 的数据成员,我们执行以下操作:

var.B    // For a variable use dot 
(*pntr).B or pntr->B    //For a pointer we can use * . or ->

在您的代码中,while(nodeL != (elem *)(&a->B)) 遍历列表,直到再次遇到循环列表的头部。

我们可以通过:

A* a;
//SOME INITIAL CODE
A* pntr;
pntr = a;
head = (elem*)&(pntr->B)

所以看样子:

while( nodeL != (elem *) ( & ( a->B ) ) )

【讨论】:

  • 感谢您的回答,但是,在这种情况下,我的循环不会运行,对吗?因为,最初,它们是相等的
  • 是的,它不会运行,因为它们是平等的。
猜你喜欢
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 2011-12-15
相关资源
最近更新 更多