首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >变量的声明与全局、局部和静态变量同名

变量的声明与全局、局部和静态变量同名
EN

Stack Overflow用户
提问于 2014-01-17 18:33:52
回答 5查看 8.1K关注 0票数 3

我有以下代码片段,我必须分析输出是什么:

代码语言:javascript
复制
#include <stdio.h>

  void f(int d);

  int a = 1, b = 2, c = 3, d = 4;

  int main(){
    int a = 5, c = 6;
    f(a);
    f(b);
    f(c);
    printf("%d %d %d %d\n",a,b,c,d);
    return 0;
  }

  void f(int d){
    static int a = 0;
    a = a + 7;
    b = a + d;
    c++;
    d--;
    printf("%d %d %d %d\n",a,b,c,d);
  }

我得到的输出如下:

代码语言:javascript
复制
7 12 4 4  
15 26 5 11  
21 27 6 5  
5 27 6 4  

这真的把我搞糊涂了。我注意到,在所有3个函数调用中,全局声明的a都经历了赋值,并且在来自main()主体的printf()中,打印了在main()中声明的a。然而,我不确定其余变量的行为。这是未定义的行为,还是它实际上是有意义的?

EN

回答 5

Stack Overflow用户

发布于 2014-01-17 18:37:38

int a = 1, b = 2, c = 3, d = 4; ->全局变量

代码语言:javascript
复制
int main(){
    int a = 5, c = 6;         ---> Shadows the global `a` and `c`

……

代码语言:javascript
复制
void f(int d){
    static int a = 0;         ---> local static variable visible only inside `f`

..。

票数 3
EN

Stack Overflow用户

发布于 2014-01-17 18:45:57

这与C的标识符作用域有关。声明的作用域是C程序中该声明可见的区域。有六个作用域:

宏顶级标识符:从声明点扩展到源程序文件的末尾函数定义中的宏形式参数:扩展到函数体中的宏形式参数()标识符(

  • )标识符:扩展到block
  • Statement labels
  • Preprocessor

的末尾

在程序中发生的情况称为名称重载-在这种情况下,同一标识符可能同时与多个程序实体相关联。在C中有5个重载类(也称为命名空间):

  • Preprocessor宏names
  • Statement labels
  • Structure,联合和枚举tags
  • Component names
  • 其他名称

在C中,块开头的声明可以隐藏块外的声明。要使一个声明隐藏另一个声明,声明的标识符必须相同,必须属于同一重载类,并且必须在两个不同的作用域中声明,其中一个作用域包含另一个。

考虑到这一点,在您的代码中,本地acmain()中隐藏全局ac,而f()中的a隐藏全局a。所有其他引用都在操纵全局变量。

票数 2
EN

Stack Overflow用户

发布于 2014-01-17 18:45:18

代码语言:javascript
复制
 void f(int d){
     **static int a = 0;**
     a = a + 7;
     b = a + d;
     c++;
     d--;
     printf("%d %d %d %d\n",a,b,c,d);
   }

没错,你声明了全局函数int a和全局空函数f,但是你也声明了静态变量,当函数被调用时,引用了函数的变量。如果你想避免这个问题,你应该创建一个全局变量的指针,并引用一个指向地址的值全局变量。正如你所知道的,静态变量将保持它们的最后一个值,直到程序结束。

除非由malloc分配,否则每个函数的变量都会准确地放在"Stack“中。全局变量为"Heap“。我不确定,但是如果你反汇编你的程序,静态值a会进入堆栈,并用PUSH和pop指令处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21183675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档