繁体   English   中英

我们声明结构的两种方式有什么区别?

[英]What is the difference between the two ways we declared a struct?

作为C ++的初学者,我正在学习链表和其他数据结构。 在线查看了一些实现后,我发现了这两种定义struct的方法。 两者有什么区别。 在一个中,我们在下一个指针之前添加“struct”,而在一个中我们不添加。

方式1:

struct node
{
   int data;
   node *next;
};

方式2:

struct node
{
   int data;
   struct node *next;
};
struct node *next;

仅在C代码中是必需的。 在C中,做:

node *next;

不被允许。 但是,在C ++中,您可以使用这两种方法。 在这种情况下,它们之间没有区别。

只有在存在某种歧义或者尚未定义struct时,唯一需要在C ++中使用struct关键字进行声明的时间。 (第一个例子是stat函数,它是POSIX系统上的函数 struct )。

两者有什么区别。

不同之处在于后者(称为详细类型说明符 )声明该node是结构。

在这种情况下,声明该node是一个结构是多余的,因为它已经被声明:

struct node
^^^^^^^^^^^ <-- node is a struct
{
   int data;
   node *next;
};

一个存在差异的案例:

struct a {
    //b* pointer;      // oops, we don't know what b is
    struct b* pointer; // OK, b is a struct
};

struct b{};

通常并非绝对必须使用精心设计的类型说明符,因为可以使用单独的声明:

struct b;

struct a {
    b* pointer;
};

struct b{};

他们之间的选择是个人偏好。


我说通常是因为有时你需要它来消除类型中同名变量的歧义:

int foo;
struct foo{};

int main()
{
    foo = 10;            // refers to int
    struct foo instance; // refers to the struct
}

对于多个事物使用相同的名称通常是一个糟糕的设计,所以这不是很典型。


最后,有时需要编写可以包含在C和C ++中的头文件。 此标头必须使用两种语言的公共子集。

在C中, node不是类型名称,而是结构的标记 在C中有必要使用struct关键字引用struct标记。

第二个版本在C中是必需的,但在C ++中是坏的样式,并且在C ++中几乎没有任何情况你实际上必须添加这样的关键字。

请注意,您不必在C ++中编写自己的链接列表实现,除非它是出于学术学习目的。 使用std::liststd::forward_list

在你的情况下,没有任何区别。 但是,请考虑以下示例:

struct foo { struct node* f; };   // <- this is fine
struct foo_broken { node* f; };   // <- wont compile

struct node { };

int main() {
    foo f;
    //foo_broken g;
}

放置关键字struct允许您在声明node之前声明成员。 如果没有struct ,编译器将发出错误(对于foo_broken ):

error: ‘node’ does not name a type

也就是说,放置关键字struct就像一个前向声明。 要使用foo您需要提供node声明,但它可以在声明foo

这是因为C ++源于C和C的语法,并且语言保留了两种类型的语法,即使不再需要显式使用struct来声明变量的类型。 在某些情况下,即解决不同类型/功能/等之间的歧义。 同名,它会有所作为。 此外,通过在C ++中保持此语法有效,它可以帮助人们将C代码移植到C ++而不会引入错误。

在C中,默认情况下,您必须始终将struct关键字放在struct的名称前面。 所以只有方式#2才有效C:

struct node
{
    int data;
    node *next; //error in C!
};

struct node
{
    int data;
    struct node *next; //compiles
};

但是你经常会在C代码中看到struct声明是配对的typedef ,以便创建新的类型,例如:

typedef struct node_t
{
    int data;
    struct node *next;
} node;

这将允许node用作前面没有struct的类型。 在C ++中,它有效地为代码中的所有structclass类型自动化了这个typedef ,这就是为什么你可以使用structclass名而没有适当的限定符。

C ++中的两个声明没有区别

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM