C语言中静态全局变量和非静态全局变量的区别

6
在C语言中,“静态全局变量”和“非静态全局变量”有什么区别?
请用一些示例来解释它们的不同之处。
(因为全局静态变量和普通全局变量都在整个程序运行期间保持活动,并且可以在任何块中使用,所以我很困惑如何区分它们。)有人能用代码解释吗?

阅读您最喜欢的C资源中关于关键字“static”的简单介绍将揭示答案。 - Eugene Sh.
基本上,static 全局变量不能在定义它的文件之外通过名称引用;非 static 全局变量可以在除了定义它的源文件之外的其他源文件中通过名称引用。如何使用 extern 在源文件之间共享变量? 相当详细地涵盖了非 static 的情况(甚至有点啰嗦)。static 的情况很简单——该变量可以在定义它的源文件中通过名称访问,而在任何其他源文件中都无法访问。 - Jonathan Leffler
如果你感到困惑的是英语中的“global”和“[non-]static”这些词可以任意排列,那么这句话的意思是相同的。 - Paul Ogilvie
@Jonathan-Leffler,可能是因为英文让他感到困惑了。您能否撤销您的编辑并恢复那一部分呢? - Paul Ogilvie
你可以撤销它。我不认为这是一个问题,但如果你认为是的话,你可以修复它。 - Jonathan Leffler
1个回答

26

基本上有四种情况:

  • 在函数外声明,不带static
  • 在函数外声明,带static
  • 在函数内声明,不带static
  • 在函数内声明,带static

让我们依次讨论这些情况。

在函数外声明,不带static

这是一个传统的全局符号。您可以从任何源文件中访问它(虽然在其他源文件中,您通常需要使用extern声明)。

在函数外声明,带static

这就是你所问的“静态”全局变量。只能在定义它的源文件中访问它。它对该源文件“私有”,但您可以从该源文件中的任何函数中访问它(实际上是在声明之后的任何函数中)。像任何全局变量一样,它会在程序生命周期内保持其值。

在函数内声明,不带static

这是一个传统的局部变量。只能在该函数内访问它。每次调用该函数(包括递归调用),都会获得一个新的变量实例。如果不初始化,它将以不可预测的值开始。它在调用之间不保持其值。

使用static关键字声明在函数内部

这是一个静态局部变量,只能在该函数内部访问。它只有一份副本,被所有对该函数的调用所共享(包括递归调用)。如果您不初始化它,则它的值默认为零。它会在函数调用之间始终保持其值。

在这三种情况中,如果您没有提供显式的初始值,变量将被保证初始化为0。但是对于真正的局部变量,如果您没有提供显式的初始值,则其初始值将包含一个不可预测的值,您不能依赖它。

形式上,这里有两个概念:可见性和生命周期。真正的全局变量在程序的任何地方都可见。静态全局变量仅在其源文件中可见。局部变量仅在其函数中可见。所有全局变量和静态变量具有静态持续时间——它们持续的时间与程序一样长。(也是那些保证初始化为0的变量。)真正的局部变量具有“自动”持续时间——随着包含函数的调用和返回而来来去去。

与持续时间密切相关的问题是变量将实际存储在何处。静态持续时间变量通常存储在数据段中。自动持续时间变量通常——虽然不一定——存储在堆栈上。


1
这是一些高质量的答案。我非常感激。谢谢! - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接