C的日记-变量的作用域、生存期和内存位置

“天地玄黄,宇宙洪荒”,先有天地,之后方有古今。
变量同是,先有变量的作用域(存在的地点),然后出现了变量的生存期(存在的时间)。

【变量存储的方式】
首先变量实际上是存放到两个区域的:

  • 静态存储区:是指在程序运行区间由系统分配固定的存储空间的方式。
  • 动态存储区:程序运行期间根据需要动态的分配存储空间。

【变量分类】

  1. 局部变量:在[函数]内部声明的变量。

    【作用域】:从定义变量的位置到本函数结束。

      <1>自动变量(auto变量),即动态局部变量,不专门声明为static的变量。
                 分类:<11>函数形参;
                            <12>函数中定义的变量;
                            <13>函数调用的现场保护和返回地址;
                 存放位置:动态存储区;
                 【生存期】:调用函数时,赋初值生存,结束调用死亡。
            <2>静态局部变量(static局部变量),通过static声明;
                  存放位置:静态存储区;
                 【生存期】:调用函数时,赋初值生存,结束调用继续存在
                 【缺点】:长期占用不释放,多占内存,不建议多使用。
            <3>寄存器变量(register变量),通过register声明;
                  存放位置:寄存器(寄存器的访问速度超过内存访问速度);
                 【生存期】:同静态局部变量,较少见。

  2. 全局变量(外部变量):在[函数]之外定义的变量。
        【生存期】:存在于程序的整个运行中。
        【作用域】:从定义变量的位置到本函数结束。
        【作用域扩展】
         <1>在定义变量之前可以访问,在声明变量之前如果想要对该变量进行操作,可以使用extern,如:
               extern int a;
               a++;
               int a;        //这个定义必须是外部变量定义
         <2>在其他文件中可以访问,在其他文件中使用本文件的变量时必须加上extern。
           在遇到extern时,编译器先从本文件中查找是否有外部变量的定义,如果没有再从其他文件中查找外部变量的定义。
         <3>将外部变量作用域限制在本文件中(默认的外部变量定义后在其他文件中都是可查的),现在我们不想在其他文件中可以访问本文件的变量,可以在变量前声明static,这样作用域就限制在本文件中了。

        [在main函数中定义变量是局部还是全局的]
        是局部变量,任何函数内部的变量都是局部的。

【内存中的堆和栈】

  • .[内存分区]
        <1>栈区:处于相对较高的地址以地址的增长方向为上的话,栈地址是向下增长的。栈中分配[自动变量]
        <2>堆区:是向上增长的用于分配程序员申请的内存空间;
        <3>静态区:是分配[静态局部变量][全局变量]空间的;
        <4>文字常量区:常量字符串就是放在这里的,程序结束后由系统释放。
        <5>程序代码区:存放[函数体]的二进制代码。

        // 来看一个网上很流行的经典例子:main.c
        int a = 0; 全局初始化区
        char *p1; 全局未初始化区
        main(){
            int b; 栈
            char s[] = "abc"; 栈
            char *p2; 栈
            char *p3 = "123456"; 123456\0在常量区,p3在栈上。
            static int c =0; 全局(静态)初始化区
            p1 = (char *)malloc(10);  堆
            p2 = (char *)malloc(20);  堆
        }
  • [注释]:
        <1>堆是由用户来分配的,用malloc,calloc函数申请,相应的用free来释放,或者用realloc重分配。
            注:malloc/calloc/realloc函数的基类型(返回的指针所指的类型)都是void(不确定的)类型,在使用的时候必须类型转换为需要的基类型。内存的动态分配主要用于建立程序中的动态数据结构,如链表。
        <2>栈是系统自动分配的,子程序调用时,返回地址压入栈,退出时从栈顶取返回地址。如果在子程序中定义局部变量,这些变量就分配在栈上,用来了,子程序退出的时候退栈,局部变量就失效。

            void sub()
            {
              int a[100];     // 局部变量,分配在栈上,退出子程序自动释放。
              int *p = (int *)malloc( 100 );     // 分配在堆上,需要用free释放。
            }

【变量的声明和定义的关系】
把建立存储空间的声明成为定义(int a=4;),把未建立存储空间的声明成为声明(extern int a;);

【内部函数和外部函数】
函数本质上是外部的,可以被外部的其他函数和外部文件夹中的文件所访问。

    • 内部函数
          我们不希望函数被外部文件夹的文件访问,所以我们我们使用static修饰当前函数。就只能在本文件中访问。
    • 外部函数
          函数在外部文件访问是有条件的,即在定义该函数的时候在前面加上extern,这样我们可以在本文件所在文件夹下的其他函数中对该函数进行具体的实现,include就是采用这种方法,导入一个大类库,我们可以调用类库中的函数.
时间: 2024-10-14 05:11:49

C的日记-变量的作用域、生存期和内存位置的相关文章

javascript学习日记之变量的作用域

