对"C"项目架构指南的建议?

Sie*_*geX 19 c architecture coding-style

现在,我把头脑缠绕在'C'语言上,以至于我觉得自己足够精通编写干净的代码,我想把注意力集中在项目架构指南上.我正在寻找一个包含以下主题的好资源:

  1. 如何创建一个促进代码可维护性的界面,并且可以扩展以用于将来的升级.
  2. 图书馆创建指南.例如,我应该何时考虑使用静态库和动态库.如何正确设计ABI以应对任何一个.
  3. 头文件:分区和何时分区.何时使用1:1 vs 1:许多.h到.c的示例
  4. 任何你觉得我错过的东西,但在尝试构建一个新的C项目时很重要.

理想情况下,我希望看到一些示例项目,从小到大,看看架构如何根据项目大小,功能或客户而变化.

您会为这些主题推荐哪些资源?

Eri*_*sen 11

每当我认真编写C代码时,我都必须在其中模拟C++特性.值得做的主要是:

  • 把每个模块想象成一个类.您在标题中公开的函数就像公共方法.如果它是模块所需接口的一部分,则只在头部放置一个函数.

  • 避免循环模块依赖.模块A和模块B不应该互相调用.您可以将某些内容重构为模块C以避免这种情况.

  • 再次,遵循C++模式,如果您有一个可以对不同数据实例执行相同操作的模块,则在您的接口中创建一个create和delete函数,该函数将返回一个指向struct的指针,该指针将传递回其他函数.但是为了封装,在公共接口中返回一个void指针并强制转换到模块内部的struct.

  • 避免使用模块范围变量 - 之前描述的模式通常可以满足您的需求.但是,如果您确实需要模块范围变量,请将它们分组存储在一个存储在名为"m"的单个模块范围变量中的结构中,或者保持一致.然后在你的代码中,每当你看到"m.variable"时,你就会一眼就知道它是模块范围结构之一.

  • 为了避免头部问题,将#ifndef MY_HEADER_H #define MY_HEADER_H声明放入防止双重包括.模块的头文件.h文件应该只包含#includes所需的头文件.模块.c文件可以包含编译模块所需的更多包含,但不要将这些包含添加到模块头文件中.这样可以避免许多命名空间冲突和包含顺序问题.

  • Re:公共接口中的void指针 - 我更喜欢使用typedef的不透明结构.这样你就不需要重新投射,它提供了同样的实现保护.http://en.wikipedia.org/wiki/Opaque_pointer#C (2认同)

Nor*_*sey 8

关于架构系统的真理是永恒的,它们跨越语言边界.以下是关于C的一些建议:

  • 每个模块都隐藏着一个秘密.构建系统周围的接口隐藏信息,从他们的客户.C唯一的类型安全信息隐藏构造是指向不完整结构的指针.彻底学习并经常使用它.

  • 实现的一个接口是一个很好的经验法则.(接口是.h,实现是.c.)有时你会想要提供两个与同一个实现相关的接口:一个隐藏表示,一个暴露它.

  • 您需要命名约定.

Dave Hanson的C接口和实现是如何在C中处理这些问题的极好模型.在其中,您将了解如何设计良好的接口和实现,以及一个接口如何构建另一个接口以形成一个连贯的库.您还将获得一组优秀的入门接口,您可以在自己的应用程序中使用它们.对于你所在职位的人,我不能过高地推荐这本书. 它是C语言中架构良好的系统的原型.