简体   繁体   English

将指向相同类型的结构成员的结构的指针分配给指向相同类型的结构的另一个指针

[英]Assign a pointer to a struct that is a member of a struct of the same type to another pointer to a struct of the same type

This question sounds super confusing even for me, and it may seem obvious or already answered, but I have searched a lot and although I found interesting things, I didn't find an answer exactly for my question. 甚至对我来说,这个问题听起来也很令人困惑,它看起来似乎很明显或已经回答了,但是我进行了很多搜索,尽管我发现了一些有趣的东西,但并未找到完全适合我问题的答案。 Here is some C code that will show much better my doubt: 这是一些C代码,这些代码将更好地显示我的疑问:

typedef struct Node_struct {
   char keyLine[100];
   int occurrences;
   struct Node* leftChild;
   struct Node* rightChild;
   struct Node* parent;
} Node;

typedef struct Tree_struct {
   Node* root;
} Tree;

int insertNode(Tree* myTree, Node* newNode) {
    ...
    Node* currentNode = myTree->root;
    ...
    if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
        currentNode = (Node*)currentNode->leftChild;
    }
    ...
 }

Is this code correct? 此代码正确吗? Since currentNode is of type Node* , and currentNode->leftChild is of type struct Node* , I had to cast (Node*)currentNode->leftChild so that it could be assigned to currentNode . 由于currentNode的类型为Node* ,而currentNode->leftChild的类型为struct Node* ,因此我必须转换(Node*)currentNode->leftChild以便可以将其分配给currentNode But I am not sure if this is correct, necessary, or if there is a better way to do the same. 但是我不确定这是否正确,必要,或者是否有更好的方法可以做到这一点。

Similarly, I also have this: 同样,我也有这个:

Node* coverNode = NULL;
...
coverNode->leftChild = (struct Node*)newNode;

What should be written 应该写什么

Suppose the code in the question were written like this: 假设问题中的代码是这样写的:

typedef struct Node {     // Not Node_struct as in the question!
   char keyLine[100];
   int occurrences;
   struct Node* leftChild;
   struct Node* rightChild;
   struct Node* parent;
} Node;

Then the name Node would be a synonym (alias) for struct Node . 然后,名称Node将成为struct Node的同义词(别名)。 (For any typedef XY; , Y becomes a synonym for type X — where in your case, X would be struct Node and Y would be Node.) (对于任何typedef XY;Y成为X类型的同义词-在您的情况下, X将为struct NodeY将为Node。)

The cast in: 演员表:

currentNode = (Node *)currentNode->leftChild;

would be unnecessary (but mostly harmless) because it would be a no-op — the types struct Node * and Node * would be two names for the same pointer type. 它将是不必要的(但大多数情况下是无害的),因为它将是无操作的struct Node *Node *类型将是同一指针类型的两个名称。 Similarly for: 同样适用于:

coverNode->leftChild = (struct Node *)newNode;

The cast would be unnecessary but (mostly) harmless. 强制转换是不必要的,但(大多数)无害。 There would be a small risk of confusing people with the cast. 将演员与演员混淆的风险很小。 It is better to avoid casts when possible, and these would be better written without the casts: 最好在可能的情况下避免使用强制类型转换,而如果没有强制类型转换,则最好将其编写为:

currentNode = currentNode->leftChild;
coverNode->leftChild = newNode;

What is written 写什么

typedef struct Node_struct {
   char keyLine[100];
   int occurrences;
   struct Node* leftChild;
   struct Node* rightChild;
   struct Node* parent;
} Node;

Now we have three type names in play: struct Node_struct , struct Node , and Node . 现在我们可以使用三个类型名称: struct Node_structstruct NodeNode In this case, struct Node_struct and Node are synonyms, and struct Node is an incomplete structure type (or, at least, it is not completed by any code in the question). 在这种情况下, struct Node_structNode是同义词,而struct Node是不完整的结构类型(或者,至少,问题中的任何代码都未完成)。 It is wholly unrelated to either struct Node_struct or Node except by the coincidence that it is referenced inside the structure. 它与struct Node_structNode完全无关,除了巧合的是,它在结构内部被引用。

With this notation, the casts are 'necessary' because you're converting between pointers to unrelated types ( struct Node * and struct Node_struct * ). 使用这种表示法时,强制转换是“必需的”,因为您要在指向不相关类型( struct Node *struct Node_struct * )的指针之间进行转换。 Fortunately, there are rules that say all structure type pointers are inter-convertible and must have the same size and alignment requirements (C11 §6.2.5 Types ¶28 and §6.3.2.3 Pointers ¶7 ). 幸运的是,有规则说所有结构类型指针都是可相互转换的,并且必须具有相同的大小和对齐要求( C11§6.2.5类型¶28§6.3.2.3指针¶7 )。

