31

我想知道在staticC 中使用关键字作为文件中变量的范围限制。

在我看来,构建 C 程序的标准方法是:

  • 有一堆定义函数和变量的 c 文件,可能范围受限于static.
  • 有一堆 h 文件声明相应 c 文件的函数和可能的变量,供其他 c 文件使用。私有函数和变量不在 h 文件中发布。
  • 每个 c 文件都单独编译成一个 o 文件。
  • 所有 o 文件都链接到一个应用程序文件。

static如果变量没有在 h 文件中发布,我看到将 gobal 声明为的两个原因:

  • 一是为了可读性。通知包括我自己在内的未来读者,在任何其他文件中都没有访问变量。
  • 第二个是防止另一个 c 文件将变量重新声明为extern. 我想链接器不喜欢既是externand的变量static。(我不喜欢文件将其他人拥有的变量重新声明为的想法,extern这可以练习吗?)

还有什么原因吗?

函数也是如此static。如果原型没有在 h 文件中发布,其他文件可能无论如何都不会使用该功能,那为什么要定义它static呢?我可以看到相同的两个原因,但仅此而已。

4

6 回答 6

31

当您谈论通知其他读者时,请将编译器本身视为读者。如果声明了变量static,则可能会影响优化的程度。

重新定义一个static变量extern是不可能的,但编译器会(像往常一样)给你足够的绳索让你上吊。

如果我static int foo;在一个文件和int foo;另一个文件中写入,尽管它们具有相同的名称和类型,但它们被认为是不同的变量- 编译器不会抱怨,但您稍后可能会在尝试读取和/或调试代码时感到非常困惑。(如果我在第二种情况下写,除非我在其他地方extern int foo;声明非静态,否则链接将失败。)int foo;

全局变量很少出现在头文件中,但当它们出现时,它们应该被声明extern。如果不是,则取决于您的编译器,您可能会冒每个包含该头文件的源文件都将声明其自己的变量副本的风险:充其量这将导致链接失败(多重定义的符号),最坏的情况是会导致一些令人困惑的遮蔽情况。

于 2010-06-04T12:20:23.863 回答
10

static通过在文件级别声明一个变量(static在函数内具有不同的含义),您可以禁止其他单元访问它,例如,如果您尝试在另一个单元内使用该变量(用 声明extern),链接器将找不到此符号。

于 2010-06-04T12:04:37.707 回答
9

当您声明一个静态函数时,对该函数的调用是“近调用”,理论上它比“远调用”执行得更好。您可以谷歌了解更多信息。是我通过简单的谷歌搜索找到的。

于 2010-06-04T13:07:58.047 回答
2

如果全局变量被声明为静态的,编译器有时可以做出比没有声明更好的优化。因为编译器知道无法从其他源文件访问该变量,所以它可以更好地推断您的代码在做什么(例如“此函数不会修改此变量”),这有时会导致它生成更快的代码。很少有编译器/链接器可以跨不同的翻译单元进行此类优化。

于 2010-06-04T12:19:07.030 回答
1

如果您在文件 ac 中声明一个变量 foo 而不使其成为静态,而在文件 bc 中声明一个变量 foo 而不使其成为静态,则两者都自动为外部,这意味着如果您初始化两者,链接器可能会抱怨,如果它没有分配相同的内存位置不要抱怨。期待调试您的代码的乐趣。

如果你在文件 ac 中编写了一个函数 foo () 而不使其成为静态,并且在文件 bc 中编写一个函数 foo () 而不使其成为静态,链接器可能会抱怨,但如果没有,所有对 foo () 的调用都会调用相同的功能。期待调试您的代码的乐趣。

于 2014-04-01T06:58:23.940 回答
-1

我最喜欢的 static 用法是能够存储我不必注入或创建要使用的对象的方法,在我看来,私有静态方法总是有用的,而 public static 你必须花更多时间思考你做了什么来避免被疯子定义的东西,让你自己的绳子太多,不小心把自己吊起来!

我喜欢为我的大多数项目保留一个 Helper 类的文件夹,这些项目主要由静态方法组成,可以快速有效地做事,不需要任何对象!

于 2010-06-04T13:51:48.540 回答