关于C#:我什么时候应该输入structdef struct to指向struct?

When should I typedef struct vs. pointer to struct?

我不是低层非面向对象编程语言的专家,我正在为工作中的项目编写一些C代码。我正在尝试创建一些合适的抽象数据类型来使用,在谷歌搜索中我发现人们使用基于结构的ADT有两种方式。有些人将数据类型定义为结构:

1
2
3
typedef struct adt {
    //content here
} adt;

并在头文件中向世界公开。

其他人将数据类型定义为指向结构的指针:

1
2
3
4
5
6
7
8
// In .c file:
typedef struct adt_s {
    //content here
} adt_s, *adt;


// In .h file:
typedef struct adt_s *adt;

我理解这种方法允许您在不向外界提供任何关于结构内部内容的知识的情况下对结构进行typedef,因此程序员只能使用同一头文件中提供的函数来操作此数据类型。

有没有其他的理由比另一个强?对于何时将ADT定义为结构,以及何时将它们定义为指向结构的指针,是否有一个通用的"经验法则"?


您也可以转发声明不带typedef的结构-唯一区别是:

  • 无论使用关键字struct还是不使用关键字struct,界面看起来都更干净。
  • 无论有没有显式指针*,接口看起来是否更干净

如。

1
2
3
4
5
6
7
struct S1;
typedef struct S2 S2;
typedef struct S3_s *S3;

void foo1(struct S1 *arg);
void foo2(S2 *arg);
void foo3(S3);

显然,这只适用于接口头中的前向声明结构。

如果您不首先隐藏结构实现,那么在S1S2之间进行选择是一个偏好(或一致性)问题。我不会使用S3,除非它是一个真正不透明/隐藏的类型。

个人偏好是对大/复杂聚合使用S1(explicit struct keyword),对小结构使用S2,您可能将其视为值,而不总是通过指针传递。YMMV。


阅读Linus Torvalds的文章第5章:typedef


藏匿或不藏匿的决定完全取决于你作为图书馆设计师的能力。如果你想保留将来随意改变你的struct的权利,你不应该让它的任何成员暴露在"世界"之下。如果你提供一个struct作为一开始与你的图书馆交流的手段(例如,一个struct代表一个三维的点),那么你就不能把它的成员隐藏起来,因为它会破坏目的。