But you should drop the _struct part of Node_struct to make the rules of the first part of this answer apply. 但是,你应该放下_struct的一部分Node_struct使这个答案的第一部分的规则。 In C, it is (IMO) sensible to use: 在C语言中,使用(IMO)明智:

typedef struct SomeTag SomeTag;

so that you can subsequently use SomeTag * etc. The first SomeTag is in the tags name space and does not conflict with the second SomeTag , which is in the ordinary identifiers name space. 这样您便可以随后使用SomeTag *等。第一个SomeTag位于标签名称空间中,并且与第二个SomeTag冲突,后者位于普通标识符名称空间中。 See C11 §6.2.3 Name spaces of identifiers . 参见C11§6.2.3标识符的命名空间

See also: 也可以看看:

In c++ , when you say struct Node , Node [immediately] becomes a type. c++ ,当您说struct NodeNode [立即]成为一种类型。 So, you could say: 因此,您可以说:

struct Node {
    char keyLine[100];
    int occurrences;
    Node *leftChild;
    Node *rightChild;
    Node *parent;
};

struct Tree {
    Node *root;
};

int
insertNode(Tree *myTree, Node *newNode)
{
    Node *currentNode = myTree->root;
    if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
        currentNode = currentNode->leftChild;
    }
}

But, in c , it is merely in the "tag" namespace and does not define a type. 但是, c ,它仅仅是在“标签”命名空间, 没有定义类型。 Thus, you want: 因此,您想要:

typedef struct Node {
    char keyLine[100];
    int occurrences;
    struct Node *leftChild;
    struct Node *rightChild;
    struct Node *parent;
} Node;

typedef struct Tree_struct {
    Node *root;
} Tree;

int
insertNode(Tree *myTree, Node *newNode)
{
    Node *currentNode = myTree->root;
    if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
        currentNode = currentNode->leftChild;
    }
}

As an alternative, you can use a forward declaration : 另外,您可以使用前向声明

// forward declaration
struct Node;
typedef struct Node Node;

struct Node {
    char keyLine[100];
    int occurrences;
    Node *leftChild;
    Node *rightChild;
    Node *parent;
};

typedef struct Tree_struct {
    Node *root;
} Tree;

int
insertNode(Tree *myTree, Node *newNode)
{
    Node *currentNode = myTree->root;
    if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
        currentNode = currentNode->leftChild;
    }
}

Note that the struct name does not have to match the type name: 需要注意的是, struct的名字不必匹配类型名称:

// forward declaration
struct Node_struct;
typedef struct Node_struct Node;

struct Node_struct {
    char keyLine[100];
    int occurrences;
    Node *leftChild;
    Node *rightChild;
    Node *parent;
};

typedef struct Tree_struct {
    Node *root;
} Tree;

int
insertNode(Tree *myTree, Node *newNode)
{
    Node *currentNode = myTree->root;
    if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
        currentNode = currentNode->leftChild;
    }
}

To allow cross linking of your two structs, we could do: 为了允许您的两个结构的交叉链接,我们可以这样做:

// forward declaration
struct Node_struct;
typedef struct Node_struct Node;

struct Tree_struct;
typedef struct Tree_struct Tree;

struct Node_struct {
    char keyLine[100];
    int occurrences;
    Node *leftChild;
    Node *rightChild;
    Node *parent;
    Tree *tree;
};

struct Tree_struct {
    Node *root;
};

int
insertNode(Tree *myTree, Node *newNode)
{
    Node *currentNode = myTree->root;
    if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
        currentNode = currentNode->leftChild;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 结构可以具有一个成员,该成员是指向相同类型结构的指针吗? - Can a struct have a member which is a pointer to a struct of the same type? 可以使用指向结构成员的指针来访问同一结构的另一个成员吗? - Can a pointer to a member of a struct be used to access another member of the same struct? 将类型为struct的类型的struct成员初始化为null - Initializing struct member of type struct pointer to null 将结构转换为成员类型的指针 - Converting struct to pointer of member type 具有相同参数类型的结构中的函数指针 - function pointer in a struct with same argument type 使用 GetMessage 接收消息结构类型,然后分配给另一个相同的结构 - Receive a message struct type using GetMessage and then assign to another same struct 指针算术通过先前的成员地址(在同一个结构中)导致指向另一个结构成员的指针 - Pointer arithmetic result in pointer to another struct member via previous member address (in the same struct) 如何在另一个结构指针中分配给一个结构指针 - How to assign to a struct pointer in another struct pointer 将一个结构的属性复制到另一个相同类型的结构 - Copy atributes of a struct to another struct of the same type struct指针作为返回类型 - struct pointer as return type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM