这个问题是关于普通的c函数,而不是c++的静态方法,在评论中已经澄清了。

我知道什么是静态变量,但是什么是静态函数呢?

为什么如果我声明一个函数,让我们说void print_matrix,在让我们说a.c(没有a.h),并包括“a.c”-我得到“print_matrix@@....)已经定义在a.b obj”,但如果我声明它为静态void print_matrix,然后它编译?

只是澄清一下——我知道包含。c是不好的,就像你们很多人指出的那样。我这样做只是为了暂时清除main.c中的空间,直到我更好地了解如何将所有这些函数分组到适当的.h和.c文件中。只是一个临时的,快速的解决方案。


当前回答

下面是关于普通C函数的——在c++类中,修饰符“static”另有含义。

如果你只有一个文件,这个修饰符完全没有区别。不同之处在于有多个文件的大型项目:

在C语言中,每个“模块”(sample.c和sample.h的组合)都是独立编译的,然后每个被编译的目标文件(sample.o)都被链接器链接到一个可执行文件。

假设你有几个文件,包括在主文件和两个内部的函数仅用于方便叫添加(int a、b)——编译器会轻松地创建对象文件这两个模块,但链接器将抛出一个错误,因为它找到具有相同名称的两个函数,它不知道应该使用哪一个(即使没有什么联系,因为他们不习惯别的地方,但在它自己的文件中)。

这就是为什么这个函数,只在内部使用,是一个静态函数。在这种情况下,编译器不会为链接器创建典型的“you can link this thing”-标志,这样链接器就不会看到这个函数,也就不会产生错误。

其他回答

因为静态函数只在这个文件中可见。 实际上,编译器可以为你做一些优化,如果你声明“静态”的一些函数。

这里有一个简单的例子。

c

#include <stdio.h>

static void test() 
{
    ghost(); // This is an unexist function.
}

int main()
{
    int ret = 0;

#ifdef TEST
#else
    test();
#endif
    return (ret);
} 

并使用

gcc -o main main.c

你会看到它失败了。因为你甚至没有实现ghost()函数。

但是如果我们使用下面的命令。

gcc -DTEST -O2 -o main main.c

测试成功,程序可以正常运行。

为什么?这里有3个关键点。

-O2:编译器优化级别至少2。 -DTEST:定义TEST,因此TEST()将不会被调用。 为test()定义了“static”。

只有这3个条件都为真,才能通过编译。 由于这个“静态”声明,编译器可以确认test()将永远不会在其他文件中被调用。编译器可以在编译时删除test()。因为我们不需要test(),所以是否定义或实现ghost()并不重要。

静态函数是仅对同一文件中的其他函数可见的函数(更准确地说,是同一翻译单元)。

编辑:对于那些认为问题的作者指的是一个“类方法”的人:因为问题被标记为C,他指的是一个普通的C函数。对于(c++ /Java/…)类方法,静态意味着该方法可以在类本身上调用,不需要该类的实例。

静态函数是可以在类本身上调用的函数,而不是类的实例。

例如,一个非静态变量是:

Person* tom = new Person();
tom->setName("Tom");

此方法作用于类的实例,而不是类本身。然而,你可以有一个静态方法,它可以在没有实例的情况下工作。有时会在Factory模式中使用:

Person* tom = Person::createNewPerson();

静态函数定义将此符号标记为内部符号。因此,从外部链接它将是不可见的,而只能链接到同一编译单元中的函数,通常是同一文件。

静态函数的答案取决于语言:

1)在像C这样没有oop的语言中,这意味着函数只能在定义它的文件中访问。

2)在c++等带有oop的语言中,这意味着可以直接在类上调用函数,而无需创建它的实例。