C - 在结构中包装全局变量?

电器工程 C 固件
2022-01-18 03:39:11

关于 C 的固件样式问题。

我有一些我正在整理的遗留代码。令人讨厌的特性之一是全局变量分散在源文件中。我可以让其中一些成为当地人,这很好。不过,剩下的怎么处理。我喜欢创建一个结构并将它们放入其中。

我知道在访问它们时理论上存在另一个级别的间接性,但是从风格 POV 来看,这比将它们放在文件 globals.c 和/或 globals.h 中更好还是更差?

4个回答

拥有像“globals.h”或“includes.h”等“超级头”文件是众所周知的坏习惯,因为除了全局变量一开始就不好之外,这还会在每个文件之间产生紧密的耦合依赖。项目中的单个不相关文件。

假设您有一个 PWM 驱动程序和一个 RS-232 调试打印模块。您想要获取 RS-232 调试打印模块并在另一个项目中重新使用它。突然间,您发现自己需要一些 PWM.h,但您不知道它是什么或需求来自何处。你会发现自己在问为什么你需要一个 PWM 驱动器来运行 RS-232。

然后我们甚至还没有考虑过这个凌乱的全局结构的重入。让我们甚至不要那样做。


解开全球意大利面条的正确方法是这样的:

  • 首先使用变量吗?如果没有,请删除。(这很常见)
  • 可以将变量移动到函数内的本地范围吗?
  • 可以.c通过制作将变量移动到本地文件范围static吗?.c您可以通过实现 setter/getter 函数来减少从文件外部对其的访问吗?

如果上述所有方法都失败了,那么您发现自己查看的变量应该是寄存器映射的内存映射硬件寄存器部分,或者是在维护期间添加的一些实时关键脏修复。

它可以定义一个您实例化为单个全局变量的结构。对“the_global.the_var”形式的访问不会增加运行时开销,并且可以澄清它确实是一个全局的。正如https://stackoverflow.com/questions/2868651/includes-c-header-file-with-lots-of-global-variables所提到的,它使您免于单独的声明和定义。

就个人而言,我不会费心制作一个结构,而是更喜欢将全局变量排序到我认为它们在逻辑上属于的头文件中,并为每个头文件使用一个公共前缀。示例:文件 calculate.h 声明“extern int calc_result;” 并计算.c 定义“int calc_result;”

其他变量逃脱了文件本地,即“静态int结果;” 在 .c 文件中。

由于您有遗留代码,我猜除了整理它之外您不会做很多工作,我会说,使结构清晰的最快解决方案是最好的。

如果你不能摆脱全局变量,我会说你应该只在它们实际上相关的情况下将它们打包在一个结构中。如果没有,那么我会将它们分开或放在较小的结构中。

另外,我也不喜欢 globals.h 文件。将它们放在最属于它们的源文件的顶部。这样,在浏览代码时,您可能会留在您所在的地方或前往您可能想去的地方。

实际上,这并不是更好,唯一的好处是您“知道”哪些是全球性的。因此,您将所有全局变量放在一个地方,但它们仍然分散在各处。

C

对于每个全局:

  • 找到创建或使用它的初始文件。
  • 在该文件中使其成为静态
  • 如果全局在许多地方使用,请从其他文件外部使用它(使用extern关键字)。
  • 但最好的方法是将变量传递到需要它的地方。

C++

对于每个全局:

  • 找到创建或使用它的初始位置。
  • 找到最适合的课程。
  • 将其移至该类(作为字段,连接到对象)。
  • 现在创建一个 Get/Set 方法(函数)。Set 方法最好是受保护的或私有的)。
  • 除了 Get 和 Set 方法,您还可以通过方法参数传递它们。
  • 使用其他类的 Get/Set 方法。
  • 在某些情况下,您会看到它不能是类的字段,例如当只能有“一个”时。在这种情况下,请使用 Singleton 设计模式。(请注意这一点;它仍然是一种全球性的,因此请确保将来您永远不会制造更多它们;否则它是变相的全球空间)。