我刚开始学习C编程。在一些书籍和网络文章中,我可以发现 C 中的任何全局变量默认对应于static
存储类但具有外部链接。这是否意味着它是部分static
和部分的extern
?因为根据我的理解,任何带有static
存储类说明符的全局变量都只有内部链接,并且可以在同一个文件中访问。
PS:我提到了这个问题C 中的全局变量是否是静态的?,但无法真正了解全局变量是否在 C 中是static
或extern
默认情况下。
我刚开始学习C编程。在一些书籍和网络文章中,我可以发现 C 中的任何全局变量默认对应于static
存储类但具有外部链接。这是否意味着它是部分static
和部分的extern
?因为根据我的理解,任何带有static
存储类说明符的全局变量都只有内部链接,并且可以在同一个文件中访问。
PS:我提到了这个问题C 中的全局变量是否是静态的?,但无法真正了解全局变量是否在 C 中是static
或extern
默认情况下。
每当您不打算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
将使其对其他翻译单元隐藏。
C中的全局变量默认对应
static
存储类,但有外部链接。这是否意味着它是部分static
和部分的extern
?
英文单词“static”在 C 中具有混淆和多重含义,是的,在函数外部声明的变量的默认值是具有静态存储持续时间和外部链接。
因为这里有多个概念和一些混合使用的词义,所以我们应该澄清一些术语和格式:
static
. 在谈到静态存储时长或外部链接时,“静态”和“外部”只是英文形容词,不应采用代码风格。英文单词“static”通常表示不变。static
C 标准以多种方式使用这个词和关键字:
static
关键字,除了下面的之外,都给出了对象静态存储持续时间,并且在函数外部的声明中,给出了标识符内部链接。static
在参数声明中的下标标记内使用关键字,如void foo(int a[static 3])
,表示参数至少指向规定数量的元素。_Static_assert
,提供编译时测试(这可以帮助检测错误或确保程序正在使用预期的设置进行编译)。这些多重用途是不幸的,至少部分是由于 C 语言的开发历史。
你混淆了static
静态存储的持续时间。
存储期限和联动是不同的术语。C 中没有任何东西称为“全局”,尽管该术语通常草率地用于在文件范围内声明的任何变量- 即:在任何函数之外。更正确地使用术语“全局”是变量具有外部链接,这意味着它可以在整个项目的任何地方引用。
在文件范围内声明的所有变量都具有静态存储持续时间。这决定了这些变量是如何初始化的,并且它们在程序的整个执行过程中持续存在(实际上,这也可能意味着变量最终出现在实现中.data
或.bss
部分实现中)。
在文件范围内声明但没有任何存储类说明符(既没有static
也没有extern
)的变量具有外部链接,但它仍然具有静态存储持续时间。从 6.2.4 开始:
如果对象标识符的声明具有文件范围且没有存储类说明符,则其链接是外部的。
但是,如果您将存储类说明符添加到文件范围变量中,您将同时指定存储持续时间和链接。6.2.4/3:
如果对象或函数的文件范围标识符的声明包含存储类说明符
static
,则该标识符具有内部链接。
正如您所说,具有内部链接的变量只能从同一个文件中引用(严格来说是相同的“翻译单元”)。
static
如果您添加到局部变量,这里会有一些细微的差别- 然后它指定存储持续时间而不是链接。整个术语链接相当混乱 - 简单地说,该术语的目的是规定两个具有相同名称的变量何时引用相同的对象或不同的对象。对于那些制作编译器/链接器的人以及意大利面条程序员来说,这主要是一个问题。遵循以下建议,避免属于后一类。
初学者不必担心以上任何问题。初学者的经验法则:
static
.extern
.static
如果函数不打算从其他文件调用,请在函数前面使用。这将使您走得很远,并且您实际上需要在不同文件之间共享变量的罕见情况是另一个故事/高级主题。