C中的static
关键字是否仅用于将变量的范围限制为单个文件?
我需要知道我是否理解这一点。请假设以下3个文件,
file1.c中
int a;
file2.c中
int b;
file3.c中
static int c;
现在,如果3个文件一起编译,那么变量“a”& “b”应具有全局范围,可以从3个文件中的任何一个访问。但是,变量“c”是静态的,只能从file3.c访问,对吗?
static
在C中有任何其他用途吗? (除了限制变量的范围,如上所示?)
答案 0 :(得分:12)
static
关键字在C中有两个不同的用途,我称之为持续时间(对象的生命周期)和可见性(可以使用对象)。请记住,C标准实际上对这两个概念使用了不同的单词,但我发现在语言教学中最好先使用日常术语。
在文件级别(任何功能之外)使用时,它控制可见性。在文件级别定义的变量的持续时间已经定义为程序的整个持续时间,因此您不需要static
。
文件级别的静态变量对于翻译单元以外的任何内容都是不可见的(链接器无法看到它)。
在功能级别(函数内部)使用时,它控制持续时间。那是因为可见性已被定义为该功能的本地。
在这种情况下,变量的持续时间是程序的整个持续时间,并且在函数的调用之间保持值。
答案 1 :(得分:5)
您滥用术语“范围”。 C中的static
与范围完全无关。
范围是可见实体名称(变量,函数,类型名称等)的区域。在C语言中,“文件范围”是有史以来最大的范围。出于这个原因,将任何内容限制在单个文件中是没有意义的:没有什么比这更大的了。在C中没有“全局范围”这样的东西。术语“全局范围”有时是非正式使用的,但在这种情况下它与“文件范围”具有相同的含义。
同样,C中的static
与范围完全无关。 C中的static
会影响对象的存储持续时间和标识符的链接。当与对象一起使用时(变量)static
给出对象静态存储持续时间(即,只要程序运行,对象就存在)。并且,当与非本地对象或函数的标识符一起使用时,它为它们提供内部链接,这意味着相同的标识符指的是单个翻译单元(定义实体的位置)内的同一实体,但不在其他翻译单位。
答案 2 :(得分:4)
static
也在函数定义中用于定义一个变量,该变量在函数调用之间保持其值。我找到了an example here。相反,每次函数调用重新创建的变量都称为自动变量。
答案 3 :(得分:3)
增加Kinopiko答案的一个例子:
#include <stdio.h>
int foo() {
static int foo = 0;
return ++foo;
}
int main() {
printf("%i\n", foo()); // 1
printf("%i\n", foo()); // 2
}
这可以用于例如返回指向本地函数变量的安全指针。或者在Objective-C中,它有时用于防止重复的类初始化:
- (void) initialize
{
static BOOL initialized = NO;
if (initialized)
return;
// …perform initialization…
initialized = YES;
}
答案 4 :(得分:1)
你是对的,这被称为“静态链接”:声明为static
的符号仅在定义它的编译单元中可用。
static
的另一种用法是在函数内部:
void f() {
static int counter = 0;
counter++;
// ...
}
在这种情况下,变量仅初始化一次并通过该函数的不同调用保持其值,就像它将是一个全局变量一样。在此示例中,counter
变量计算调用函数的次数。
答案 5 :(得分:1)
变量可能有三种存储方式:
全局变量始终存储在静态区域中。但是要在静态区域中存储局部变量,您需要关键字static
。由于静态变量未在堆栈上分配,因此您可以在后续调用中访问该变量
全局范围内的static
关键字也提供了可变的内部链接。因此,使用extern
限定符无法从其他文件访问该变量。
答案 6 :(得分:1)
内部联系与外部联系的例子
// file1.c中
#include <stdio.h>
int glb_var=3;//global variable
int func(); //prototype of function
int main()
{
func();
func();
func();
return 0;
}
int func()
{
static int counter=0;//static varible
printf("val of counter=%d",counter);
counter+=5;
return 0;
}
当我们编译这个程序并运行这个程序时,os会将这个程序加载到内存中。接下来会发生一些事情:
glb_var标识符将存储在初始化的数据段中。
计数器标识符将存储在名为“.bss”的未初始化数据段中。
关于静态变量的一个重要的事情是它有内部链接。所以我们可以将这个变量访问到一个特定的文件。它们被定义(不在其他文件中)。
我们可以使用extern关键字访问其他文件中的全局变量glb_var。 例如:
// file2.c中
#include <stdio.h>
extern glb_var; //for declaration of this variable
int main()
{
if(glb_var)
{
printf("glb_var=%d",glb_var);
}
}
输出:3 这被称为外部联系。