类型定义、标记和未标记的结构以及不兼容的指针类型 [英] Typedefs, tagged and untagged structures, and incompatible pointer types

查看:17
本文介绍了类型定义、标记和未标记的结构以及不兼容的指针类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下 C 代码片段:

Consider the following C code snippet:

typedef struct node{
    int val;
    struct node* left;
    struct node* right;
}node;

void inorderTraversal(node *p){
    inorderTraversal(p->left);
    printf("%d",p->val);
    inorderTraversal(p->right);
}

如果我只写 typedef struct 而不是 typedef struct node,当我调用 inorderTraversal(root)main() 中.为什么即使程序没有显示任何错误,我也会收到此警告?

If I write only typedef struct instead of typedef struct node, I get a warning saying "passing argument of incompatible pointer type" when I call inorderTraversal(root) in main(). Why do I get this warning even though the program doesn't show any error?

推荐答案

如果你不给结构体一个标签名称,

If you don't give a tag name to the struct,

struct node* left;

在结构定义中声明了一个新的(不完整的)类型struct node.因此,当您传递指向该(不完整的)类型的指针时,其中需要 node*,您传递的是不兼容类型的指针.

in the struct definition declares a new (incomplete) type struct node. So when you pass a pointer to that (incomplete) type, where a node* is expected, you're passing a pointer of an incompatible type.

当您定义的结构具有指向相同类型的指针的成员时,您必须能够在定义中命名该类型,因此该类型必须在范围内.

When the struct you define has members that are pointers to the same type, you must be able to name that type in the definition, so the type must be in scope.

如果你给 struct 一个名字,那么类型就是 - 从那时起 - 在范围内并且可以作为 struct node 引用,虽然还不完整(如果标签是 node).在 typedef 完成后,类型可以被称为 struct nodenode,无论你喜欢哪个.

If you give the struct a name, the type is - from that point on - in scope and can be referred to, although not yet complete, as struct node (if the tag is node). After the typedef is complete, the type can then be referred to as either struct node or node, whichever you prefer.

但是如果你不给 struct 一个标签,类型在 typedef 完成之前是匿名的,并且在此之前不能以任何方式被引用.从什么时候开始

But if you don't give the struct a tag, the type is anonymous until the typedef is complete, and cannot in any way be referred to before that. And since when the line

struct node *left;

遇到

struct node 所指的类型是未知的,该行声明了一个新类型,struct node,其中什么都不知道.编译器没有理由将该类型与当前定义的类型连接起来.所以在这一点上,struct 包含一个成员,它是一个指向未知不完整类型的指针.现在,在 inorderTraversal 中,当你调用

is encountered, no type that struct node refers to is known, that line declares a new type, struct node, of which nothing is known. The compiler has no reason to connect that type with the one currently being defined. So at that point, the struct contains a member that is a pointer to an unknown incomplete type. Now, in inorderTraversal, when you call

inorderTraversal(p->left);

node *p,根据node的定义,p->left是一个指向未知不完整类型结构节点.如果创建了 p 使得 p->left 实际上是一个指向 node 的指针,那么事情仍然可以工作(除非可能在平台上指向不同类型的指针具有不同的表示形式),但是您将指针传递给一种类型,其中需要指向不同类型的指针.由于一种类型不完整,因此与预期类型不兼容.

with node *p, by the definition of node, p->left is a pointer to the unknown incomplete type struct node. If p has been created so that p->left is actually a pointer to node, things will work nevertheless (except possibly on platforms where pointers to different types have different representations), but you're passing a pointer to one type where a pointer to a different type is expected. Since the one type is incomplete, it is incompatible with the expected type.

这篇关于类型定义、标记和未标记的结构以及不兼容的指针类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