C中的类型声明(概念)
一般来说,这个问题更多的是一个概念问题,而不是本质上的编码问题。当我偶然发现这些代码时,我很好奇它们是否有效。或者基本上为什么,如果有人能给我一个解释的话 以下是C中的一些类型声明:C中的类型声明(概念),c,struct,type-declaration,C,Struct,Type Declaration,一般来说,这个问题更多的是一个概念问题,而不是本质上的编码问题。当我偶然发现这些代码时,我很好奇它们是否有效。或者基本上为什么,如果有人能给我一个解释的话 以下是C中的一些类型声明: typedef struct Rec1 * Ptr1; typedef struct Rec2 * Ptr2; struct Rec1 { int data; Ptr2 next; }; struct Rec2 { double data; Ptr2 next; }; 这些应该
typedef struct Rec1 * Ptr1;
typedef struct Rec2 * Ptr2;
struct Rec1
{
int data;
Ptr2 next;
};
struct Rec2
{
double data;
Ptr2 next;
};
这些应该被允许吗?允许吗?为什么
它们有效吗
是的,它们是有效的
原因:
Ptr1
和Ptr2
作为struct Rec1*
和struct Rec2*
的类型定义
struct Rec1
和struct Rec2
作为不完整的类型,并且它们只是将Rec2
作为递归类型(通常用于创建数据结构)和Rec1
作为指向Rec2
对象的指针
Ptr1
和Ptr2
作为struct Rec1*
和struct Rec2*
的类型定义
struct Rec1
和struct Rec2
作为不完整的类型,并且它们只是将Rec2
作为递归类型(通常用于创建数据结构)和Rec1
作为指向Rec2
对象的指针
- 应该允许吗?对
- 它们是(转发类型定义)吗?对
- 为什么
- 应该允许吗?对
- 它们是(转发类型定义)吗?对
- 为什么
如果没有这种复杂、相互依赖的机制,就不可能定义数据类型。typedef只是它所引用的实际类型的别名。您可以将其视为一个宏,但它不是在编译的预处理阶段被替代的东西
只需用struct Rec1*替换所有出现的Ptr1即可生成有效代码,这是确认代码是否有效的最简单方法;) typedef只是它所引用的实际类型的别名。您可以将其视为一个宏,但它不是在编译的预处理阶段被替代的东西
只需用struct Rec1*替换所有出现的Ptr1即可生成有效代码,这是确认代码是否有效的最简单方法;) 根据语言标准,它们是有效的,因此应该被允许 现在,如果你问这一切是如何运作的,很简单 指针通常只是内存地址。如果对象由整数个字节(每个字节都有一个唯一的地址)表示,则可以有一个指向内存中任何对象的指针。我在这里说“整数”是因为你不能有一个指向结构位字段的指针(至少,你不能有一个指向那些不以字节边界开始并占用整数字节数的字段的指针) 因此,
Ptr2
只是一种预先已知大小的指针类型(如果CPU的地址空间为0到4 GB,则32位地址足以寻址每个字节,32位将是此CPU上的本机指针大小)您可以在struct Rec1
和struct Rec2
中为这样一个指针分配空间,即使这个指针指向的东西还不知道,这就是我们在讨论中的代码Ptr1
和Ptr2
被定义为不完整类型,这是它的正式名称
在语言中实现这种不完整指针类型的基本原理非常实用。如果要创建链接列表或树,它们的元素或节点必须以某种方式指向与之链接的其他元素或节点。理论上,您可以为最后一个元素(或叶节点)创建不同的元素/节点类型,然后为指向它的元素/节点类型,然后为指向该元素的元素/节点类型,依此类推。但是,如果您的元素或节点不止几个,那么这就不能很好地扩展。如果你想要一百万呢?定义一百万个几乎相同的类型充其量是不切实际的。因此,语言为您提供了避免这种情况的捷径。您还可以将next
指针声明为void*
指针,但是您需要将它们到处强制转换为struct Rect1*
或s