我在C代码的不同地方看到过静态这个词;这是否像c#中的静态函数/类(实现是跨对象共享的)?
当前回答
函数中的静态变量在调用之间保持其值。 静态全局变量或函数只能在声明它的文件中“看到”
(1)对于新手来说是比较陌生的话题,所以这里有一个例子:
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
这个打印:
a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60
这对于函数需要在调用之间保持某种状态,而又不想使用全局变量的情况很有用。但是要注意,这个特性应该非常谨慎地使用——它使您的代码不是线程安全的,而且更难理解。
(2)作为“访问控制”功能被广泛使用。如果你有一个实现某些功能的.c文件,它通常只向用户公开几个“公共”函数。其余的函数应该是静态的,这样用户就不能访问它们。这就是封装,一个很好的实践。
引用维基百科:
在C语言中,是静态的 与全局变量和 函数将其作用域设置为 包含文件。在局部变量中, Static用于存储变量 在静态分配的内存中 而不是自动分配 内存。而语言却没有 指定任意一种方法的实现 内存类型,静态分配 内存通常保留在数据中 编译时的程序段 时间,当自动 已分配内存正常 实现为一个瞬态调用堆栈。
回答你的第二个问题,它不像c#。
然而,在c++中,static也用于定义类属性(在同一类的所有对象之间共享)和方法。在C语言中没有类,所以这个特性无关紧要。
其他回答
从维基百科:
在C编程语言中,static与全局变量和函数一起使用,以将它们的作用域设置为包含文件。在局部变量中,static用于将变量存储在静态分配的内存中,而不是自动分配的内存中。虽然语言没有规定这两种类型内存的实现,但静态分配的内存通常在编译时保留在程序的数据段中,而自动分配的内存通常作为瞬态调用堆栈实现。
C语言中的静态变量具有程序的生命周期。
如果在函数中定义,则它们具有局部作用域,即只能在这些函数中访问它们。静态变量的值在函数调用之间保留。
例如:
void function()
{
static int var = 1;
var++;
printf("%d", var);
}
int main()
{
function(); // Call 1
function(); // Call 2
}
在上面的程序中,var存储在数据段中。它的生命周期是整个C程序。
函数调用1后,var变为2。函数调用2后,var变为3。
var的值不会在函数调用之间被销毁。
如果var在非静态变量和局部变量之间,它将被存储在C程序的堆栈段中。由于函数的堆栈帧在函数返回后被销毁,因此var的值也被销毁。
初始化的静态变量存储在C程序的数据段中,而未初始化的静态变量存储在BSS段中。
关于静态的另一个信息:如果一个变量是全局的并且是静态的,那么它具有C程序的生命周期,但是它具有文件作用域。它只在该文件中可见。
试试这个:
file1.c
static int x;
int main()
{
printf("Accessing in same file%d", x):
}
file2.c
extern int x;
func()
{
printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
}
run gcc -c file1.c
gcc -c file2.c
现在试着把它们连接起来:
gcc -o output file1.o file2.o
它会给出一个链接器错误,因为x的文件作用域是file1.c,而链接器将无法解析file2.c中使用的对变量x的引用。
引用:
http://en.wikipedia.org/wiki/Translation_unit_(编程) http://en.wikipedia.org/wiki/Call_stack
函数中的静态变量在调用之间保持其值。 静态全局变量或函数只能在声明它的文件中“看到”
(1)对于新手来说是比较陌生的话题,所以这里有一个例子:
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
这个打印:
a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60
这对于函数需要在调用之间保持某种状态,而又不想使用全局变量的情况很有用。但是要注意,这个特性应该非常谨慎地使用——它使您的代码不是线程安全的,而且更难理解。
(2)作为“访问控制”功能被广泛使用。如果你有一个实现某些功能的.c文件,它通常只向用户公开几个“公共”函数。其余的函数应该是静态的,这样用户就不能访问它们。这就是封装,一个很好的实践。
引用维基百科:
在C语言中,是静态的 与全局变量和 函数将其作用域设置为 包含文件。在局部变量中, Static用于存储变量 在静态分配的内存中 而不是自动分配 内存。而语言却没有 指定任意一种方法的实现 内存类型,静态分配 内存通常保留在数据中 编译时的程序段 时间,当自动 已分配内存正常 实现为一个瞬态调用堆栈。
回答你的第二个问题,它不像c#。
然而,在c++中,static也用于定义类属性(在同一类的所有对象之间共享)和方法。在C语言中没有类,所以这个特性无关紧要。
简单的回答……视情况而定。
静态定义的局部变量不会在函数调用之间丢失它们的值。换句话说,它们是全局变量,但作用域是定义它们的局部函数。 静态全局变量在定义它们的C文件之外是不可见的。 静态函数在定义它们的C文件之外是不可见的。
需要注意的是,函数中的静态变量在第一次进入该函数时被初始化,并且即使在调用结束后仍然存在;对于递归函数,静态变量只初始化一次,并且在所有递归调用中持续存在,甚至在函数调用结束后仍然存在。
如果变量是在函数外部创建的,则意味着程序员只能在声明变量的源文件中使用该变量。