这两个结构声明有什么区别?

4da*_*ong 32 c c++ struct typedef declaration

我对不同教程中的这两种结构感到困惑:

typedef struct complex {
    float real;
    float imag;
} COMPLEX;

typedef struct {
    float real;
    float imag;
} COMPLEX;

COMPLEX c1;
Run Code Online (Sandbox Code Playgroud)

他们都正确吗?为什么?struct 之前是否需要添加小写字母complex?一般情况是怎样的?

Som*_*ude 31

对于第一个,您可以使用类型别名COMPLEXstruct complex.

对于第二个,你有一个匿名结构,只能与 type-alias 一起使用COMPLEX

话虽如此,在 C++ 中,任何结构名称也是类型名称,可以直接用作类型:

struct complex { ... };
complex c1;
Run Code Online (Sandbox Code Playgroud)

  • 仅当无法以其他方式解析时,才会在 C++ 中查找结构标记。因此,结构标签并不完全是类型名称。 (5认同)

Dev*_*lar 18

typedef struct complex{
    float  real;
    float imag;
}COMPLEX;
Run Code Online (Sandbox Code Playgroud)

这是一个struct complex已被类型定义为 的COMPLEX。您现在可以同时使用struct complex c1;COMPLEX c1;。当您标记此问题 C++ 时,您还可以使用complex c1;as struct(因此,typedef避免它)在 C++ 中是不必要的。

typedef struct {
    float  real;
    float imag;
}COMPLEX;
Run Code Online (Sandbox Code Playgroud)

这是一个未命名的结构,类型定义为COMPLEX。您现在可以使用COMPLEX c1;.

到目前为止,这两个 (C) 结构之间的差异。

当您标记此问题 C++ 时,正确的做法是使用 C++ 标头的功能<complex>

std::complex< float > c1;
Run Code Online (Sandbox Code Playgroud)


Vla*_*cow 10

首先,没有其他人在回答您的问题时所写的匿名结构。存在一个别名为 COMPLEX 的未命名结构(没有标记名称的结构)

\n
typedef struct {\n    float real;\n    float imag;\n} COMPLEX;\n
Run Code Online (Sandbox Code Playgroud)\n

在 C++ 中,术语未命名类/结构的记录如下(C++ 14 标准,9 个类)

\n
\n

其类头省略类头名称的类说明符定义了未命名的类。

\n
\n

至于概念匿名结构,则在 C 中按以下方式定义(6.7.2.1 结构和联合说明符,p.#1)

\n
\n

13 没有标记的结构类型的未命名成员称为\nanonymous 结构;没有标记的联合类型的未命名成员\n称为匿名联合。匿名结构或联合的成员被视为包含结构或联合的成员。如果包含的结构或联合也是匿名的,则这会递归地应用。

\n
\n

这是匿名结构的示例

\n
struct A\n{\n    struct { int x; int y; };  // <== anonymous structure\n    int z;\n};\n
Run Code Online (Sandbox Code Playgroud)\n

请记住,与 C 相反,C++ 中不存在匿名结构这样的概念。在C++中只有匿名联合的概念。

\n

至于你的问题

\n
\n

他们都正确吗?为什么?struct 前是否需要添加小写\nof 复合体?一般情况是怎样的?

\n
\n

那么两个 typedef 声明都是正确的。并且不需要使用完全小写的名称复合体作为结构标记。您还可以使用大写名称 COMPLEX 作为结构标记。

\n
typedef struct COMPLEX {\n    float real;\n    float imag;\n} COMPLEX;\n
Run Code Online (Sandbox Code Playgroud)\n

在这个结构声明中

\n
typedef struct {\n    float  real;\n    float imag;\n}COMPLEX;\n
Run Code Online (Sandbox Code Playgroud)\n

声明了一个没有标签名称的结构。所以你只能通过它的别名来引用它COMPLEX

\n

在 C 结构中,标记名称有自己的名称空间,不会与其他名称空间中的标识符名称冲突。

\n

来自 C 标准(6.2.3 标识符的名称空间)

\n
\n

1 如果特定标识符的多个声明在翻译单元中的任何点\n可见,则语法上下文\n会消除引用不同实体的使用的歧义。因此,不同类别的标识符有不同的名称空间,如下所示:

\n

\xe2\x80\x94 关键字 struct、union 或 enum 的结构、联合和枚举的标记(通过紧跟其后的 any32 消除歧义);

\n
\n

例如,考虑以下程序。

\n
#include <stdio.h>\n\ntypedef struct {\n    float  real;\n    float imag;\n} COMPLEX;\n\nint main(void) \n{\n    int COMPLEX;\n    COMPLEX c = { 0.0f, 0.0f };\n    \n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译器将发出错误,因为局部变量 COMPLEX 的声明隐藏了文件范围中声明的未命名结构的别名。

\n

但是如果你会写

\n
#include <stdio.h>\n\ntypedef struct COMPLEX {\n    float  real;\n    float imag;\n} COMPLEX;\n\nint main(void) \n{\n    int COMPLEX;\n    struct  COMPLEX c = { 0.0f, 0.0f };\n    \n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

那么局部变量的名称 COMPLEX 不会与结构体的标记名称 COMPLEX 冲突。C编译器只能发出声明变量未使用的消息。

\n

另一个重要的区别是,有时您需要在结构定义本身中引用声明的结构说明符。

\n

例如,如果你想在 C 中声明一个单链表,你需要编写

\n
typedef struct Node\n{\n    int data,\n    struct Node *next;\n} Node;\n
Run Code Online (Sandbox Code Playgroud)\n

没有标签名称,例如

\n
typedef struct \n{\n    int data,\n    struct Node *next;\n} Node;\n
Run Code Online (Sandbox Code Playgroud)\n

编译器将此结构定义视为两个不同类型说明符的声明:具有别名 Node 的未命名结构和另一个具有标记名称 Node 的结构。这些类型不兼容。

\n

对于 C++,您可以使用结构标记的名称而不指定关键字struct

\n

例如

\n
struct complex{\n    float  real;\n    float imag;\n};\n\nstruct complex c1;\ncomplex c2;\n
Run Code Online (Sandbox Code Playgroud)\n

您还可以在其定义中引用结构说明符,而无需使用关键字 struct,因为(C++ 15 标准,9 个类)

\n
\n

2 在看到类名后,类名会立即插入到其声明的作用域中。类名也被插入到类本身的范围中;这被称为注入类名。

\n
\n

例如

\n
struct Node\n{\n    int data,\n    Node *next;\n};\n
Run Code Online (Sandbox Code Playgroud)\n

但变量或函数的声明可以隐藏结构的声明。在这种情况下,您需要使用关键字 struct。这种使用带有关键字 struct 的名称在 C++ 中称为详细类型说明符。

\n

例如

\n
struct complex{\n    float  real;\n    float imag;\n};\n\nint complex;\nstruct complex c;\n
Run Code Online (Sandbox Code Playgroud)\n

如果不指定关键字 struct,编译器将发出错误,因为整型变量的声明隐藏了结构的声明。

\n

注意,很多程序员甚至不知道 C 和 C++ 中的 typedef 也可以这样重写

\n
struct COMPLEX {\n    float  real;\n    float imag;\n} typedef COMPLEX;\n
Run Code Online (Sandbox Code Playgroud)\n