更新时间:2023-11-28 22:55:04
假设问题中的代码是这样写的:
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;
那么名称Node
将是struct Node
的同义词(别名).(对于任何 typedef XY;
,Y
成为 X
类型的同义词——在你的情况下,X
是 struct Node
和 Y
将是节点.)
Then the name Node
would be a synonym (alias) for struct Node
. (For any typedef X Y;
, Y
becomes a synonym for type X
— where in your case, X
would be struct Node
and Y
would be Node.)
演员阵容:
currentNode = (Node *)currentNode->leftChild;
将是不必要的(但大部分是无害的),因为它是一个空操作——类型 struct Node *
和 Node *
将是同一个指针的两个名称类型.类似的:
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. 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;
typedef struct Node_struct {
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
现在我们使用了三个类型名称:struct Node_struct
、struct Node
和 Node
.在这种情况下,struct Node_struct
和 Node
是同义词,而 struct Node
是一个不完整的结构类型(或者,至少,它是不完整的通过问题中的任何代码).它与 struct Node_struct
或 Node
完全无关,除非巧合的是它在结构内部被引用.
Now we have three type names in play: struct Node_struct
, struct Node
, and Node
. 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). It is wholly unrelated to either struct Node_struct
or Node
except by the coincidence that it is referenced inside the structure.
使用这种表示法,强制转换是必要的",因为您在指向不相关类型(struct Node *
和 struct Node_struct *
)的指针之间进行转换.幸运的是,有规则说所有结构类型指针都是可以相互转换的,并且必须具有相同的大小和对齐要求(C11 §6.2.5 类型¶28 和 §6.3.2.3 指针¶7).
With this notation, the casts are 'necessary' because you're converting between pointers to unrelated types (struct Node *
and 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).
但是您应该删除 Node_struct
的 _struct
部分,以使本答案第一部分的规则适用.在 C 中,使用 (IMO) 是明智的:
But you should drop the _struct
part of Node_struct
to make the rules of the first part of this answer apply. In C, it is (IMO) sensible to use:
typedef struct SomeTag SomeTag;
以便您随后可以使用 SomeTag *
等.第一个 SomeTag
在标签名称空间中,不会与第二个 SomeTag
冲突>,它在普通标识符命名空间中.参见 C11 §6.2.3 标识符的命名空间.
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. See C11 §6.2.3 Name spaces of identifiers.
另见:
struct uperms_entry
类型?struct
、union
、enum
标记与类型名称相同,有任何错误吗?struct uperms_entry
types in this code?struct
, union
, enum
tag same as type name bad in any way?