【问题标题】:Best practice in use of static variables in C [closed]在 C 中使用静态变量的最佳实践 [关闭]
【发布时间】:2011-11-11 14:50:30
【问题描述】:

全局变量通常被认为是一种糟糕的编程习惯

在 C 语言中,静态变量(即具有模块(文件)范围的变量)是否认为可以?

我的想法是,面向对象语言中的成员变量的危险性不能比 C 中的静态变量小很多,而且成员变量似乎被认为是一件好事。

我厌倦了通过多个函数传递参数,并且可以看到静态变量对此的吸引力,特别是如果它们是const

但我很想知道这是否令人不悦 - 以及在其多个方法中使用成员变量的大对象与包含几个使用静态变量的函数?

【问题讨论】:

  • 为什么要关闭它?这是很多程序员应该好奇的一个很好的具体问题。
  • 非常感谢在问题结束之前偷偷提供的答案 - 他们帮助我澄清了问题。
  • 令人难以置信的是,他们如何以“不具建设性”为由结束这样的问题,但在每个“建设性”的答案中,人们都会插入“但你不应该这样做你应该这样做,因为是的,这就是我们在现实世界中的做法”
  • “好”SO 问题的范围实际上相当狭窄,并且严格执行了界限。我想这也可能是我的第一个问题,版主对那些声望很低的人肯定更严厉!

标签: c variables static


【解决方案1】:

C 中的静态(文件范围)变量类似于 C++ 中的静态成员变量。

任何使用非常量静态变量在函数之间进行通信都会使这些函数不可重入和线程不安全。因此,通常最好通过参数传递信息。

非静态成员变量的一个更好的类比是结构成员。只需在结构中收集“成员变量”并将该结构作为“this”参数传递。

【讨论】:

    【解决方案2】:

    最大的区别是:成员变量可以有多个对象,每个对象都有自己的成员变量。使用模块范围静态变量,您只有一个变量实例。

    如果你想比较模块级静态变量和静态类成员变量,那么并没有太大的区别。两者都只实例化一次,只是范围和访问规则不同。

    【讨论】:

      【解决方案3】:

      静态变量的一大缺点是“副作用”,即当函数的结果不仅仅取决于输入参数时,这会使测试和调试变得更加困难。 没有副作用的函数更容易测试,因为您可以假设每次调用具有相同参数集的函数时都可以预期相同的结果。

      如果您有错误,您可以根据输入参数检查结果是否正确。如果你意识到输入参数是错误的,那么你可以在你的代码中跟踪哪里/谁是错误的参数。如果您的函数依赖于静态变量,而静态变量没有预期值,您如何跟踪/查找其变化的原因和方式?

      因此,如果您想使用常量,请使用适当的常量(#DEFINE)或将您的参数分组到一个结构中,并尽量避免使用静态变量。 (至少#DEFINE 值不会在内存中损坏)

      【讨论】:

        【解决方案4】:

        静态变量可能比全局变量稍微好一点,但也不是很多。然而,不像全局变量那样邪恶并不是什么值得称赞的!

        当您有多个线程或可重入函数时,它们是不够的。更重要的是使用它们作为参数传递机制将导致代码非常难以阅读和维护。静态变量有一些用途,但我永远不会将它们用于参数传递。在某些情况下,将参数收集到要传递的结构中会更好。

        【讨论】:

        • 线程或可重入函数不应该在没有同步对象的情况下访问静态变量,但这不是静态变量本身的错。此外,还有很多没有参数的东西,如回调函数、中断等。那么无论你是写 C 还是 C++,除了静态你别无选择。
        • @lundin 问题专门关于使用模块静态作为参数传递的替代方案。
        • 是的,那为什么要引入多线程呢? OP 没有提及代码的平台或用途。
        【解决方案5】:

        您可以使用全局变量或静态变量,但请谨慎使用。我不确定模块范围的静态变量是否比全局变量好得多。

        特别是,即使是在一个大程序中也有十几个全局变量,可能也很糟糕(但确实会发生这种情况)。

        您可能更喜欢将静态或全局数据分组到更大的struct-s 中。

        【讨论】:

        • 为什么会很差?它们是私有封装的,不会污染全局命名空间。
        • 关于品味不佳,我在考虑全局(非静态)变量。您可以通过指针传输静态变量,有时您可能会遇到一些与此相关的奇怪错误。当然,这取决于...
        【解决方案6】:

        在您尝试使用它们的上下文中,模块变量可能不是一个好主意。通过参数传递所有内容的好处是很难与您的方法调用不同步。每个方法都会做一些事情并将其中的一些组件传递给另一个方法,因此很容易跟踪 - 变量仅在方法调用期间存在。如果变量存在于其他地方,则调试变得更加困难 - 诸如使用陈旧变量之类的事情从不可能变为很有可能。

        静态变量通常用作 flags - 一个常见的变量是一个布尔值,您可以设置它以一种微妙的方式改变整个模块的模式(一个准内置的一个是 DEBUG)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-17
          • 1970-01-01
          • 2020-09-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多