在C中正确使用静态函数是什么?

时间:2020-03-25 18:07:51

标签: c static

我发现了在C中使用静态函数的两种方法。

第一个是:

afile.h

static void afunc(void); // leaving this out gives errors

afile.c

void afunc(void)
{
   puts("a");
}

void callafunc(void)
{
   afunc();
}

main.c

void afunc(void)
{
   puts("b");
}

int main(void)
{
   afunc(); // prints b
   callafunc(); // prints a
}

另一种方式是:

afile.h

// declare nothing w.r.t. static functions

afile.c

static void afunc(void)
{
   ...
}

main.c

static void afunc(void)
{
   ...
}

这两种使用静态函数的方法中哪一种是正确的?

2 个答案:

答案 0 :(得分:4)

这两种使用静态函数的方法中哪一种是正确的?

第二种方法是正确的。

static void afunc(void);是一个函数声明。该函数的定义存在于某处。由于它也是 static ,因此如果在此编译中使用该函数,则其定义也需要在此单元的此编译中。该功能具有本地链接。

在第二种情况下,main.cafile.c都使用其本地定义的afunc(void)

无需向全局命名空间声明afunc()存在。没有其他编译单元需要了解main.c, afile.c

的这些局部功能

第一个通常是不正确的。

第一种情况“有效”是因为main.cafile.c都使用并具有本地定义的afunc(void)

如果另一个文件foo.c(),使用#include "afile.h"并尝试调用afunc(),除非它也有一个本地定义的,否则它将找不到匹配的本地afunc() afunc()

"*.h"可以进一步说明"*.c"具有供全局名称空间使用的功能,对象,定义,类型等。属于static的东西最好放在"*.c"上方以供自己使用,而不要放在"*.h"中。


在狭窄的情况下,第一个可能是正确的。

例如,"afile.h"声明并定义一个小助手函数,目的是使包含"*.c"的{​​{1}}都将获得其自己的{ {1}}。通过使其"afile.h",这些本地afunc()不会与潜在的全局static或彼此冲突。

答案 1 :(得分:2)

拥有头文件的要点如下:

如果多个translation units(即“ .c文件”)使用相同的数据类型,函数或变量,则相应的声明必须出现在每个翻译单元中。尽管理论上程序员可以直接将所有这些声明写到每个.c文件中,但这将使程序员很难更改声明,因为在每个.c文件中都必须更改它们。因此,仅为多个翻译单元制作一个通用的头文件,并使用C preprocessor将各个翻译单元#include制作为头文件会更容易。

基于此,您将在第一个示例中执行的操作在某种意义上是“正确的”,因为它将起作用并且它是有效的C代码。但是,它仍然没有意义,因为您对两个不相关的函数使用了相同的声明。

即使这些功能具有相同的名称和prototype,这些功能仍然彼此无关。这是因为函数具有internal linkage(由于关键字static)。

不相关的函数在头文件中共享相同的声明是没有意义的。例如,如果您决定修改一个函数的声明,那么如何在源代码中对其进行修改?您无法修改头文件,因为那样的话,您还将在所有其他翻译单元中使用该名称修改其他函数。

因此,将static函数声明存储在.c文件中而不是公共头文件中更有意义。