为什么在这个C程序中全局变量被定义为静态变量?


Why a global variable is defined as static in this C program?

本问题已经有最佳答案,请猛点这里访问。

我正在尝试使用本教程学习C。这里有一个例子,作者试图学习什么是static存储类。

这就是例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

/* function declaration */
void func(void);

static int count = 5; /* global variable */

main()
{
   while(count--)
   {
      func();
   }
   return 0;
}
/* function definition */
void func( void )
{
   static int i = 5; /* local static variable */
   i++;

   printf("i is %d and count is %d
"
, i, count);
}

我的问题是:为什么他/她被定义为count作为static?换句话说,上面的程序和下面的程序有什么区别?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

/* function declaration */
void func(void);

int count = 5; /* global variable */

main()
{
   while(count--)
   {
      func();
   }
   return 0;
}
/* function definition */
void func( void )
{
   static int i = 5; /* local static variable */
   i++;

   printf("i is %d and count is %d
"
, i, count);
}

我是说,我们什么时候必须使用第一个程序,什么时候必须使用第二个程序?


在您的特定示例中,将您的count定义为全局变量或static变量并不重要(其中每个程序只有一个源文件,即一个翻译单元)。但是对于i(没有static关键字,它将成为一个自动局部变量),因为它是在函数内部声明的。但是,对于任何由几个翻译单元组成的程序(链接在一起以使其可执行),这都将非常重要。

如果您在两个不同的翻译单元(即在foo1.cfoo2.c中)中定义了一个count全局变量,那么链接器会抱怨多个定义(当您在Linux系统上使用gcc foo1.o foo2.o -o foofoo1.ofoo2.o构建foo可执行文件时);如果您定义了static int count;变量bo在foo1.cfoo2.c中,这是正常的(但是你有两个同义变量,每个变量都有自己的地址,并且每个变量都隐式初始化为0;imho这通常是不好的味道,因为它使源代码的可读性变差)。

作为例外,您可以在两个不同的翻译单元中声明一个同名的全局变量,而不必显式初始化它。名称引用相同且唯一的全局(初始化为0)。

所以拥有

1
2
// in file foo1.c
int globalcount; // a global variable *declaration*

1
2
// in file foo2.c
int globalcount; // a global variable *declaration*

1
2
// in file foo1.c
int globalcount = 0; // a global variable *definition* with initialization

1
2
// in file foo2.c
extern int globalcount;  // an external variable declaration

实际上,这个外部声明通常应该在一些头文件foo.h中,由两个foo1.cfoo2.c都得到#included。

因此,插件也看不到静态变量(主程序的)。阅读更多关于可见性属性(在Linux上)的内容,使变量仅由单个插件或共享库(但不在其外部)可见。

阅读链接器和动态链接器上的wikipage,然后阅读Levine的图书链接器和加载器。

实际上,我建议对非局部变量(全局变量和静态变量)使用唯一的名称,以便可读性和方便性(因为grep它们很容易);但有时您可能希望在不同的编译单元中有几个同名的static变量。如果您这样做了,我建议您评论一下原因,并有一些一致的命名约定。

在一些用C编写的免费软件中寻找例子。


全局变量的static使其仅对该文件(编译单元)是全局的。它将无法从其他文件(编译单元)访问