``` 很显然第一个弹出框并没有如我所想弹出的global而是undefined 这是为什么呢? 其实由于函数作用域特性 函数域始终优于全局域 同名的局部变量会覆盖掉全局变量 而第一次调用alert的时候scope还没正式定义 所以为undefined 以上代码可以理解为: ``` function f(){ var scope; alert(scope); var scope ="local"; alert(scope); }; f(); //等价与函数内变量的声明'提前'至函数体顶

php变量的作用域和生存期

要修改一个php的系统,才发现php变量的作用域和生存期是很不同的,特此记录已被查阅: PHP脚本中变量主要有:内置超级全局变量,一般的变量,常量,全局变量,静态变量等等: 1.内置超级全局变量可以在脚本的任何地方使用和可见.即是说,如果我们在一个PHP页面中改变了其中的一个值,那么在其他PHP页面中使用时,它的值也会发生改变. 超级全局变量的完整列表如下:1.$GOBALS 所有全局变量数组2.$_SERVER 服务器环境变量数组3.$_POST 通过POST方法传递给该脚本的变量数组4.$_

c++变量的作用域、生存期和可见性

局部变量 范围:在一个函数内部定义的变量,作用范围只限于本函数体内. 生存期:程序执行到本函数才会给局部变量分配内存单元,函数执行完毕局部变量所占的存储单元就被释放 全局变量 在函数体外部定义的变量是全局变量,可以被本文件所有其他函数访问使用. 作用域:所有文件.在一个cpp定义的全局变量在另一个cpp中使用,应该在使用它的函数体内部或外部进行extern说明 生存期:全局变量在程序的全部执行过程中占用固定的内存单元,生存周期是整个程序运行期间. 实验代码 /* * 变量的作用域.生存期和可见性

JVM中各内存区域解释,以及变量的作用域解释

转载自:http://blog.csdn.net/zz87250976/article/details/42875301 JVM内存分四种:1.栈区(stacksegment)—由编译器自动分配释放,存放函数的参数值,局部变量的值等,具体方法执行结束之后,系统自动释放JVM内存资源:2.堆区(heapsegment)—一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收:3.静态区(datasegment)—存放全局变量,静态变量和字符串常

C语言入门(十四)变量的作用域和存储类型

变量的作用域和存储类型 一.作用域和生存期 C程序的标识符作用域有三种:局部.全局.文件.标识符的作用域决定了程序中的哪些语句可以使用它,换句话说,就是标识符在程序其他部分的可见性.通常,标识符的作用域都是通过它在程序中的位置隐式说明的. 1.局部作用域 前面各个例子中的变量都是局部作用域,他们都是声明在函数内部,无法被其他函数的代码所访问.函数的形式参数的作用域也是局部的,它们的作用范围仅限于函数内部所用的语句块. void add(int); main() { int num=5; add(

C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期

全局变量 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件.) 生命周期:程序运行期一直存在 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量. 内存分布:全局数据区 注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义 全局静态变量 作用域:文件作用域(只在被定义的文件中可见.) 生命周期:程序运行期一直存在 内存分布:全局数据区 定义方法:static关键字,const 关键字 注意:只要文件不互相包含,在两个不同的文件中

C/C++中变量的作用域和存储类型简介

写在开头 对于很多C/C++的初学者来说,很容易理不清变量的作用域和存储类型这一块的一些概念,也容易将其中的一些概念搞混淆.作为一个C/C++的初学者,笔者希望在这里能够尝试着去理一理这些较为繁杂的概念,主要当作自己备忘之用.当然,由于笔者水平有限,经验不足,在这里也只能罗列一些常用概念和使用方法,且可能会有些许不专业之处,望君理解并指正. 一定要把变量的作用域和存储类型分开来看 很多人很容易把变量的作用于和存储类型搞混,但其实只要我们从它们定义出发来看,这个问题是很容易解决的.作用域是一个变量

第四章—变量,作用域和内存问题(二)

第四章-变量,作用域和内存问题(二) JS没有块级作用域 js没有块级作用域,这个概念容易导致误解,这里就区分下几个情况,大家好好参考下: 我们知道,在其他类C的语言中,由花挂号封闭的代码块都有自己的作用域.但是在JS中,却没有块级作用域: 这里if(true){}代表条件永真,永远执行这条.if(false){}的话就是永远不执行这条. 这个代码执行之后,在if语句定义的变量,在if语句外可以访问的到.在if语句中的变量声明会将变量添加到当前的执行环境中(这里是全局环境). 还有如下的两个例子

Js中变量的作用域

一.理解函数作用域需要理解以下几点:    1.函数变量的作用域有全局变量和局部变量两种,全局变量写在函数的最前面,局部变量写在函数体内,局部变量省略了var 也就默认成为了全局变量!    2.函数体内部可以读取到函数外的变量,而函数外不能读取到函数内的变量! 在理解了函数变量的作用域之后,也需要理解函数的作用域链了:    1.每一个函数都有一个与之相关的作用域链,当js在查找变量X时,它会从链的第一个对象开始查找,如果这个对象有一个名为X的属性值,则会直接使用这个 属性值,如果没有就继续下