为什么在C中声明变量或函数静态?

时间:2009-11-03 04:29:32

标签: c static

我理解静态的作用,但不是我们使用它的原因。它只是用于保留抽象层吗?

4 个答案:

答案 0 :(得分:23)

在C中使用static有几个原因。

当与函数一起使用时,是的意图是创建抽象。 C源代码文件范围的原始术语是“翻译单元”。静态函数只能在同一个翻译单元中到达。这些静态函数类似于C ++中的私有方法,自由解释(在这个类比中,翻译单元定义了一个类)。

全局级别的静态数据也无法从翻译单元外部访问,这也用于创建抽象。此外,所有静态数据都初始化为零,因此可以使用static来控制初始化。

本地(“自动”)变量级别的静态用于抽象函数的实现,该函数跨调用维护状态,但避免在转换单元范围使用变量。同样,由于静态认证,变量被初始化为零。

答案 1 :(得分:9)

关键字static有几种用途;在函数之外,它只是将函数或变量的可见性限制在函数或变量出现的编译单元(.c文件)中。这样,函数或变量就不会变为全局。这是一件好事,它促进了一种“需要知道”的原则(不要暴露不需要暴露的东西)。此类型的静态变量初始化为零,但当然全局变量也初始化为零,因此static关键字本身不负零初始化。

变量也可以在函数内声明为static。此功能意味着变量不是自动的,即在每次调用函数时在堆栈上分配和释放。相反,变量在静态数据区域中分配,它被初始化为零并在程序的生命周期中持续存在。如果函数在一次调用期间修改它,则新修改的值将在下次调用时可用。这听起来是件好事,但有很好的理由“auto”是默认值,并且函数中的“静态”变量应该谨慎使用。简而言之,自动变量具有更高的内存效率,如果您希望函数是线程安全的,那么它们是必不可少的。

答案 2 :(得分:6)

static同时用作storage class specifierlinkage specifier。作为链接说明符,它将全局变量或函数的范围限制为单个编译单元。这允许例如编译单元具有与其他编译单元具有相同标识符名称的变量和函数但不引起冲突,因为这样的标识符从链接器“隐藏”。如果您要创建一个库并且需要内部“帮助”函数,这不会导致与用户代码冲突,这非常有用。

作为应用于局部变量的存储类说明符,它完全具有不同的语义,但您的问题似乎暗示您指的是静态链接。

答案 3 :(得分:0)

C中的静态函数

在C中,默认情况下函数是全局的。函数名前的“static”关键字使其成为静态。例如,下面的函数fun()是静态的。

static int fun(void)
{
  printf("I am a static function ");
}

与C中的全局函数不同,对静态函数的访问仅限于声明它们的文件。因此,当我们想要限制对函数的访问时,我们将它们设置为静态。使函数成为静态的另一个原因是可以在其他文件中重用相同的函数名。

例如,如果我们将以下程序存储在一个文件file1.c

/* Inside file1.c */
static void fun1(void)
{
  puts("fun1 called");
}

将以下程序存储在另一个文件file2.c中

/* Iinside file2.c  */
int main(void)
{
  fun1(); 
  getchar();
  return 0;  
}

现在,如果我们使用命令“gcc file2.c file1.c”编译上述代码,我们会在file1.c中收到错误“未定义的fun1’” . This is because fun1() is declared static”引用,并且不能在file2.c中使用。另请参阅代码来自的explanation here