3

我正在研究静态变量,我在 wikipedia 上遇到了这段代码。静态 int x 在整个程序中存储它的值。即使我们在全局范围内声明它,它也会存储以前的值。这是否意味着静态变量和全局变量被视为相同。如果不是,两者如何工作?

#include <stdio.h>

 void func() {
       static int x=0;
        // x is initialized only once across three calls of func()
        printf("%d\n", x); // outputs the value of x
        x = x + 1;
}

 int main(int argc, char *argv[]) {
        func(); // prints 0
        func(); // prints 1
        func(); // prints 2
        return 0;
}
4

7 回答 7

9

说明符static的含义略有不同,具体取决于您使用它的位置。您有 3 个选项来声明要在程序的整个生命周期中保留其值的变量:

1) 当static在函数内声明变量(即局部变量)时,意味着它的值将在程序的整个生命周期内的函数调用之间保留。如果将变量初始化为一个值,则这是该变量在第一次函数调用时的起始值;所有后续函数调用都将保留变量的值,而不是重新初始化。

2)当声明一个全局变量(没有说明static符)时,它的值在程序的整个生命周期中都被保留,就好像它是一个局部静态变量一样,但不同的是全局变量是可见的(可以读取和写入)通过程序的任何文件的任何功能。

3)当声明一个全局static变量时,它的值会在程序的整个生命周期中再次被保留,但与普通的全局变量相比,它只能被同一文件中的其他函数访问。

总之,所有这三种类型的变量都保留了它们的值;区别在于它们的范围,这意味着哪些函数可以访问这个变量。

以下代码的所有 3 个变量在程序的整个生命周期中都保持其值。

int x = 100;         // visible to any function within any .c file of this program
static int y = 5000;  // visible from any function within this .c
int func (int i)
{
  static int z = 0;      // invisible to all other functions
  x += i;
  y += i;
  z += i;
  return z;
}

可以在这里找到详尽的解释。

于 2016-04-13T14:36:23.077 回答
2

static函数中的变量和全局变量之间有相似之处。两者的生命周期与整个程序的生命周期相同。这意味着对函数中的静态变量所做的任何更改都会在函数调用之间保留。

但是,最大的区别是函数中的静态变量只能在该函数中按名称访问。如果函数使指针可用于其他代码,则可以通过指针访问它。但除此之外,它隐藏在函数内部,其他函数可以有一个同名的静态变量,也可以有一个同名的文件范围变量(这将隐藏在函数内部)。

相比之下,全局变量可以在任何声明它的地方通过名称访问——可能在多个源文件中。

于 2013-09-17T04:43:24.240 回答
1

已修改您的代码以同时具有全局变量和静态变量。

#include <stdio.h>

 int z;              // can be accessed by other modules
 static int y;       // can only be used by this source module

 void func() {
       static int x=0;
        // x is initialized only once across three calls of func()
        printf("%d %d\n", x); // outputs the value of x
        x++;
        y++;
}

 int main(int argc, char *argv[]) {
        y = 3;
        func(); // prints: 0 3
        func(); // prints: 1 4
        func(); // prints: 2 5
        return 0;
}

y持续存在并且可以从main和访问funcx仍然存在,但只能从中读取funcz可以从其他源模块中的其他代码中读取,如果它们声明:extern int z;.

于 2013-09-17T04:57:56.417 回答
0

是的,它们几乎都一样。在函数内声明static的变量只能由该函数引用/使用。

这有利于限制仅该特定函数使用的变量的范围。创建一个仅由一个函数使用的全局变量是没有意义的。它使您的程序不那么清晰。

于 2013-09-17T04:42:29.900 回答
0

是的,静态变量的存储方式与全局变量一样。它的价值将在程序的整个生命周期中持续存在。

static如果在函数外部声明,关键字也会影响变量的范围。不能从另一个源文件按名称访问该变量。

于 2013-09-17T04:42:49.253 回答
0

全球与本地更多的是关于可访问性。静态变量与实例变量不同,因为它处理数据的存储方式,静态数据存储在类型级别,这意味着它在特定类型的所有变量之间共享。另一方面,实例变量与特定实例相关联,并且对于该实例是唯一的。

于 2013-09-17T04:43:14.543 回答
0

这是一个关于变量范围和生命周期的经典问题。

变量的范围是可以引用或访问该变量的范围。范围可以在特定函数或整个文件或整个程序内。

另一方面,变量的生命周期是变量在内存中保留其空间的时间。生命周期可能仅限于函数调用或程序的整个执行。

基于这些因素,变量的位置也会发生变化。例如,局部变量占用堆栈空间。但是,如果此局部变量具有说明符 static,则此变量会占用数据部分中的空间,但是链接(或可见性)仅在声明它的函数内。因此,当函数调用完成时,它不会丢失其当前值,而是只能在函数内访问。

另一方面,全局变量具有定义它的整个文件的范围,并占用数据部分的空间。

因此,正如您在上面看到的,静态变量和全局变量都占用数据部分的空间,但它们与程序的链接是不同的,即分别是函数和整个文件。希望有帮助!

这个问题的最佳参考是“The C Programming Language”。

于 2013-09-17T05:06:14.363 回答