【问题标题】:Typedef struct vs struct? |Definition difference|Typedef 结构与结构? |定义差异|
【发布时间】:2014-02-06 01:58:30
【问题描述】:

以下块在 main() 之外和每个函数之前(全局范围)

第一块:

struct flight {
    int number;
    int capacity;
    int passengers;
};

有了这个你可以创建数组、指针、变量,而不是写} var;(它只定义了这个自定义数据类型的一个变量(struct flight))

第二块:

typedef struct flight {
    int number;
    int capacity;
    int passengers;
} flight;

声明这会创建一个数据类型flight,而不必一直编写struct flight
我的问题是为什么 typedef 需要在块末尾第二次写入 flight ?
这有点令人困惑(看起来只是该数据类型的变量)

【问题讨论】:

  • 考虑:typedef unsigned char uint8_t;——引入的类型名称是uint8_t,它的别名是unsigned char。现在考虑:typedef struct flight flight;——引入的类型名称是flight,它的派生类型是struct flight。如果之前没有提到struct flight,这也引入了struct flight类型作为不透明的结构类型。随后您可以使用struct flight { ... }; 定义类型。 C++ 不需要结构类型的 typedef,但原始 C 没有这种功能,也从未添加过。
  • C 中没有全局作用域,我想你的意思是 文件作用域
  • @ouah:C 中没有所谓的全局作用域,但对于标准所称的文件作用域来说,它并不是一个糟糕的名字。 (是的,称之为“文件范围”更好。)
  • @KeithThompson 这不仅仅是一个术语问题:如果存在“全局变量”或“全局范围”,我希望在此范围内声明的对象将在所有翻译单元的范围内可见。
  • @Brandin 对我来说,解决方案(尽可能)是针对这一特定点遵循 Linux 内核样式,而不是使用 typedef 来表示结构类型。

标签: c struct typedef definition


【解决方案1】:

我的问题是为什么 typedef 需要在块的末尾再次写入一次 flight ?

当您声明时:

typedef struct flight{
    int number;
    int capacity;
    int passengers;
 }flight;

你实际上声明了两件事:

  • 一种新的结构类型struct flight
  • struct flight 的类型别名 flight

typedef 的类型别名出现在声明末尾的原因与任何普通声明一样,是因为由于历史原因,typedef 被置于与存储类说明符相同的说明符类别中(如 @987654327 @ 或 auto)。

请注意,您可以只声明:

typedef struct {
    int number;
    int capacity;
    int passengers;
}flight;

如果您打算只使用类型标识符flight,则不带标签名称。

【讨论】:

  • +1。你说'如果你打算只使用';你可以说“你只能使用”——在无标签版本中没有struct flight 可用(除非它是一些不相关的结构类型,这将是糟糕的编码风格,但远非不可能)。
  • 没有标签名称,flight 类型不能有flight* 类型的成员(因为标识符flight 不够早可见)。
  • 值得注意的是,很多软件经常使用符号:typedef struct flight { ... } flight_t,有时也使用typedef struct flight_s { ... } flight_t
  • @Dogbert 但在 POSIX 系统上 *_t 如果包含 POSIX 使用的任何标头,则实现保留名称。
  • @ouah 您能否详细说明一下,或发布链接?我做了相当多的嵌入式开发(主要是驱动程序开发),并没有遇到任何妨碍使用这种约定的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
相关资源
最近更新 更多