【问题标题】:How to avoid globals in C?如何避免C中的全局变量?
【发布时间】:2011-03-24 03:05:10
【问题描述】:

作为初学者,我到处阅读以避免过度使用全局变量。那么该怎么做呢?我的低技能失败了。我最终会传递大量的结构,而且它比使用全局变量更难阅读。啊,我的代码一团糟,有什么好的书/文章推荐可以指导这个问题/应用程序结构设计吗?

【问题讨论】:

  • 这里很难说一般的东西。一般而言,有一些关于结构化编程的书籍可能会有所帮助,但如果您在某个特定的地方看到问题,如果您向我们展示一些签名和调用以了解您想要实现的目标,可能会更容易。您可以剥离其余代码。
  • 使用本地人:) ...尽可能使用通过引用传递...

标签: c globals


【解决方案1】:

根据变量的作用,全局作用域可能是最佳作用域。 (认为​​标志表示中断已经到达,并且应该在计算循环中间的方便时间处理。)

通过使用全局变量,小型实用程序通常会感觉更干净(我特别想到小型语言解析器);但这使得将来将小型实用程序集成到更大的程序中变得更加困难。总会有取舍。

但很有可能“正确”的数据组织不会觉得那么麻烦。如果您在此处发布代码,有人可能会建议更简洁的布局,但真正的问题是当代码超出易于理解的小样本时。

我有很多最喜欢的编程风格书籍,但我认为解决这种情况的最好方法是The Elements of Programming Style,作者 Kernighan 和 Plauger。它很老,很难找到,但是很短,很甜,很值得在某个地方找到。

它没有那么短,也没有那么甜美,但仍然值得找到Code Complete, 2nd edition。它更详细,提供更多代码,并提供设计软件所涉及的更多多样性。这很棒,但可能更令人生畏。

没有什么比学习大师更重要的了:Advanced Programming in the Unix Environment, 2nd Edition 中的代码非常棒,值得每一个小时的学习。

当然,经验总是有的,但这需要时间来获得。从自己的错误中吸取教训往往比从别人的错误中吸取教训更有效。所以坚持下去。 :)

【讨论】:

  • Kernighan 和 Plauger 的书很棒(我们的作品有一个副本,我想我最近在 ebay 上看到它以超过 100 英镑的价格出售!)。一本较新的书(涵盖 C/C++ 和 Java)是 Kernighan 和 Pike 的 The Practice of Programming。和其他 Kernighan 的书一样,它简短、甜美且易于阅读和阅读。 en.wikipedia.org/wiki/The_Practice_of_Programming
【解决方案2】:

我建议 Yourdon 和 Constantine 的结构化设计。一本按照计算机标准的旧书(它有涉及磁带的示例!)但对您遇到的问题非常合理。

【讨论】:

    【解决方案3】:

    您可以使用以下两个选项来改善您的情况:

    1. 对于只读结构,具有可以使用 const 指针控制对数据的访问的函数:

      结构我的结构;

      const my_struct* GetMyStruct(void) const;

    2. 通过将全局结构声明为静态来限制其暴露。这样它就只有文件范围:

      静态 mystruct myStructInstance;

    【讨论】:

      【解决方案4】:

      如果您的程序是那种“小”项目,其中全局变量感觉不那么糟糕,但您认为将来可能需要将其集成到更大的项目中,一个非常简单的解决方案是添加一个每个函数的上下文指针参数并将所有“全局”变量存储在其中。如果你总是给它起同样的名字,你甚至可以做这样的事情:

      #define current_filename   context->current_filename
      #define option_flags       context->option_flags
      

      等等。并且您的代码看起来几乎与使用全局变量的外观相同,只是您可以在单个程序中拥有它的多个实例,将其集成到库中,等等,而无需大惊小怪。只需将这些定义保存在源模块使用的私有标头中,而不是公共接口标头中。

      【讨论】:

        【解决方案5】:

        @PeterK 问题是结构本身总是在 C 书籍中呈现为容器,可以多次声明/传递给不同的函数,这可能会让我感到困惑,我从未想过将其用作简单的一个实例全局容器(这可能使我的代码更具可读性)。

        我正在编写 3 相电机控制应用程序来控制 1 个电机。 根据您写的所有内容,请检查我目前解决问题的想法是否正确:

        1. 根据函数 ex. 将一些全局信息打包在结构中。 (sInverterState、sButtonsState、sInverterParameters 等)
        2. 如果我编写菜单 UI,我可以在 C 文件中使用静态变量,并且当我只有 1 个 LCD 时不必关心传递结构。我不想让它看起来像 GTK++。
        3. 我现在还不适合编写可重入代码,而且为此目的过度。
        4. 在 IT 领域接受适当的教育。

        我最终可能会得到很多全局变量,但至少它们的包装和可读性都很好。

        【讨论】:

        • 听起来你的直觉很好。如果您将与电机相关的所有数据放入一个结构中,您可以将指向 struct motor 的指针传递给需要它的函数,然后通过存储数组轻松移动到多个电机struct motor 结构,并在将来轻松传递指向数组中正确元素的指针。目前还没有必要使用struct motor 的数组,但是当时机成熟时,很容易进行这种转换。如果都是全局数据,则需要重写所有函数来使用参数。
        猜你喜欢
        • 2012-12-19
        • 2010-12-22
        • 1970-01-01
        • 2016-03-19
        • 2012-02-02
        • 2015-12-26
        • 1970-01-01
        • 1970-01-01
        • 2011-04-10
        相关资源
        最近更新 更多