我正在尝试使用 this 学习 C教程。那里有一个例子,作者试图让我们了解什么是 static
存储类。
就是这个例子:
#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\n", i, count);
}
我的问题是:为什么他/她被count
定义为static
?也就是说,上面的程序和下面的程序有什么区别?
#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\n", i, count);
}
我的意思是,我们什么时候必须使用第一个程序,什么时候必须使用第二个程序?
定义您的 count
作为全局变量或 static
在您的特定示例中,一个无关紧要(每个程序只有一个源文件,即一个 translation unit )。但这对 i
很重要(如果没有 static
关键字,它将成为一个自动局部变量),因为它是在 inside 函数中声明的。但是,对于由多个翻译单元(链接在一起以生成可执行文件)组成的任何程序来说,这都非常重要。
如果你定义一个count
两个不同翻译单元中的全局变量(即在 foo1.c
和 foo2.c
中)链接器会提示多个定义(当您从 foo
和 foo1.o
构建 foo2.o
可执行文件时 gcc foo1.o foo2.o -o foo
在您的 Linux 系统上);如果你定义了一个 static int count;
foo1.c
中的变量在foo2.c
没关系(但是你有 两个 同义变量,每个都有自己的地址,每个都隐式初始化为 0;恕我直言,这通常很糟糕,因为它使源代码的可读性降低)。
作为异常(exception),您可以在两个不同的翻译单元中声明而不显式初始化一个同名的全局变量。名称指的是相同和唯一全局(初始化为0)。
所以有
// in file foo1.c
int globalcount; // a global variable *declaration*
和
// in file foo2.c
int globalcount; // a global variable *declaration*
等同于拥有
// in file foo1.c
int globalcount = 0; // a global variable *definition* with initialization
和
// in file foo2.c
extern int globalcount; // an external variable declaration
实际上,外部声明通常应该在某个头文件中 foo.h
得到#include
-d 由两个foo1.c
& foo2.c
.
因此,(主程序的)静态变量对于 plugins 也是不可见的.阅读更多关于 visibility attribute 的信息(在 Linux 上)使变量仅对单个插件或共享库可见(但不在其外部)。
在 linkers 上阅读维基页面& dynamic linkers然后莱文的书linkers and loaders
实际上,我建议为非局部变量(全局变量和静态变量)使用唯一名称,以提高可读性和便利性(因为很容易 grep
它们);但有时你可能想要一些 static
不同编译单元中的同名变量。如果你这样做,我建议评论为什么,并有一些一致的命名约定。
在一些 free software 中寻找示例用 C 编码。