我在C代码的不同地方看到过静态这个词;这是否像c#中的静态函数/类(实现是跨对象共享的)?


当前回答

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

其他回答

我讨厌回答一个老问题,但我认为没有人提到K&R在“C编程语言”的A4.1节中是如何解释它的。

简而言之,“static”一词有两层含义:

静态是两个存储类之一(另一个是 自动)。静态对象在调用之间保持其值。在所有块外声明的对象总是静态的,不能自动的。 但是,当静态关键字(强调它被用于 代码作为关键字)与声明一起使用,它提供了该对象的内部链接,因此它只能在该翻译单元中使用。但是如果在函数中使用关键字,它将改变对象的存储类(无论如何,对象只在该函数中可见)。与static相对的是extern关键字,它提供对象外部链接。

Peter Van Der Linden在“Expert C Programming”中给出了两个含义:

在函数内部,在调用之间保留其值。 在函数级,仅在此文件中可见。

人们总是说C语言中的“static”有两层含义。我提供了另一种看待它的方式,赋予它一个单一的含义:

对一个项目应用“static”会迫使该项目具有两个属性:(a)在当前范围外不可见;(b)它是持久的。

它似乎有两种含义的原因是,在C语言中,每个“static”可能应用的项都已经具有这两个属性之一,所以似乎这种特殊用法只涉及另一个。

例如,考虑变量。在函数外部声明的变量已经具有持久性(在数据段中),因此应用'static'只能使它们在当前作用域(编译单元)之外不可见。相反,在函数内部声明的变量在当前作用域(函数)之外已经具有不可见性,因此应用“static”只能使它们持久。

将“static”应用于函数就像应用于全局变量一样——代码必须是持久的(至少在语言中),所以只能改变可见性。

注意:这些注释只适用于C。在c++中,对类方法应用'static'是真正赋予关键字不同的含义。C99数组参数扩展也是如此。

这里还有一种用法没有涉及,它是数组类型声明的一部分,作为函数的参数:

int someFunction(char arg[static 10])
{
    ...
}

在这个上下文中,它指定传递给这个函数的参数必须是char类型的数组,其中至少有10个元素。更多信息请看我的问题。

在C语言中,static有两个含义,这取决于它的使用范围。在全局作用域中,当在文件级声明对象时,这意味着该对象仅在该文件中可见。

在任何其他作用域,它声明一个对象,该对象将在输入特定作用域的不同时间之间保留其值。例如,如果一个int在一个过程中被delcare:

void procedure(void)
{
   static int i = 0;

   i++;
}

在第一次调用过程时,'i'的值被初始化为零,并且在以后每次调用过程时保留该值。如果打印'i',它将输出一个0,1,2,3,…

需要注意的是,函数中的静态变量在第一次进入该函数时被初始化,并且即使在调用结束后仍然存在;对于递归函数,静态变量只初始化一次,并且在所有递归调用中持续存在,甚至在函数调用结束后仍然存在。

如果变量是在函数外部创建的,则意味着程序员只能在声明变量的源文件中使用该变量。