关于C#:声明全局变量和静态变量

Declaring a global and a static variable

我在研究静态变量,在维基百科上发现了这段代码。静态int x在整个程序中存储它的值。即使我们全局声明它,它也将存储以前的值。这是否意味着静态变量和全局变量被视为相同的,如果不是,这两个变量是如何工作的?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

 void func() {
       static int x=0;
        // x is initialized only once across three calls of func()
        printf("%d
"
, 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;
}

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

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

2)当声明一个全局变量(不带static说明符)时,它的值在程序的整个生命周期内保持不变,就好像它是一个局部静态变量一样,但不同的是,一个全局变量可以被程序的任何文件的任何函数看到(读写)。

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

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

以下代码的所有3个变量在程序生命周期之外都保留其值。

1
2
3
4
5
6
7
8
9
10
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;
}

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


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

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

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


已修改代码,使其同时具有全局变量和静态变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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
"
, 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持续存在,可从mainfunc访问。x持续存在,但只能从func中读取。如果其他源模块声明:extern int z;,则可以从其他源模块中的其他代码中读取z


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

变量的作用域是变量可以被引用或访问的范围。作用域可以在特定的函数、整个文件或整个程序中。

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

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

另一方面,全局变量具有整个文件的作用域,在该文件中定义它并在数据段中占用空间。

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

对于这个问题最好的参考是"C编程语言"。


全局与局部更注重可访问性。静态变量和实例变量是不同的,因为它处理如何存储数据,静态数据存储在类型级别,这意味着它在某个类型的所有变量之间共享。另一方面,实例变量与特定实例相关联,并且对该实例是唯一的。


是的,静态变量像全局变量一样存储。它的值将在程序的整个生命周期中保持不变。

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


是的,它们都差不多。函数内声明为static的变量只能由该函数引用/使用。

这有助于限制只使用特定函数的变量的范围。生成只由一个函数使用的全局变量没有意义。它使你的程序不那么清晰。