静态全局和本地标识符的阴影

以下程序是在课堂上给出的练习工作表上。 我们被要求提供它的输出,但是根据我对链接的理解,file2.c不应该有静态标识符b的两个实例,但程序编译时会发出警告并且运行正常。 我的问题是,为什么允许这样做? 我认为静态链接的目的是能够访问该文件中的所有标识符?

澄清:问题是关于file2.c:有两个“static int b”声明。 为什么允许这样做?

/ * file1.c * /

#include  extern int a; static int b; void f(int); void g(void); int main() { a = 10; b = 20; f(a); f(b); g(); printf("main: %d %d\n", a, b); return 0; } 

/ * file2.c * /

 include  int a; static int b; void f(int c) { static int b = 5; a += b; b += c; printf("f: %d %d\n", a , b ) ; } void g(void) { a += 5; b = 10; printf("g: %d %d\n", a , b); } 

提前感谢您的帮助(这是我的第一次发帖,所以如果有格式错误,我道歉!)。

编译器为每个全局静态变量创建一个不同的实例,即使您有多个具有相同名称的变量也是如此。

实际上,编译器(或可能是预处理器)根据声明它的源文件的名称隐式地更改每个这样的变量的名称。

您可以通过在头文件中声明全局静态变量来certificate这一点,然后将此头文件包含在几个不同的源文件中。 尝试在每个源文件中将其设置为不同的值,您将看到此变量在每个源文件中保留其不同的值。

如果要在多个源文件中访问相同的全局变量实例 ,则应避免将其声明为static

  • 如果在头文件中声明它,则使用extern作为前缀,并在每个使用此变量的源文件中包含头文件。
  • 如果在源文件中声明它,则必须在使用此变量的每个其他源文件中将其声明为extern

外部全局变量的地址仅在链接期间确定。 这与以下情况形成对比,其中在编译期间确定变量的地址:

  • 一个局部变量
  • 一个静态局部变量
  • 静态全局变量
  • 非外部全局变量

我认为术语static linkage是指编译对象(或库) 在构建过程中与可执行映像 dynamic linkage ,而不是dynamic linkage ,它指的是已编译代码(也称为DLL)与可执行映像的链接仅在运行时


更新:

在阅读了您的澄清之后,我理解唯一的问题是局部变量和同名的全局变量( static属性对此问题没有任何影响)。

在函数内部,对于具有相同名称的全局变量,局部变量始终是“编译器首选”。 换句话说,在函数f ,变量b上的所有运算都应用于局部变量而不是全局变量。