c - 隐藏静态全局和局部标识符

标签 c

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

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

/* 文件1.c */

#include <stdio.h> 

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; 
} 

/* 文件2.c */

include <stdio.h> 

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); 

} 

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

最佳答案

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

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

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

如果您希望在多个源文件中访问全局变量的相同实例,那么您应该避免将其声明为static :

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

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

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

我相信术语静态链接是指在构建过程中将已编译对象(或库)链接到可执行镜像中,而不是动态链接,是指仅在运行时将已编译代码(也称为 DLL)链接到可执行镜像。


更新:

阅读您的说明后,我了解到唯一的问题是局部变量和同名全局变量(static 属性对这个问题没有影响)。

在函数内部,局部变量总是比同名的全局变量“更受编译器青睐”。换句话说,在函数 f 中,对变量 b 的所有操作都应用于局部变量而不是全局变量。

关于c - 隐藏静态全局和局部标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22120362/

相关文章:

c - 在链表中查找或创建元素,而不丢失头

c - 理解内存中的结构

c - LUA 在没有的地方显示错误

c++ - 警告 : deprecated conversion from string constant to 'char*' '

c++ - `pow` 不返回 (IEEE) 非规范化 float ?

c - C中的泛型编程

c - 尝试使用 MPI_Recv 接收 vector

c - 外部并行循环中的内部顺序循环 - OMP

c - 何时将数组名或函数名“转换”为指针? (在C中)

检查字符而不是整数