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

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

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

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

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

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

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

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

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

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

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 ”编译上面的代码,我们得到错误“未定义引用fun1'” . This is because fun1() is declared fun1'” . This is because fun1() is declared在file1.c中fun1'” . This is because fun1() is declared static`,不能在file2.c中使用。 另请参阅此处的说明 ,代码来自何处。