c - C 类型语法如何避免循环定义?
问题描述
此陈述和示例来自Nick Parlante 的 Essential C。
C 类型语法的一个好处是它避免了当指针结构需要引用自身时出现的循环定义问题。以下定义定义了链表中的一个节点。请注意,不需要预先声明节点指针类型。
struct node {
int data;
struct node* next;
};
struct node*
当它仍在结构节点内时,C 编译器如何知道它是什么。
还有另一个循环定义的例子,其中一个类型struct treenode*
在被进一步定义之前被使用。
typedef struct treenode* Tree;
struct treenode {
int data;
Tree smaller, larger; // equivalently, this line could say
// "struct treenode *smaller, *larger"
};
C 编译器如何知道struct treenode*
尚未定义的内容。
相关SO问题:当结构中的指针指向结构本身时,C如何解析循环定义?(这是相关的,它不回答“如何”的问题)。
编辑:我假设 C 编译器能够一次性完成此操作。
解决方案
C 标准在§6.2.5 Types ¶28中规定(强调):
指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。48)同样,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求。所有指向结构类型的指针都应具有彼此相同的表示和对齐要求。所有指向联合类型的指针都应具有彼此相同的表示和对齐要求。指向其他类型的指针不需要具有相同的表示或对齐要求。
因此,C 编译器知道如何处理任何结构指针类型,因为所有结构指针必须具有相同的表示和对齐要求。无论您嵌入 astruct node *
还是 a都适用struct value *
——无论编译器之前是否知道 type struct value
。这也有助于“不透明类型”——您可以拥有指向编译器不知道结构内容的结构类型的指针。
你不能做的struct node
是struct node *
在struct node
. 您可以将以前已知的结构类型作为值嵌入到结构中。您还可以在另一个中定义结构类型:
struct node
{
int data;
struct node *next;
struct key_value
{
int key;
char *value;
} kv;
};
与 C++ 不同,该struct key_value
类型可用而没有范围问题——它不限于在 type 中使用struct node
。这不是好的编码习惯,但它是允许的。
推荐阅读
- python - 如何在 django 上创建进度条的天数
- c# - Azure AD (MSAL) 身份验证不适用于 ASP.NET 核心 API
- github - Github 预定提醒 - 一些 Slack 提及没有关联
- java - 在 Java 中创建对 API 的请求
- python - 使用分布式训练(例如 DDP)时如何在 pytorch 中修复 SIGSEGV?
- mediawiki - 在 Wikibase 中添加更多语言
- python - 您能否让我知道在 selenium python 浏览器的网络选项卡中捕获除 200 以外的状态代码的代码吗?
- javascript - 如何防止使用正则表达式添加一定数量的字符?
- excel - 如何使用具有一系列值的自动填充/填充
- javascript - 如何水平滚动div内的元素javascript / jquery