【问题标题】:Accessing structs in linked list (tree with a list of pointer to their children implementation) [closed]访问链表中的结构(带有指向其子实现的指针列表的树)[关闭]
【发布时间】:2019-06-07 08:29:06
【问题描述】:

我需要实现 3 个函数(addElem、member 和 findPathCost),它们在树上操作,其中包含指向具有链表的子节点的指针列表。 struct treeNode 定义树中的节点,childrenListElem 定义treeNode 的子节点列表。

struct tree::treeNode {
    Label label;
    Weight weight;
    childrenList children;   //pointer to the list of its children
};

struct tree::childrenListElem {
    treeNode* child;   //pointer to the first element of the children's list
    childrenListElem* next;  //pointer to the next one
};

在标题中:

struct treeNode;             // forward declaration
typedef treeNode* Tree;      // pointer to root of tree
const Tree emptyTree = NULL; // empty tree

struct childrenListElem;                     // forward declaration
typedef childrenListElem* childrenList;      
const childrenList emptyChildrenList = NULL; // empty children list

我的问题是我无法从 treeNode 结构中访问子列表,这是我制作的 addAlemen 和成员的辅助函数中的一个示例:

//AUXILIARY FUNCTION: getNode(Label, Tree) returns the node with the given label in the tree.
//Used both in addElem and in member.

Tree getNode(Label & l, const Tree t)
{
    Tree aux = t;
    while (!isEmpty(aux)) {
        if (aux->label == l)
            return aux;
        aux = (aux->children)->next; //HERE IS MY PROBLEM:
                                     //usually I would have just done
                                     //aux = aux->NextVertex
                                     //(with NextVertex being the next
                                     //treeNode in the tree t);
                                     //but I can't seem to access the
                                     //second struct as the compiler
                                     //tells me that "children" is
                                     //apparently not a pointer.
                                     //How can I access the second struct?
    }
    return emptyTree;
}

这是我的编译器显示的错误:

 The error is: "error: cannot convert 'tree::childrenListElem*' to 'tree::Tree' {aka 'tree::treeNode*'} in assignment aux = aux->children->next;"

当我改为使用 aux = aux->children.next;我看到了这个错误(我正在使用 gcc 编译器):

The error is: "error: request for member 'next' in 'aux->tree::treeNode::children', which is of pointere type 'tree::childrenList' {aka 'tree::childrenListElem*'} (maybe you meant to use '->'?)

【问题讨论】:

  • 请尝试创建一个合适的minimal reproducible example 向我们展示。 Tree 是什么?
  • childrenList 是如何定义的?真的和childrenListElem一样吗?
  • 也许解决方案就像aux->children.next一样简单?
  • 不幸的是它不是!我也试过(aux.children)->下一步,什么都没有!
  • 请发布错误。

标签: c++ pointers struct linked-list


【解决方案1】:

(已编辑)简短回答:

在尝试编译您的示例后,我注意到 children 实际上不是 childrenListElem 的实例,而是一个指针,您访问它的方式是正确的。抱歉,对那些 typedef 有点困惑。 但是您尝试分配

的值
(aux->children)->next 

类型为childrenListElem* 的变量为Tree aka treeNode*。改成之后

aux = (aux->children)->child;

它在我的电脑上编译,也使用 gcc。

(旧的和错误的)简答:

使用点运算符。

aux = aux->children.next;

(现在错了)解释:

如果我们分解这一条语句,它会变成这样:

aux = aux->children->next;
//can also be written like the following to lines:

childrenList child = aux->children;
//1. dereference aux and retrieve the member children
//the result is instance of childrenList

aux = child->next
//2. dereference child and retrieve member next.
//this fails, because child is not a pointer

(可能仍然有帮助)扩展答案:

也许您刚刚将 '->'-operator 与 '.'-operator 混淆了,这在我身上经常发生 :) 或者你对指针和成员有一个普遍的误解。在这种情况下,也许这个简短的例子会对你有所帮助:

struct a;

struct b
{
   //this is a full instance of a
   a instanceOfA;
   // this is just a pointer to an instance of a
   a* pointerToA;
}

void foo()
{
    b instanceOfB;
    //members of an instance are always accessed with the dot-operator:
    a instanceOfA = instanceOfB.instanceOfA;
    a *pointerToA = instanceOfB.pointerToA;

    //if you have a pointer you need to use the -> operator
    b *pointerToB = new b();
    instanceOfA = pointerToB->instanceOfA;
    pointerToA = pointerToB->pointerToA;

    //The -> operator is just the shortcut for dereferencing + member access
    //It does the same like this:
    instanceOfA = (&pointerToB).instanceOfA;
    pointerToA = (&pointerToB).pointerToA;
}

我希望这能解决您的问题并澄清一些细节:)

【讨论】:

  • 非常感谢您的解释!我完全理解了一切,实际上我确实混淆了这两个运算符,但不知何故编译器仍然说它是错误的(我使用的是 gcc 编译器)!
  • 是的,抱歉,我忽略了其中一个 typedef 并编辑了我的答案。只需稍加改动,它现在就可以在我的电脑上编译。无论如何,我不知道为什么编译器会给你这样一个奇怪的信息。
猜你喜欢
  • 2020-05-10
  • 2013-02-13
  • 2023-03-31
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 2020-07-17
  • 2017-01-04
  • 1970-01-01
相关资源
最近更新 更多