静态与全局


Answers:


70

i具有内部链接,因此您不能i在其他源文件(严格地是翻译单元)中使用该名称来引用同一对象。

j具有外部链接,因此j如果extern在另一个翻译单元中声明该对象,则可以使用它来引用该对象。


2
如果您执行相同的操作,则运行时不应存在差异,因为编译器可能会生成相同的代码。但是,对于全局变量,编译范围可能会稍长一些,因为它的范围更广。
弗洛里安·卡斯泰拉内

25

i在模块外部不可见;j可全局访问。

也就是说,链接到它的另一个模块可以执行

然后能够读取和写入中的值j。另一个模块无法访问i,但可以声明它自己的实例,甚至是全局实例,第一个模块不可见。


1
“外部”声明是否必要?
Thomas Matthews'2

1
这取决于实现方式。的用途extern是保证不造成麻烦,提供一个模块具有符号作为非extern和公共(分配了它)。早期的Unix实现将具有相同名称的符号合并在一起(很像Fortran通用名称),因此extern不需要。
wallyk'2

1
请注意,“不可见”并不表示其超出范围。这意味着,如果您要在其他编译单元中声明i,并从.c文件中删除静态i,则全局i将对您的.c文件可见。相反,如果全局i不在范围内,则在.c文件中声明了静态i都无关紧要。全球范围将永远不可见。优先于在另一个编译单元中定义的全局i的静态i被称为“ shadowing”。它也发生在函数locals中,而不是仅用于c ++ / c的东西。
木星

6

区别在于i具有内部链接和j具有外部链接。这意味着您可以j从与之链接的其他文件进行访问,而i仅在声明该文件的文件中可用。


4

i将具有静态链接,即该变量只能在当前文件中访问。

j应该定义为extern,即

在另一个头文件(.h)中,它将具有外部链接,并且可以跨文件进行访问。


2

尽管您将文件包含为不同源文件的一部分,但静态变量/函数的作用域在同一文件内。

全局变量的范围是包含它的所有文件的范围。为了将变量包含在其他源文件中,我们extern在变量声明之前使用。在这种情况下,不会再为该变量分配内存。

extern用于声明C变量而不定义它。extern关键字扩展了C变量和C函数的可见性。由于默认情况下函数在整个程序中都是可见的,extern因此在函数声明/定义中不需要使用。它的使用是多余的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.