0

我刚开始学习C编程。在一些书籍和网络文章中,我可以发现 C 中的任何全局变量默认对应于static存储类但具有外部链接。这是否意味着它是部分static和部分的extern?因为根据我的理解,任何带有static存储类说明符的全局变量都只有内部链接,并且可以在同一个文件中访问。

PS:我提到了这个问题C 中的全局变量是否是静态的?,但无法真正了解全局变量是否在 C 中是staticextern默认情况下。

4

3 回答 3

1

每当您不打算variable在不同文件的一个文件中使用声明时,您应该static在声明之前使用关键字

文件1.c:

static int number = 63;   // this variable is used only in this file

...

文件2.c:

float brightness = 0.5;   // is needed in some Other file;

...

文件 3.c:

extern float brightness;  // use external declaration to use it here

...

只要有可能,您应该使用静态变量。

如果您想global在两个不同的translation units(c 文件)中使用两个变量,那么您的编译器将抛出一个错误,指出该变量已在其他地方声明。

使用static将使其对其他翻译单元隐藏。

于 2020-08-17T08:53:24.787 回答
1

C中的全局变量默认对应static存储类,但有外部链接。这是否意味着它是部分static和部分的extern

英文单词“static”在 C 中具有混淆和多重含义,是的,在函数外部声明的变量的默认值是具有静态存储持续时间和外部链接。

因为这里有多个概念和一些混合使用的词义,所以我们应该澄清一些术语和格式:

  • 使用代码样式来引用源代码中的特定文本,例如关键字static. 在谈到静态存储时长或外部链接时,“静态”和“外部”只是英文形容词,不应采用代码风格。
  • “全局”意味着在整个程序中可见。C 标准没有为此目的使用这个词。它使用“外部”来指代任何功能之外(外部)的事物。(但它也将“外部”用于其他目的。)全局变量不能有内部链接,因为它不会在整个程序中可见。
  • 变量由一个对象(为表示值而保留的内存)和一个标识符(名称)组成。存储持续时间是对象的一个​​属性。链接是标识符的一个属性。

英文单词“static”通常表示不变。staticC 标准以多种方式使用这个词和关键字:

  • 静态存储持续时间意味着对象的内存在整个程序执行过程中都会保留。
  • 在声明中使用static关键字,除了下面的之外,都给出了对象静态存储持续时间,并且在函数外部的声明中,给出了标识符内部链接。
  • static在参数声明中的下标标记内使用关键字,如void foo(int a[static 3]),表示参数至少指向规定数量的元素。
  • 静态断言,使用_Static_assert,提供编译时测试(这可以帮助检测错误或确保程序正在使用预期的设置进行编译)。

这些多重用途是不幸的,至少部分是由于 C 语言的开发历史。

于 2020-08-17T10:01:56.960 回答
0

你混淆了static静态存储的持续时间

存储期限和联动是不同的术语。C 中没有任何东西称为“全局”,尽管该术语通常草率地用于在文件范围内声明的任何变量- 即:在任何函数之外。更正确地使用术语“全局”是变量具有外部链接,这意味着它可以在整个项目的任何地方引用。

在文件范围内声明的所有变量都具有静态存储持续时间。这决定了这些变量是如何初始化的,并且它们在程序的整个执行过程中持续存在(实际上,这也可能意味着变量最终出现在实现中.data.bss部分实现中)。

在文件范围内声明但没有任何存储类说明符(既没有static也没有extern)的变量具有外部链接,但它仍然具有静态存储持续时间。从 6.2.4 开始:

如果对象标识符的声明具有文件范围且没有存储类说明符,则其链接是外部的。

但是,如果您将存储类说明符添加到文件范围变量中,您将同时指定存储持续时间和链接。6.2.4/3:

如果对象或函数的文件范围标识符的声明包含存储类说明符static,则该标识符具有内部链接。

正如您所说,具有内部链接的变量只能从同一个文件中引用(严格来说是相同的“翻译单元”)。

static如果您添加到局部变量,这里会有一些细微的差别- 然后它指定存储持续时间而不是链接。整个术语链接相当混乱 - 简单地说,该术语的目的是规定两个具有相同名称的变量何时引用相同的对象或不同的对象。对于那些制作编译器/链接器的人以及意大利面条程序员来说,这主要是一个问题。遵循以下建议,避免属于后一类。


初学者不必担心以上任何问题。初学者的经验法则:

  • 永远不要在函数之外声明变量,除非它们是static.
  • 永远不要在头文件中声明变量。
  • 永远不要使用extern.
  • static如果函数不打算从其他文件调用,请在函数前面使用。

这将使您走得很远,并且您实际上需要在不同文件之间共享变量的罕见情况是另一个故事/高级主题。

于 2020-08-17T09:50:29.857 回答