【问题标题】:How are Pointers, data type initialization and multiple pointer declaration handled in c++?C++中如何处理指针、数据类型初始化和多指针声明?
【发布时间】:2020-05-23 12:58:54
【问题描述】:

当我们为一棵树或一个链表创建一个结构时,这种性质的东西:

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

队列存储结构节点的类型是什么?我认为这是一个指向结构的指针。

std::queue<TreeNode*> q;

但是如果我尝试像这样初始化多个节点:

TreeNode* l = nullptr, r = nullptr;

它不起作用,你必须这样做

TreeNode *l = nullptr, TreeNode *r = nullptr;

有人可以帮我更好地理解这一点吗?

编辑:阅读此答案后Declaring multiple object pointers on one line causes compiler error 我的理解是:在 C 和 C++ 中, * 绑定到声明符,而不是类型说明符。在这两种语言中,声明都是基于表达式的类型,而不是对象。

那么队列是如何声明的呢?

【问题讨论】:

  • 什么是queue?是您正在使用的std::queue,还是您没有向我们展示的某个自定义(如果是,为什么)?
  • 倒数第二个声明了一个TreeNode * 和一个TreeNode(当你用nullptr 初始化它时,后者会彻底混淆编译器)。很明显,您收到了一个错误,它可能会告诉您同样多的信息。 “它不起作用”是模糊的。您应该包含收到的逐字错误消息,以及您不理解的具体内容。而且,让我们明确一点,TreeNode *l = nullptr, TreeNode *r = nullptr; 也不起作用;那应该是TreeNode *l = nullptr; TreeNode *r = nullptr;。或TreeNode *l = nullptr, *r = nullptr;
  • TreeNode* l = nullptr, r = nullptr; 不起作用,因为stackoverflow.com/questions/13618282/…
  • @WhozCraig 我稍后在程序中为其分配 TreeNode* 类型的值时出现类型不匹配,其中包含“从 nullptr 到非标量类型 TreeNode 的无效转换”字样,我也从TreeNode* 为 int,如果我在开始时将其分配为 root 而不是 nullptr,然后稍后将其更改为 TreeNode*。
  • That all belongs in your question,不清楚您不理解的错误消息是什么。

标签: c++ pointers syntax


【解决方案1】:

第二个变量r没有声明为指针,应该是:

TreeNode *l = nullptr, *r = nullptr;

TreeNode* 是一个类型,类似于charint,但如果在同一行中声明它,则必须使用* 间接运算符,以便编译器知道特定变量是指针反对,而不是对象。当您在 dequevector 或类似的东西中声明它时,您还必须能够判断所承认的 tpyes 是否是指向对象的指针,因此在尖括号内声明 TreeNode*

如果你仔细想想,它在语义上是有意义的。

【讨论】:

  • 这只是一个错字,我的主要问题与队列类型有关。
  • 所以当你说“但是如果我尝试像这样初始化多个节点:TreeNode* l = nullptr, r = nullptr; 它不起作用,你必须这样做TreeNode *l = nullptr, TreeNode *r = nullptr;”,这不是问题吗?跨度>
  • @idclev463035818 我知道如何让它工作,但这只是经验和调整,我想知道发生了什么
  • Then how is the queue declared the way it is? -> 因为TreeNode* 也是具有基础类型TreeNode 的指针类型的正确语法。同样T&amp; 是一个引用类型。
  • 语法中的“不一致”源于定义声明的方式。请参阅en.cppreference.com/w/cpp/language/declarations,尤其是示例代码。 4) Pointer declarator: the declaration S * D; declares D as a pointer to the type determined by decl-specifier-seq S.
【解决方案2】:

std::queue&lt;TreeNode*&gt; q; 中,方括号包含一个完整的类型名称。 (“名称”是指类型的整个声明符TreeNode *,而不是标识符。)使用声明符描述类型时,所使用的形式就好像带有标识符的完整普通声明已删除其标识符。例如,以声明TreeNode *Placeholder 开头,类型名称为TreeNode *

TreeNode* l = nullptr, r = nullptr; 中,没有括号将*TreeNode 分组。根据 C++ 语法,它与l 分组。如果这里允许使用括号,这样我们就可以写&lt;TypeNode *&gt; l = nullptr, r = nullptr;,那么就可以了。这里的问题就像你写- a + b一样:规则只是-a分组,所以表达式是-a + b,而不是- (a + b)

您当然可以使用typedef TreeNode *TreeNodeP; TreeNodeP l = nullptr, r = nullptr; 解决此问题。这表明效果只是 C++ 语法结构的结果——编译器没有内在的原因不能先接受任何类型描述​​,然后是用该类型声明的标识符列表,但语法设计根本不支持。

(这样做的一个后果是写成int* a 会产生误导,因为文本中标记的接近程度不同于它们在语法中的接近程度——* 在文本中更接近于int,但在语法中更接近a,因此空格会发送错误信息。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 2011-06-17
    • 2020-10-03
    • 1970-01-01
    • 2011-02-08
    • 2014-09-08
    • 1970-01-01
    相关资源
    最近更新 更多