【问题标题】:Trying to understand pointers and double pointers试图理解指针和双指针
【发布时间】:2012-07-17 21:49:32
【问题描述】:

我正在尝试在 C++ 中实现一个简单的链表。我可以创建节点,它们似乎可以正确链接自己。我的问题涉及 listIterate() 函数,但我在此处附上了整个代码以备不时之需。

#include <iostream>
using namespace std;

//Wrapper class which allows for easy list management
class LinkedList {

    //Basic node struct
    struct node {
        int data;
        node *link; 
    }; 

    node *head; //Pointer to the head (also referred to as root) node, or the first node created.
    node *current; //Pointer to the /latest/ node, or the node currently being operated on.
    node *tail; //Pointer to the tail node, or the last node in the list. 

public:

    //Default constructor. Creates an empty list.
    LinkedList() {
        head = NULL;
        current = NULL;
        tail = NULL;
        cout << "*** Linked list created. Head is NULL. ***\n";
    }

    //Default destructor. Use to remove the entire list from memory.
    ~LinkedList() {
        while(head != NULL) {
            node *n = head->link;
            delete head;
            head = n;
        }
    }

    /*
    appendNode() 
    Appends a new node to the end of the linked list. Set the end flag to true to set the last node to      null, ending the list.
    */
    void appendNode(int i) {

        //If there are no nodes in the list, create a new node and point head to this new node.
        if (head == NULL) {
            node *n = new node;
            n->data = i;
            n->link = NULL;
            head = n;

            //head node initialized, and since it is ALSO the current and tail node (at this point), we must update our pointers
            current = n;
            tail = n;
            cout << "New node with data (" << i << ") created. \n---\n"; 

        } else {

        //If there are nodes in the list, create a new node with inputted value.
        node *n = new node;
        n->data = i;
        cout << "New node with data (" << i << ") created. \n"; 

        //Now, link the previous node to this node.
        current->link = n;
        cout << "Node with value (" << current->data << ") linked to this node with     value (" << i << ").  \n---\n";     

        //Finally, set our "current" pointer to this newly created node.
        current = n;
        }
    }

    /*
    listIterate()
    Iterates through the entire list and prints every element.
    */
    void listIterate() {

        //cursor
        node *p;

        //Start by printing the head of the list.
        cout << "Head - Value: (" << head->data << ") | Linked to: (" << head->link     << ") \n";

        p = head->link;
        cout << *p;

    }

}; 

int main() {

    LinkedList List;
    List.appendNode(0);
    List.appendNode(10);
    List.appendNode(20);
    List.appendNode(30);
    List.listIterate(); 

}

现在,我将参考这个方法,listIterate()。

void listIterate() {

        //cursor
        node *p;

        //Start by printing the head of the list.
        cout << "Head - Value: (" << head->data << ") | Linked to: (" << head->link << ") \n";

        p = head->link; 
        cout << *p;

    }

命令cout &lt;&lt; *p; 抛出错误,我相信这就是原因:此时,p 指向head-&gt;link,这是另一个指向我的头节点的链接字段的指针。现在,我知道如果我在程序中取消引用 p ,head-&gt;link 中将没有实际值,因为它指向一个变量。

对我来说,如果我取消引用 p 两次 (**p),它应该跟随指针两次 (p -> head-&gt;link -> 链表中第二个节点的值 (10)。但是,取消引用 p 两次会引发此错误。

LinkedListADT.cc:89: error: no match for ‘operator*’ in ‘** p’

谁能帮我理解为什么会这样?这是非法操作吗?是否以我不熟悉的其他方式执行?

【问题讨论】:

  • 第一个错误是什么?没有它,这个问题是不完整的。请注意,用四个空格作为前缀的行将它们标记为代码,这不是错误消息的适当标记。在SE平台supports &lt;samp&gt;之前,最合适的标记输出方式是用&lt;blockquote&gt;&lt;pre&gt;
  • 此问题已修复。感谢您的提醒。第一个错误是尝试取消引用无效的指针的结果。问题的原始措辞给人的印象是我不知道为什么会发生这种情况,这是不正确的。对第二点更感兴趣。

标签: c++ pointers dereference


【解决方案1】:

cout &lt;&lt; *p 尝试打印 node 对象。由于没有为节点对象定义打印操作(即没有为输出流定义operator&lt;&lt;),因此尝试打印它会失败。您可能正在寻找的是:

cout << p->data;

对于您的第二点,该陈述可以这样分解:

**p == *(*p)

所以第一个星号取消引用p,返回一个node。第二颗星尝试取消引用该操作的结果,但由于节点是 struct 而不是指针,因此编译器会报错。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您的节点类缺少operator *,因此当p 的类型为node * 时,构造**p 在语义上是错误的。要查看重载 operator * 的示例,请查看实现智能指针的示例。

    【讨论】:

      【解决方案3】:

      **p 不“跟随指针两次”。该操作只是尝试取消引用p 两次。

      ppointernode。第一个取消引用 (*p) 将评估为 p 指向的节点。第二次取消引用 (**p) 将导致错误,因为 nodestruct 而不是 pointer,并且没有定义重载的 operator*

      如果你想取消引用指向下一个节点的指针:

      *(p-&gt;link)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        • 1970-01-01
        • 2013-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多