C++ 结构上的差异?
这两者之间的区别是什么:C++ 结构上的差异?,c++,c,data-structures,C++,C,Data Structures,这两者之间的区别是什么: typedef struct part { int a; } Part; 及 我知道第二个是“匿名”的,但它们不同吗?在这两种情况下,您都定义了一个结构类型,以及一个名为Part的类型别名,它引用了该类型 在第一种情况下,还定义了结构名部分< /> >,因此结构类型也可以被称为“代码>结构部分< /COD>,或者只是C++中的代码>部分。 在第二种情况下,结构本身没有名称(因此为“匿名”),只能由类型别名引用。由于该别名仅在结构定义之后声明,因此该结构不能引用
typedef struct part
{
int a;
} Part;
及
我知道第二个是“匿名”的,但它们不同吗?在这两种情况下,您都定义了一个结构类型,以及一个名为
Part
的类型别名,它引用了该类型
在第一种情况下,还定义了结构名<代码>部分< /> >,因此结构类型也可以被称为“代码>结构部分< /COD>,或者只是C++中的代码>部分。
在第二种情况下,结构本身没有名称(因此为“匿名”),只能由类型别名引用。由于该别名仅在结构定义之后声明,因此该结构不能引用自身。除了Mike Seymour answer之外,下面是一个示例,说明原因: 例如链表
// this works
typedef struct part {
struct part *next;
} Part;
// this doesn't work
typedef struct {
struct Part *next;
} Part;
// neither this
typedef struct {
Part *next;
} Part;
除了@EoiFirst的答案
typedef struct part
{
int a;
struct part *next;
} Part;
这是有效的,因为next
是指向struct part
的指针,因此它的大小与指针类型相同
C是一种类型化语言,因此编译器知道next
的类型,在struct part
完全定义之后,它将能够确定下面的代码是否有效。它知道next
是一个指向struct part
的指针,它有一个字段inta
void test(struct part *p) {
if (p != NULL && p->next != NULL) {
printf("%d\n", p->next->a); // this is valid
}
}
你可以申报
typedef struct part
{
int a;
void *next;
} Part;
struct part
的大小仍然与上面声明的相同。现在next
是指向任何东西的指针,上面带有test()
的代码编译时会出错
warning: dereferencing 'void *' pointer
error: request for member 'a' in something not a structure or union
您需要编写printf(“%d\n”,((struct part*)p->next)->a)代码>
此外,您将无法申报此信息
typedef struct part
{
int a;
struct part nested;
} Part;
您将得到一个编译器错误
error: field 'nested' has incomplete type
@MikeSeymur和其他人给出了很好的答案。我想补充一个没有人明确说明的要点
在大型项目中,重要的是尽量减少标题,并避免#include
-在绝对必要的情况下隐藏其他标题
假设您的结构是在某个头文件part.h
中定义的。定义的命名结构类型Part
允许使用您的代码的其他人通过使用所谓的“转发声明”跳过#包括“Part.h”:
在匿名结构的情况下,文件foo.h被迫包含文件part.h
//file foo.h forced to #include part.h because "part" is typedef of anonymous type
#include "part.h"
void foo(part* p);
在遗留代码中,这些匿名类型常常导致这样一种情况,即每个头都包含如此多的其他头,以至于维护和代码重用成为一场噩梦
一般来说,我建议不要使用匿名类型,除非您确切地知道自己在做什么(在很多情况下,它们完全可以,例如作为其他类型的实现成员)。在第二种情况下,您将无法将该类型称为结构部分
。当你做一个自引用(列表或树)数据结构时,差异是显著的,其中“代码>结构部分*子< /代码>必须是Stult.@ Selvay-Debug的一个成员。它也是有效的C++代码,而OP并没有说它们只关心C。这两个结构在运行时没有区别。如果这是你问题的主要要点。它们有不同的名称,与struct A{}
和struct B{}
有相同的区别,但是只要你能引用它,你为什么会在乎如何引用它呢?@dfg:你只能在结构定义中引用它(在部分
声明之前)按结构名称-并且只有当它有一个时。为什么?做出这样的限制有什么意义?为什么不允许你自己引用它?@dfg:一般来说,你只能在声明名称后才能使用它们。这种限制的要点是允许在一个过程中解析程序,从而使编译比其他过程快得多。为什么?做出这样的限制有什么意义?为什么不允许你做第二件事呢?在第二个例子中,编译器怎么知道什么是Part(在第二个例子中)当它还没有定义时?但是当它的定义还没有完成时,编译器怎么知道struct Part*next
是什么呢?@dfg编译器不需要知道类的定义,只要它知道它在那里。这就像向前声明某些东西一样。@dfg指针或引用不需要完整的类型定义。您只需要知道类型是否存在。
//file foo.h knows struct Part "by name only"
struct Part;
void foo(struct Part* p); //in pure C, works for C++ too
void bar(Part* p); //in C++
//file foo.h forced to #include part.h because "part" is typedef of anonymous type
#include "part.h"
void foo(part* p);