本地变量,全局变量,静态变量区别分析

c/c++

浏览数:191

2019-3-29

AD:资源代下载服务

1.定义在函数内部的变量就是本地变量

函数的每次运行,就产生了一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的,称作:本地变量

  • 本地变量=局部变量=自动变量(之所以这么叫是因为:它的生存期是自动的)。
  • 写在函数表里的参数也是本地变量。
  • 生存期:什么时候这个变量开始出现了,到什么时候它消亡了。
  • 作用域:在(代码的)什么范围内可以访问这个变量(这个变量可以起作用)。
  • 对于本地变量,这两个问题的答案是统一的:大括号内—我们把大括号称作’块’。

本地变量使用规则:

 1.它是定义在块内的(包括函数块,语句块,甚至随便拉一对大括号来定义变量) 
 2.程序运行进入这个块之前,其中的变量不存在,离开这个块,其中的变量就消失了 
 3.块外面定义的变量在里面依然有效,块里面定义的变量在外面无效
 4.块里面定义了和外面同名的变量则掩盖了外面的
 5.不能在一个块内定义同名的变量
 6.本地变量不会被默认初始化

2.定义在函数外面的变量是全局变量

  • 全局变量具有全局的生存期和作用域: 1.它们与任何函数都无关。
    2.在任何函数内部都可以使用它们。

全局变量使用规则:

  1.没有做初始化的全局变量会得到0值---指针会得到NULL值 
  2.只能用编译时刻已知的值来初始化全局变量---不能用其他全局变量来对全局变量赋值 
      (程序严格按照顺序执行)                         
  3.它们的初始化发生在main函数之前        
  4.如果函数内部存在与全局变量同名的变量,则全局变量被隐藏
    C语言总是以最小的地方定义的变量为主,隐藏其他的外部变量---里面覆盖外面

如何在多个.c源程序中使用全局变量?(同一项目共享一个全局变量)

全局变量的声明—使用:extern int all;
如此便告诉了编译器在整个项目的某个地方有个叫all的东西

注意:在使用extern对全局变量声明时不能对全局变量初始化,因为初始化是定义的事情

3.静态本地变量(阉割的全局变量)

static+本地变量=静态本地变量 当函数离开的时候,静态本地变量会继续存在并保持其值

静态本地变量的初始化只会在第一次进入这个函数时做,以后进入函数时会保持上次离开时的值

静态本地变量实际上是特殊的全局变量,它们位于相同的内存区域 静态本地变量具有全局的生存期,函数内的局部作用域

static在这里的意思是局部作用域(本地可访问)

返回指针的函数注意点

1.返回本地变量的地址是危险的

2.返回全局变量或静态本地变量的地址是安全的

3.返回在函数内malloc的内存是安全的,但是容易造成问题

4.最好的做法是返回传入的指针

 #include<stdio.h> 
 int f(void);
 int g(void);
 int t(void);
 int gall;  
int main(int argc,char const *argv[])
{    
   printf("in %s gall=%d\n",__func__,gall);
   f();
   printf("again in %s gall=%d\n",__func__,gall);
   g();
   g();
   t();
   return 0;
}
//__func__是预置在编译器中的宏,并不包含于任何头文件,所以直接调用即可。
//注意__和_ 
//__func__是一个字符串,值为调用__func__函数的函数名。 
int f(void)//测试全局变量gall 
{    
     printf("in %s gall=%d\n",__func__,gall);
     gall+=2;
     printf("again in %s gall=%d\n",__func__,gall);
}
int g(void)//测试静态本地变量all 
{    static int all=1;  
     printf("all=%d\n",all);
     all+=2;
}
int t(void)//探索静态本地变量的本质 
{    static int sall=0; 
            int tall=0;
     printf("&全局变量=%p\n",&gall);//输出全局变量的地址
     printf("&静态本地变量=%p\n",&sall);//输出静态本地变量的地址 
     printf("&本地变量=%p\n",&tall);//输出本地变量的地址 
}