struct s{
int a;
struct s b;
};
以上代码段在
时抛出错误error: field 'b' has incomplete type
struct s{
int a;
struct s *b;
};
不会出现任何错误。我不明白为什么这是指针允许但不是非指针变量!
答案 0 :(得分:5)
类成员在声明时必须具有完整的类型,以便它们的大小可用于确定类布局。
在类定义中,类本身是不完整的,因此您不能声明相同类型的成员。无论如何这都是不可能的(至少如果还有其他成员),因为班级必须比自己大。
指针是一个完整的类型,即使它指向的类型不是,所以你可以声明一个类成员是一个指向类类型的指针。
(注意:我使用“class”这个词,因为我是一名C ++程序员。我只是注意到这个问题也被标记为C,C ++已被删除。我相信答案仍然正确那个语言,如果你用“结构”取代“class”,但我不完全确定,因为它们是不同的语言。如果你只询问一种语言会更好,因为存在差异(有时是主要的,有时是微妙的)语言之间。)
答案 1 :(得分:2)
答:不完整类型是一种具有标识符但缺少确定标识符大小所需信息的类型。
要完成不完整的类型,我们需要指定缺失的类型 信息。
示例:
struct Employee *ptr; // Here 'Employee' is incomplete
要使“员工”完整,我们需要指定缺少的信息,如下所示
typedef struct Employee
{
char name[25];
int age;
int employeeID;
char department[25];
}EMP;
在你的情况下,
struct s
{
int a;
struct s b; // Structure is incomplete.
}// Till this point the structure is incomplete.
struct s b;
structure s
不完整。我们可以声明一个指向不完整类型而不是变量的指针。
答案 2 :(得分:1)
为了充分定义s,编译器需要知道s的大小。在第一个示例中,s的大小取决于s的大小,但不取决于s的大小。
在第一个例子中,通过定义,sizeof(s) = sizeof(int) + sizeof(s) + padding
。如果我们尝试为sizeof(s)
解决这个等式,我们得到0 = sizeof(int) + padding
,这显然是不可能的。
在第二个中,sizeof(s) = sizeof(int) + sizeof(s*) + padding
。如果我们假设sizeof(s*) ~= sizeof(int)
,那么sizeof(s) = 2*sizeof(int) + padding
。
答案 3 :(得分:0)
我将假设struct s **b**
中的额外星号是强调的,而不是某种疯狂的指针声明。 (请不要这样做!分析某人的代码,如果它的运行完全正确,则会更容易。)
执行此操作时,未将b
声明为指针:
struct s{
int a;
struct s b;
};
编译器不知道需要为b
字段分配多少空间,因为此时您还没有完成对struct s
的定义。事实上,编译器不可能定义这个特定的结构:无论为struct s
分配了多少字节,它都需要再添加4个字节来为int a
字段腾出空间。 / p>
声明b
是指向struct s
的指针会让事情变得更轻松:
struct s{
int a;
struct s *b;
};
无论您向struct s
添加多少个字段,编译器都知道b
字段只需要包含结构的地址,并且不会根据结构的大小而改变本身就是它。